Refactor runtime bootstrap and ship control flows
This commit is contained in:
76
apps/viewer/src/authSession.ts
Normal file
76
apps/viewer/src/authSession.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import type { AuthSessionResponse } from "./contractsAuth";
|
||||
|
||||
const STORAGE_KEY = "space-game.auth.session";
|
||||
|
||||
export interface AuthSession {
|
||||
userId: string;
|
||||
email: string;
|
||||
roles: string[];
|
||||
accessToken: string;
|
||||
accessTokenExpiresAtUtc: string;
|
||||
refreshToken: string;
|
||||
refreshTokenExpiresAtUtc: string;
|
||||
}
|
||||
|
||||
let currentSession: AuthSession | null = loadStoredSession();
|
||||
const listeners = new Set<(session: AuthSession | null) => void>();
|
||||
|
||||
export function getAuthSession(): AuthSession | null {
|
||||
return currentSession;
|
||||
}
|
||||
|
||||
export function setAuthSession(session: AuthSessionResponse | null) {
|
||||
currentSession = session ? { ...session } : null;
|
||||
persistSession(currentSession);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
export function clearAuthSession() {
|
||||
currentSession = null;
|
||||
persistSession(null);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
export function subscribeToAuthSession(listener: (session: AuthSession | null) => void) {
|
||||
listeners.add(listener);
|
||||
return () => listeners.delete(listener);
|
||||
}
|
||||
|
||||
function loadStoredSession(): AuthSession | null {
|
||||
if (typeof window === "undefined") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const raw = window.localStorage.getItem(STORAGE_KEY);
|
||||
if (!raw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(raw) as AuthSession;
|
||||
return parsed?.accessToken && parsed?.refreshToken
|
||||
? { ...parsed, roles: Array.isArray(parsed.roles) ? parsed.roles : [] }
|
||||
: null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function persistSession(session: AuthSession | null) {
|
||||
if (typeof window === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
window.localStorage.removeItem(STORAGE_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(session));
|
||||
}
|
||||
|
||||
function notifyListeners() {
|
||||
for (const listener of listeners) {
|
||||
listener(currentSession);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user