const crypto=require('node:crypto'); function totp(secret){ const alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';let bits='';for(const c of secret)bits+=alphabet.indexOf(c).toString(2).padStart(5,'0'); const bytes=[];for(let i=0;i+8<=bits.length;i+=8)bytes.push(parseInt(bits.slice(i,i+8),2)); const counter=Buffer.alloc(8);counter.writeBigUInt64BE(BigInt(Math.floor(Date.now()/30000))); const digest=crypto.createHmac('sha1',Buffer.from(bytes)).update(counter).digest(),offset=digest[19]&15; return String((digest.readUInt32BE(offset)&0x7fffffff)%1000000).padStart(6,'0'); } module.exports=async function completeMfa(page,password){ if(!await page.getByRole('heading',{name:'Account security',exact:true}).count())return; const secret=(await page.locator('pre').textContent()).trim(); await page.locator('[name=current_password]').fill(password);await page.locator('[name=mfa_code]').fill(totp(secret)); await Promise.all([page.waitForNavigation(),page.getByRole('button',{name:'Verify',exact:true}).click()]); await page.getByRole('heading',{name:'Save your recovery codes'}).waitFor(); await Promise.all([page.waitForNavigation(),page.getByRole('link',{name:'I have saved my recovery codes'}).click()]); }; module.exports.totp=totp;