Files
umami/src/lib/two-factor/backup-codes.ts
T

32 lines
865 B
TypeScript

import { randomBytes } from 'crypto';
import bcrypt from 'bcryptjs';
const BACKUP_CODE_COUNT = 10;
const BCRYPT_ROUNDS = 10;
export async function generateBackupCodes(): Promise<{
plaintext: Array<string>;
hashed: Array<string>;
}> {
const plaintext = Array.from(
{ length: BACKUP_CODE_COUNT },
() =>
randomBytes(5).toString('hex').toUpperCase() +
'-' +
randomBytes(5).toString('hex').toUpperCase(),
);
const hashed = await Promise.all(plaintext.map(code => bcrypt.hash(code, BCRYPT_ROUNDS)));
return { plaintext, hashed };
}
export async function verifyBackupCode(
inputCode: string,
storedHashes: Array<string>,
): Promise<number | null> {
for (let i = 0; i < storedHashes.length; i++) {
const match = await bcrypt.compare(inputCode.toUpperCase(), storedHashes[i]);
if (match) return i;
}
return null;
}