diff options
| author | Adam Soltys <[email protected]> | 2023-01-06 12:23:40 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2023-01-06 12:23:40 -0800 |
| commit | 46e33eb5ba63276836322b11abfbff6432c98ff6 (patch) | |
| tree | 64c1ad3760ed5c6c5f86dda8a0ec624197a75ab1 /src/routes/(app) | |
| parent | e398ccf8b21e38c5fd0bc445acce4d6542551713 (diff) | |
| download | coinos-ui-46e33eb5ba63276836322b11abfbff6432c98ff6.tar.gz coinos-ui-46e33eb5ba63276836322b11abfbff6432c98ff6.zip | |
re-encrypt entropy on password change
Diffstat (limited to 'src/routes/(app)')
5 files changed, 88 insertions, 125 deletions
diff --git a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte index b02ddca4..b2602625 100644 --- a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte +++ b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte @@ -6,10 +6,10 @@ import { Icon, Spinner, Pin } from '$comp'; import { t } from '$lib/translations'; import { failure, post, success } from '$lib/utils'; - import { avatarUpload, bannerUpload, pin } from '$lib/store'; + import { avatarUpload, bannerUpload, password, pin } from '$lib/store'; import { upload } from '$lib/upload'; import { page } from '$app/stores'; - import { sign, send } from '$lib/nostr'; + import { sign, send, reEncryptEntropy } from '$lib/nostr'; import { invalidateAll } from '$app/navigation'; import Account from './_account.svelte'; @@ -50,50 +50,62 @@ let loading; async function handleSubmit() { - loading = true; - let data = new FormData(formElement); - try { - if ($avatarUpload) { - await upload($avatarUpload.file, $avatarUpload.type, $avatarUpload.progress, token); + loading = true; + let data = new FormData(formElement); + + if (data.get('password')) { + console.log('reencrypting', user.cipher); + data.set('cipher', await reEncryptEntropy(user, data.get('password'))); + console.log(data.get('cipher')); } - if ($bannerUpload) { - await upload($bannerUpload.file, $bannerUpload.type, $bannerUpload.progress, token); + try { + if ($avatarUpload) { + await upload($avatarUpload.file, $avatarUpload.type, $avatarUpload.progress, token); + } + + if ($bannerUpload) { + await upload($bannerUpload.file, $bannerUpload.type, $bannerUpload.progress, token); + } + } catch (e) { + console.log(e); + failure('Something went wrong'); } - } catch (e) { - console.log(e); - failure('Something went wrong'); - } - let event = { - pubkey: user.pubkey, - created_at: Math.floor(Date.now() / 1000), - kind: 0, - content: JSON.stringify({ - name: user.username, - about: user.address, - picture: `${PUBLIC_COINOS_URL}/public/${user.username}-profile.webp` - }), - tags: [] - }; + let event = { + pubkey: user.pubkey, + created_at: Math.floor(Date.now() / 1000), + kind: 0, + content: JSON.stringify({ + name: user.username, + about: user.address, + picture: `${PUBLIC_COINOS_URL}/public/${user.username}-profile.webp` + }), + tags: [] + }; - await sign({ event, user }); - await send(event); + await sign({ event, user }); + await send(event); - const response = await fetch(formElement.action, { - method: 'POST', - body: data - }); + const response = await fetch(formElement.action, { + method: 'POST', + body: data + }); - const result = deserialize(await response.text()); + const result = deserialize(await response.text()); - if (result.type === 'success') { - await invalidateAll(); - } + if (result.type === 'success') { + await invalidateAll(); + if (data.get('password')) $password = data.get('password'); + } - applyAction(result); - loading = false; + applyAction(result); + loading = false; + } catch (e) { + console.log(e); + failure('Problem submitting form'); + } } let loaded; @@ -117,7 +129,7 @@ {$t('user.settings.header')} </h1> - <div class="font-bold flex justify-between items-center border-b pb-3 text-secondary"> + <div class="font-bold flex justify-around items-center border-b pb-3 text-secondary"> {#each tabs as { name, key }} <a href={`/${user.username}/settings/${name}`}> <button class="hover:opacity-80" class:text-black={tab === name} diff --git a/src/routes/(app)/[username]/settings/[...tab]/_account.svelte b/src/routes/(app)/[username]/settings/[...tab]/_account.svelte index 0359f074..6b9fb2c6 100644 --- a/src/routes/(app)/[username]/settings/[...tab]/_account.svelte +++ b/src/routes/(app)/[username]/settings/[...tab]/_account.svelte @@ -1,22 +1,19 @@ <script> import { tick } from 'svelte'; import { colorTheme, avatarUpload, bannerUpload } from '$lib/store'; - import { Icon, Toggle, LocaleSelector } from '$comp'; + import { Icon } from '$comp'; import { t } from '$lib/translations'; import { upload } from '$lib/upload'; export let user; let selectedTheme = 1; - let revealPassword = false; - let password; let profileFile; let select = (type) => files[type].el.click(); $: profile = files.profile.src; $: banner = files.banner.src; - let togglePassword = () => (revealPassword = !revealPassword); let colorThemes = [ { theme: 1, color1: 'from-[#F5F7FA]', color2: 'to-[#C3CFE2]' }, { theme: 2, color1: 'from-[#FDFCFB]', color2: 'to-[#E2D1C3]' }, @@ -56,44 +53,12 @@ $bannerUpload = { file, type, progress }; } }; - - $: user.password = user.confirm = password; </script> -<div> - <label for="language" class="font-bold block mb-1">{$t('user.settings.locale')}</label> - <LocaleSelector style="select-styles block py-3 w-full" /> -</div> - -<!-- TODO -<div> - <label for="email" class="font-bold mb-1 block">{$t('user.settings.email')}</label> - <input type="email" name="email" bind:value={user.email} /> -</div> --> - -<!-- TODO fix breaking changes when user updates this field --> -<div> - <label for="username" class="font-bold mb-1 block">{$t('user.settings.username')}</label> - <input disabled type="text" name="username" bind:value={user.username} /> - <input type="hidden" name="username" bind:value={user.username} /> -</div> - -<div class="relative"> - <label for="password" class="block font-bold block mb-1">{$t('user.settings.newPassword')}</label> - {#if revealPassword} - <input name="password" type="text" bind:value={password} /> - {:else} - <input name="password" type="password" bind:value={password} /> - {/if} - <button - type="button" - on:click={togglePassword} - on:keydown={togglePassword} - class="absolute right-5 top-11" - > - <Icon icon={revealPassword ? 'eye' : 'eye-off'} /> - </button> -</div> +<!-- <div> --> +<!-- <label for="username" class="font-bold mb-1 block">{$t('user.settings.username')}</label> --> +<!-- <input type="text" name="username" bind:value={user.username} /> --> +<!-- </div> --> <div> <label for="address" class="font-bold mb-1 block">{$t('user.settings.about')}</label> @@ -105,27 +70,6 @@ /> </div> -<!-- TODO --> -<!-- <div> --> -<!-- <div class="flex justify-between items-center"> --> -<!-- <span class="font-bold">{$t('user.settings.emailNotifications')}</span> --> -<!-- <Toggle id="email-notify" /> --> -<!-- </div> --> -<!-- <p class="text-secondary mt-1 w-9/12"> --> -<!-- {$t('user.settings.emailNotificationsDescription')} --> -<!-- </p> --> -<!-- </div> --> -<!-- --> -<!-- <div> --> -<!-- <div class="flex justify-between items-center"> --> -<!-- <span class="font-bold">{$t('user.settings.smsNotifications')}</span> --> -<!-- <Toggle id="sms-notify" /> --> -<!-- </div> --> -<!-- <p class="text-secondary mt-1 w-9/12"> --> -<!-- {$t('user.settings.smsNotificationsDescription')} --> -<!-- </p> --> -<!-- </div> --> - <div> <span class="font-bold">{$t('user.settings.profileImage')}</span> @@ -192,7 +136,6 @@ <div class="flex justify-between items-center"> <span class="font-bold">{$t('user.settings.bannerImage')}</span> </div> - <!-- found missing translation --> {#if banner} <img @@ -219,7 +162,6 @@ /> {/if} - <!-- found missing translation --> <button type="button" class="border rounded-2xl font-bold w-24 text-center px-0 py-2 hover:opacity-80" @@ -240,20 +182,3 @@ <div class="text-red-600">Max file size 10MB</div> {/if} </div> - -<!-- TODO -<div> - <span class="font-bold mb-1 block">{$t('user.settings.theme')}</span> - <p class="text-secondary mb-1">{$t('user.settings.themeDescription')}</p> - {#each colorThemes as colors} - <button - type="button" - class="hover:opacity-80 mr-2 w-10 h-10 bg-gradient-to-r {colors.color1} {colors.color2} rounded-xl border-2 {selectedTheme === - colors.theme - ? 'border-black' - : ''}" - on:click={() => handleThemeClick(colors)} - on:keydown={() => handleThemeClick(colors)} - /> - {/each} -</div> --> diff --git a/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte index b4aa3181..bade7a99 100644 --- a/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte +++ b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte @@ -1,14 +1,19 @@ <script> - import { Icon, Toggle } from '$comp'; + import { Icon, LocaleSelector } from '$comp'; import { t } from '$lib/translations'; import { success, failure } from '$lib/utils'; import { page } from '$app/stores'; export let user, rates; - const fiats = Object.keys(rates); + let fiats = Object.keys(rates); </script> <div> + <label for="language" class="font-bold block mb-1">{$t('user.settings.locale')}</label> + <LocaleSelector style="select-styles block py-3 w-full" /> +</div> + +<div> <label for="currency" class="font-bold block mb-1">{$t('user.settings.localCurrency')}</label> <select name="currency" class="select-styles block py-3 w-full" value={user.currency}> {#each fiats as fiat} diff --git a/src/routes/(app)/[username]/settings/[...tab]/_security.svelte b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte index 2d880d44..ef4b9fba 100644 --- a/src/routes/(app)/[username]/settings/[...tab]/_security.svelte +++ b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte @@ -11,6 +11,7 @@ export let user, submit; let settingPin, setting2fa, disabling2fa; + let password, revealPassword; let token = ''; let pinCode = []; let verifyCode = []; @@ -18,8 +19,10 @@ let verifying = false; let old; + let togglePassword = () => (revealPassword = !revealPassword); + let startVerifying = () => { - if (pinCode.join("").length < 6) return; + if (pinCode.join('').length < 6) return; verifying = true; }; @@ -81,7 +84,7 @@ if (user.haspin) { try { pin = null; - await tick(); + await tick(); submit.click(); } catch (e) { console.log(e); @@ -125,9 +128,27 @@ }; </script> -<div> - <input type="hidden" name="newpin" value={pin} /> +<input type="hidden" name="newpin" value={pin} /> +<input type="hidden" name="confirm" bind:value={password} /> + +<div class="relative mb-5"> + <label for="password" class="block font-bold block mb-1">{$t('user.settings.newPassword')}</label> + {#if revealPassword} + <input name="password" type="text" bind:value={password} /> + {:else} + <input name="password" type="password" bind:value={password} /> + {/if} + <button + type="button" + on:click={togglePassword} + on:keydown={togglePassword} + class="absolute right-5 top-11" + > + <Icon icon={revealPassword ? 'eye' : 'eye-off'} /> + </button> +</div> +<div> <span class="font-bold mb-1" >{verifying ? $t('user.settings.verifyPIN') : $t('user.settings.securityPIN')}</span > diff --git a/src/routes/(app)/otpsecret/+server.js b/src/routes/(app)/otpsecret/+server.js index f998fb17..31dbcec1 100644 --- a/src/routes/(app)/otpsecret/+server.js +++ b/src/routes/(app)/otpsecret/+server.js @@ -4,12 +4,12 @@ import { error } from '@sveltejs/kit'; export async function POST({ cookies, request }) { try { - let body = await request.json(); + let body = await request.json(); let { username, secret } = await post('/otpsecret', body, auth(cookies)); let uri = `otpauth://totp/coinos:${username}?secret=${secret}&period=30&digits=6&algorithm=SHA1&issuer=coinos`; return new Response(JSON.stringify({ secret, uri, qr: Qr.drawImg(uri, { size: 600 }) })); } catch (e) { - console.log(e) + console.log(e); throw new error(500, 'Problem saving secret'); } } |
