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