Let's be honest: there are already packages like totp-generator that do this. I built this one mostly for myselfβto learn how TOTP/HOTP actually works under the hood, and to have a lightweight alternative I fully understand.
No grand mission here. I wanted:
If you're looking for battle-tested libraries, check out the established ones. If you want something small and readable, this might be for you.
bun add @nowarajs/totp @nowarajs/error
Use this when you need to generate a one-time password for the current time window.
import { totp, generateSecretBytes, base32Encode } from '@nowarajs/totp';
// Generate a cryptographically secure secret
const secret = generateSecretBytes(20);
// Generate the current TOTP code
const code = await totp(secret, {
algorithm: 'SHA-1',
digits: 6,
period: 30
});
console.log('Your code:', code); // e.g., "847263"
Use this to validate the code your user just entered. The window option handles clock drift gracefully.
import { verifyTotp } from '@nowarajs/totp';
const isValid = await verifyTotp(secret, userInputCode, {
algorithm: 'SHA-1',
digits: 6,
period: 30,
window: 1 // Accept codes from Β±30 seconds
});
if (isValid) console.log('β
Access granted');
else console.log('β Invalid code');
Use this to let users scan a QR code with their authenticator app.
import { buildOtpAuthUri, generateSecretBytes, base32Encode } from '@nowarajs/totp';
const secret = generateSecretBytes(20);
const secretBase32 = base32Encode(secret);
const uri = buildOtpAuthUri({
secretBase32,
label: 'user@example.com',
issuer: 'MyApp',
algorithm: 'SHA-1',
digits: 6,
period: 30
});
// Feed this URI to any QR code library
console.log(uri);
// otpauth://totp/user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp
Use this when you need counter-based OTPs instead of time-based ones.
import { hotp } from '@nowarajs/totp';
const code = await hotp(secret, 123, {
algorithm: 'SHA-1',
digits: 6
});
Full docs: nowarajs.github.io/totp
MIT - Feel free to use it.