From 584651203b13a79a159cf67272919981a9e78cbf Mon Sep 17 00:00:00 2001 From: Robert Field Date: Mon, 9 Mar 2026 16:23:49 +0000 Subject: [PATCH] fix: preserve escape hatch param through login redirect continueTo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The adminDashboard=true override was lost when unauthenticated users were redirected to /login — the param got encoded inside continueTo rather than remaining a top-level query param. hasEscapeHatch now also checks inside continueTo. --- .../client/ep/dashboard-restriction.spec.ts | 22 +++++++++++++++++++ .../wab/client/ep/dashboard-restriction.ts | 15 ++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/platform/wab/src/wab/client/ep/dashboard-restriction.spec.ts b/platform/wab/src/wab/client/ep/dashboard-restriction.spec.ts index 3c96e386c..02943ccfd 100644 --- a/platform/wab/src/wab/client/ep/dashboard-restriction.spec.ts +++ b/platform/wab/src/wab/client/ep/dashboard-restriction.spec.ts @@ -64,6 +64,18 @@ describe("isDashboardRestricted", () => { }); expect(isDashboardRestricted(config, "?adminDashboard=true")).toBe(false); }); + + it("returns false when escape hatch is inside continueTo param", () => { + const config = makeAppConfig({ hideDashboardViews: true }); + expect( + isDashboardRestricted(config, "?continueTo=%2F%3FadminDashboard%3Dtrue") + ).toBe(false); + }); + + it("returns true when continueTo has no query string", () => { + const config = makeAppConfig({ hideDashboardViews: true }); + expect(isDashboardRestricted(config, "?continueTo=%2F")).toBe(true); + }); }); describe("redirectToDashboard", () => { @@ -213,4 +225,14 @@ describe("shouldRedirectAuthRoute", () => { shouldRedirectAuthRoute(restrictedConfig, "/login/callback", "") ).toBe(true); }); + + it("does not redirect when escape hatch is inside continueTo param", () => { + expect( + shouldRedirectAuthRoute( + restrictedConfig, + "/login", + "?continueTo=%2F%3FadminDashboard%3Dtrue" + ) + ).toBe(false); + }); }); diff --git a/platform/wab/src/wab/client/ep/dashboard-restriction.ts b/platform/wab/src/wab/client/ep/dashboard-restriction.ts index 1ef2d96e4..8c1491a35 100644 --- a/platform/wab/src/wab/client/ep/dashboard-restriction.ts +++ b/platform/wab/src/wab/client/ep/dashboard-restriction.ts @@ -9,7 +9,20 @@ import { DevFlagsType } from "@/wab/shared/devflags"; function hasEscapeHatch(appConfig: DevFlagsType, locationSearch: string): boolean { const paramName = appConfig.adminDashboardOverrideParam || "adminDashboard"; const params = new URLSearchParams(locationSearch); - return params.get(paramName) === "true"; + if (params.get(paramName) === "true") { + return true; + } + // Check inside continueTo param — the escape hatch gets encoded there + // when redirecting unauthenticated users to the login page. + const continueTo = params.get("continueTo"); + if (continueTo) { + const qIdx = continueTo.indexOf("?"); + if (qIdx !== -1) { + const innerParams = new URLSearchParams(continueTo.substring(qIdx)); + return innerParams.get(paramName) === "true"; + } + } + return false; } /** True when dashboard routes should be locked down. */