fix(tg): show Open-from-Telegram wall for empty initData in production

Opening /tg in a plain browser loads telegram.org's script, which
defines window.Telegram.WebApp with EMPTY initData (no real launch
behind it). Production posted that empty string to webapp-auth → 422 →
"Couldn't sign in". The dev path already guarded this (cb55f2b9); the
prod path didn't. Now a bridge with no initData that isn't the dev mock
shows the "Open from Telegram" wall instead of erroring — the cockpit is
a phone-from-Telegram surface, and a desktop browser gets the wall, not
a failed auth.
This commit is contained in:
Renn F
2026-07-19 10:48:05 +02:00
parent e697dba3aa
commit a072b980bc
2 changed files with 19 additions and 1 deletions
@@ -83,6 +83,20 @@ describe("TelegramMiniAppPage — auth bootstrap", () => {
expect(post).not.toHaveBeenCalled();
});
it("shows the Open-from-Telegram wall in production when the CDN bridge has empty initData", async () => {
// A plain browser at /tg: the telegram.org script defines WebApp but
// with no initData. Production must not post the empty payload (422) —
// it shows the wall, same as no bridge at all.
waitForTelegramWebApp.mockResolvedValue(mockWebApp(""));
render(<TelegramMiniAppPage />);
await waitFor(() =>
expect(screen.getByText(/open from telegram/i)).toBeInTheDocument(),
);
expect(post).not.toHaveBeenCalled();
});
it("calls ready/expand, posts initData, and renders the cockpit on success", async () => {
const webApp = mockWebApp("real-init-data");
waitForTelegramWebApp.mockResolvedValue(webApp);
+5 -1
View File
@@ -61,7 +61,11 @@ export default function TelegramMiniAppPage() {
if (!webApp?.initData && process.env.NODE_ENV === "development") {
webApp = createDevMockWebApp();
}
if (!webApp) {
// No bridge, or a bridge with empty initData that didn't become the
// dev mock (a plain browser at this URL in production) — show the
// "Open from Telegram" wall instead of posting an empty payload that
// 422s into a "Couldn't sign in" error.
if (!webApp || (!webApp.initData && !isDevMockWebApp(webApp))) {
setState({ kind: "not_in_telegram" });
return;
}