diff --git a/web/src/lib/auth.svelte.ts b/web/src/lib/auth.svelte.ts index 89152d8a4..2120955ad 100644 --- a/web/src/lib/auth.svelte.ts +++ b/web/src/lib/auth.svelte.ts @@ -8,7 +8,9 @@ import { } from "@atcute/identity-resolver"; import type { ActorIdentifier, Did } from "@atcute/lexicons/syntax"; import { + OAuthResponseError, OAuthUserAgent, + TokenRefreshError, configureOAuth, createAuthorizationUrl, deleteStoredSession, @@ -142,6 +144,12 @@ const errorMessage = (cause: unknown) => { : message; }; +const isDeadSessionError = (cause: unknown): boolean => + cause instanceof TokenRefreshError || + (cause instanceof OAuthResponseError && + cause.status === 400 && + (cause.error === "invalid_grant" || cause.error === "invalid_token")); + const resolveProfile = async ( identifier: string, bobbinUrl: string @@ -251,15 +259,17 @@ export const createAuth = ( void hydrateProfile(did, nextAgent); }; - // prune dead sessions when re-adoption fails. const activate = async (did: Did): Promise => { try { - const session = await getSession(did, { allowStale: true }); + const session = await getSession(did); adoptSession(session); return true; } catch (cause) { - deleteStoredSession(did); - saveAccounts(dropAccount(loadAccounts(), did)); + if (isDeadSessionError(cause)) { + deleteStoredSession(did); + saveAccounts(dropAccount(loadAccounts(), did)); + return false; + } state = failureState(errorMessage(cause)); return false; } @@ -367,12 +377,10 @@ export const createAuth = ( accounts = reconcileAccounts(listStoredSessions(), loadAccounts()); if (wasActive) { - const next = accounts[0]?.did ?? null; - if (next) { - await activate(next); - } else { - resetLoggedOut(); + for (const account of accounts) { + if (await activate(account.did)) return; } + resetLoggedOut(); } };