mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2024-12-22 16:26:28 +00:00
enforce limits
This commit is contained in:
parent
d112eba8fe
commit
36fa451249
@ -4,15 +4,15 @@ lazy_static! {
|
|||||||
pub static ref VERSION: String = option_env!("CARGO_PKG_VERSION")
|
pub static ref VERSION: String = option_env!("CARGO_PKG_VERSION")
|
||||||
.unwrap_or("Unknown")
|
.unwrap_or("Unknown")
|
||||||
.to_string();
|
.to_string();
|
||||||
pub static ref LIMIT: usize =
|
pub static ref LIMIT: u32 =
|
||||||
Byte::from_str(std::env::var("SIZE_LIMIT").unwrap_or("1 KiB".to_string()))
|
Byte::from_str(std::env::var("SIZE_LIMIT").unwrap_or("1 KiB".to_string()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get_bytes() as usize;
|
.get_bytes() as u32;
|
||||||
pub static ref MAX_VIEWS: usize = std::env::var("MAX_VIEWS")
|
pub static ref MAX_VIEWS: u32 = std::env::var("MAX_VIEWS")
|
||||||
.unwrap_or("100".to_string())
|
.unwrap_or("100".to_string())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
pub static ref MAX_EXPIRATION: usize = std::env::var("MAX_EXPIRATION")
|
pub static ref MAX_EXPIRATION: u32 = std::env::var("MAX_EXPIRATION")
|
||||||
.unwrap_or("360".to_string()) // 6 hours in minutes
|
.unwrap_or("360".to_string()) // 6 hours in minutes
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
pub struct Note {
|
pub struct Note {
|
||||||
pub meta: String,
|
pub meta: String,
|
||||||
pub contents: String,
|
pub contents: String,
|
||||||
pub views: Option<u8>,
|
pub views: Option<u32>,
|
||||||
pub expiration: Option<u32>,
|
pub expiration: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ use actix_web::{delete, get, post, web, HttpResponse, Responder, Scope};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
use crate::config;
|
||||||
use crate::note::{generate_id, Note, NoteInfo, NotePublic};
|
use crate::note::{generate_id, Note, NoteInfo, NotePublic};
|
||||||
use crate::store;
|
use crate::store;
|
||||||
|
|
||||||
@ -40,17 +41,22 @@ async fn create(note: web::Json<Note>) -> impl Responder {
|
|||||||
if n.views == None && n.expiration == None {
|
if n.views == None && n.expiration == None {
|
||||||
return bad_req;
|
return bad_req;
|
||||||
}
|
}
|
||||||
|
if !*config::ALLOW_ADVANCED {
|
||||||
|
n.views = Some(1);
|
||||||
|
n.expiration = None;
|
||||||
|
}
|
||||||
match n.views {
|
match n.views {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
if v > 100 {
|
if v > *config::MAX_VIEWS {
|
||||||
return bad_req;
|
return bad_req;
|
||||||
}
|
}
|
||||||
|
n.expiration = None; // views overrides expiration
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
match n.expiration {
|
match n.expiration {
|
||||||
Some(e) => {
|
Some(e) => {
|
||||||
if e > 360 {
|
if e > *config::MAX_EXPIRATION {
|
||||||
return bad_req;
|
return bad_req;
|
||||||
}
|
}
|
||||||
let expiration = now() + (e * 60);
|
let expiration = now() + (e * 60);
|
||||||
|
@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Status {
|
pub struct Status {
|
||||||
pub version: String,
|
pub version: String,
|
||||||
pub max_size: usize,
|
pub max_size: u32,
|
||||||
pub max_views: usize,
|
pub max_views: u32,
|
||||||
pub max_expiration: usize,
|
pub max_expiration: u32,
|
||||||
pub allow_advanced: bool,
|
pub allow_advanced: bool,
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
"new_note_notice": "<b>Verfügbarkeit:</b><br />es ist nicht garantiert, dass die Notiz gespeichert wird, da alles im Speicher gehalten wird. Wenn dieser voll ist, werden die ältesten Notizen entfernt.<br />(Sie werden wahrscheinlich keine Probleme haben, seien Sie nur gewarnt).",
|
"new_note_notice": "<b>Verfügbarkeit:</b><br />es ist nicht garantiert, dass die Notiz gespeichert wird, da alles im Speicher gehalten wird. Wenn dieser voll ist, werden die ältesten Notizen entfernt.<br />(Sie werden wahrscheinlich keine Probleme haben, seien Sie nur gewarnt).",
|
||||||
"errors": {
|
"errors": {
|
||||||
"note_to_big": "Notiz konnte nicht erstellt werden. Notiz ist zu groß",
|
"note_to_big": "Notiz konnte nicht erstellt werden. Notiz ist zu groß",
|
||||||
"note_error": "konnte keine Notiz erstellen. Bitte versuchen Sie es erneut."
|
"note_error": "konnte keine Notiz erstellen. Bitte versuchen Sie es erneut.",
|
||||||
|
"max": "max: {n}"
|
||||||
},
|
},
|
||||||
"copied_to_clipboard": "in die Zwischenablage kopiert 🔗"
|
"copied_to_clipboard": "in die Zwischenablage kopiert 🔗"
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
"new_note_notice": "<b>availability:</b><br />the note is not guaranteed to be stored as everything is kept in ram, if it fills up the oldest notes will be removed.<br />(you probably will be fine, just be warned.)",
|
"new_note_notice": "<b>availability:</b><br />the note is not guaranteed to be stored as everything is kept in ram, if it fills up the oldest notes will be removed.<br />(you probably will be fine, just be warned.)",
|
||||||
"errors": {
|
"errors": {
|
||||||
"note_to_big": "could not create note. note is to big",
|
"note_to_big": "could not create note. note is to big",
|
||||||
"note_error": "could not create note. please try again."
|
"note_error": "could not create note. please try again.",
|
||||||
|
"max": "max: {n}"
|
||||||
},
|
},
|
||||||
"copied_to_clipboard": "copied to clipboard 🔗"
|
"copied_to_clipboard": "copied to clipboard 🔗"
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
"new_note_notice": "<b>disponibilidad:</b><br />no se garantiza que la nota se almacene, ya que todo se guarda en la memoria RAM, si se llena se eliminarán las notas más antiguas.<br />(probablemente estará bien, sólo está advertido.)",
|
"new_note_notice": "<b>disponibilidad:</b><br />no se garantiza que la nota se almacene, ya que todo se guarda en la memoria RAM, si se llena se eliminarán las notas más antiguas.<br />(probablemente estará bien, sólo está advertido.)",
|
||||||
"errors": {
|
"errors": {
|
||||||
"note_to_big": "no se pudo crear la nota. la nota es demasiado grande",
|
"note_to_big": "no se pudo crear la nota. la nota es demasiado grande",
|
||||||
"note_error": "No se ha podido crear la nota. Por favor, inténtelo de nuevo."
|
"note_error": "No se ha podido crear la nota. Por favor, inténtelo de nuevo.",
|
||||||
|
"max": "max: {n}"
|
||||||
},
|
},
|
||||||
"copied_to_clipboard": "copiado al portapapeles 🔗"
|
"copied_to_clipboard": "copiado al portapapeles 🔗"
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
"new_note_notice": "<b>disponibilité :</b><br />la note n'est pas garantie d'être stockée car tout est conservé dans la mémoire vive, si elle se remplit les notes les plus anciennes seront supprimées.<br />(vous serez probablement bien, soyez juste averti.)",
|
"new_note_notice": "<b>disponibilité :</b><br />la note n'est pas garantie d'être stockée car tout est conservé dans la mémoire vive, si elle se remplit les notes les plus anciennes seront supprimées.<br />(vous serez probablement bien, soyez juste averti.)",
|
||||||
"errors": {
|
"errors": {
|
||||||
"note_to_big": "Impossible de créer une note. La note est trop grande",
|
"note_to_big": "Impossible de créer une note. La note est trop grande",
|
||||||
"note_error": "n'a pas pu créer de note. Veuillez réessayer."
|
"note_error": "n'a pas pu créer de note. Veuillez réessayer.",
|
||||||
|
"max": "max: {n}"
|
||||||
},
|
},
|
||||||
"copied_to_clipboard": "copié dans le presse-papiers 🔗"
|
"copied_to_clipboard": "copié dans le presse-papiers 🔗"
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
"new_note_notice": "<b>disponibilità:</b><br />la nota non è garantita per essere memorizzata come tutto è tenuto in ram, se si riempie le note più vecchie saranno rimosse.<br />(probabilmente andrà bene, basta essere avvertiti).",
|
"new_note_notice": "<b>disponibilità:</b><br />la nota non è garantita per essere memorizzata come tutto è tenuto in ram, se si riempie le note più vecchie saranno rimosse.<br />(probabilmente andrà bene, basta essere avvertiti).",
|
||||||
"errors": {
|
"errors": {
|
||||||
"note_to_big": "impossibile creare una nota. la nota è troppo grande",
|
"note_to_big": "impossibile creare una nota. la nota è troppo grande",
|
||||||
"note_error": "Impossibile creare la nota. Riprova."
|
"note_error": "Impossibile creare la nota. Riprova.",
|
||||||
|
"max": "max: {n}"
|
||||||
},
|
},
|
||||||
"copied_to_clipboard": "copiato negli appunti 🔗"
|
"copied_to_clipboard": "copiato negli appunti 🔗"
|
||||||
},
|
},
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
height: 2rem;
|
height: 2rem;
|
||||||
width: 1.25rem;
|
width: 1.25rem;
|
||||||
left: 0.125rem;
|
left: 0.125rem;
|
||||||
bottom: 0.1rem;
|
bottom: 0.125rem;
|
||||||
background-color: var(--ui-bg-1);
|
background-color: var(--ui-bg-1);
|
||||||
-webkit-transition: 0.4s;
|
-webkit-transition: 0.4s;
|
||||||
transition: var(--ui-anim);
|
transition: var(--ui-anim);
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getRandomBytes, Hex } from '$lib/crypto'
|
import { getRandomBytes, Hex } from '$lib/crypto'
|
||||||
|
|
||||||
import { fade } from 'svelte/transition'
|
|
||||||
import { t } from 'svelte-intl-precompile'
|
|
||||||
import copyToClipboard from 'copy-to-clipboard'
|
import copyToClipboard from 'copy-to-clipboard'
|
||||||
|
import { t } from 'svelte-intl-precompile'
|
||||||
|
import { fade } from 'svelte/transition'
|
||||||
import Icon from './Icon.svelte'
|
import Icon from './Icon.svelte'
|
||||||
|
|
||||||
export let label: string = ''
|
export let label: string = ''
|
||||||
export let value: any
|
export let value: any
|
||||||
|
export let validate: (value: any) => boolean | string = () => true
|
||||||
export let copy: boolean = false
|
export let copy: boolean = false
|
||||||
export let random: boolean = false
|
export let random: boolean = false
|
||||||
|
|
||||||
@ -19,6 +17,8 @@
|
|||||||
let notification: string | null = null
|
let notification: string | null = null
|
||||||
let notificationTimeout: NodeJS.Timeout | null = null
|
let notificationTimeout: NodeJS.Timeout | null = null
|
||||||
|
|
||||||
|
$: valid = validate(value)
|
||||||
|
|
||||||
$: if (isPassword) {
|
$: if (isPassword) {
|
||||||
value
|
value
|
||||||
$$restProps.type = hidden ? initialType : 'text'
|
$$restProps.type = hidden ? initialType : 'text'
|
||||||
@ -49,8 +49,11 @@
|
|||||||
<label>
|
<label>
|
||||||
<small disabled={$$restProps.disabled}>
|
<small disabled={$$restProps.disabled}>
|
||||||
{label}
|
{label}
|
||||||
|
{#if valid !== true}
|
||||||
|
<span class="error-text">{valid}</span>
|
||||||
|
{/if}
|
||||||
</small>
|
</small>
|
||||||
<input bind:value {...$$restProps} />
|
<input bind:value {...$$restProps} class:valid={valid === true} />
|
||||||
<div class="icons">
|
<div class="icons">
|
||||||
{#if isPassword}
|
{#if isPassword}
|
||||||
<Icon class="icon" icon={hidden ? 'eye' : 'eye-off'} on:click={toggle} />
|
<Icon class="icon" icon={hidden ? 'eye' : 'eye-off'} on:click={toggle} />
|
||||||
@ -73,6 +76,10 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label > small {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -86,6 +93,10 @@
|
|||||||
border-color: var(--ui-clr-primary);
|
border-color: var(--ui-clr-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input:not(.valid) {
|
||||||
|
border-color: var(--ui-clr-error);
|
||||||
|
}
|
||||||
|
|
||||||
.icons {
|
.icons {
|
||||||
border: 1px red;
|
border: 1px red;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { create, Note, PayloadToLargeError } from '$lib/api'
|
import { create, Note, PayloadToLargeError } from '$lib/api'
|
||||||
import { encrypt, getKeyFromString, getRandomBytes, Hex } from '$lib/crypto'
|
import { encrypt, getKeyFromString, getRandomBytes, Hex } from '$lib/crypto'
|
||||||
|
import { status } from '$lib/stores/status'
|
||||||
import Button from '$lib/ui/Button.svelte'
|
import Button from '$lib/ui/Button.svelte'
|
||||||
import FileUpload from '$lib/ui/FileUpload.svelte'
|
import FileUpload from '$lib/ui/FileUpload.svelte'
|
||||||
import MaxSize from '$lib/ui/MaxSize.svelte'
|
import MaxSize from '$lib/ui/MaxSize.svelte'
|
||||||
import Switch from '$lib/ui/Switch.svelte'
|
import Switch from '$lib/ui/Switch.svelte'
|
||||||
import TextArea from '$lib/ui/TextArea.svelte'
|
import TextArea from '$lib/ui/TextArea.svelte'
|
||||||
import TextInput from '$lib/ui/TextInput.svelte'
|
import TextInput from '$lib/ui/TextInput.svelte'
|
||||||
import { blur } from 'svelte/transition'
|
|
||||||
import { t } from 'svelte-intl-precompile'
|
import { t } from 'svelte-intl-precompile'
|
||||||
|
import { blur } from 'svelte/transition'
|
||||||
|
|
||||||
let note: Note = {
|
let note: Note = {
|
||||||
contents: '',
|
contents: '',
|
||||||
@ -107,7 +108,9 @@
|
|||||||
|
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<Switch class="file" label={$t('common.file')} bind:value={file} />
|
<Switch class="file" label={$t('common.file')} bind:value={file} />
|
||||||
<Switch label={$t('common.advanced')} bind:value={advanced} />
|
{#if $status?.allow_advanced}
|
||||||
|
<Switch label={$t('common.advanced')} bind:value={advanced} />
|
||||||
|
{/if}
|
||||||
<div class="grow" />
|
<div class="grow" />
|
||||||
<div class="tr">
|
<div class="tr">
|
||||||
<small>{$t('common.max')}: <MaxSize /> </small>
|
<small>{$t('common.max')}: <MaxSize /> </small>
|
||||||
@ -138,7 +141,10 @@
|
|||||||
label={$t('common.views', { values: { n: 0 } })}
|
label={$t('common.views', { values: { n: 0 } })}
|
||||||
bind:value={note.views}
|
bind:value={note.views}
|
||||||
disabled={timeExpiration}
|
disabled={timeExpiration}
|
||||||
max={100}
|
max={$status?.max_views}
|
||||||
|
validate={(v) =>
|
||||||
|
($status && v < $status?.max_views) ||
|
||||||
|
$t('home.errors.max', { values: { n: $status?.max_views ?? 0 } })}
|
||||||
/>
|
/>
|
||||||
<div class="middle-switch">
|
<div class="middle-switch">
|
||||||
<Switch label={$t('common.mode')} bind:value={timeExpiration} color={false} />
|
<Switch label={$t('common.mode')} bind:value={timeExpiration} color={false} />
|
||||||
@ -148,7 +154,10 @@
|
|||||||
label={$t('common.minutes', { values: { n: 0 } })}
|
label={$t('common.minutes', { values: { n: 0 } })}
|
||||||
bind:value={note.expiration}
|
bind:value={note.expiration}
|
||||||
disabled={!timeExpiration}
|
disabled={!timeExpiration}
|
||||||
max={360}
|
max={$status?.max_expiration}
|
||||||
|
validate={(v) =>
|
||||||
|
($status && v < $status?.max_expiration) ||
|
||||||
|
$t('home.errors.max', { values: { n: $status?.max_expiration ?? 0 } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user