From a3385e83c457a54a5cb32e5b63909f7778319109 Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 11 Aug 2026 11:29:13 +0300 Subject: [PATCH] fix(device-manager): keep auth redirects alive --- apps/device-manager/server/device-manager-auth.mjs | 5 ++++- .../server/device-manager-server.mjs | 4 ++++ .../server/device-manager-server.test.mjs | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/device-manager/server/device-manager-auth.mjs b/apps/device-manager/server/device-manager-auth.mjs index e68cf63..542e6ed 100644 --- a/apps/device-manager/server/device-manager-auth.mjs +++ b/apps/device-manager/server/device-manager-auth.mjs @@ -197,7 +197,10 @@ export function createDeviceManagerAuth({ const launch = new URL(`/api/services/${encodeURIComponent(serviceSlug)}/launch`, launcherBaseUrl); launch.searchParams.set("returnTo", safeReturnTo(`${url.pathname}${url.search}`)); loginUrl.searchParams.set("returnTo", `${launch.pathname}${launch.search}`); - if (isHtmlRequest(request, url)) return redirect(response, loginUrl.toString()); + if (isHtmlRequest(request, url)) { + redirect(response, loginUrl.toString()); + return true; + } sendJson(response, 401, { ok: false, error: "device_manager_auth_required", diff --git a/apps/device-manager/server/device-manager-server.mjs b/apps/device-manager/server/device-manager-server.mjs index 9b96aa4..1fe6364 100644 --- a/apps/device-manager/server/device-manager-server.mjs +++ b/apps/device-manager/server/device-manager-server.mjs @@ -112,6 +112,10 @@ export function createDeviceManagerServer({ } return serveStatic(request, response, url, distRoot); } catch (error) { + if (response.headersSent) { + response.destroy(); + return; + } const statusCode = normalizeStatus(error?.statusCode); return sendJson(response, statusCode, { ok: false, diff --git a/apps/device-manager/server/device-manager-server.test.mjs b/apps/device-manager/server/device-manager-server.test.mjs index 45296a4..0753362 100644 --- a/apps/device-manager/server/device-manager-server.test.mjs +++ b/apps/device-manager/server/device-manager-server.test.mjs @@ -48,6 +48,20 @@ test("production configuration starts with runner-owned file tokens", async (t) authRequired: true, deviceCoreConfigured: true, }); + + const rootResponse = await fetch(`http://127.0.0.1:${address.port}/`, { + redirect: "manual", + headers: { accept: "text/html" }, + }); + assert.equal(rootResponse.status, 302); + assert.equal( + rootResponse.headers.get("location"), + "https://hub.nodedc.ru/auth/login?returnTo=%2Fapi%2Fservices%2Fdevice-core%2Flaunch%3FreturnTo%3D%252F", + ); + + const healthAfterRedirect = await fetch(`http://127.0.0.1:${address.port}/healthz`); + assert.equal(healthAfterRedirect.status, 200); + assert.equal((await healthAfterRedirect.json()).ok, true); }); test("Device Manager BFF exposes an empty, mutation-driven project workspace", async (t) => {