/** * Cross-tab auth storage policy (document-only). * * Credentials mirror in sessionStorage and localStorage under `aetherforge_auth`. * Reads prefer sessionStorage, then fall back to localStorage (survives tab close). * * Same-tab sync: login/logout dispatch the `aetherforge-auth` CustomEvent so SessionGate, * WebSocketProvider, and PresenceContext re-read credentials without a full reload. * * Cross-tab: intentionally NOT synced via the `storage` event. Logout in tab A clears * localStorage but tab B keeps in-memory session until refresh or a 401. Each tab owns * its WS lifecycle after auth changes in that tab. */ export const AUTH_STORAGE_KEY = 'aetherforge_auth'; export const AUTH_EXPIRED_FLAG_KEY = 'aetherforge_auth_expired'; export const AUTH_SYNC_EVENT = 'aetherforge-auth'; /** By policy we never listen to cross-tab `storage` events for auth. */ export const AUTH_CROSS_TAB_STORAGE_SYNC = false; export function describeAuthStoragePolicy(): string { return 'dual-write session+local; same-tab aetherforge-auth; no storage-event cross-tab sync'; }