diff options
| author | tv <tv@krebsco.de> | 2026-11-07 22:35:22 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-07 22:35:22 +0100 |
| commit | 56a3dca1874fba17c3d174be451af9478b3bfb9d (patch) | |
| tree | 819e3a1d4902c6847b429dd69269ef475d067a45 /src/api/dashboard/dashboard.html | |
| parent | 7323e8ed8598cda9784493aa3334d947120b53d8 (diff) | |
dashboard: a token handed over to another member's dashboard
Opening another member's dashboard passes a token reading only, for
five minutes, in the URL's fragment; its login page begins a session
with it. Tokens may be asked for with a shorter lifetime.
Auth plan M3 (hand-off).
Diffstat (limited to 'src/api/dashboard/dashboard.html')
| -rw-r--r-- | src/api/dashboard/dashboard.html | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html index fa4d436..17ff44b 100644 --- a/src/api/dashboard/dashboard.html +++ b/src/api/dashboard/dashboard.html @@ -2058,7 +2058,7 @@ if (handOver) { // The fragment that opens another node's dashboard (`id`'s) as this page is now // (`handOver`). What is in focus stays, but `id` itself: its page is its own. Also this // node's own page, reloaded for a new version (`id` null). -function handOff(id) { +function handOff(id, handed) { const settings = {}; try { for (let i = 0; i < localStorage.length; i++) { @@ -2076,6 +2076,9 @@ function handOff(id) { legend: !document.getElementById("legends").hidden, figures: [...open], document: [...documentOpen], + // A token reading only, for five minutes: the other node's login page begins a + // session with it (`login.html`), where the browser has none there. + token: handed || undefined, })); } // `[x, y]` turned by `angle`. @@ -2446,11 +2449,19 @@ addEventListener("keydown", event => { // opened in this page; else its halo flashes red, larger than usual, and "no dashboard" // rises from it in the same red, both fading out. This node's own: here already. const FLASH_MS = 1200; -function openDashboard(id) { +const READ_ALL = [{ path: [], rights: ["read"] }, { path: ["_continuum"], rights: ["read"] }]; +async function openDashboard(id) { const member = state.graph.members[id]; if (!member || member.self) return; if (member.dashboard) { - location.assign(member.dashboard.split("#")[0] + handOff(id)); + let handed = null; + if (token) { + try { + handed = (await tokenCall("../auth/refresh", token.token, + { limit: READ_ALL, lifetime: 300 })).token; + } catch (_) { /* the other dashboard asks for a login then */ } + } + location.assign(member.dashboard.split("#")[0] + handOff(id, handed)); return; } const layer = document.getElementById("flashes"); |
