65 lines
2.3 KiB
JavaScript
65 lines
2.3 KiB
JavaScript
// Shows a management toolbar + signed-in indicator on every page when the
|
|||
|
|
// browser holds valid credentials. The public gallery is static and carries no
|
||
|
|
// markup for this; the bar is built here only after /api/session confirms the
|
||
|
|
// viewer is authenticated, so logged-out visitors see nothing and get no login
|
||
|
|
// dialog.
|
||
|
|
//
|
||
|
|
// A page may set <body data-slug="..."> (the photo pages do) to get an
|
||
|
|
// "Edit this" link straight to that post in /manage.
|
||
|
|
(function () {
|
||
|
|
fetch("/api/session", { headers: { Accept: "application/json" }, cache: "no-store" })
|
||
|
|
.then((r) => (r.ok ? r.json() : { authenticated: false }))
|
||
|
|
.then((s) => {
|
||
|
|
if (s && s.authenticated) buildBar();
|
||
|
|
})
|
||
|
|
.catch(() => {});
|
||
|
|
|
||
|
|
function el(tag, cls, text) {
|
||
|
|
const e = document.createElement(tag);
|
||
|
|
if (cls) e.className = cls;
|
||
|
|
if (text != null) e.textContent = text;
|
||
|
|
return e;
|
||
|
|
}
|
||
|
|
|
||
|
|
function buildBar() {
|
||
|
|
document.body.classList.add("authed");
|
||
|
|
|
||
|
|
const bar = el("div", "session-bar");
|
||
|
|
const path = location.pathname.replace(/\/$/, "");
|
||
|
|
|
||
|
|
const link = (href, label) => {
|
||
|
|
const a = el("a", null, label);
|
||
|
|
a.href = href;
|
||
|
|
bar.appendChild(a);
|
||
|
|
};
|
||
|
|
|
||
|
|
if (path !== "/upload") link("/upload", "Upload");
|
||
|
|
if (path !== "/manage") link("/manage", "Manage");
|
||
|
|
|
||
|
|
const slug = document.body.dataset.slug;
|
||
|
|
if (slug) link("/manage?edit=" + encodeURIComponent(slug), "Edit this");
|
||
|
|
|
||
|
|
bar.appendChild(el("span", "session-dot", "● signed in"));
|
||
|
|
|
||
|
|
// Best-effort logout. HTTP Basic has no real sign-out — the browser caches
|
||
|
|
// credentials and clears them reliably only when the window closes — so
|
||
|
|
// this overwrites the cached credential with a throwaway one and reloads.
|
||
|
|
// It works in some browsers and not others; a dependable logout would need
|
||
|
|
// cookie sessions.
|
||
|
|
const out = el("a", "session-out", "log out");
|
||
|
|
out.href = "#";
|
||
|
|
out.title = "Best-effort — HTTP Basic auth has no reliable logout";
|
||
|
|
out.addEventListener("click", (e) => {
|
||
|
|
e.preventDefault();
|
||
|
|
fetch("/api/session", {
|
||
|
|
headers: { Authorization: "Basic " + btoa("logout:" + Date.now()) },
|
||
|
|
cache: "no-store",
|
||
|
|
})
|
||
|
|
.catch(() => {})
|
||
|
|
.finally(() => setTimeout(() => location.reload(), 150));
|
||
|
|
});
|
||
|
|
bar.appendChild(out);
|
||
|
|
|
||
|
|
document.body.appendChild(bar);
|
||
|
|
}
|
||
|
|
})();
|