/** * Auth token persistence — Tauri Store (encrypted on disk via plugin-store). * Falls back to in-memory object on web (dev mode) so the app is testable from `pnpm dev`. * * IMPORTANT: never use localStorage for tokens here — Tauri Store is what the spec mandates. */ import { Store } from '@tauri-apps/plugin-store'; import type { AuthTokens, User } from '@arac-hasar/types'; let storePromise: Promise | null = null; async function getStore(): Promise { if (typeof window === 'undefined') return null; if (!('__TAURI_INTERNALS__' in window)) return null; try { if (!storePromise) { storePromise = Store.load('auth.json', { autoSave: true, defaults: {} }); } return await storePromise; } catch { return null; } } // Web-fallback memory bag (only used when running outside Tauri). const memBag: Record = {}; async function rawGet(key: string): Promise { const s = await getStore(); if (!s) return (memBag[key] as T) ?? null; return ((await s.get(key)) as T) ?? null; } async function rawSet(key: string, value: unknown): Promise { const s = await getStore(); if (!s) { memBag[key] = value; return; } await s.set(key, value); await s.save(); } async function rawDelete(key: string): Promise { const s = await getStore(); if (!s) { delete memBag[key]; return; } await s.delete(key); await s.save(); } export interface PersistedAuth { user: User; tokens: AuthTokens; } export async function loadAuth(): Promise { const tokens = await rawGet('tokens'); const user = await rawGet('user'); if (!tokens || !user) return null; return { tokens, user }; } export async function saveAuth(data: PersistedAuth): Promise { await rawSet('tokens', data.tokens); await rawSet('user', data.user); } export async function clearAuth(): Promise { await rawDelete('tokens'); await rawDelete('user'); } export async function updateTokens(tokens: AuthTokens): Promise { await rawSet('tokens', tokens); }