From 10c20c0c5b130c389680e37e4e4aba8e2abdbf1e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 24 Dec 2022 05:22:50 -0800 Subject: password prompt and pin fixes --- src/components/Feed.svelte | 82 +++++++++++----------- src/components/Password.svelte | 77 ++++++++++++++++++++ src/components/Pin.svelte | 3 + src/components/index.js | 1 + src/lib/nostr.js | 30 ++++++++ src/lib/store.js | 1 + src/lib/utils.js | 5 +- src/routes/(app)/[username]/generate/+page.svelte | 6 +- .../[username]/settings/[...tab]/+page.svelte | 8 +-- src/routes/(app)/login/+server.js | 6 ++ src/routes/(app)/password/+server.js | 8 +++ 11 files changed, 177 insertions(+), 50 deletions(-) create mode 100644 src/components/Password.svelte create mode 100644 src/lib/nostr.js create mode 100644 src/routes/(app)/login/+server.js create mode 100644 src/routes/(app)/password/+server.js diff --git a/src/components/Feed.svelte b/src/components/Feed.svelte index 00226692..0ccda7b8 100644 --- a/src/components/Feed.svelte +++ b/src/components/Feed.svelte @@ -1,55 +1,51 @@ + +
+
+

Please enter your password

+
+
+ {#if revealPassword} + + {:else} + + {/if} + +
+
+ + +
+
+
+
diff --git a/src/components/Pin.svelte b/src/components/Pin.svelte index 80e003b9..9b1bb4ea 100644 --- a/src/components/Pin.svelte +++ b/src/components/Pin.svelte @@ -4,6 +4,8 @@ let pinCode = ''; let pinInput; + let cancel = () => ($pin = '000000'); + $: pinCode.length > 5 && ($pin = pinCode); @@ -15,6 +17,7 @@ diff --git a/src/components/index.js b/src/components/index.js index 90bc1e7e..b0802c25 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -1,3 +1,4 @@ +export { default as Password } from './Password.svelte'; export { default as Feed } from './Feed.svelte'; export { default as Invoice } from './Invoice.svelte'; export { default as Request } from './Request.svelte'; diff --git a/src/lib/nostr.js b/src/lib/nostr.js new file mode 100644 index 00000000..df63d5d8 --- /dev/null +++ b/src/lib/nostr.js @@ -0,0 +1,30 @@ +import { entropyToMnemonic, mnemonicToSeedSync } from 'bip39'; +import { Buffer } from 'buffer'; +import { bech32m } from 'bech32'; +import { bip32, post, stretch } from '$lib/utils'; +import { calculateId, signId } from 'nostr'; + +const { decode, fromWords } = bech32m; + +export let send = async (event, { cipher, username, salt }, password) => { + let mnemonic, key, seed, entropy, child, privkey; + entropy = Buffer.from( + await crypto.subtle.decrypt( + { name: 'AES-GCM', iv: new Uint8Array(16) }, + await stretch(password, Buffer.from(salt, 'hex')), + Uint8Array.from(fromWords(decode(cipher, 180).words)) + ), + 'hex' + ).toString('hex'); + + mnemonic = entropyToMnemonic(entropy); + seed = mnemonicToSeedSync(mnemonic); + key = bip32.fromSeed(seed); + child = key.derivePath("m/44'/1237'/0'/0/0"); + privkey = child.privateKey; + + event.id = await calculateId(event); + event.sig = await signId(privkey, event.id); + + await post(`/${username}`, { event }); +}; diff --git a/src/lib/store.js b/src/lib/store.js index 1a1a88c2..9660bf55 100644 --- a/src/lib/store.js +++ b/src/lib/store.js @@ -56,3 +56,4 @@ export const invoice = writable(); export const txns = persistLocal('transactions', []); export const events = writable({}); export const password = writable(); +export const passwordPrompt = writable(); diff --git a/src/lib/utils.js b/src/lib/utils.js index 79509cc1..d4d78007 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -49,9 +49,10 @@ export const post = (url, body, headers) => { try { let { message } = JSON.parse(text); if (message) return JSON.stringify({ name: 'Error', message }); - } catch (e) {} + } catch (e) { + } - return text; + return { error: text }; }) .then((body) => { try { diff --git a/src/routes/(app)/[username]/generate/+page.svelte b/src/routes/(app)/[username]/generate/+page.svelte index 559d0d14..330ccedb 100644 --- a/src/routes/(app)/[username]/generate/+page.svelte +++ b/src/routes/(app)/[username]/generate/+page.svelte @@ -7,7 +7,7 @@ import * as ecc from 'tiny-secp256k1'; import { bip32, stretch, post } from '$lib/utils'; import { goto, invalidate } from '$app/navigation'; - import { loginRedirect } from '$lib/store'; + import { loginRedirect, password } from '$lib/store'; import { Pin } from '$comp'; import { pin } from '$lib/store'; @@ -16,7 +16,7 @@ const { encode, toWords } = bech32m; - let loaded, mnemonic, key, password, seed, entropy, cipher, pubkey, salt, child; + let loaded, mnemonic, key, seed, entropy, cipher, pubkey, salt, child; onMount(async () => { setTimeout(() => (loaded = true), 50); @@ -35,7 +35,7 @@ let bytes = new Uint8Array( await crypto.subtle.encrypt( { name: 'AES-GCM', iv: new Uint8Array(16) }, - await stretch(password, salt), + await stretch($password, salt), Uint8Array.from(Buffer.from(entropy, 'hex')) ) ); diff --git a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte index d47ce0de..3b213a11 100644 --- a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte +++ b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte @@ -28,10 +28,10 @@ $: form?.success && success('Settings saved!'); - // $: if (form?.message?.startsWith('Pin')) { - // failure('Wrong pin, try again'); - // $pin = ''; - // } + $: if (form?.message?.startsWith('Pin')) { + failure('Wrong pin, try again'); + $pin = ''; + } let tabs = [ { name: 'account', key: 'ACCOUNT', comp: Account }, diff --git a/src/routes/(app)/login/+server.js b/src/routes/(app)/login/+server.js new file mode 100644 index 00000000..e08356a0 --- /dev/null +++ b/src/routes/(app)/login/+server.js @@ -0,0 +1,6 @@ +import { json } from "@sveltejs/kit"; +import { post } from "$lib/utils"; + +export async function POST({ request }) { + return json(await post('/checkPassword', await request.json())); +} diff --git a/src/routes/(app)/password/+server.js b/src/routes/(app)/password/+server.js new file mode 100644 index 00000000..ed9b4dbb --- /dev/null +++ b/src/routes/(app)/password/+server.js @@ -0,0 +1,8 @@ +import { json } from '@sveltejs/kit'; +import { auth, post } from '$lib/utils'; + +export async function POST({ cookies, request }) { + let result = await post('/checkPassword', await request.json(), auth(cookies)); + return json(result); +} + -- cgit v1.2.3