/** * @typedef {'base32' | 'base32padded' | 'hex' | 'raw'} SecretEncoding */ /** * @typedef {object} SecretOptions * @property {number} [bytes=20] * Number of random bytes to generate. Default matches RFC 4226's * "recommended minimum" — 20 bytes = 160 bits, the size of a * SHA-1 output. Use 32 for SHA-256, 64 for SHA-512. * @property {SecretEncoding} [encoding='base32'] * How to encode the returned string. Google Authenticator and every * other TOTP app expects `base32` (RFC 4648, no padding). */ /** * Generate a cryptographically random OTP secret. * * The default (20 bytes, base32, no padding) is what every mainstream * TOTP app understands — the string is what you render in a QR / * paste on the enrollment screen. * * @param {SecretOptions} [options] * @returns {string} */ export function generateSecret(options?: SecretOptions): string; /** * Decode any of the accepted secret encodings into a Buffer for HMAC * use. Accepts base32 (with or without padding, case-insensitive, * spaces stripped — matches how users paste), hex, and raw Buffers / * Uint8Arrays. Never trusts the caller — throws on malformed input. * * **Auto-detection ambiguity.** When `encoding` is omitted, a string is * probed as base32 first, then hex. Some strings are valid under BOTH * alphabets (e.g. `'abcdef'` — only `a-f`), and auto-detect will read * them as base32, producing the wrong key bytes for a caller who meant * hex. If you store secrets hex-encoded, pass `encoding: 'hex'` (or * `'base32'`) explicitly to remove the guesswork. * * @param {string | Buffer | Uint8Array} secret * @param {{ encoding?: 'base32' | 'hex' }} [options] * Force the input encoding instead of auto-detecting. Recommended * whenever the secret is not a base32 enrollment string. * @returns {Buffer} */ export function decodeSecret(secret: string | Buffer | Uint8Array, options?: { encoding?: "base32" | "hex"; }): Buffer; export type SecretEncoding = "base32" | "base32padded" | "hex" | "raw"; export type SecretOptions = { /** * Number of random bytes to generate. Default matches RFC 4226's * "recommended minimum" — 20 bytes = 160 bits, the size of a * SHA-1 output. Use 32 for SHA-256, 64 for SHA-512. */ bytes?: number | undefined; /** * How to encode the returned string. Google Authenticator and every * other TOTP app expects `base32` (RFC 4648, no padding). */ encoding?: SecretEncoding | undefined; };