From f846b0681d2ed686cda00cff01b5ff1ef0705584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 14 Jun 2026 10:52:44 +0200 Subject: [PATCH] fix(demo): hide the Coach FAB in demo mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Coach floating button was mounted unconditionally, so a demo visitor could tap it and send a message. /api/insights/chat is not in the proxy's demo-mutation allowlist, so the send returned a raw 403. Demo is read-only by design, so the FAB has no job there — gate its mount on !demoMode and pin the contract in the hoist test. Co-Authored-By: Claude Opus 4.8 --- .../layout/__tests__/auth-shell-coach-hoist.test.ts | 8 ++++++++ src/components/layout/auth-shell.tsx | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components/layout/__tests__/auth-shell-coach-hoist.test.ts b/src/components/layout/__tests__/auth-shell-coach-hoist.test.ts index 7774acae1..67893ea11 100644 --- a/src/components/layout/__tests__/auth-shell-coach-hoist.test.ts +++ b/src/components/layout/__tests__/auth-shell-coach-hoist.test.ts @@ -51,6 +51,14 @@ describe("v1.4.34 IW-B — CoachLaunchProvider hoist", () => { expect(source).toContain(""); }); + it("gates the LayoutCoachFab on `!demoMode` so demo visitors can't hit the proxy-blocked send (v1.16.13)", () => { + const source = readFileSync(AUTH_SHELL_PATH, "utf8"); + // `/api/insights/chat` is not in the proxy's DEMO_MUTATION_ALLOWLIST, + // so a tappable FAB in demo mode produces a raw 403 on send. The mount + // must be conditioned on the demo flag. + expect(source).toContain("{!demoMode && }"); + }); + it("no longer mounts any Coach surface in the routed insights layout", () => { const source = readFileSync(INSIGHTS_LAYOUT_PATH, "utf8"); // The provider import drops; the drawer mount lives on the shell. diff --git a/src/components/layout/auth-shell.tsx b/src/components/layout/auth-shell.tsx index 02202979a..02fb68705 100644 --- a/src/components/layout/auth-shell.tsx +++ b/src/components/layout/auth-shell.tsx @@ -272,7 +272,12 @@ export function AuthShell({ - + {/* v1.16.13 — the Coach FAB stays hidden in demo mode. Its send hits + `/api/insights/chat`, which is not in the proxy's + `DEMO_MUTATION_ALLOWLIST`, so a demo visitor who tapped it and sent + got a raw 403. Demo is read-only by design; the FAB has no job + here, so it's mounted only outside demo mode. */} + {!demoMode && } ); }