photo_server_json_con_aves22/public/js/auth.js
2026-04-18 20:14:42 +02:00

181 lines
No EOL
4 KiB
JavaScript

// ===============================
// 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();
}
})();