diff options
| author | Adam Soltys <[email protected]> | 2026-04-08 22:33:43 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-04-08 22:57:55 -0700 |
| commit | 757a59c5c9c4b56120446cae1ac495773b9905c8 (patch) | |
| tree | 58ae7c3e3f11fb32164dae59b6e952e54dc6ac93 /src/routes | |
| parent | c7136dbefa4da50297513955cf51084afa23d98c (diff) | |
| download | coinos-ui-staging.tar.gz coinos-ui-staging.zip | |
breez style passkey derivationstaging
Diffstat (limited to 'src/routes')
| -rw-r--r-- | src/routes/(app)/settings/security/+page.svelte | 53 | ||||
| -rw-r--r-- | src/routes/(static)/login/+page.svelte | 4 |
2 files changed, 53 insertions, 4 deletions
diff --git a/src/routes/(app)/settings/security/+page.svelte b/src/routes/(app)/settings/security/+page.svelte index 80d09ace..894536dd 100644 --- a/src/routes/(app)/settings/security/+page.svelte +++ b/src/routes/(app)/settings/security/+page.svelte @@ -4,10 +4,14 @@ import PhNumpadBold from "virtual:icons/ph/numpad-bold"; import PhDeviceMobileBold from "virtual:icons/ph/device-mobile-bold"; import PhFingerprintBold from "virtual:icons/ph/fingerprint-bold"; + import PhCopyBold from "virtual:icons/ph/copy-bold"; + import PhEyeBold from "virtual:icons/ph/eye-bold"; + import PhEyeSlashBold from "virtual:icons/ph/eye-slash-bold"; import { getContext } from "svelte"; import { tick } from "svelte"; import { t } from "$lib/translations"; import Pin from "$comp/Pin.svelte"; + import Mnemonic from "$comp/Mnemonic.svelte"; import Qr from "$comp/Qr.svelte"; import Spinner from "$comp/Spinner.svelte"; import { copy, post, success, fail, hashPin } from "$lib/utils"; @@ -35,7 +39,8 @@ nsec = $state(), otp: any = $state(), pin: any = $state(""), - revealSeed, + recoveryMnemonic: string | undefined = $state(), + revealSeed = $state(false), revealNsec = $state(), token: any = $state(""), setting2fa = $state(), @@ -58,10 +63,30 @@ }; let toggleSeed = async () => { + if (revealSeed) { + revealSeed = false; + recoveryMnemonic = undefined; + return; + } try { - revealSeed = !revealSeed; + let prfKey = getCachedPrfKey(); + if (!prfKey) { + const { getWalletEntropy } = await import("$lib/walletEntropy"); + prfKey = await getWalletEntropy(); + } + if (!prfKey) { + fail($t("accounts.failedToDecryptSeed")); + return; + } + const [{ entropyToMnemonic }, { wordlist }] = await Promise.all([ + import("@scure/bip39"), + import("@scure/bip39/wordlists/english.js"), + ]); + recoveryMnemonic = entropyToMnemonic(new Uint8Array(prfKey).slice(0, 16), wordlist); + revealSeed = true; } catch (e) { console.log(e); + fail($t("accounts.failedToDecryptSeed")); } }; @@ -268,3 +293,27 @@ Add Passkey </button> </div> + +<div> + <span class="font-bold mb-1">{$t("user.settings.recoveryPhrase")}</span> + <p class="text-secondary mb-1">{$t("user.settings.recoveryPhraseDescription")}</p> + <button type="button" class="btn" onclick={toggleSeed}> + {#if revealSeed} + <PhEyeSlashBold width="32" /> + {$t("user.settings.hideRecoveryPhrase")} + {:else} + <PhEyeBold width="32" /> + {$t("user.settings.showRecoveryPhrase")} + {/if} + </button> + + {#if revealSeed && recoveryMnemonic} + <div class="mt-4 space-y-4"> + <Mnemonic mnemonic={recoveryMnemonic} /> + <button onclick={() => copy(recoveryMnemonic as string)} type="button" class="btn"> + <PhCopyBold width="32" /> + <div class="my-auto">{$t("accounts.copy")}</div> + </button> + </div> + {/if} +</div> diff --git a/src/routes/(static)/login/+page.svelte b/src/routes/(static)/login/+page.svelte index 0132ac75..e73902ea 100644 --- a/src/routes/(static)/login/+page.svelte +++ b/src/routes/(static)/login/+page.svelte @@ -253,7 +253,7 @@ let passkeyLogin = async () => { passkeyLoading = true; try { - const { credential, challengeId, prfKey } = await loginWithPasskey(); + const { credential, challengeId, prfKey, legacyKey } = await loginWithPasskey(); const formData = new FormData(); formData.append("credential", JSON.stringify(credential)); @@ -273,7 +273,7 @@ passkeyMethodId(credential.id), prfKey, result.data?.encryptedKeys, - prfKey, + legacyKey, ); } catch (e) { console.log("Canonical key resolution failed", e); |
