// The signed-in account & session: the bootstrap `me` probe, multi-account switch/list, sign-out, // app version, and preference save. Only touches core's req. import { req } from "./core"; export interface Me { id: number; email: string; display_name: string | null; avatar_url: string | null; role: string; is_demo: boolean; has_google: boolean; has_password: boolean; google_enabled: boolean; plex_enabled: boolean; can_read: boolean; can_write: boolean; pending_invites: number; /** Admin-only: false when SMTP is incomplete, so every outbound message is silently skipped. */ email_configured: boolean; preferences: Record; } export interface Account { id: number; email: string; display_name: string | null; avatar_url: string | null; active: boolean; } export interface VersionInfo { app_version: string; git_sha: string; build_date: string | null; db_revision: string | null; } export const accountApi = { // Bootstrap probe: 200 always. Returns the user when signed in, or null when logged out // (the endpoint answers `{authenticated:false}` rather than 401, so the public landing never // logs a failed request to the console). React Query treats the null as data, not an error. me: async (): Promise => { // Always 200: `{ authenticated: false }` when logged out, else the full Me + `authenticated`. const r = await req<{ authenticated: boolean } & Partial>("/api/me"); return r.authenticated ? (r as Me) : null; }, accounts: (): Promise => req("/api/me/accounts"), deleteAccount: (): Promise<{ deleted: boolean }> => req("/api/me/account", { method: "DELETE" }), switchAccount: (userId: number): Promise<{ ok: boolean; user_id: number }> => req("/api/me/switch", { method: "POST", body: JSON.stringify({ user_id: userId }) }), // Signs the current tab's active account out of the browser wallet (per-tab aware via the // X-Siftlode-Account header that req() attaches). logout: (): Promise<{ ok: boolean; switched: boolean }> => req("/auth/logout", { method: "POST" }), version: (): Promise => req("/api/version"), // Overwriting preferences is idempotent, so let it retry on a transient gateway blip. savePrefs: (p: Record) => req("/api/me/preferences", { method: "PUT", body: JSON.stringify(p) }, { idempotent: true }), };