Fix "From Telegram" phone button showing for guests without Telegram
index.html loads Telegram's telegram-web-app.js SDK unconditionally, and that script always defines window.Telegram.WebApp — requestContact included — as a harmless stub even in a plain desktop browser with no real Telegram client. canRequestContact only checked "does the method exist", which was true for everyone, so a guest ordering without Telegram (see the guest-ordering feature) saw a "From Telegram" button that could never do anything for them. Adds isInsideTelegram(), which checks initData is actually a non-empty signed string (only ever true inside a real Telegram client), and gates both the manual button and requestContactPhone()'s auto-prompt on it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
5cfcf71154
commit
ac3e34b173
2 changed files with 20 additions and 3 deletions
|
|
@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from "react";
|
|||
import { api } from "../api";
|
||||
import { useI18n } from "../i18n";
|
||||
import { PickupIcon } from "../icons";
|
||||
import { getTelegram, haptic, requestContactPhone } from "../telegram";
|
||||
import { getTelegram, haptic, isInsideTelegram, requestContactPhone } from "../telegram";
|
||||
import type { Cart, CheckoutResult, PromoValidateResult, PublicSettings } from "../types";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -100,7 +100,13 @@ export function CheckoutPage({ mode, cart, settings, onBack, onOrderPlaced }: Pr
|
|||
// a manual button whenever that API exists at all, so a customer whose
|
||||
// client didn't support it on first launch (or who dismissed the popup)
|
||||
// always has an explicit way to retry instead of being silently stuck.
|
||||
const canRequestContact = !!tg?.requestContact;
|
||||
// isInsideTelegram() matters here too: index.html loads Telegram's own
|
||||
// SDK script unconditionally, and that script always defines the full
|
||||
// window.Telegram.WebApp API (requestContact included) as a harmless
|
||||
// stub even in a plain desktop browser — so `tg?.requestContact` alone is
|
||||
// truthy for a guest with no Telegram account at all (see the
|
||||
// guest-ordering feature), which used to show this button to everyone.
|
||||
const canRequestContact = !!tg?.requestContact && isInsideTelegram();
|
||||
const [requestingPhone, setRequestingPhone] = useState(false);
|
||||
|
||||
const handleRequestPhone = async () => {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,17 @@ export function getTelegram(): TelegramWebApp | null {
|
|||
return typeof window !== "undefined" && window.Telegram ? window.Telegram.WebApp : null;
|
||||
}
|
||||
|
||||
/** Whether this page is actually running inside a real Telegram client, not
|
||||
* just a plain browser that happened to load telegram-web-app.js (index.html
|
||||
* includes that script unconditionally). Telegram's own SDK always exposes
|
||||
* the full `window.Telegram.WebApp` object — methods like requestContact
|
||||
* included — as a harmless stub even outside Telegram, so checking "does
|
||||
* the method exist" isn't enough. `initData` is only ever a real, signed,
|
||||
* non-empty string when a genuine Telegram client opened this page. */
|
||||
export function isInsideTelegram(): boolean {
|
||||
return !!getTelegram()?.initData;
|
||||
}
|
||||
|
||||
export function getInitData(): string {
|
||||
return getTelegram()?.initData ?? "";
|
||||
}
|
||||
|
|
@ -91,7 +102,7 @@ export function addToHomeScreen() {
|
|||
export function requestContactPhone(): Promise<string | null> {
|
||||
return new Promise((resolve) => {
|
||||
const tg = getTelegram();
|
||||
if (!tg?.requestContact) {
|
||||
if (!tg?.requestContact || !isInsideTelegram()) {
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue