navbytes / totp-native

High-performance TOTP library using native Web Crypto API

Home Page:https://navbytes.github.io/totp-native/

Repository from Github https://github.comnavbytes/totp-nativeRepository from Github https://github.comnavbytes/totp-native

TOTP Native

npm version license downloads

High-performance TOTP (Time-based One-Time Password) library using native Web Crypto API

A lightweight, RFC 6238 compliant TOTP implementation built with TypeScript and Web Crypto API. Perfect for generating and verifying time-based one-time passwords in both browser and Node.js environments.

✨ Features

  • πŸš€ Native Performance - Uses Web Crypto API for optimal performance
  • πŸ”’ RFC 6238 Compliant - Follows official TOTP specification
  • πŸ“¦ Zero Dependencies - No external dependencies required
  • πŸ”§ TypeScript Support - Full TypeScript definitions included
  • 🌐 Universal - Works in browsers and Node.js (16+)
  • ⚑ Lightweight - Minimal bundle size
  • 🎯 Dual API - Both class-based and static methods
  • πŸ” Multiple Algorithms - SHA-1, SHA-256, SHA-512 support
  • πŸ“± Google Authenticator Compatible - Standard URI format

πŸš€ Installation

npm install totp-native
yarn add totp-native
pnpm add totp-native

πŸ“– Quick Start

Class-based API (Recommended)

import { TotpGenerator } from 'totp-native';

// Create a generator instance
const totp = new TotpGenerator({
  secret: 'JBSWY3DPEHPK3PXP'
});

// Generate current TOTP token
const token = await totp.generate();
console.log(`Current TOTP: ${token}`); // e.g., "123456"

// Verify a token
const isValid = await totp.verify('123456');
console.log(`Token valid: ${isValid}`);

Static API (One-off operations)

import { Totp } from 'totp-native';

// Generate token directly
const token = await Totp.generate('JBSWY3DPEHPK3PXP');

// Verify token directly
const isValid = await Totp.verify('JBSWY3DPEHPK3PXP', '123456');

βš™οΈ Configuration Options

interface TotpConfig {
  secret: string;                    // Base32 encoded secret (required)
  digits?: number;                   // Token length 4-8 (default: 6)
  period?: number;                   // Time step in seconds (default: 30)
  algorithm?: 'SHA1' | 'SHA256' | 'SHA512'; // Hash algorithm (default: SHA1)
  skew?: number;                     // Clock skew tolerance (default: 1)
  explicitZeroPad?: boolean;         // Zero padding (default: true)
  timestamp?: number;                // Custom timestamp in ms (default: current time)
}

Advanced Configuration Examples

// 8-digit tokens with SHA-256
const totp = new TotpGenerator({
  secret: 'JBSWY3DPEHPK3PXP',
  digits: 8,
  algorithm: 'SHA256'
});

// 60-second period with higher skew tolerance
const totp = new TotpGenerator({
  secret: 'JBSWY3DPEHPK3PXP',
  period: 60,
  skew: 2
});

// Generate token for specific timestamp
const token = await totp.generateAt(1640995200);

πŸ” Security Features

Secret Generation

// Generate cryptographically secure random secret
const secret = TotpGenerator.generateSecret();
console.log(secret); // e.g., "JBSWY3DPEHPK3PXP"

// Custom length (default: 32 bytes)
const longSecret = TotpGenerator.generateSecret(64);

Google Authenticator URI

const totp = new TotpGenerator({ secret: 'JBSWY3DPEHPK3PXP' });

// Generate QR code compatible URI
const uri = totp.generateUri('MyApp', 'user@example.com');
console.log(uri);
// otpauth://totp/MyApp:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp...

// Parse existing URI
const config = TotpGenerator.parseUri(uri);

πŸ• Time Utilities

// Get remaining seconds in current time window
const remaining = Totp.getRemainingTime(30);
console.log(`Token expires in ${remaining} seconds`);

// Verify with custom time skew
const isValid = await totp.verifyWithSkew('123456', 2);

🎯 API Reference

TotpGenerator Class

class TotpGenerator {
  constructor(config: TotpConfig)
  
  // Instance methods
  async generate(): Promise<string>
  async generateAt(timestamp: number): Promise<string>
  async verify(token: string): Promise<boolean>
  async verifyWithSkew(token: string, skew: number): Promise<boolean>
  generateUri(issuer: string, accountName: string): string
  
  // Static methods
  static generateSecret(length?: number): string
  static parseUri(uri: string): TotpConfig
}

Totp Static Class

class Totp {
  static async generate(secret: string, options?: Partial<TotpConfig>): Promise<string>
  static async generateAt(secret: string, timestamp: number, options?: Partial<TotpConfig>): Promise<string>
  static async verify(secret: string, token: string, options?: Partial<TotpConfig>): Promise<boolean>
  static async verifyWithSkew(secret: string, token: string, skew: number, options?: Partial<TotpConfig>): Promise<boolean>
  static generateSecret(length?: number): string
  static parseUri(uri: string): TotpConfig
  static createUri(secret: string, issuer: string, accountName: string, options?: Partial<TotpConfig>): string
  static getRemainingTime(period?: number): number
}

πŸ”§ Error Handling

import { TotpError } from 'totp-native';

try {
  const totp = new TotpGenerator({ secret: 'INVALID!' });
  await totp.generate();
} catch (error) {
  if (error instanceof TotpError) {
    console.log(`TOTP Error: ${error.message}`);
    console.log(`Error Code: ${error.code}`);
  }
}

Error Codes

  • MISSING_SECRET - Secret is required
  • INVALID_DIGITS - Digits must be between 4 and 8
  • INVALID_PERIOD - Period must be greater than 0
  • INVALID_SKEW - Skew must be non-negative
  • INVALID_BASE32 - Invalid Base32 character in secret
  • INVALID_URI - Invalid TOTP URI format
  • PARSE_ERROR - Failed to parse URI
  • GENERATION_ERROR - Failed to generate TOTP

🌐 Environment Support

  • Node.js: 16.0.0+
  • Browsers: Modern browsers with Web Crypto API support
  • TypeScript: 4.0+

πŸ“¦ Bundle Size

  • Minified: ~15KB
  • Gzipped: ~5KB
  • Zero dependencies

πŸ” Testing

npm test              # Run tests
npm run test:coverage # Run with coverage
npm run test:watch    # Watch mode

πŸ›  Development

npm run build         # Build library
npm run dev           # Watch mode
npm run lint          # Lint code
npm run lint:fix      # Fix lint issues

πŸ“ Examples

Integration with QR Code Libraries

import { TotpGenerator } from 'totp-native';
import QRCode from 'qrcode';

// Generate secret and QR code
const secret = TotpGenerator.generateSecret();
const totp = new TotpGenerator({ secret });
const uri = totp.generateUri('MyApp', 'user@example.com');

// Generate QR code
const qrCodeUrl = await QRCode.toDataURL(uri);
console.log(`Show this QR code to user: ${qrCodeUrl}`);

Express.js Middleware

import { Totp } from 'totp-native';

function totpMiddleware(req, res, next) {
  const { token, secret } = req.body;
  
  Totp.verify(secret, token)
    .then(isValid => {
      if (isValid) {
        next();
      } else {
        res.status(401).json({ error: 'Invalid TOTP token' });
      }
    })
    .catch(error => {
      res.status(500).json({ error: 'TOTP verification failed' });
    });
}

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

MIT License - see LICENSE file for details.

πŸ”— Related


Built with ❀️ using Web Crypto API

About

High-performance TOTP library using native Web Crypto API

https://navbytes.github.io/totp-native/


Languages

Language:TypeScript 92.3%Language:JavaScript 7.7%