const API = window.location.origin; async function signup(username, password) { const res = await fetch(API + "/api/auth/signup", { method: "POST", headers: {"Content-Type": "application/json", "X-CSRF-Token": getCsrfToken()}, body: JSON.stringify({username, password}), credentials: "include" }); let data; try { data = await res.json(); } catch { data = {}; } if (res.ok) { window.location.href = "/dashboard"; } else { throw new Error(data.error || "Signup failed (server error)"); } } async function login(username, password) { const res = await fetch(API + "/api/auth/login", { method: "POST", headers: {"Content-Type": "application/json", "X-CSRF-Token": getCsrfToken()}, body: JSON.stringify({username, password}), credentials: "include" }); let data; try { data = await res.json(); } catch { data = {}; } if (res.ok) { window.location.href = "/dashboard"; } else { throw new Error(data.error || "Login failed (server error)"); } } async function logout() { await fetch(API + "/api/auth/logout", { method: "POST", headers: {"X-CSRF-Token": getCsrfToken()}, credentials: "include" }); window.location.href = "/login"; } function getCsrfToken() { const match = document.cookie.match(/csrf_token=([^;]+)/); return match ? decodeURIComponent(match[1]) : ""; } async function apiFetch(path, options = {}) { const headers = {"Content-Type": "application/json", ...options.headers}; if (options.method && options.method !== "GET") { headers["X-CSRF-Token"] = getCsrfToken(); } const res = await fetch(API + path, {...options, headers, credentials: "include"}); if (res.status === 401) { window.location.href = "/login"; return null; } let data; try { data = await res.json(); } catch { data = {}; } return data; } async function checkAuth() { try { const res = await fetch(API + "/api/auth/me", {credentials: "include"}); if (!res.ok) { window.location.href = "/login"; return null; } let data; try { data = await res.json(); } catch { data = {}; } return data; } catch { window.location.href = "/login"; return null; } }