Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@codeverselab/otp

A lightweight, zero-dependency, cryptographically secure OTP engine for Node.js applications with stateless HMAC verification and built-in Dev/Mock mode.

npm version zero dependencies


⚑ Why @codeverselab/otp?

Most OTP libraries are either too basic or too bloated.

  • πŸš€ Zero Runtime Dependencies
  • πŸ“¦ Single-Call API
  • πŸ”’ Stateless & Tamper-Proof
  • πŸ›‘οΈ Timing-Attack Proof
  • πŸ§ͺ Dev / Mock Mode
  • πŸ› οΈ ESM + CJS Support

πŸ“¦ Installation

npm install @codeverselab/otp

# or
yarn add @codeverselab/otp

# or
pnpm add @codeverselab/otp

πŸš€ Quick Start

import { OtpManager } from '@codeverselab/otp';

// Initialize manager
const otpManager = new OtpManager({
  otpSize: 6,
  expiryInMinutes: 5,
  secret: process.env.OTP_SECRET,
});

// Generate everything in a single call ⚑
const { otp, hash, id, expiredAt, expiresInSeconds } = otpManager.generate();

console.log(otp);              // "799159" -> Send via Email / SMS
console.log(hash);             // "e555e4..." -> Return to client or save in session/DB
console.log(id);               // "4f3bdb4e-..." -> Tracking ID
console.log(expiredAt);        // 2026-07-24T15:20:37.641Z
console.log(expiresInSeconds); // 300

// Verify the user's input
const result = otpManager.verify({
  otp: userInputOtp,
  hash: clientHash,
  id: clientId,
  expiredAt: clientExpiredAt,
});

if (result.valid) {
  console.log('OTP verified successfully!');
} else {
  console.log('Verification failed:', result.reason); // 'EXPIRED' | 'INVALID_OTP'
}

βš™οΈ Configuration (OtpConfig)

Option Type Default Description
otpSize number 6 Length of the generated numeric OTP.
expiryInMinutes number 5 Minutes until the generated OTP expires.
secret string 'codeverse-default-secret' HMAC secret key used for hash generation.
isDev boolean false When true, forces OTP output to the mock value (000000).
mockOtp string undefined Custom mock OTP value used when isDev is enabled.

πŸ§ͺ Development & Testing Mode

Testing OTP workflows locally can burn SMS credits and slow down developer velocity. @codeverselab/otp includes an optional Dev Mode that automatically substitutes generated OTPs with predictable values (like "000000") while keeping the underlying HMAC verification logic 100% real.

Option A: Auto-detect via Environment Variable

Set OTP_DEV_MODE=true in your .env file (when NODE_ENV !== 'production'):

NODE_ENV=development
OTP_DEV_MODE=true
const otpManager = new OtpManager();
const { otp, isMock } = otpManager.generate();

console.log(otp);    // "000000"
console.log(isMock); // true

Option B: Instance-Level Configuration

const devOtpManager = new OtpManager({
  otpSize: 4,
  isDev: true,
  mockOtp: '1234', // Optional custom override
});

const { otp } = devOtpManager.generate();
console.log(otp); // "1234"

🌐 Express / API Usage Example

import express from 'express';
import { OtpManager } from '@codeverselab/otp';

const app = express();
app.use(express.json());

const otpManager = new OtpManager({
  otpSize: 6,
  expiryInMinutes: 5,
  secret: process.env.OTP_SECRET || 'fallback-secret',
});

// Route: Send OTP
app.post('/api/send-otp', async (req, res) => {
  const { mobile } = req.body;

  const { otp, hash, id, expiredAt, expiresInSeconds } = otpManager.generate();

  // Send SMS using your preferred provider
  await sendSmsProvider(mobile, `Your verification code is ${otp}`);

  // Send metadata back to client for stateless verification
  res.json({
    success: true,
    message: 'OTP sent successfully',
    data: { hash, id, expiredAt, expiresInSeconds },
  });
});

// Route: Verify OTP
app.post('/api/verify-otp', async (req, res) => {
  const { otp, hash, id, expiredAt } = req.body;

  const { valid, reason } = otpManager.verify({ otp, hash, id, expiredAt });

  if (!valid) {
    return res.status(400).json({
      success: false,
      error: reason === 'EXPIRED' ? 'OTP has expired' : 'Invalid OTP code',
    });
  }

  res.json({ success: true, message: 'Phone number verified!' });
});

πŸ“˜ API Reference

generate(overrideSecret?: string): GeneratedOtp
Generates an OTP and returns a complete, ready-to-use payload:

interface GeneratedOtp {
  otp: string;             // Numeric OTP string (e.g. "849201")
  hash: string;            // SHA-256 HMAC hash
  id: string;              // UUID v4 tracking ID
  expiredAt: Date;         // Expiration timestamp
  expiresInSeconds: number; // Duration in seconds
  isMock?: boolean;        // Indicates if generated under Dev mode
}

verify(params): { valid: boolean; reason?: 'EXPIRED' | 'INVALID_OTP' }
Verifies an input OTP against the provided hash and metadata in constant time:

interface VerifyParams {
  otp: string;                        // OTP code entered by the user
  hash: string;                       // Stored or returned HMAC hash
  id: string;                         // Unique generation ID
  expiredAt: Date | string | number;  // Expiration timestamp
  secret?: string;                    // Optional override secret key
}

πŸ”’ Security Architecture

@codeverselab/otp protects against common authentication attacks out of the box:

  • Stateless HMAC Signatures: The generated hash is constructed using HMAC-SHA256(secret, "${otp}.${id}.${expiredAt}"). An attacker cannot tamper with the expiration timestamp or swap the tracking ID without invalidating the signature.
  • Cryptographic Randomness: Numeric OTP generation uses Node's native crypto.randomInt, which draws directly from system entropy (unlike insecure Math.random()).
  • Timing-Attack Resistance: Verification relies on crypto.timingSafeEqual to compare hashes in constant time, neutralizing side-channel analysis.

πŸ“„ License

Distributed under the MIT License.

Developed with ❀️ by Codeverse Lab.

About

A lightweight, zero-dependency, cryptographically secure OTP engine for Node.js applications with stateless HMAC verification and built-in Dev/Mock mode.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages