fix: bind Telegram pairing to expiring single-use account challenges

This commit is contained in:
2026-09-06 14:50:11 +03:00
parent aca1f5c3d1
commit 283bfe5990
9 changed files with 137 additions and 23 deletions
+13 -6
View File
@@ -2,14 +2,14 @@ import {useApp} from '../../context/AppContext';
import {getToken} from '../../services/auth';
import React, { useEffect, useState, useRef } from 'react';
import { Send, CheckCircle2, AlertTriangle, Loader2, Unplug } from 'lucide-react';
import { telegramDurum, telegramBagla, telegramTest, telegramSil } from '../../services/account';
import { telegramDurum, telegramKodOlustur, telegramBagla, telegramTest, telegramSil } from '../../services/account';
/**
* Telegram bildirim bağlantısı — kullanıcı kendi kurar.
* Bot tokenı sunucuda (TELEGRAM_BOT_TOKEN); kullanıcı 6 haneli kodu bota yazar,
* Bot tokenı sunucuda (TELEGRAM_BOT_TOKEN); kullanıcı süreli bağlama kodunu bota yazar,
* "Doğrula" deyince sunucu kodu görüp sohbeti hesaba bağlar. Token bizden geçmez.
*/
const kodUret = () => String(Math.floor(100000 + Math.random() * 900000));
export const TelegramBaglanti = () => {
const {authUser,isAdmin}=useApp();
@@ -17,7 +17,8 @@ export const TelegramBaglanti = () => {
};
const TelegramPanel = ({isAdmin}) => {
const [d, setD] = useState(null);
const [kod] = useState(kodUret);
const [challenge,setChallenge]=useState(null);
const kod=challenge?.kod;
const [busy, setBusy] = useState(null);
const [mesaj, setMesaj] = useState(null);
@@ -90,10 +91,16 @@ const TelegramPanel = ({isAdmin}) => {
: <span className="font-bold">(bot adı alınamadı — yöneticiye sorun)</span>}
{' '}ve <strong>Başlat</strong>'a basın.
</li>
<li>Bota şu kodu yazıp gönderin: <code className="bg-white border border-sky-300 px-2 py-0.5 rounded font-mono text-sm font-black tracking-widest">{kod}</code></li>
<li>Yeni kod oluşturun ve bota kodun tamamını gönderin: <code className="bg-white border border-sky-300 px-2 py-0.5 rounded font-mono text-sm font-black break-all">{kod || 'Henüz kod oluşturulmadı'}</code></li>
<li>Sonra buraya dönüp <strong>Doğrula</strong>'ya basın.</li>
</ol>
<button onClick={() => calistir('bagla', () => telegramBagla(kod), 'Telegram bağlantısı kaydedildi.')} disabled={!!busy}
<button disabled={!!busy} className="border rounded px-3 py-2" onClick={()=>calistir('kod',async()=>{
const data=await telegramKodOlustur();
if(typeof data.kod!=='string'||!/^[a-f0-9]{48}$/.test(data.kod)||!Number.isFinite(data.expiresAt))throw new Error('Bağlama kodu doğrulanamadı.');
if(alive.current)setChallenge(data);
})}>Yeni bağlama kodu oluştur</button>
{challenge&&<p>Kod 10 dakika geçerlidir. Son geçerlilik: {new Date(challenge.expiresAt).toLocaleTimeString('tr-TR')}. Yeni kod oluşturmak önceki kodu geçersiz kılar.</p>}
<button onClick={() => calistir('bagla', () => telegramBagla(kod), 'Telegram bağlantısı kaydedildi.')} disabled={!!busy || !kod}
className="bg-sky-600 hover:bg-sky-500 disabled:opacity-40 text-white font-bold text-xs px-5 py-2 rounded-lg flex items-center gap-1.5">
{busy === 'bagla' ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <CheckCircle2 className="w-3.5 h-3.5" />} Doğrula
</button>