ultisuite-client/lib/auth/native-session.ts
R3D347HR4Y d6d18f911b
Some checks failed
E2E / Playwright e2e (push) Has been cancelled
Lots of stuff and mobile app
2026-06-17 00:13:28 +02:00

57 lines
1.8 KiB
TypeScript

/**
* Native session bridge: reads the session from the OS secure store, applies it
* to the in-memory auth store, and refreshes against Authentik when needed.
* Mirrors `session-sync.ts` (the web/httpOnly-cookie path) for the Tauri shells.
*/
import { useAuthStore } from "@/lib/api/auth-store"
import { useSessionGuardStore } from "@/lib/auth/session-guard-store"
import type { PlatformUser } from "@/lib/auth/jwt-claims"
import { readSession, type NativeSession } from "@/lib/native/secure-store"
import { nativeRefresh } from "@/lib/auth/native-auth"
const REFRESH_LEAD_MS = 60_000
function applyNativeSession(session: NativeSession | null): boolean {
if (session?.accessToken && session.expiresAt) {
useAuthStore
.getState()
.login(
session.accessToken,
session.refreshToken ?? "",
session.expiresAt,
(session.user as PlatformUser | null) ?? null
)
useSessionGuardStore.getState().clear()
return true
}
return false
}
/** Hydrate the store from the secure store (used on boot). */
export async function loadNativeSession(): Promise<boolean> {
return applyNativeSession(await readSession())
}
/** Return a valid bearer token, refreshing first if it's about to expire. */
export async function ensureNativeAccessToken(): Promise<string | null> {
let session = await readSession()
if (!session) {
useAuthStore.getState().logout()
return null
}
const aboutToExpire = Date.now() >= session.expiresAt - REFRESH_LEAD_MS
if (aboutToExpire && session.refreshToken) {
const refreshed = await nativeRefresh()
if (refreshed) session = refreshed
}
if (Date.now() >= session.expiresAt && !session.refreshToken) {
useAuthStore.getState().logout()
return null
}
applyNativeSession(session)
return useAuthStore.getState().accessToken
}