A comprehensive Node.js package that simplifies the implementation of One-Time Password (OTP) authentication using HMAC-based One-Time Password (HOTP) and Time-based One-Time Password (TOTP) algorithms.
- Support both HOTP and TOTP algorithms
- Easy-to-use API for generating and verifying OTPs
- Customizable OTP length, counters and time window
- Supports various hashing algorithms (SHA-1, SHA-256, SHA-512)
- Compatible with popular OTP generators like Google Authenticator and Authy
Install the package using NPM:
npm i --save time2fa
// Import Totp
import { Totp } from "time2fa";
const key = Totp.generateKey({ issuer: "N0C", user: "[email protected]" });
console.log(key);
// GenerateKey {
// issuer: 'N0C',
// user: '[email protected]',
// config: { algo: 'sha1', digits: 6, period: 30, secretSize: 10 },
// secret: 'ABCDEFGHIJKLMN12',
// url: 'otpauth://totp/N0C:johndoe%40n0c.com?issuer=N0C&period=30&secret=ABCDEFGHIJKLMN12'
// }
// Import Totp
import { Totp } from "time2fa";
const valid = Totp.validate({ passcode: "123456", secret: "ABCDEFGHIJKLMN12" });
console.log(valid);
// true || false
// Import Totp, and generateConfig for default configuration
import { Totp, generateConfig } from "time2fa";
const config = generateConfig();
const codes = Totp.generatePasscodes({ secret: "ABCDEFGHIJKLMN12" }, config);
console.log(codes);
// [ 123456 ]
You must use an external library. For the example below we use qrcode.
// Import Totp and qrcode
import { Totp } from "time2fa";
import * as qrcode from "qrcode";
const key = Totp.generateKey({ issuer: "N0C", user: "[email protected]" });
console.log(key);
// GenerateKey {
// issuer: 'N0C',
// user: '[email protected]',
// config: { algo: 'sha1', digits: 6, period: 30, secretSize: 10 },
// secret: 'ABCDEFGHIJKLMN12',
// url: 'otpauth://totp/N0C:johndoe%40n0c.com?issuer=N0C&period=30&secret=ABCDEFGHIJKLMN12'
// }
qrcode.toDataURL(key.url, (err, url) => {
console.log(url); // Returns a Data URI containing a representation of the QR Code image.
});
// Import Hotp, and generateConfig for default configuration and generateSecret
import { Hotp, generateConfig, generateSecret } from "time2fa";
const config = generateConfig();
const secret = generateSecret();
const code = Hotp.generatePasscode({ secret, counter: 1 }, config);
console.log(code);
// 123456
// Import Hotp
import { Hotp } from "time2fa";
const valid = Hotp.validate({
passcode: "123456",
secret: "ABCDEFGHIJKLMN12",
counter: 1,
});
console.log(valid);
// true || false
Generate default configuration
// Import generateConfig
import { generateConfig } from "time2fa";
const config = generateConfig();
console.log(config);
// { algo: 'sha1', digits: 6, period: 30, secretSize: 10 }
Only support base32 at the moment
// Import generateSecret
import { generateSecret } from "time2fa";
const secret = generateSecret();
console.log(secret);
// ABCDEFGHIJKLMN12
// Import generateSecret
import { generateUrl } from "time2fa";
const url = generateUrl({
issuer: "N0C",
user: "[email protected]",
secret: "ABCDEFGHIJKLMN12",
});
console.log(url);
// otpauth://totp/N0C:johndoe%40n0c.com?issuer=N0C&period=30&secret=ABCDEFGHIJKLMN12
Backup code should only be used once
// Import generateBackupCodes
import { generateBackupCodes } from "time2fa";
const backupCodes = generateBackupCodes();
console.log(backupCodes);
// [
// '810550', '236884',
// '979342', '815504',
// '835313', '529942',
// '263100', '882025',
// '204896', '516248'
// ]
generateConfig(config?: TotpConfig): ValidTotpConfig
generateSecret(secretSize: number = DEFAULT_TOTP_SECRET_SIZE): string
generateBackupCodes(numCodes = 10, codeLength = DEFAULT_TOTP_DIGITS): string[]
generateUrl(options: UrlOptions, config: ValidTotpConfig): string
Totp.generateKey(options: TotpOptions, config?: TotpConfig): GenerateKey
Totp.generatePasscodes(options: TotpCode, config: ValidTotpConfig): string[]
Totp.validate(options: TotpValidateOptions, config?: TotpConfig): boolean
Hotp.generatePasscode(options: HotpCode, config: ValidTotpConfig): string
Hotp.validate(options: HotpValidateOptions, config?: TotpConfig): boolean
Parameter | Type | default | Description |
---|---|---|---|
secretSize |
number |
10 | Optional - Secret size |
period |
number |
30 | Optional - Period of time |
digits |
number |
6 | Optional- Code length |
algo |
Algorithms |
sha1 | Optional - 'sha1' | 'sha256' | 'sha512' |
Parameter | Type | default | Description |
---|---|---|---|
secretSize |
number |
- | Required - Secret size |
period |
number |
- | Required - Period of time |
digits |
number |
- | Required- Code length |
algo |
Algorithms |
- | Required - 'sha1' | 'sha256' | 'sha512' |
Parameter | Type | default | Description |
---|---|---|---|
issuer |
string |
- | Required - Issuer name |
user |
string |
- | Required - Username |
Parameter | Type | default | Description |
---|---|---|---|
issuer |
string |
- | Required - Issuer name |
user |
string |
- | Required - Username |
secret |
string |
- | Required - Secret |
Parameter | Type | default | Description |
---|---|---|---|
secret |
string |
- | Required - Secret |
drift |
number |
0 | Optional - Time tolerance |
Parameter | Type | default | Description |
---|---|---|---|
passcode |
string |
- | Required - The passcode to validate |
secret |
string |
- | Required - Secret |
drift |
number |
0 | Optional - Time tolerance |
Parameter | Type | default | Description |
---|---|---|---|
secret |
string |
- | Required - Secret |
counter |
number |
- | Required - Custom counter value |
Parameter | Type | default | Description |
---|---|---|---|
passcode |
string |
- | Required - The passcode to validate |
secret |
string |
- | Required - Secret |
counter |
number |
- | Required - Custom counter value |
All PR's are welcome!
To run tests, run the following command
npm run test