From 1bad32fd90a86bf91b54c53ba3bd6b1753756dc3 Mon Sep 17 00:00:00 2001 From: shuaiplus <2327005759@qq.com> Date: Mon, 6 Jul 2026 01:07:26 +0800 Subject: [PATCH] fix: keep remembered 2fa token on bad password --- webapp/src/lib/api/auth.ts | 12 +++++++++++- webapp/src/lib/types.ts | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/webapp/src/lib/api/auth.ts b/webapp/src/lib/api/auth.ts index cfd9b41..8cd895c 100644 --- a/webapp/src/lib/api/auth.ts +++ b/webapp/src/lib/api/auth.ts @@ -89,6 +89,16 @@ function clearRememberTwoFactorToken(): void { localStorage.removeItem(TOTP_REMEMBER_TOKEN_KEY); } +function hasTwoFactorChallenge(error: TokenError): boolean { + const providers = error.TwoFactorProviders ?? error.CustomResponse?.TwoFactorProviders; + const providers2 = error.TwoFactorProviders2 ?? error.CustomResponse?.TwoFactorProviders2; + if (Array.isArray(providers)) return providers.length > 0; + if (providers && typeof providers === 'object') return Object.keys(providers as Record).length > 0; + if (Array.isArray(providers2)) return providers2.length > 0; + if (providers2 && typeof providers2 === 'object') return Object.keys(providers2 as Record).length > 0; + return providers != null || providers2 != null; +} + export function loadSession(): SessionState | null { try { const raw = localStorage.getItem(SESSION_KEY); @@ -282,7 +292,7 @@ export async function loginWithPassword( const json = (await parseJson(resp)) || {}; if (resp.ok) { saveRememberTwoFactorToken((json as TokenSuccess).TwoFactorToken); - } else if (rememberedToken) { + } else if (rememberedToken && hasTwoFactorChallenge(json)) { clearRememberTwoFactorToken(); } if (!resp.ok) return json; diff --git a/webapp/src/lib/types.ts b/webapp/src/lib/types.ts index d97f6be..063f5e9 100644 --- a/webapp/src/lib/types.ts +++ b/webapp/src/lib/types.ts @@ -455,6 +455,11 @@ export interface TokenError { error?: string; error_description?: string; TwoFactorProviders?: unknown; + TwoFactorProviders2?: unknown; + CustomResponse?: { + TwoFactorProviders?: unknown; + TwoFactorProviders2?: unknown; + }; } export interface AccountPasskeyCredential {