🔒 Блокировка trial без Telegram ID

 Что сделано:
- app/page.tsx: Добавлена проверка tgUser?.id перед созданием trial
- app/plans/page.tsx: Добавлена валидация user?.id в createUser()
- app/api/create-user/route.ts: Серверная валидация telegramId (400 если отсутствует)
- types/telegram.ts: Расширен TelegramWebApp интерфейс (MainButton, BackButton, HapticFeedback)
- types/telegram.d.ts: Глобальная декларация Window.Telegram
- hooks/useTelegramWebApp.ts: Упрощено - использует (window as any)

 ПРОБЛЕМА (user_... имена):
Имена вида user_1770605873419 появляются когда Telegram WebApp не передает данные пользователя.
Теперь система блокирует создание trial/подписки если нет tgUser.id

 РЕШЕНИЕ:
Приложение должно быть открыто ВНУТРИ Telegram Mini App, а не в браузере!
Если пользователь видит user_..., значит открыто не через бота.
This commit is contained in:
Umbrix Dev
2026-02-09 06:38:35 +03:00
parent 088df817f3
commit 806b668a6d
6 changed files with 92 additions and 144 deletions

16
types/telegram.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
/**
* Global Telegram WebApp type declarations
* Расширяет Window interface для доступа к Telegram WebApp API
*/
import { TelegramWebApp } from './telegram';
declare global {
interface Window {
Telegram?: {
WebApp: TelegramWebApp;
};
}
}
export {};

View File

@@ -46,6 +46,39 @@ export interface TelegramWebApp {
showPopup(params: any, callback?: () => void): void;
onEvent(eventType: string, callback: () => void): void;
offEvent(eventType: string, callback: () => void): void;
// Additional methods used in useTelegramWebApp
setHeaderColor(color: string): void;
setBackgroundColor(color: string): void;
enableClosingConfirmation(): void;
disableClosingConfirmation(): void;
MainButton: {
text: string;
isVisible: boolean;
isActive: boolean;
setText(text: string): void;
onClick(callback: () => void): void;
offClick(callback: () => void): void;
show(): void;
hide(): void;
enable(): void;
disable(): void;
};
BackButton: {
isVisible: boolean;
onClick(callback: () => void): void;
offClick(callback: () => void): void;
show(): void;
hide(): void;
};
HapticFeedback: {
impactOccurred(style: 'light' | 'medium' | 'heavy' | 'rigid' | 'soft'): void;
notificationOccurred(type: 'error' | 'success' | 'warning'): void;
selectionChanged(): void;
};
}
export interface TelegramUserData {