mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2024-12-22 08:16:28 +00:00
always encrypt content
This commit is contained in:
parent
dc212d7441
commit
7a3397f978
@ -5,11 +5,10 @@ const base = axios.create({ baseURL: dev ? 'http://localhost:5000' : undefined }
|
||||
|
||||
export type Note = {
|
||||
contents: string
|
||||
password: boolean
|
||||
views?: number
|
||||
expiration?: number
|
||||
}
|
||||
export type NoteInfo = Pick<Note, 'password'>
|
||||
export type NoteInfo = {}
|
||||
export type NotePublic = Pick<Note, 'contents'>
|
||||
|
||||
export async function create(note: Note) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type { Note } from '$lib/api'
|
||||
import { create } from '$lib/api'
|
||||
import { getKeyFromString, encrypt } from '$lib/crypto'
|
||||
import { getKeyFromString, encrypt, Hex, getRandomBytes } from '$lib/crypto'
|
||||
|
||||
import Button from '$lib/ui/Button.svelte'
|
||||
import Switch from '$lib/ui/Switch.svelte'
|
||||
@ -10,11 +10,9 @@
|
||||
|
||||
let note: Note = {
|
||||
contents: '',
|
||||
password: false,
|
||||
views: 1,
|
||||
expiration: 60,
|
||||
}
|
||||
let password: string = ''
|
||||
let result: { password: string; id: string } | null = null
|
||||
let advanced = false
|
||||
let type = false
|
||||
@ -37,18 +35,15 @@
|
||||
try {
|
||||
error = null
|
||||
loading = true
|
||||
const password = Hex.encode(getRandomBytes(32))
|
||||
const key = await getKeyFromString(password)
|
||||
const data: Note = {
|
||||
contents: note.contents,
|
||||
password: !!password,
|
||||
contents: await encrypt(note.contents, key),
|
||||
}
|
||||
// @ts-ignore
|
||||
if (type) data.expiration = parseInt(note.expiration)
|
||||
// @ts-ignore
|
||||
else data.views = parseInt(note.views)
|
||||
if (data.password) {
|
||||
const key = await getKeyFromString(password)
|
||||
data.contents = await encrypt(data.contents, key)
|
||||
}
|
||||
|
||||
const response = await create(data)
|
||||
result = {
|
||||
@ -68,11 +63,12 @@
|
||||
</script>
|
||||
|
||||
{#if result}
|
||||
{#if result.password}
|
||||
<TextInput type="password" readonly value={result.password} copy />
|
||||
<br />
|
||||
{/if}
|
||||
<TextInput type="text" readonly value="{window.location.origin}/note/{result.id}" copy />
|
||||
<TextInput
|
||||
type="text"
|
||||
readonly
|
||||
value="{window.location.origin}/note/{result.id}/{result.password}"
|
||||
copy
|
||||
/>
|
||||
<br />
|
||||
<Button on:click={reset}>new</Button>
|
||||
{:else}
|
||||
@ -112,15 +108,6 @@
|
||||
max={360}
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
<TextInput
|
||||
type="password"
|
||||
label="password"
|
||||
placeholder="optional"
|
||||
bind:value={password}
|
||||
copy
|
||||
random
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -26,9 +26,9 @@
|
||||
|
||||
<b>▶ Features</b>
|
||||
<ul>
|
||||
<li>server cannot decrypt contents due to client side encryption</li>
|
||||
<li>view and time constrains</li>
|
||||
<li>in memory, no persistence</li>
|
||||
<li>in browser encryption → server cannot decrypt contents</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
@ -17,8 +17,8 @@
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
export let id: string
|
||||
let needPassword = false
|
||||
let password: string = ''
|
||||
export let password: string
|
||||
|
||||
let note: NotePublic | null = null
|
||||
let exists = false
|
||||
|
||||
@ -29,8 +29,7 @@
|
||||
try {
|
||||
loading = true
|
||||
error = null
|
||||
const data = await info(id)
|
||||
needPassword = data.password
|
||||
await info(id)
|
||||
exists = true
|
||||
} catch {
|
||||
exists = false
|
||||
@ -40,17 +39,15 @@
|
||||
})
|
||||
|
||||
async function show() {
|
||||
const data = note || (await get(id)) // Don't get the content twice on wrong password.
|
||||
if (needPassword) {
|
||||
try {
|
||||
const key = await getKeyFromString(password)
|
||||
data.contents = await decrypt(data.contents, key)
|
||||
error = false
|
||||
} catch {
|
||||
error = true
|
||||
}
|
||||
try {
|
||||
error = false
|
||||
const data = note || (await get(id)) // Don't get the content twice on wrong password.
|
||||
const key = await getKeyFromString(password)
|
||||
data.contents = await decrypt(data.contents, key)
|
||||
note = data
|
||||
} catch {
|
||||
error = true
|
||||
}
|
||||
note = data
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -67,17 +64,12 @@
|
||||
{:else}
|
||||
<form on:submit|preventDefault={show}>
|
||||
<p>click below to show and delete the note if the counter has reached it's limit</p>
|
||||
{#if needPassword}
|
||||
<TextInput type="password" label="password" bind:value={password} />
|
||||
<br />
|
||||
{/if}
|
||||
<Button type="submit">show note</Button>
|
||||
{#if error}
|
||||
<br />
|
||||
<p class="error-text">
|
||||
wrong password. could not decipher.
|
||||
wrong password. could not decipher. probably a broken link. note was destroyed.
|
||||
<br />
|
||||
note already destroyed. try again without reloading the page.
|
||||
</p>
|
||||
{/if}
|
||||
</form>
|
@ -5,15 +5,12 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Note {
|
||||
pub contents: String,
|
||||
pub password: bool,
|
||||
pub views: Option<u8>,
|
||||
pub expiration: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct NoteInfo {
|
||||
pub password: bool,
|
||||
}
|
||||
pub struct NoteInfo {}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct NotePublic {
|
||||
|
@ -23,11 +23,7 @@ async fn one(path: web::Path<NotePath>) -> impl Responder {
|
||||
let note = store::get(&p.id);
|
||||
match note {
|
||||
None => return HttpResponse::NotFound().finish(),
|
||||
Some(note) => {
|
||||
return HttpResponse::Ok().json(NoteInfo {
|
||||
password: note.password,
|
||||
})
|
||||
}
|
||||
Some(_) => return HttpResponse::Ok().json(NoteInfo {}),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user