aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/dashboard
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/dashboard')
-rw-r--r--src/api/dashboard/dashboard.html44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html
index 0f31d7c..cad0bcf 100644
--- a/src/api/dashboard/dashboard.html
+++ b/src/api/dashboard/dashboard.html
@@ -306,6 +306,8 @@
<span id="node" class="id"></span>
<span id="clock-warning"></span>
<span id="connection"><span id="dot"></span><span id="connection-text">connecting…</span></span>
+ <span id="who" class="gloss"></span>
+ <button id="logout" class="toggle" type="button" hidden>log out</button>
</header>
<main>
<section id="map">
@@ -2310,14 +2312,49 @@ async function tokenCall(url, bearer, body) {
if (!response.ok) throw new Error(response.status + " " + (answer.error || response.statusText));
return answer;
}
+// How the page got in: by its session ("session"), which logging out ends, or by what
+// it can't end (`login` of `POST /auth/login`): the browser's password ("htpasswd"), the
+// proxy's ("header").
+let loggedIn = null;
+function showWho() {
+ const who = document.getElementById("who");
+ const by = { htpasswd: " (by this browser's password: close the browser to log out)",
+ header: " (by your proxy: log out there)" };
+ who.textContent = token ? token.user + (by[loggedIn] || "") : "";
+ document.getElementById("logout").hidden = !token || loggedIn !== "session";
+}
+document.getElementById("logout").addEventListener("click", async () => {
+ // This browser's session ends; other sessions of the user go on.
+ await fetch("../auth/session", { method: "DELETE", credentials: "same-origin" }).catch(() => {});
+ clearTimeout(tokenTimer);
+ token = narrowToken = null;
+ // In still, by what the page can't end: said so; else to the login page.
+ try {
+ token = await tokenCall("../auth/login");
+ loggedIn = token.login;
+ showWho();
+ obtainTokens();
+ } catch (_) {
+ location.assign("../login");
+ }
+});
async function obtainTokens() {
clearTimeout(tokenTimer);
try {
// Refreshed as the session (`POST /auth/session`), whose cookie lets the page in;
// the first: by that cookie, else by the browser's password or the proxy's.
- token = token && token.expiresAt > Date.now() + 60000
- ? await tokenCall("../auth/session", token.token)
- : await tokenCall("../auth/session").catch(() => tokenCall("../auth/login"));
+ if (token && token.expiresAt > Date.now() + 60000) {
+ token = await tokenCall("../auth/session", token.token);
+ } else {
+ try {
+ token = await tokenCall("../auth/session");
+ loggedIn = "session";
+ } catch (_) {
+ token = await tokenCall("../auth/login");
+ loggedIn = token.login;
+ }
+ }
+ showWho();
narrowToken = await tokenCall("../auth/refresh", token.token, { limit: READ_MEMBERS });
tokenWhy = null;
const life = Math.min(token.expiresAt, narrowToken.expiresAt) - Date.now();
@@ -2330,6 +2367,7 @@ async function obtainTokens() {
} catch (error) {
token = narrowToken = null;
tokenWhy = "no token: " + error.message;
+ showWho();
tokenTimer = setTimeout(obtainTokens, 30000);
}
}