/** * When the server runs behind ALBION_API_KEY (any public deployment), the web * UI must send it too. We store the key in localStorage and transparently add * `Authorization: Bearer ` to same-origin /api requests via a fetch wrapper, * so individual pages keep calling fetch('/api/...') unchanged. * * On localhost with no key configured, everything works with an empty key. */ const STORAGE_KEY = 'albion_api_key'; export function getApiKey(): string { return localStorage.getItem(STORAGE_KEY) ?? ''; } export function setApiKey(key: string): void { if (key) localStorage.setItem(STORAGE_KEY, key); else localStorage.removeItem(STORAGE_KEY); } let unauthorizedHandler: (() => void) | null = null; export function onUnauthorized(handler: () => void): void { unauthorizedHandler = handler; } export function installFetchAuth(): void { const original = window.fetch.bind(window); window.fetch = async (input, init) => { const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : (input as Request).url; const isApi = url.startsWith('/api/') || url.includes(`${location.origin}/api/`); const key = getApiKey(); let nextInit = init; if (isApi && key) { const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined)); if (!headers.has('Authorization')) headers.set('Authorization', `Bearer ${key}`); nextInit = { ...init, headers }; } const res = await original(input as any, nextInit); if (isApi && res.status === 401) unauthorizedHandler?.(); return res; }; }