CampFireID/app/utils/telegram.ts
2025-03-16 11:25:09 +03:00

67 lines
1.7 KiB
TypeScript

import crypto from 'crypto';
interface TelegramUser {
id: number;
first_name: string;
last_name?: string;
username?: string;
language_code?: string;
}
interface TelegramInitData {
query_id?: string;
user: TelegramUser;
auth_date: number;
hash: string;
}
export async function verifyTelegramWebAppData(initData: string): Promise<TelegramInitData | null> {
try {
const botToken = process.env.TELEGRAM_BOT_TOKEN;
if (!botToken) {
throw new Error('TELEGRAM_BOT_TOKEN is not defined');
}
// Разбираем строку initData
const searchParams = new URLSearchParams(initData);
const hash = searchParams.get('hash');
searchParams.delete('hash');
// Сортируем параметры
const params = Array.from(searchParams.entries())
.sort(([a], [b]) => a.localeCompare(b))
.map(([key, value]) => `${key}=${value}`)
.join('\n');
// Создаем секретный ключ
const secretKey = crypto
.createHmac('sha256', 'WebAppData')
.update(botToken)
.digest();
// Вычисляем хеш
const calculatedHash = crypto
.createHmac('sha256', secretKey)
.update(params)
.digest('hex');
// Проверяем хеш
if (calculatedHash !== hash) {
return null;
}
// Парсим данные пользователя
const user: TelegramUser = JSON.parse(searchParams.get('user') || '{}');
const authDate = parseInt(searchParams.get('auth_date') || '0', 10);
return {
query_id: searchParams.get('query_id') || undefined,
user,
auth_date: authDate,
hash: hash || '',
};
} catch (error) {
console.error('Error verifying Telegram data:', error);
return null;
}
}