From f7edc59abbda9440e228caa0cfe61da11f4e6b1e Mon Sep 17 00:00:00 2001 From: iven Date: Sat, 11 Apr 2026 12:32:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(auth):=20=E4=BF=AE=E5=A4=8D=E9=87=8D?= =?UTF-8?q?=E5=90=AF=E5=90=8E=E6=97=A0=E6=B3=95=E5=AF=B9=E8=AF=9D=20?= =?UTF-8?q?=E2=80=94=20restoreSession=20=E4=BC=98=E5=85=88=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=20SaaS=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: 心跳降级将 'tauri' 持久化到 localStorage,重启后盲信该值。 修复: token refresh 成功时强制恢复 'saas' 模式;connectionMode 携带时间戳。 --- desktop/src/lib/saas-session.ts | 31 ++++++++++++++++++++++++++++--- desktop/src/store/saasStore.ts | 5 ++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/desktop/src/lib/saas-session.ts b/desktop/src/lib/saas-session.ts index a7ddaeb..113b4ca 100644 --- a/desktop/src/lib/saas-session.ts +++ b/desktop/src/lib/saas-session.ts @@ -157,16 +157,41 @@ export async function clearSaaSSession(): Promise { } /** - * Persist the connection mode to localStorage. + * Persist the connection mode to localStorage with timestamp. */ export function saveConnectionMode(mode: string): void { - localStorage.setItem(SAASMODE_KEY, mode); + const data = JSON.stringify({ mode, timestamp: Date.now() }); + localStorage.setItem(SAASMODE_KEY, data); } /** * Load the connection mode from localStorage. + * Handles both new JSON format and legacy plain string format. * Returns null if not set. */ export function loadConnectionMode(): string | null { - return localStorage.getItem(SAASMODE_KEY); + const raw = localStorage.getItem(SAASMODE_KEY); + if (!raw) return null; + try { + const parsed = JSON.parse(raw); + if (typeof parsed === 'string') return parsed; // legacy format + return parsed.mode ?? null; + } catch { + return raw; // legacy format (plain string) + } +} + +/** + * Load the timestamp of the persisted connection mode. + * Returns null if not set or format is legacy. + */ +export function loadConnectionModeTimestamp(): number | null { + const raw = localStorage.getItem(SAASMODE_KEY); + if (!raw) return null; + try { + const parsed = JSON.parse(raw); + return parsed.timestamp ?? null; + } catch { + return null; + } } diff --git a/desktop/src/store/saasStore.ts b/desktop/src/store/saasStore.ts index 052fc5f..31040ea 100644 --- a/desktop/src/store/saasStore.ts +++ b/desktop/src/store/saasStore.ts @@ -818,8 +818,11 @@ export const useSaaSStore = create((set, get) => { account, saasUrl: restored.saasUrl, authToken: newToken, - connectionMode: loadConnectionMode() === 'saas' ? 'saas' : 'tauri', + // If token refresh succeeded, always restore to 'saas' mode + // regardless of what was persisted (heartbeat may have degraded to 'tauri') + connectionMode: 'saas', }); + saveConnectionMode('saas'); get().fetchAvailableModels().catch(() => {}); get().fetchAvailableTemplates().catch(() => {}); get().fetchAssignedTemplate().catch(() => {});