29 lines
1.7 KiB
JavaScript
29 lines
1.7 KiB
JavaScript
import { randomBytes, createHash } from 'node:crypto';
|
||
const digest = code => createHash('sha256').update(code).digest('hex');
|
||
export function createTelegramLinker(store,clock=Date.now) {
|
||
function validate(email,code) {
|
||
const snapshot=store.getDataSnapshot(email),value=snapshot.veri.telegram;
|
||
if(typeof code!=='string'||!/^[a-f0-9]{48}$/.test(code)||value?.challengeHash!==digest(code)||
|
||
!Number.isFinite(value.expiresAt)||clock()>=value.expiresAt)
|
||
throw Object.assign(new Error('Bağlama kodu geçersiz veya süresi dolmuş. Yeni kod oluşturun.'),{status:400,kod:'TELEGRAM_CHALLENGE_INVALID'});
|
||
return {value,revision:snapshot.revisions.telegram ?? null};
|
||
}
|
||
return {
|
||
issue(email) {
|
||
const snapshot=store.getDataSnapshot(email);
|
||
if(snapshot.veri.telegram?.chatId)throw Object.assign(new Error('Önce mevcut Telegram bağlantısını kaldırın.'),{status:409});
|
||
const code=randomBytes(24).toString('hex'),issuedAt=clock(),expiresAt=issuedAt+10*60000;
|
||
store.setData(email,'telegram',{challengeHash:digest(code),issuedAt,expiresAt},snapshot.revisions.telegram ?? null);
|
||
return {kod:code,expiresAt};
|
||
},
|
||
async link(email,code,find) {
|
||
const {value}=validate(email,code);
|
||
const found=await find(code,{issuedAt:value.issuedAt,expiresAt:value.expiresAt,now:clock()});
|
||
if(!found)throw Object.assign(new Error('Kod özel sohbette bulunamadı. Yeni kodu bota gönderip tekrar doğrulayın.'),{status:404});
|
||
const current=validate(email,code);
|
||
store.setData(email,'telegram',{chatId:found.chatId,ad:found.ad,baglanma:new Date(clock()).toISOString()},current.revision);
|
||
return found;
|
||
},
|
||
};
|
||
}
|