diff options
| author | Adam Soltys <[email protected]> | 2026-09-14 12:54:23 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-14 12:54:23 -0700 |
| commit | 1d87d0d36feea526f8f6bf4a62b012132bd36128 (patch) | |
| tree | 60d93cc41bbdfbcf9b3a9adb3e8482a3bdd0ed91 /src | |
| parent | 57191e941016f15a9c52de7e95e7bb2a04c9de13 (diff) | |
| download | coinos-ui-1d87d0d36feea526f8f6bf4a62b012132bd36128.tar.gz coinos-ui-1d87d0d36feea526f8f6bf4a62b012132bd36128.zip | |
register: start the session from the register response
/register now verifies the recaptcha token itself, and Google tokens are
single-use — so the follow-up /login that reused the same token came back
"failed captcha" for an account that had just been created. The register
response already carries the JWT; set the session cookies from it and only
fall back to /login when registration itself failed.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_0166Ci2XdCair1B9ych7w8dq
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/utils.ts | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 14a1370e..b6bbdb53 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -172,8 +172,6 @@ export const login = async ( host?: string, extraHeaders?: Record<string, string>, ) => { - const maxAge = 380 * 24 * 60 * 60; - const headers: Record<string, string> = { "content-type": "application/json", accept: "application/json", @@ -198,6 +196,18 @@ export const login = async ( const { user: u, token } = JSON.parse(text); if (!token) throw new Error("Login failed"); + setSession(cookies, user, u, token); +}; + +// Session cookies for a freshly issued JWT — shared by login and register, +// which both get a token back from the server. +const setSession = ( + cookies, + user: { username: string; password: string }, + u: { language?: string; nsec?: string }, + token: string, +) => { + const maxAge = 380 * 24 * 60 * 60; const expires = new Date(); expires.setSeconds(expires.getSeconds() + maxAge); @@ -507,19 +517,30 @@ export const register = async (user, ip, cookies, loginRedirect, host?, extraHea }; if (ip) headers["cf-connecting-ip"] = ip; - let sk; + let sk, token, u; try { - ({ sk } = await post("/register", { user }, headers)); + ({ sk, token, ...u } = await post("/register", { user }, headers)); } catch (e) { ({ message: error } = e as Error); } - try { - await login(user, cookies, ip, host, extraHeaders); + // /register verifies the recaptcha token itself now, and Google tokens + // are single-use: a follow-up /login carrying the same token comes back + // "failed captcha" for an account that was just created. The register + // response already includes the JWT, so start the session from it and + // only fall back to /login when registration failed (e.g. the username + // already exists and this is really a login). + if (token) { + setSession(cookies, user, u, token); error = null; - } catch (e) { - const { message } = e as Error; - error ||= message; + } else { + try { + await login(user, cookies, ip, host, extraHeaders); + error = null; + } catch (e) { + const { message } = e as Error; + error ||= message; + } } const expires = new Date(); |
