add frontend error pages

This commit is contained in:
Maxime Cannoodt 2022-06-29 16:05:25 +02:00
parent e24e4e19cb
commit d735237e8f
5 changed files with 42 additions and 22 deletions

Binary file not shown.

View File

@ -28,7 +28,7 @@ app.listen(process.env.PORT, () => {
app.post("/note/", async (req: Request<{}, {}, EncryptedNote>, res) => {
const note = req.body;
const savedNote = await prisma.encryptedNote.create({
data: { ...note, expire_time: addDays(new Date(), 14) },
data: { ...note, expire_time: addDays(new Date(), 30) },
});
res.json({
view_url: `${process.env.FRONTEND_URL}/note/${savedNote.id}`,

View File

@ -1,16 +1,16 @@
import { AES, enc, HmacSHA256 } from 'crypto-js';
// TODO: should be same source code as used in the plugin!!
export default function decrypt(cryptData: {
export default async function decrypt(cryptData: {
ciphertext: string;
hmac: string;
key: string;
}): string {
}): Promise<string> {
const hmac_calculated = HmacSHA256(cryptData.ciphertext, cryptData.key).toString();
const is_authentic = hmac_calculated == cryptData.hmac;
if (!is_authentic) {
throw Error('Cannot decrypt ciphertext with this key.');
throw Error('Failed HMAC check');
}
const md = AES.decrypt(cryptData.ciphertext, cryptData.key).toString(enc.Utf8);
return md;

View File

@ -2,9 +2,16 @@
import type { Load } from '@sveltejs/kit';
export const load: Load = ({ error, status }) => {
let explainText = '';
if (status == 404) {
explainText = `No note was found for this link. It may be that the note that was once connected to this link has expired.`;
}
return {
props: {
title: `${status}: ${error?.message}`
title: `${status}: ${error?.message}`,
explainText: explainText
}
};
};
@ -12,8 +19,10 @@
<script lang="ts">
export let title: string;
export let explainText: string;
</script>
<div class="prose max-w-2xl">
<h1>{title}</h1>
<p class="prose-xl">{explainText}</p>
</div>

View File

@ -41,13 +41,15 @@
export let note: EncryptedNote;
let plaintext: string;
let timeString: string;
let decryptFailed = false;
onMount(() => {
if (browser) {
// Decrypt note
console.log(note);
const key = location.hash.slice(1);
plaintext = decrypt({ ...note, key });
decrypt({ ...note, key })
.then((value) => (plaintext = value))
.catch(() => (decryptFailed = true));
}
});
@ -74,19 +76,28 @@
}
</script>
<div class="max-w-2xl mx-auto">
<p class="mb-4 text-sm flex justify-between text-neutral-500">
<span class="flex gap-1.5 items-center uppercase">
<span class="h-5"><IconEncrypted /></span>
<span>e2e encrypted | <span>Shared {timeString} ago</span></span>
</span>
<button class="flex gap-1.5 uppercase items-center">
<span>Raw Markdown</span>
<span class="h-6"><LogoMarkdown /></span>
</button>
</p>
{#if plaintext}
{#if plaintext}
<div class="max-w-2xl mx-auto">
<p class="mb-4 text-sm flex justify-between text-neutral-500">
<span class="flex gap-1.5 items-center uppercase">
<span class="h-5"><IconEncrypted /></span>
<span>e2e encrypted | <span>Shared {timeString} ago</span></span>
</span>
<button class="flex gap-1.5 uppercase items-center">
<span>Raw Markdown</span>
<span class="h-6"><LogoMarkdown /></span>
</button>
</p>
<MarkdownRenderer {plaintext} />
{/if}
</div>
</div>
{/if}
{#if decryptFailed}
<div class="prose max-w-2xl">
<h1>Error: Cannot decrypt file</h1>
<p class="prose-xl">This note could not be decrypted with this link.</p>
<p class="prose-xl">
If you think this is an error, please double check that you copied the entire URL.
</p>
</div>
{/if}