fix: clear consumed Telegram challenges after link changes
This commit is contained in:
+25
-2
@@ -44,10 +44,33 @@ const qaDelivery=qaSubscriptionStore.reserveDelivery(qaReviewSub.id,{to:user.ema
|
||||
qaSubscriptionStore.failDelivery(qaDelivery,'Sentetik belirsiz sağlayıcı sonucu.');
|
||||
qaSubscriptionStore.reserveDelivery(qaReviewSub.id,null,[]);
|
||||
let subscriptionFailure='read';
|
||||
let telegramFailure=true;
|
||||
let telegramFailure=true,telegramFixture=false,telegramInbox=null,telegramLatestCode=null,telegramClockOffset=0;
|
||||
const qaTelegramStore=await import('../server/user-store.mjs');
|
||||
const {createTelegramLinker}=await import('../server/telegram-link.mjs');
|
||||
const qaTelegramLinker=createTelegramLinker(qaTelegramStore,()=>Date.now()+telegramClockOffset);
|
||||
const ui=await createServer({server:{host:'127.0.0.1',port:0,proxy:{'/api':{target:'http://127.0.0.1:'+port}}},plugins:[{name:'qa-fixtures',configureServer(server){server.middlewares.use(async(req,res,next)=>{
|
||||
if(req.url==='/qa-responsive'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(`<html lang="tr"><h1>Yerel ekran boyutu testi</h1><p>Gerçek uygulama ayrı bir görünüm alanında yüklenir.</p><button data-width="390">390 piksel</button><button data-width="768">768 piksel</button><button data-width="1440">1440 piksel</button><pre id="metrics" aria-label="Görünüm ölçümleri"></pre><iframe title="İhaleist test görünümü" src="/" style="display:block;width:390px;height:900px;border:0"></iframe><script>document.querySelectorAll('button').forEach(button=>button.onclick=()=>document.querySelector('iframe').style.width=button.dataset.width+'px');setInterval(()=>{const doc=document.querySelector('iframe').contentDocument;if(!doc?.body)return;const width=doc.documentElement.clientWidth;const groups=[...doc.querySelectorAll('nav[aria-label="Çalışma alanları"] button')].map(el=>({label:el.textContent.trim(),left:Math.round(el.getBoundingClientRect().left),right:Math.round(el.getBoundingClientRect().right)}));document.getElementById('metrics').textContent=JSON.stringify({width,scrollWidth:doc.documentElement.scrollWidth,groups},null,2);},400);</script></html>`);return;}
|
||||
if(req.url==='/qa-telegram-controls'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(`<html lang="tr"><h1>Yerel Telegram testi</h1><button id="recover">Telegram durum hatasını kapat</button><p role="status"></p><script>document.getElementById('recover').onclick=async()=>{await fetch('/qa-telegram-recover',{method:'POST'});document.querySelector('[role=status]').textContent='Hata kapatıldı';};</script></html>`);return;}
|
||||
if(req.url==='/qa-telegram-controls'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(`<html lang="tr"><h1>Yerel Telegram testi</h1><p>Gerçek Telegram mesajı gönderilmez.</p><button id="recover">Telegram durum hatasını kapat</button><button id="enable">Sentetik bağlamayı aç</button><button id="receive">Son kodu sentetik sohbete ulaştır</button><button id="expire">Kod süresini bitir</button><p role="status"></p><script>for(const mode of ['recover','enable','receive','expire'])document.getElementById(mode).onclick=async()=>{const r=await fetch('/qa-telegram-fixture?mode='+mode,{method:'POST'});document.querySelector('[role=status]').textContent=await r.text();};</script></html>`);return;}
|
||||
if(req.url?.startsWith('/qa-telegram-fixture?')&&req.method==='POST'){
|
||||
const mode=new URL(req.url,'http://localhost').searchParams.get('mode');
|
||||
if(mode==='recover')telegramFailure=false;
|
||||
if(mode==='enable'){telegramFixture=true;telegramFailure=false;}
|
||||
if(mode==='receive')telegramInbox=telegramLatestCode;
|
||||
if(mode==='expire')telegramClockOffset+=11*60000;
|
||||
res.end('Sentetik Telegram durumu: '+mode);return;
|
||||
}
|
||||
if(req.url==='/api/me/telegram'&&telegramFixture&&['GET','POST'].includes(req.method)){
|
||||
const reply=(status,data)=>{res.writeHead(status,{'Content-Type':'application/json'});res.end(JSON.stringify(data));};
|
||||
if(req.headers.authorization!=='Bearer '+token){reply(401,{success:false,error:'Test hesabı gerekli.'});return;}
|
||||
try {
|
||||
if(req.method==='GET'){const tg=qaTelegramStore.getData(user.email,'telegram');reply(200,{success:true,yapilandirilmis:true,bagli:!!tg?.chatId,bot:null,ad:tg?.ad||null});return;}
|
||||
let raw='';for await(const chunk of req)raw+=chunk;const body=JSON.parse(raw);
|
||||
if(body.islem==='kod'){const challenge=qaTelegramLinker.issue(user.email);telegramLatestCode=challenge.kod;reply(200,{success:true,...challenge});return;}
|
||||
if(body.islem==='test'){reply(400,{success:false,error:'Bu test gerçek mesaj göndermez.'});return;}
|
||||
const found=await qaTelegramLinker.link(user.email,body.kod,async code=>code===telegramInbox?{chatId:'123456789',ad:'QA Sentetik Sohbet'}:null);
|
||||
reply(200,{success:true,ad:found.ad});
|
||||
}catch(error){reply(error.status||400,{success:false,error:error.message,kod:error.kod});}return;
|
||||
}
|
||||
if(req.url==='/qa-telegram-recover'&&req.method==='POST'){telegramFailure=false;res.end('ok');return;}
|
||||
if(req.url==='/api/me/telegram'&&req.method==='GET'&&telegramFailure){res.writeHead(503,{'Content-Type':'application/json'});res.end(JSON.stringify({success:false,error:'QA: Telegram durumu alınamadı.'}));return;}
|
||||
if(req.url==='/qa-subscription-controls'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(`<html lang="tr"><h1>Yerel abonelik testi</h1><button id="read">Abonelik liste hatası</button><button id="delete">Abonelik silme hatası</button><button id="none">Abonelik hatalarını kapat</button><p role="status"></p><script>for(const mode of ['read','delete','none'])document.getElementById(mode).onclick=async()=>{const r=await fetch('/qa-subscription-failure?mode='+mode,{method:'POST'});document.querySelector('[role=status]').textContent=await r.text();};</script></html>`);return;}
|
||||
|
||||
@@ -15,14 +15,14 @@ test('server challenge belongs to its account, expires, rotates and is consumed
|
||||
let time=1000000;const linker=createTelegramLinker(store,()=>time),email='link@example.test';
|
||||
const first=linker.issue(email);assert.match(first.kod,/^[a-f0-9]{48}$/);
|
||||
assert.ok(!JSON.stringify(store.getData(email,'telegram')).includes(first.kod));
|
||||
await assert.rejects(linker.link('other@example.test',first.kod,async()=>found),{status:400});
|
||||
await assert.rejects(linker.link('other@example.test',first.kod,async()=>found),{status:400,kod:'TELEGRAM_CHALLENGE_INVALID'});
|
||||
const second=linker.issue(email);assert.notEqual(second.kod,first.kod);
|
||||
await assert.rejects(linker.link(email,first.kod,async()=>found),{status:400});
|
||||
await assert.rejects(linker.link(email,first.kod,async()=>found),{status:400,kod:'TELEGRAM_CHALLENGE_INVALID'});
|
||||
time=second.expiresAt;
|
||||
await assert.rejects(linker.link(email,second.kod,async()=>found),{status:400});
|
||||
await assert.rejects(linker.link(email,second.kod,async()=>found),{status:400,kod:'TELEGRAM_CHALLENGE_INVALID'});
|
||||
const current=linker.issue(email);
|
||||
assert.deepEqual(await linker.link(email,current.kod,async()=>found),found);
|
||||
await assert.rejects(linker.link(email,current.kod,async()=>found),{status:400});
|
||||
await assert.rejects(linker.link(email,current.kod,async()=>found),{status:400,kod:'TELEGRAM_CHALLENGE_INVALID'});
|
||||
assert.equal(store.getData(email,'telegram').chatId,'123');
|
||||
assert.throws(()=>linker.issue(email),{status:409});
|
||||
});
|
||||
@@ -30,10 +30,10 @@ test('server challenge belongs to its account, expires, rotates and is consumed
|
||||
test('disconnect or expiration during provider lookup cannot restore a removed link',async()=>{
|
||||
let time=1000000;const linker=createTelegramLinker(store,()=>time),email='disconnect@example.test';
|
||||
const challenge=linker.issue(email);
|
||||
await assert.rejects(linker.link(email,challenge.kod,async()=>{store.setData(email,'telegram',null);return found;}),{status:400});
|
||||
await assert.rejects(linker.link(email,challenge.kod,async()=>{store.setData(email,'telegram',null);return found;}),{status:400,kod:'TELEGRAM_CHALLENGE_INVALID'});
|
||||
assert.equal(store.getData(email,'telegram'),null);
|
||||
const next=linker.issue(email);
|
||||
await assert.rejects(linker.link(email,next.kod,async()=>{time=next.expiresAt;return found;}),{status:400});
|
||||
await assert.rejects(linker.link(email,next.kod,async()=>{time=next.expiresAt;return found;}),{status:400,kod:'TELEGRAM_CHALLENGE_INVALID'});
|
||||
});
|
||||
|
||||
test('matching accepts only a fresh exact code from a private non-bot sender',async()=>{
|
||||
|
||||
Reference in New Issue
Block a user