// =============================== // AUTH.JS — Login + Token + Redirect + Auto-Login // =============================== // parseJwt DEVE essere globale function parseJwt(token) { try { const base64Url = token.split('.')[1]; const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); const jsonPayload = decodeURIComponent( atob(base64) .split('') .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)) .join('') ); return JSON.parse(jsonPayload); } catch (e) { console.error("Errore parseJwt:", e); return null; } } (() => { const LOGIN_ENDPOINT = "/auth/login"; const TOKEN_KEY = "token"; // ------------------------------- // Helpers token // ------------------------------- function saveToken(token) { try { localStorage.setItem(TOKEN_KEY, token); } catch (err) { console.error("Errore salvataggio token:", err); } } function getToken() { try { return localStorage.getItem(TOKEN_KEY) || ""; } catch { return ""; } } function clearToken() { try { localStorage.removeItem(TOKEN_KEY); } catch {} } // ------------------------------- // JWT decode // ------------------------------- function decode(token) { return parseJwt(token); } // ------------------------------- // LOGIN // ------------------------------- async function login(email, password) { try { const res = await fetch(LOGIN_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }) }); if (!res.ok) { const msg = await res.text(); throw new Error(msg || "Credenziali non valide"); } const data = await res.json(); if (!data?.token) { throw new Error("Token mancante nella risposta"); } saveToken(data.token); // Notifica globale window.dispatchEvent(new CustomEvent("login:success", { detail: data })); // Auto-logout programmato scheduleAutoLogout(); return data; } catch (err) { console.error("Errore login:", err); throw err; } } // ------------------------------- // CHECK LOGIN // ------------------------------- function isLoggedIn() { const token = getToken(); if (!token) return false; const payload = decode(token); if (!payload?.exp) return false; return payload.exp * 1000 > Date.now(); } // ------------------------------- // USER INFO // ------------------------------- function getUser() { const token = getToken(); if (!token) return null; return decode(token); } // ------------------------------- // REQUIRE AUTH // ------------------------------- function requireAuth(redirectUrl = "/login") { if (!isLoggedIn()) { window.location.assign(redirectUrl); return false; } return true; } // ------------------------------- // AUTO-LOGOUT // ------------------------------- let autoLogoutTimer = null; function scheduleAutoLogout() { clearTimeout(autoLogoutTimer); const token = getToken(); if (!token) return; const payload = decode(token); const expSec = payload?.exp; if (!expSec) return; const msToExp = expSec * 1000 - Date.now(); if (msToExp <= 0) { window.AppAuth.logout?.({ redirect: true }); return; } autoLogoutTimer = setTimeout(() => { window.AppAuth.logout?.({ redirect: true }); }, msToExp); } // ------------------------------- // EXPORT API // ------------------------------- window.AppAuth = Object.freeze({ login, logout: (opts) => window.AppAuthLogout?.logout(opts), isLoggedIn, getUser, requireAuth, scheduleAutoLogout }); // ------------------------------- // INIT // ------------------------------- function init() { if (isLoggedIn()) { scheduleAutoLogout(); } } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); } })();