Files
EpicNext-Cms/src/lib/auth/totp.ts
T
SimoandCursor 2ff08e5127
Deploy / release (push) Skipped
Deploy / deploy (push) Successful in 1m35s
chore: patch deps, CSP style nonces, otplib 13, and PR CI
Co-authored-by: Cursor <[email protected]>
2026-07-21 20:46:02 +02:00

54 lines
1.3 KiB
TypeScript

import {
createGuardrails,
generateSecret,
generateSync,
generateURI,
verifySync,
} from "otplib";
// Laravel Fortify / pragmarx google2fa: HMAC-SHA1, 6 digits, 30s period.
// Allow legacy secrets shorter than otplib v13's default 16-byte minimum
// (many existing AtomCMS/Fortify secrets decode to ~10 bytes).
const guardrails = createGuardrails({ MIN_SECRET_BYTES: 10 });
// ±1 time-step of clock skew (30s period → epochTolerance 30).
const EPOCH_TOLERANCE = 30;
/** Verify a 6-digit TOTP code against a base32 secret. */
export function verifyTotp(token: string, secret: string): boolean {
try {
const result = verifySync({
secret,
token,
epochTolerance: EPOCH_TOLERANCE,
guardrails,
});
return result.valid === true;
} catch {
return false;
}
}
/** Current TOTP code for a secret (used in tests / tooling). */
export function generateTotp(secret: string): string {
return generateSync({ secret, guardrails });
}
/** Generate a fresh base32 secret for enrolling a new authenticator. */
export function generateTotpSecret(): string {
return generateSecret();
}
/** otpauth:// URI for provisioning a QR code. */
export function totpKeyUri(
secret: string,
accountName: string,
issuer: string,
): string {
return generateURI({
issuer,
label: accountName,
secret,
});
}