Files
ihaleist/tests/telegram-link.test.mjs
T

57 lines
3.5 KiB
JavaScript

import {test,after} from 'node:test';
import assert from 'node:assert/strict';
import {mkdtempSync,rmSync} from 'node:fs';
import {join} from 'node:path';
import {tmpdir} from 'node:os';
import {createTelegramLinker} from '../server/telegram-link.mjs';
import {kodIleBagla} from '../server/telegram.mjs';
const directory=mkdtempSync(join(tmpdir(),'telegram-link-'));
process.env.IHALEIST_USER_DATA_DIR=directory;
const store=await import('../server/user-store.mjs');
after(()=>rmSync(directory,{recursive:true,force:true}));
const found={chatId:'123',ad:'Test'};
test('server challenge belongs to its account, expires, rotates and is consumed once',async()=>{
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,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,kod:'TELEGRAM_CHALLENGE_INVALID'});
time=second.expiresAt;
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,kod:'TELEGRAM_CHALLENGE_INVALID'});
assert.equal(store.getData(email,'telegram').chatId,'123');
assert.throws(()=>linker.issue(email),{status:409});
});
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,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,kod:'TELEGRAM_CHALLENGE_INVALID'});
});
test('matching accepts only a fresh exact code from a private non-bot sender',async()=>{
const oldFetch=globalThis.fetch,oldToken=process.env.TELEGRAM_BOT_TOKEN;
process.env.TELEGRAM_BOT_TOKEN='synthetic-token';
const code='a'.repeat(48),window={issuedAt:1000000,expiresAt:1600000,now:1100000};
const good={text:code,date:1050,chat:{id:123,type:'private',first_name:'QA'},from:{id:123,is_bot:false}};
let updates=[];
globalThis.fetch=async()=>({ok:true,json:async()=>({ok:true,result:updates})});
try {
for(const message of [{...good,text:'prefix '+code},{...good,text:code+' suffix'},{...good,date:999},
{...good,date:1101},{...good,chat:{id:123,type:'group'}},{...good,from:{id:123,is_bot:true}},
{...good,from:{id:999,is_bot:false}}]) {
updates=[{message}];assert.equal(await kodIleBagla(code,window),null);
}
updates=[{edited_message:good}];assert.equal(await kodIleBagla(code,window),null);
updates=[{message:good}];assert.equal((await kodIleBagla(code,window)).chatId,'123');
updates=[{message:{...good,text:'/start '+code}}];assert.equal((await kodIleBagla(code,window)).ad,'QA');
} finally {globalThis.fetch=oldFetch;if(oldToken===undefined)delete process.env.TELEGRAM_BOT_TOKEN;else process.env.TELEGRAM_BOT_TOKEN=oldToken;}
});