Skip to content

Instantly share code, notes, and snippets.

@thuykaka
Created May 29, 2025 08:23
Show Gist options
  • Select an option

  • Save thuykaka/2b67a58a73375a8df0a3cc9cbbb45f61 to your computer and use it in GitHub Desktop.

Select an option

Save thuykaka/2b67a58a73375a8df0a3cc9cbbb45f61 to your computer and use it in GitHub Desktop.
2FA Generate & Verify
import speakeasy from 'speakeasy';
import qrcode from 'qrcode';
/*
Steps:
1. Generate a secret
2. Show a QR code for the user to scan in
3. Authenticate the token for the first time
*/
const generateSecret = (name?: string, issuer?: string) => {
return speakeasy.generateSecret({ length: 20, name, issuer });
};
const genQrCode = async (otpAuthUrl = '') => {
return qrcode.toDataURL(otpAuthUrl);
};
const verifyOtp = (otp: string, userSecret: string) => {
return speakeasy.totp.verify({
secret: userSecret,
encoding: 'base32',
token: otp,
});
};
const getRemainingTOTPTime = (step: number) => {
const currentUnixTime = Math.floor(Date.now() / 1000);
return step - (currentUnixTime % step);
};
const genOtp = (userSecret: string, step = 30): { otp: string; remaining: number } => {
const otp = speakeasy.totp({ secret: userSecret, encoding: 'base32', step });
const remaining = getRemainingTOTPTime(step);
return {
otp,
remaining,
};
};
const setupQrCode = async () => {
// Đầu tiên phải gen 1 secret và gắn cho user
const secret = generateSecret('Thuykaka: thuykaka.app');
console.log(`secret: ${JSON.stringify(secret)}`);
// Cần lưu lại secret này ở đâu đó cho user, ví dụ
// user.two_factor_temp_secret = secret.base32;
// Hiển thị QR code để người dùng quét
const qrCodeUrl = await genQrCode(secret.otpauth_url);
console.log(`qrCodeUrl: ${qrCodeUrl}`);
};
const checkGenOtp = () => {
const userSecret = 'EMG4WGZIYMMVP75AJ3YUFWDVYGOWKRVC';
const otp = genOtp(userSecret);
console.log(`otp: ${JSON.stringify(otp)}`);
};
const checkVerifyOtp = () => {
const userSecret = 'KRJUQ2DNMMSSSKBUFJXVQNKQLBFDK3ZD';
const otp = genOtp(userSecret);
console.log(`otp: ${JSON.stringify(otp)}`);
console.log('verifyOtp:', verifyOtp(otp.otp, userSecret));
};
// setupQrCode();
// checkGenOtp();
// checkVerifyOtp();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment