aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/(app)
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-01-06 12:23:40 -0800
committerAdam Soltys <[email protected]>2023-01-06 12:23:40 -0800
commit46e33eb5ba63276836322b11abfbff6432c98ff6 (patch)
tree64c1ad3760ed5c6c5f86dda8a0ec624197a75ab1 /src/routes/(app)
parente398ccf8b21e38c5fd0bc445acce4d6542551713 (diff)
downloadcoinos-ui-46e33eb5ba63276836322b11abfbff6432c98ff6.tar.gz
coinos-ui-46e33eb5ba63276836322b11abfbff6432c98ff6.zip
re-encrypt entropy on password change
Diffstat (limited to 'src/routes/(app)')
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/+page.svelte86
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_account.svelte85
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_pos.svelte9
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_security.svelte29
-rw-r--r--src/routes/(app)/otpsecret/+server.js4
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');
}
}