From f87505670676bc8d3014231726033b1daa081c38 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 14 Jun 2026 09:08:22 +0200 Subject: [PATCH] webui: reload page on reconnect -> /login When we reconnect to a device we should reload the page instead of silently resume. Because the device may have been rebooted from the CLI or experienced power loss. Either way, our session in RAM only is likely gone, and if so we'll be redirected to /login again. Signed-off-by: Joachim Wiberg --- src/webui/static/js/app.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/webui/static/js/app.js b/src/webui/static/js/app.js index 288a1f75..f740d419 100644 --- a/src/webui/static/js/app.js +++ b/src/webui/static/js/app.js @@ -68,14 +68,25 @@ tickerId = setInterval(tick, 1000); } - function hide() { - banner.hidden = true; - banner.textContent = 'Device unreachable'; - firstFailureMs = null; + // Reconnect: the device is answering again after a disconnect. It may + // have rebooted or been upgraded out of band, in which case + // running-config reverted to startup (activated-but-unsaved changes + // are gone), operational data is stale, and the in-memory session may + // no longer exist. So we do NOT resume the page the user was on — + // we reload it. A live session re-fetches true post-reboot state; a + // dead one makes the server 303-redirect the navigation to /login. + // The watchdog only fires `show()` after a >=5 s outage, so this never + // triggers on a sub-second blip — only on outages long enough to + // plausibly be a reboot. + function reconnect() { + if (firstFailureMs === null) return; // we were never down + banner.hidden = false; + banner.textContent = 'Device back online — reloading…'; if (tickerId !== null) { clearInterval(tickerId); tickerId = null; } + window.location.reload(); } document.addEventListener('htmx:configRequest', function (evt) { @@ -93,12 +104,9 @@ if (!evt.detail) return; var xhr = evt.detail.xhr; var status = xhr ? xhr.status : 0; - // Any HTTP response < 500 means the server is reachable — hide. - // (Pre-fix the banner stuck on after the next poll returned 404 - // because the old check used `successful`, which is true only for - // 2xx.) status === 0 = no response, leave the banner alone; - // sendError / timeout handles it. - if (status > 0 && status < 500) hide(); + // Any HTTP response < 500 means the server is reachable again. + // status === 0 = no response; leave it to sendError / timeout. + if (status > 0 && status < 500) reconnect(); }); }