fix: prevent stale session warning redirect loops
This commit is contained in:
@@ -18,6 +18,8 @@
|
|||||||
let lastConfirmedAt = Date.now();
|
let lastConfirmedAt = Date.now();
|
||||||
let warningVisible = false;
|
let warningVisible = false;
|
||||||
let keepaliveInFlight = false;
|
let keepaliveInFlight = false;
|
||||||
|
let timeoutCheckInFlight = false;
|
||||||
|
let redirectInFlight = false;
|
||||||
|
|
||||||
function getCsrfToken() {
|
function getCsrfToken() {
|
||||||
const cookie = document.cookie
|
const cookie = document.cookie
|
||||||
@@ -44,11 +46,22 @@
|
|||||||
status.textContent = "";
|
status.textContent = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function redirectToLogin() {
|
||||||
|
if (redirectInFlight) return;
|
||||||
|
redirectInFlight = true;
|
||||||
|
window.location.href = config.loginUrl;
|
||||||
|
}
|
||||||
|
|
||||||
function readStoredConfirmedAt() {
|
function readStoredConfirmedAt() {
|
||||||
try {
|
try {
|
||||||
const raw = window.localStorage.getItem(storageKey);
|
const raw = window.localStorage.getItem(storageKey);
|
||||||
const parsed = raw ? Number.parseInt(raw, 10) : NaN;
|
const parsed = raw ? Number.parseInt(raw, 10) : NaN;
|
||||||
return Number.isFinite(parsed) ? parsed : null;
|
if (!Number.isFinite(parsed)) return null;
|
||||||
|
const maxAgeMs = config.idleTimeoutSeconds * 1000;
|
||||||
|
if (Date.now() - parsed >= maxAgeMs) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return parsed;
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -95,8 +108,9 @@
|
|||||||
credentials: "same-origin",
|
credentials: "same-origin",
|
||||||
body: JSON.stringify({ keepalive: true }),
|
body: JSON.stringify({ keepalive: true }),
|
||||||
});
|
});
|
||||||
if (!response.ok) {
|
const contentType = (response.headers.get("content-type") || "").toLowerCase();
|
||||||
window.location.href = config.loginUrl;
|
if (!response.ok || response.redirected || !contentType.includes("application/json")) {
|
||||||
|
redirectToLogin();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
syncConfirmedAt(Date.now(), "self");
|
syncConfirmedAt(Date.now(), "self");
|
||||||
@@ -108,12 +122,46 @@
|
|||||||
hideStatus();
|
hideStatus();
|
||||||
}, 1200);
|
}, 1200);
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
window.location.href = config.loginUrl;
|
redirectToLogin();
|
||||||
} finally {
|
} finally {
|
||||||
keepaliveInFlight = false;
|
keepaliveInFlight = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function confirmSessionOrRedirect() {
|
||||||
|
if (timeoutCheckInFlight || keepaliveInFlight || redirectInFlight) return;
|
||||||
|
timeoutCheckInFlight = true;
|
||||||
|
try {
|
||||||
|
const response = await fetch(config.keepaliveUrl, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-CSRFToken": getCsrfToken(),
|
||||||
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
|
},
|
||||||
|
credentials: "same-origin",
|
||||||
|
body: JSON.stringify({ keepalive: true, timeout_check: true }),
|
||||||
|
});
|
||||||
|
const contentType = (response.headers.get("content-type") || "").toLowerCase();
|
||||||
|
if (!response.ok || response.redirected || !contentType.includes("application/json")) {
|
||||||
|
try {
|
||||||
|
window.localStorage.removeItem(storageKey);
|
||||||
|
} catch (_error) {
|
||||||
|
// Ignore storage cleanup failures.
|
||||||
|
}
|
||||||
|
redirectToLogin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
syncConfirmedAt(Date.now(), "self");
|
||||||
|
hideWarning();
|
||||||
|
hideStatus();
|
||||||
|
} catch (_error) {
|
||||||
|
redirectToLogin();
|
||||||
|
} finally {
|
||||||
|
timeoutCheckInFlight = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const storedConfirmedAt = readStoredConfirmedAt();
|
const storedConfirmedAt = readStoredConfirmedAt();
|
||||||
if (storedConfirmedAt) {
|
if (storedConfirmedAt) {
|
||||||
lastConfirmedAt = storedConfirmedAt;
|
lastConfirmedAt = storedConfirmedAt;
|
||||||
@@ -149,7 +197,7 @@
|
|||||||
const elapsedSeconds = Math.floor((Date.now() - lastConfirmedAt) / 1000);
|
const elapsedSeconds = Math.floor((Date.now() - lastConfirmedAt) / 1000);
|
||||||
const secondsLeft = config.idleTimeoutSeconds - elapsedSeconds;
|
const secondsLeft = config.idleTimeoutSeconds - elapsedSeconds;
|
||||||
if (secondsLeft <= 0) {
|
if (secondsLeft <= 0) {
|
||||||
window.location.href = config.loginUrl;
|
confirmSessionOrRedirect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (secondsLeft <= warningLeadSeconds) {
|
if (secondsLeft <= warningLeadSeconds) {
|
||||||
|
|||||||
Reference in New Issue
Block a user