From cb55f2b9b9156a3fdb2d73bf08364b92cb375d62 Mon Sep 17 00:00:00 2001 From: Renn F Date: Sun, 19 Jul 2026 00:37:15 +0200 Subject: [PATCH] fix(tg): dev mock engages when the CDN bridge loads outside Telegram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live browser smoke caught it: a bare tab still loads telegram-web-app.js, so window.Telegram.WebApp EXISTS outside Telegram — just with empty initData. The dev fallback keyed on a null bridge only, so a dev browser went down the real-auth path and posted empty initData instead of mounting the mock. The fallback now treats bridge-with-no-initData the same as no bridge (a real Telegram launch always carries initData); production behavior is unchanged. --- panel/src/app/(tg)/tg/__tests__/page.test.tsx | 14 ++++++++++++++ panel/src/app/(tg)/tg/page.tsx | 6 +++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/panel/src/app/(tg)/tg/__tests__/page.test.tsx b/panel/src/app/(tg)/tg/__tests__/page.test.tsx index 02a7f539..e23ac7cf 100644 --- a/panel/src/app/(tg)/tg/__tests__/page.test.tsx +++ b/panel/src/app/(tg)/tg/__tests__/page.test.tsx @@ -131,6 +131,20 @@ describe("TelegramMiniAppPage — auth bootstrap", () => { ).not.toBeInTheDocument(); }); + it("dev mock also engages when the CDN bridge loaded with empty initData", async () => { + // A bare browser tab still loads telegram-web-app.js, so the bridge + // object exists — only a real Telegram launch carries initData. + vi.stubEnv("NODE_ENV", "development"); + waitForTelegramWebApp.mockResolvedValue(mockWebApp("")); + + render(); + + await waitFor(() => + expect(screen.getByTestId("tg-tab-bar")).toBeInTheDocument(), + ); + expect(post).not.toHaveBeenCalled(); + }); + it("starts Telegram theme sync against the #tg-shell element once ready", async () => { const shell = document.createElement("div"); shell.id = "tg-shell"; diff --git a/panel/src/app/(tg)/tg/page.tsx b/panel/src/app/(tg)/tg/page.tsx index 3c5e2dc8..4149e054 100644 --- a/panel/src/app/(tg)/tg/page.tsx +++ b/panel/src/app/(tg)/tg/page.tsx @@ -54,7 +54,11 @@ export default function TelegramMiniAppPage() { void (async () => { let webApp = await waitForTelegramWebApp(); if (cancelled) return; - if (!webApp && process.env.NODE_ENV === "development") { + // Outside Telegram the CDN script still loads and defines a bridge + // object — just with empty initData (a real launch always carries + // it). Either shape means "not a Telegram launch" for the dev + // fallback. + if (!webApp?.initData && process.env.NODE_ENV === "development") { webApp = createDevMockWebApp(); } if (!webApp) {