147 lines
3.8 KiB
JavaScript
147 lines
3.8 KiB
JavaScript
// ===============================
|
|
// LOGOUT — pulizia token + revoca + auto-logout JWT
|
|
// ===============================
|
|
|
|
(() => {
|
|
const AUTH_LOGOUT_ENDPOINT = "/auth/logout";
|
|
const TOKEN_KEYS = ["token", "access_token", "refresh_token"];
|
|
|
|
// -------------------------------
|
|
// Helpers token
|
|
// -------------------------------
|
|
function getToken() {
|
|
try {
|
|
return (
|
|
localStorage.getItem("token") ||
|
|
localStorage.getItem("access_token") ||
|
|
""
|
|
);
|
|
} catch {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
function clearTokens() {
|
|
try {
|
|
TOKEN_KEYS.forEach(k => localStorage.removeItem(k));
|
|
} catch {}
|
|
}
|
|
|
|
// -------------------------------
|
|
// Logout lato server
|
|
// -------------------------------
|
|
async function serverLogout(token) {
|
|
try {
|
|
const headers = token ? { Authorization: `Bearer ${token}` } : {};
|
|
await fetch(AUTH_LOGOUT_ENDPOINT, { method: "POST", headers });
|
|
} catch (err) {
|
|
console.warn("Logout server fallito (ignoro):", err);
|
|
}
|
|
}
|
|
|
|
// -------------------------------
|
|
// Redirect
|
|
// -------------------------------
|
|
function getRedirectUrl() {
|
|
const btn = document.querySelector("[data-logout]");
|
|
return btn?.getAttribute("data-redirect") || "/";
|
|
}
|
|
|
|
function redirect(url) {
|
|
window.location.assign(url || "/");
|
|
}
|
|
|
|
// -------------------------------
|
|
// Auto-logout alla scadenza JWT
|
|
// -------------------------------
|
|
let autoLogoutTimer = null;
|
|
|
|
function scheduleAutoLogout() {
|
|
clearTimeout(autoLogoutTimer);
|
|
|
|
const token = getToken();
|
|
if (!token) return;
|
|
|
|
const payload = parseJwt(token); // usa la funzione globale già esistente
|
|
const expSec = payload?.exp;
|
|
if (!expSec) return;
|
|
|
|
const msToExp = expSec * 1000 - Date.now();
|
|
if (msToExp <= 0) {
|
|
doLogout({ doRedirect: true });
|
|
return;
|
|
}
|
|
|
|
autoLogoutTimer = setTimeout(() => {
|
|
doLogout({ doRedirect: true });
|
|
}, msToExp);
|
|
}
|
|
|
|
// -------------------------------
|
|
// UI helpers
|
|
// -------------------------------
|
|
function setButtonsDisabled(disabled) {
|
|
document.querySelectorAll("[data-logout]").forEach(btn => {
|
|
btn.disabled = disabled;
|
|
btn.setAttribute("aria-busy", disabled ? "true" : "false");
|
|
});
|
|
}
|
|
|
|
// -------------------------------
|
|
// Azione principale
|
|
// -------------------------------
|
|
async function doLogout({ doRedirect = true } = {}) {
|
|
const token = getToken();
|
|
setButtonsDisabled(true);
|
|
|
|
await serverLogout(token);
|
|
clearTokens();
|
|
|
|
try {
|
|
window.dispatchEvent(new CustomEvent("logout:success"));
|
|
} catch {}
|
|
|
|
if (doRedirect) redirect(getRedirectUrl());
|
|
|
|
setButtonsDisabled(false);
|
|
}
|
|
|
|
// -------------------------------
|
|
// Bind pulsanti
|
|
// -------------------------------
|
|
function bindLogoutButtons() {
|
|
document.querySelectorAll("[data-logout]").forEach(btn => {
|
|
btn.addEventListener("click", async (e) => {
|
|
e.preventDefault();
|
|
if (btn.disabled) return;
|
|
await doLogout({ doRedirect: true });
|
|
});
|
|
});
|
|
}
|
|
|
|
// -------------------------------
|
|
// Public API
|
|
// -------------------------------
|
|
window.AppAuth = Object.freeze({
|
|
logout: (opts) => doLogout(opts),
|
|
isLoggedIn: () => !!getToken()
|
|
});
|
|
|
|
// -------------------------------
|
|
// Init
|
|
// -------------------------------
|
|
function init() {
|
|
bindLogoutButtons();
|
|
scheduleAutoLogout();
|
|
|
|
document.querySelectorAll("[data-logout]").forEach(btn => {
|
|
if (!window.AppAuth.isLoggedIn()) btn.style.display = "none";
|
|
});
|
|
}
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|