From 16da2cb00d16f87d02535bfdae815f83f19f251f Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 27 Feb 2026 15:24:13 -0800 Subject: fix race condition --- src/components/Account.svelte | 24 ++++++------ src/routes/(static)/login/+page.server.ts | 51 -------------------------- src/routes/(static)/register/auth/+page.svelte | 4 +- 3 files changed, 15 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/components/Account.svelte b/src/components/Account.svelte index 45ffdd8b..ff9218fe 100644 --- a/src/components/Account.svelte +++ b/src/components/Account.svelte @@ -18,8 +18,8 @@ let arkBalance = $state(0); let arkLoading = $state(false); - let tryUnlockArk = async () => { - const deriveArkKey = async (key: ArrayBuffer) => { + let tryUnlockArk = async (): Promise => { + const deriveArkKey = async (key: ArrayBuffer): Promise => { const [{ HDKey }, { entropyToMnemonic, mnemonicToSeed }, { wordlist }] = await Promise.all([ import("@scure/bip32"), import("@scure/bip39"), @@ -36,8 +36,7 @@ const s = await mnemonicToSeed(mnemonicStr); const master = HDKey.fromMasterSeed(s, versions); const arkChild = master.derive("m/86'/0'/0'/0/0"); - $arkkey = bytesToHex(arkChild.privateKey!); - $arkaid = id; + return bytesToHex(arkChild.privateKey!); }; // Try cached PRF key or silent nsec @@ -45,8 +44,7 @@ const entropy = await getWalletEntropy(); if (entropy) { try { - await deriveArkKey(entropy); - return true; + return await deriveArkKey(entropy); } catch (e) { console.log("Wallet entropy unlock failed", e); } @@ -55,8 +53,7 @@ // Try interactive nostr derivation try { const interactiveEntropy = await deriveNostrEntropy(); - await deriveArkKey(interactiveEntropy); - return true; + return await deriveArkKey(interactiveEntropy); } catch (e) { console.log("Interactive nostr unlock failed", e); return false; @@ -69,9 +66,14 @@ document.cookie = `aid=${id}; path=/; max-age=86400`; if (isArk) { if ($arkkey && $arkaid === id) { - goto(url); - } else if (await tryUnlockArk()) { - goto(url); + await goto(url); + } else { + const key = await tryUnlockArk(); + if (key) { + await goto(url); + $arkkey = key; + $arkaid = id; + } } } else { $arkkey = undefined; diff --git a/src/routes/(static)/login/+page.server.ts b/src/routes/(static)/login/+page.server.ts index d402fdad..68143d83 100644 --- a/src/routes/(static)/login/+page.server.ts +++ b/src/routes/(static)/login/+page.server.ts @@ -97,57 +97,6 @@ export const actions = { }; }, - passwordAuth: async ({ cookies, fetch, request }) => { - const form = await fd(request); - let { event, challenge, username, loginRedirect, recaptcha, token: twofa } = form; - if (loginRedirect === "null" || loginRedirect === "undefined") loginRedirect = undefined; - event = JSON.parse(event); - - const maxAge = 380 * 24 * 60 * 60; - - const res = await fetch(`${PUBLIC_COINOS_URL}/authKeyLogin`, { - method: "POST", - body: JSON.stringify({ event, challenge, username, recaptcha, twofa }), - headers: { - "content-type": "application/json", - accept: "application/json", - "cf-connecting-ip": request.headers.get("cf-connecting-ip") ?? "", - "x-forwarded-host": request.headers.get("host") ?? "", - }, - }); - - const text = await res.text(); - - if (res.status === 401) { - if (text.startsWith("2fa")) throw new Error("2fa"); - throw new Error(text); - } - - if (!res.ok) { - let message; - try { - ({ message } = JSON.parse(text)); - } catch { - message = text; - } - return fail(400, { error: message || "Login failed" }); - } - - const { user, token } = JSON.parse(text); - if (!token) return fail(400, { error: "Login failed" }); - const { username: uname, language } = user; - - const expires = new Date(); - expires.setSeconds(expires.getSeconds() + maxAge); - - const opts = { path: "/", expires }; - if (language) cookies.set("lang", language, opts); - cookies.set("username", uname, opts); - cookies.set("token", token, opts); - - redirect(307, loginRedirect || `/${uname}`); - }, - passkey: async ({ cookies, fetch, request }) => { const form = await fd(request); let { credential, challengeId, loginRedirect } = form; diff --git a/src/routes/(static)/register/auth/+page.svelte b/src/routes/(static)/register/auth/+page.svelte index d285e0af..ad5d6e54 100644 --- a/src/routes/(static)/register/auth/+page.svelte +++ b/src/routes/(static)/register/auth/+page.svelte @@ -71,7 +71,7 @@ const getRecaptchaToken = () => new Promise((resolve, reject) => { - if (isTor) return resolve(""); + if (isTor || !recaptchaSiteKey) return resolve(""); if (!browser || !grecaptcha) return reject(new Error("captcha unavailable")); grecaptcha.ready(() => { grecaptcha.execute(recaptchaSiteKey, { action: "register" }).then(resolve).catch(reject); @@ -144,7 +144,7 @@ const result = deserialize(await response.text()); - if (result.type === "success") { + if (result.type === "success" || result.type === "redirect") { try { const { deriveAuthKeypair } = await import("$lib/deriveAuthKey"); const { sk } = await deriveAuthKeypair(user.username, user.password); -- cgit v1.2.3