v0.31.3
This commit is contained in:
1 parent
0facfe6f5c
commit
95c55da2ee
39 files changed
+715
-151
No files matched your search
@@ -0,0 +1,74 @@
|
||||
// One in-flight validation per authenticated document. Neither BFCache restore nor
|
||||
// visibility resume may trigger a reload: a 403 is a recoverable, visible error.
|
||||
function revalidateSession() {
|
||||
if (!authenticated) return Promise.resolve(false);
|
||||
if (sessionCheckPromise) return sessionCheckPromise;
|
||||
const epoch = authEpoch;
|
||||
window.rustProxyRefresh?.suspendForSessionValidation();
|
||||
const check = (async () => {
|
||||
try {
|
||||
const info = await api("/api/auth/session");
|
||||
if (!authenticated || epoch !== authEpoch) return false;
|
||||
sessionInfo = info;
|
||||
csrf = info.csrf_token;
|
||||
renderSession();
|
||||
hideSessionValidationFailure();
|
||||
window.rustProxyRefresh?.completeSessionValidation(true);
|
||||
return true;
|
||||
} catch (error) {
|
||||
// api() locks and navigates to the login document on a 401.
|
||||
if (!authenticated || epoch !== authEpoch || error?.status === 401) return false;
|
||||
window.rustProxyRefresh?.completeSessionValidation(false);
|
||||
showSessionValidationFailure(error);
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
sessionCheckPromise = check;
|
||||
void check.then(
|
||||
() => { if (sessionCheckPromise === check) sessionCheckPromise = null; },
|
||||
() => { if (sessionCheckPromise === check) sessionCheckPromise = null; }
|
||||
);
|
||||
return check;
|
||||
}
|
||||
function displayStartupError(error, sessionResume = false) {
|
||||
$("login").hidden = true;
|
||||
$("workspace").hidden = true;
|
||||
$("logout").hidden = !authenticated;
|
||||
document.documentElement.classList.add("app-loading", "app-startup-failed");
|
||||
document.documentElement.classList.toggle("app-session-failed", sessionResume);
|
||||
$("app-startup-title").textContent = sessionResume
|
||||
? t("sessionValidationFailed")
|
||||
: (languagePacks.size ? t("startupFailed") : "Could not load RustProxy");
|
||||
const detail = $("app-startup-detail");
|
||||
detail.textContent = error?.message || String(error);
|
||||
detail.hidden = false;
|
||||
$("app-startup-reload").hidden = sessionResume;
|
||||
$("app-session-retry").hidden = !sessionResume;
|
||||
}
|
||||
function showSessionValidationFailure(error) {
|
||||
// Keep the workspace inaccessible while its session cannot be verified.
|
||||
displayStartupError(error, true);
|
||||
}
|
||||
function hideSessionValidationFailure() {
|
||||
if (!document.documentElement.classList.contains("app-session-failed")) return;
|
||||
document.documentElement.classList.remove("app-session-failed", "app-loading", "app-startup-failed");
|
||||
$("app-startup-detail").hidden = true;
|
||||
$("app-startup-detail").textContent = "";
|
||||
$("app-startup-reload").hidden = false;
|
||||
$("app-session-retry").hidden = true;
|
||||
$("workspace").hidden = false;
|
||||
$("logout").hidden = false;
|
||||
}
|
||||
$("app-session-retry").addEventListener("click", () => {
|
||||
const button = $("app-session-retry");
|
||||
button.disabled = true;
|
||||
void revalidateSession().then(
|
||||
() => { button.disabled = false; },
|
||||
() => { button.disabled = false; }
|
||||
);
|
||||
});
|
||||
function showStartupFailure(error) {
|
||||
// All startup failure paths stop background tasks and show visible recovery.
|
||||
window.rustProxyRefresh?.stop();
|
||||
displayStartupError(error);
|
||||
}
|
||||
Reference in new issue
Block a user