From 7576c0fe85c5ced25a92d2be496572d5980a9315 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:02:45 +0000 Subject: [PATCH] Fix reboot flow: add /api/ping, fix waitForServerReboot polling, fix security.js handler Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/ee8673cf-ad65-4f65-b5c8-2f170e78022f Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com> --- app/sovran_systemsos_web/server.py | 7 ++++++- app/sovran_systemsos_web/static/js/security.js | 2 ++ app/sovran_systemsos_web/static/js/update.js | 14 ++++++-------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/app/sovran_systemsos_web/server.py b/app/sovran_systemsos_web/server.py index 6500e7e..ffafebd 100644 --- a/app/sovran_systemsos_web/server.py +++ b/app/sovran_systemsos_web/server.py @@ -87,7 +87,7 @@ LOGIN_FAIL_WINDOW = 60.0 # rolling window (seconds) for counting failures LOGIN_FAIL_MAX = 10 # max failures in window before extra delay # Public paths that are accessible without a valid session -_AUTH_EXEMPT_PATHS = {"/login", "/api/login", "/api/updates/status", "/api/rebuild/status", "/auto-login"} +_AUTH_EXEMPT_PATHS = {"/login", "/api/login", "/api/updates/status", "/api/rebuild/status", "/auto-login", "/api/ping"} # Prefixes for static assets required by the login page _AUTH_EXEMPT_PREFIXES = ("/static/css/", "/static/sovran-hub-icon.svg") @@ -2596,6 +2596,11 @@ async def api_updates_check(): return {"available": available is not False} +@app.get("/api/ping") +async def api_ping(): + return {"ok": True} + + @app.post("/api/reboot") async def api_reboot(): try: diff --git a/app/sovran_systemsos_web/static/js/security.js b/app/sovran_systemsos_web/static/js/security.js index 3a92efd..f17eda1 100644 --- a/app/sovran_systemsos_web/static/js/security.js +++ b/app/sovran_systemsos_web/static/js/security.js @@ -161,6 +161,8 @@ function openSecurityModal() { rebootBtn.disabled = true; rebootBtn.textContent = "Rebooting\u2026"; if ($rebootOverlay) $rebootOverlay.classList.add("visible"); + _rebootStartTime = Date.now(); + _serverWentDown = false; setTimeout(waitForServerReboot, REBOOT_INITIAL_DELAY); var rebootCtrl = new AbortController(); setTimeout(function() { rebootCtrl.abort(); }, REBOOT_REQUEST_TIMEOUT); diff --git a/app/sovran_systemsos_web/static/js/update.js b/app/sovran_systemsos_web/static/js/update.js index a109612..2a7ce7f 100644 --- a/app/sovran_systemsos_web/static/js/update.js +++ b/app/sovran_systemsos_web/static/js/update.js @@ -185,21 +185,19 @@ function waitForServerReboot() { var controller = new AbortController(); var timeoutId = setTimeout(function() { controller.abort(); }, REBOOT_FETCH_TIMEOUT); - fetch("/api/config", { cache: "no-store", signal: controller.signal, headers: { "Connection": "close" } }) + fetch("/api/ping", { cache: "no-store", signal: controller.signal, headers: { "Connection": "close" } }) .then(function(res) { clearTimeout(timeoutId); - if (res.ok && _serverWentDown) { - // Server is back after having been down — reboot is complete + if (_serverWentDown) { + // Server is responding after having been down — reboot is complete. + // Any response (even 401/500) means the server process is back. window.location.reload(); - } else if (res.ok && !_serverWentDown && (Date.now() - _rebootStartTime) < 90000) { + } else if ((Date.now() - _rebootStartTime) < 90000) { // Server still responding but hasn't gone down yet — keep waiting setTimeout(waitForServerReboot, REBOOT_CHECK_INTERVAL); - } else if (res.ok) { + } else { // Been over 90 seconds and server is responding — just reload window.location.reload(); - } else { - _serverWentDown = true; - setTimeout(waitForServerReboot, REBOOT_CHECK_INTERVAL); } }) .catch(function() {