diff --git a/_ts_packages/packages/cortex-ui/src/lib/api.ts b/_ts_packages/packages/cortex-ui/src/lib/api.ts index 1b19610..c389247 100644 --- a/_ts_packages/packages/cortex-ui/src/lib/api.ts +++ b/_ts_packages/packages/cortex-ui/src/lib/api.ts @@ -13,9 +13,16 @@ async function api( Authorization: `Bearer ${c.token}`, 'Content-Type': 'application/json', }, - credentials: 'include', + // Bearer auth via explicit header; no cookies needed. credentials:'omit' + // is the safe cross-origin default and avoids Safari quirks around + // credentials:'include' stripping Authorization on some redirects. + credentials: 'omit', }); - if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); + if (!res.ok) { + let body = ''; + try { body = (await res.text()).slice(0, 200); } catch { /* ignore */ } + throw new Error(`${res.status} ${res.statusText}${body ? ` — ${body}` : ''}`); + } return res.json() as Promise; } diff --git a/_ts_packages/packages/cortex-ui/src/lib/config.ts b/_ts_packages/packages/cortex-ui/src/lib/config.ts index dba36bb..c3ae0d7 100644 --- a/_ts_packages/packages/cortex-ui/src/lib/config.ts +++ b/_ts_packages/packages/cortex-ui/src/lib/config.ts @@ -7,12 +7,22 @@ const DEFAULT_DAEMON = 'http://localhost:9797'; const KEY_DAEMON = 'kei-cortex-daemon'; const KEY_TOKEN = 'kei-cortex-token'; +/** Strip ALL whitespace (spaces, tabs, newlines, zero-width) from a token. */ +function sanitize_token(raw: string): string { + return raw.replace(/\s+/g, ''); +} + export function load_config(): CortexConfig | null { const params = new URLSearchParams(window.location.search); - const override = params.get('daemon'); + const url_daemon = params.get('daemon')?.trim(); + const url_token_raw = params.get('token'); + const url_token = url_token_raw ? sanitize_token(url_token_raw) : null; + if (url_daemon) localStorage.setItem(KEY_DAEMON, url_daemon); + if (url_token) localStorage.setItem(KEY_TOKEN, url_token); const daemon_url = - override ?? localStorage.getItem(KEY_DAEMON) ?? DEFAULT_DAEMON; - const token = params.get('token') ?? localStorage.getItem(KEY_TOKEN) ?? ''; + url_daemon ?? localStorage.getItem(KEY_DAEMON) ?? DEFAULT_DAEMON; + const stored_token = localStorage.getItem(KEY_TOKEN); + const token = url_token ?? (stored_token ? sanitize_token(stored_token) : ''); if (!token) return null; return { daemon_url, token }; }