Documentation

Complete guide to integrating modern-totp in your JavaScript applications.

Installation

Install modern-totp using your preferred package manager:

npm install modern-totp
# or
yarn add modern-totp
# or
pnpm add modern-totp

Basic Usage

Get started with TOTP authentication in three simple steps:

basic-usage.js
import { generateSecret, generateTOTP, verifyTOTP } from 'modern-totp';

// 1. Generate a secret for the user (store this securely)
const secret = generateSecret();
console.log(secret); // "JBSWY3DPEHPK3PXP"

// 2. Generate a TOTP code
const token = generateTOTP(secret);
console.log(token); // "123456"

// 3. Verify the TOTP code
const isValid = verifyTOTP(token, secret);
console.log(isValid); // true

QR Code Integration

Generate QR codes for easy setup with authenticator apps:

qr-code.js
import { generateSecret, generateQRCodeURL } from 'modern-totp';
import QRCode from 'qrcode'; // Use with QR code library

const secret = generateSecret();
const issuer = 'MyApp';
const accountName = 'user@example.com';

// Generate QR code URL
const qrCodeURL = generateQRCodeURL(secret, issuer, accountName);


QRCode.toDataURL(qrCodeURL, (err, url) => {
  // Display the QR code to the user
  document.getElementById('qr-code').src = url;
});

API Reference

generateSecret(length?: number): string

Generates a cryptographically secure random secret for TOTP generation.

Parameters:

  • length (optional): Length of the secret in bytes. Default: 20

Returns: Base32-encoded secret string

generateTOTP(secret: string, options?: TOTPOptions): string

Generates a TOTP code for the given secret.

Parameters:

  • secret: Base32-encoded secret string
  • options (optional): TOTP configuration options

Returns: 6-digit TOTP code

verifyTOTP(token: string, secret: string, options?: TOTPOptions): boolean

Verifies a TOTP code against the given secret.

Parameters:

  • token: TOTP code to verify
  • secret: Base32-encoded secret string
  • options (optional): TOTP configuration options

Returns: true if valid, false otherwise

generateQRCodeURL(secret: string, issuer: string, accountName: string): string

Generates a QR code URL for authenticator app setup.

Parameters:

  • secret: Base32-encoded secret string
  • issuer: Your application name
  • accountName: User identifier (usually email)

Returns: otpauth:// URL for QR code generation

Advanced Configuration

advanced-config.js
import { generateTOTP, verifyTOTP, generateSecret } from 'modern-totp';

// Custom time step and digits
const options = {
  timeStep: 30,     // 30 seconds (default)
  digits: 6,        // 6 digits (default)
  algorithm: 'SHA1' // SHA1 (default)
};

const secret = generateSecret(32); // 32 byte secret
const token = generateTOTP(secret, options);
const isValid = verifyTOTP(token, secret, options);

Framework Examples

Next.js API Routes

nextjs-example.js
// pages/api/auth/setup-2fa.js
import { generateSecret, generateQRCodeURL } from 'modern-totp';

export default function handler(req, res) {
  if (req.method === 'POST') {
    const { email } = req.body;
    
    // Generate secret for user
    const secret = generateSecret();
    
    // Store secret in database (encrypted)
    await saveUserSecret(email, secret);
    
    // Generate QR code URL
    const qrCodeURL = generateQRCodeURL(secret, 'MyApp', email);
    
    res.json({ qrCodeURL, secret });
  }
}

// pages/api/auth/verify-2fa.js
import { verifyTOTP } from 'modern-totp';

export default function handler(req, res) {
  if (req.method === 'POST') {
    const { email, token } = req.body;
    
    // Get user secret from database
    const secret = await getUserSecret(email);
    
    // Verify TOTP
    const isValid = verifyTOTP(token, secret);
    
    if (isValid) {
      // Create session or JWT token
      res.json({ success: true });
    } else {
      res.status(401).json({ error: 'Invalid token' });
    }
  }
}

React Component

react-component.jsx
import React, { useState, useEffect } from 'react';
import { generateTOTP } from 'modern-totp';

function TOTPDisplay({ secret }) {
  const [token, setToken] = useState('');
  const [timeLeft, setTimeLeft] = useState(30);

  useEffect(() => {
    const updateToken = () => {
      const newToken = generateTOTP(secret);
      setToken(newToken);
    };

    const updateTimer = () => {
      const now = Date.now();
      const timeStep = 30000; // 30 seconds
      const timeLeft = timeStep - (now % timeStep);
      setTimeLeft(Math.ceil(timeLeft / 1000));
    };

    updateToken();
    updateTimer();

    const interval = setInterval(() => {
      updateToken();
      updateTimer();
    }, 1000);

    return () => clearInterval(interval);
  }, [secret]);

  return (
    <div>
      <div className="totp-code">{token}</div>
      <div className="timer">Expires in {timeLeft}s</div>
    </div>
  );
}

Security Best Practices

Secure Secret Storage

Always encrypt TOTP secrets before storing them in your database. Never store secrets in plain text.

// ❌ Bad
const secret = generateSecret();
await db.users.update({ id }, { totpSecret: secret });

// ✅ Good
const secret = generateSecret();
const encryptedSecret = encrypt(secret, process.env.ENCRYPTION_KEY);
await db.users.update({ id }, { totpSecret: encryptedSecret });

Rate Limiting

Implement rate limiting for TOTP verification attempts to prevent brute force attacks.

// Limit to 3 attempts per minute per user
const attempts = await redis.get(`totp_attempts:${userId}`);
if (attempts && attempts > 3) {
  throw new Error('Too many attempts. Try again later.');
}

const isValid = verifyTOTP(token, secret);
if (!isValid) {
  await redis.incr(`totp_attempts:${userId}`);
  await redis.expire(`totp_attempts:${userId}`, 60);
}

Backup Codes

Always provide backup codes for account recovery in case the user loses access to their authenticator.

// Generate backup codes during 2FA setup
const backupCodes = Array.from({ length: 10 }, () => 
  generateSecret(8).replace(/[^A-Z0-9]/g, '')
);

// Hash and store backup codes
const hashedCodes = backupCodes.map(code => bcrypt.hash(code, 10));
await db.users.update({ id }, { backupCodes: hashedCodes });

⚠️ Important Security Notes

  • Never expose TOTP secrets in client-side code
  • Use HTTPS for all authentication endpoints
  • Implement proper session management
  • Consider time window tolerance for network delays
  • Log authentication attempts for security monitoring