225 lines
4.5 KiB
JavaScript
225 lines
4.5 KiB
JavaScript
// ===============================
|
|
// AUTH.JS
|
|
// Login, JWT, redirect e auto logout
|
|
// ===============================
|
|
|
|
// Deve rimanere globale se viene usata da altri file
|
|
function parseJwt(token) {
|
|
try {
|
|
const payload = token.split(".")[1];
|
|
|
|
if (!payload) return null;
|
|
|
|
const base64 = payload
|
|
.replace(/-/g, "+")
|
|
.replace(/_/g, "/")
|
|
.padEnd(Math.ceil(payload.length / 4) * 4, "=");
|
|
|
|
const json = decodeURIComponent(
|
|
atob(base64)
|
|
.split("")
|
|
.map((char) =>
|
|
`%${char.charCodeAt(0).toString(16).padStart(2, "0")}`
|
|
)
|
|
.join("")
|
|
);
|
|
|
|
return JSON.parse(json);
|
|
} catch (error) {
|
|
console.error("[AUTH] JWT non valido:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
(() => {
|
|
"use strict";
|
|
|
|
const LOGIN_ENDPOINT = "/auth/login";
|
|
const LOGIN_PAGE = "/login";
|
|
const TOKEN_KEY = "token";
|
|
|
|
let autoLogoutTimer = null;
|
|
|
|
// -------------------------------
|
|
// TOKEN
|
|
// -------------------------------
|
|
|
|
function saveToken(token) {
|
|
try {
|
|
localStorage.setItem(TOKEN_KEY, token);
|
|
} catch (error) {
|
|
console.error("[AUTH] Errore salvataggio token:", error);
|
|
}
|
|
}
|
|
|
|
function getToken() {
|
|
try {
|
|
return localStorage.getItem(TOKEN_KEY) || "";
|
|
} catch {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
function clearToken() {
|
|
clearTimeout(autoLogoutTimer);
|
|
autoLogoutTimer = null;
|
|
|
|
try {
|
|
localStorage.removeItem(TOKEN_KEY);
|
|
} catch (error) {
|
|
console.error("[AUTH] Errore rimozione token:", error);
|
|
}
|
|
}
|
|
|
|
// -------------------------------
|
|
// LOGIN
|
|
// -------------------------------
|
|
|
|
async function login(email, password) {
|
|
const response = await fetch(LOGIN_ENDPOINT, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ email, password }),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const message = await response.text();
|
|
throw new Error(message || "Credenziali non valide");
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (!data?.token) {
|
|
throw new Error("Token mancante nella risposta");
|
|
}
|
|
|
|
saveToken(data.token);
|
|
scheduleAutoLogout();
|
|
|
|
window.dispatchEvent(
|
|
new CustomEvent("login:success", {
|
|
detail: data,
|
|
})
|
|
);
|
|
|
|
return data;
|
|
}
|
|
|
|
// -------------------------------
|
|
// VERIFICA AUTENTICAZIONE
|
|
// -------------------------------
|
|
|
|
function isLoggedIn() {
|
|
const token = getToken();
|
|
const payload = token ? parseJwt(token) : null;
|
|
|
|
if (!payload?.exp) {
|
|
return false;
|
|
}
|
|
|
|
const valid = payload.exp * 1000 > Date.now();
|
|
|
|
console.log("[AUTH CHECK]", {
|
|
valid,
|
|
user: payload.name,
|
|
exp: new Date(payload.exp * 1000).toISOString(),
|
|
});
|
|
|
|
return valid;
|
|
}
|
|
|
|
function getUser() {
|
|
const token = getToken();
|
|
return token ? parseJwt(token) : null;
|
|
}
|
|
|
|
function requireAuth(redirectUrl = LOGIN_PAGE) {
|
|
if (isLoggedIn()) {
|
|
return true;
|
|
}
|
|
|
|
clearToken();
|
|
|
|
const currentPath =
|
|
window.location.pathname +
|
|
window.location.search +
|
|
window.location.hash;
|
|
|
|
const separator = redirectUrl.includes("?") ? "&" : "?";
|
|
|
|
window.location.replace(
|
|
`${redirectUrl}${separator}redirect=${encodeURIComponent(currentPath)}`
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
// -------------------------------
|
|
// AUTO LOGOUT
|
|
// -------------------------------
|
|
|
|
function scheduleAutoLogout() {
|
|
clearTimeout(autoLogoutTimer);
|
|
autoLogoutTimer = null;
|
|
|
|
const payload = getUser();
|
|
const expiresAt = payload?.exp ? payload.exp * 1000 : 0;
|
|
const timeout = expiresAt - Date.now();
|
|
|
|
if (!expiresAt) {
|
|
return;
|
|
}
|
|
|
|
if (timeout <= 0) {
|
|
logout({ redirect: true });
|
|
return;
|
|
}
|
|
|
|
autoLogoutTimer = setTimeout(() => {
|
|
logout({ redirect: true });
|
|
}, timeout);
|
|
}
|
|
|
|
function logout(options = {}) {
|
|
clearToken();
|
|
|
|
if (window.AppAuthLogout?.logout) {
|
|
return window.AppAuthLogout.logout(options);
|
|
}
|
|
|
|
if (options.redirect !== false) {
|
|
window.location.replace(LOGIN_PAGE);
|
|
}
|
|
}
|
|
|
|
// -------------------------------
|
|
// INIT
|
|
// -------------------------------
|
|
|
|
function init() {
|
|
if (isLoggedIn()) {
|
|
scheduleAutoLogout();
|
|
}
|
|
}
|
|
|
|
// -------------------------------
|
|
// API GLOBALE
|
|
// -------------------------------
|
|
|
|
window.AppAuth = Object.freeze({
|
|
login,
|
|
logout,
|
|
isLoggedIn,
|
|
getUser,
|
|
requireAuth,
|
|
scheduleAutoLogout,
|
|
});
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", init, { once: true });
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|