feat: add session expiry warning
This commit is contained in:
82
backend/workflows/static/workflows/js/session_warning.js
Normal file
82
backend/workflows/static/workflows/js/session_warning.js
Normal file
@@ -0,0 +1,82 @@
|
||||
(function () {
|
||||
const config = window.WorkdockSessionConfig;
|
||||
if (!config || !config.idleTimeoutSeconds) return;
|
||||
|
||||
const warningLeadSeconds = Math.min(300, Math.max(60, Math.floor(config.idleTimeoutSeconds / 6)));
|
||||
const modal = document.getElementById("app-session-warning-modal");
|
||||
const countdown = document.getElementById("app-session-warning-countdown");
|
||||
const extendButton = document.getElementById("app-session-warning-extend");
|
||||
if (!modal || !countdown || !extendButton) return;
|
||||
|
||||
let lastConfirmedAt = Date.now();
|
||||
let warningVisible = false;
|
||||
let keepaliveInFlight = false;
|
||||
|
||||
function getCsrfToken() {
|
||||
const cookie = document.cookie
|
||||
.split(";")
|
||||
.map((item) => item.trim())
|
||||
.find((item) => item.startsWith("csrftoken="));
|
||||
return cookie ? decodeURIComponent(cookie.split("=")[1]) : "";
|
||||
}
|
||||
|
||||
function hideWarning() {
|
||||
if (!warningVisible) return;
|
||||
modal.hidden = true;
|
||||
modal.setAttribute("aria-hidden", "true");
|
||||
warningVisible = false;
|
||||
}
|
||||
|
||||
function showWarning(secondsLeft) {
|
||||
countdown.textContent = `Noch etwa ${secondsLeft} Sekunden bis zur automatischen Abmeldung.`;
|
||||
if (warningVisible) return;
|
||||
modal.hidden = false;
|
||||
modal.setAttribute("aria-hidden", "false");
|
||||
warningVisible = true;
|
||||
}
|
||||
|
||||
async function sendKeepalive() {
|
||||
if (keepaliveInFlight) return;
|
||||
keepaliveInFlight = 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 }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
window.location.href = config.loginUrl;
|
||||
return;
|
||||
}
|
||||
lastConfirmedAt = Date.now();
|
||||
hideWarning();
|
||||
} catch (_error) {
|
||||
window.location.href = config.loginUrl;
|
||||
} finally {
|
||||
keepaliveInFlight = false;
|
||||
}
|
||||
}
|
||||
|
||||
function tick() {
|
||||
const elapsedSeconds = Math.floor((Date.now() - lastConfirmedAt) / 1000);
|
||||
const secondsLeft = config.idleTimeoutSeconds - elapsedSeconds;
|
||||
if (secondsLeft <= 0) {
|
||||
window.location.href = config.loginUrl;
|
||||
return;
|
||||
}
|
||||
if (secondsLeft <= warningLeadSeconds) {
|
||||
showWarning(secondsLeft);
|
||||
}
|
||||
}
|
||||
|
||||
extendButton.addEventListener("click", function () {
|
||||
sendKeepalive();
|
||||
});
|
||||
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
Reference in New Issue
Block a user