export const csrfToken = () => document.cookie .split("; ") .find((v) => v.startsWith("rp_csrf=")) ?.split("=")[1] || ""; export const protectedFetch = (url, options = {}) => fetch(url, { ...options, headers: { ...options.headers, "x-csrf-token": csrfToken() }, }); export async function api(url, options = {}) { const response = await protectedFetch(url, { ...options, headers: { "content-type": "application/json", ...options.headers }, }); const body = await response.json().catch(() => ({})); if (response.status === 401 && body.code === "unauthorized") { // This is specifically requireAuth's code for "no valid session" — the session expired // or was revoked mid-page (account/admin pages otherwise show a permanent "could not // load" error with no indication the user was signed out). A 401 with any other code // (e.g. a wrong current password on an account form) is a normal request failure, not a // sign-out, and must not redirect the user away mid-form. location.assign("/login"); return new Promise(() => {}); // navigation is already underway; never resolve } if (!response.ok) { const error = new Error(body.error || body.code || "request_failed"); error.code = body.code; error.status = response.status; throw error; } return body; }