(function () { "use strict"; const TOKEN_KEY = "orgWebJwt"; const LOGIN_PATH = "/home/login.html"; function token() { return window.localStorage.getItem(TOKEN_KEY) || ""; } function isLoginPage() { return window.location.pathname === LOGIN_PATH; } function loginUrl() { const next = window.location.pathname + window.location.search + window.location.hash; return `${LOGIN_PATH}?next=${encodeURIComponent(next)}`; } function redirectToLogin() { if (!isLoginPage()) { window.location.assign(loginUrl()); } } function authHeaders(existingHeaders = {}) { const headers = new Headers(existingHeaders); const jwt = token(); if (jwt) headers.set("Authorization", `Bearer ${jwt}`); return headers; } async function authFetch(input, options = {}) { const response = await fetch(input, { ...options, credentials: options.credentials || "same-origin", headers: authHeaders(options.headers), }); if (response.status === 401) { window.localStorage.removeItem(TOKEN_KEY); redirectToLogin(); } return response; } async function login(username, password) { const response = await fetch("/api/auth/login", { method: "POST", credentials: "same-origin", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password }), }); const data = await response.json().catch(() => ({})); if (!response.ok) { throw new Error(data.error || "Login failed"); } window.localStorage.setItem(TOKEN_KEY, data.token); return data.token; } async function hasServerSession() { if (token()) return true; const response = await fetch("/api/auth/check", { method: "GET", credentials: "same-origin", cache: "no-store", }); return response.status === 204; } function initLoginForm() { const form = document.getElementById("login-form"); if (!form) return; const message = document.getElementById("login-message"); form.addEventListener("submit", async (event) => { event.preventDefault(); const submit = form.querySelector("button[type='submit']"); form.classList.add("is-loading"); form.setAttribute("aria-busy", "true"); if (submit) submit.disabled = true; if (message) message.textContent = ""; try { await login(form.username.value.trim(), form.password.value); const params = new URLSearchParams(window.location.search); window.location.assign(params.get("next") || "/"); } catch (error) { if (message) message.textContent = error.message; } finally { if (submit) submit.disabled = false; form.classList.remove("is-loading"); form.removeAttribute("aria-busy"); } }); } window.orgAuth = { fetch: authFetch, headers: authHeaders, token, logout: async () => { await fetch("/api/auth/logout", { method: "POST", credentials: "same-origin", }).catch(() => {}); window.localStorage.removeItem(TOKEN_KEY); redirectToLogin(); }, }; document.addEventListener("DOMContentLoaded", async () => { initLoginForm(); if (!isLoginPage() && !(await hasServerSession())) { redirectToLogin(); } }); })();