otp-toolkit
Version:
Secure, pluggable OTP generation and validation toolkit for Node.js (TypeScript ready).
92 lines (60 loc) ⢠2.23 kB
Markdown
pluggable OTP (One-Time Password) generation and validation for Node.js.
TypeScript-first, one-time use, auto-expiry, and no plaintext OTP storage.
## ⨠Features
- Numeric / alphanumeric / hex OTPs
- Auto-expiry (default 5 minutes)
- One-time use (consumed on success)
- In-memory store by default; plug in Redis/DB easily
- TypeScript types included
```bash
npm i otp-toolkit
š Quick Start
import { OtpToolkit } from "otp-toolkit";
const otp = new OtpToolkit();
// Generate a 6-digit numeric OTP (default)
const { code, token, expiresAt } = await otp.generate({
length: 6,
expirySeconds: 300,
charset: "numeric",
metadata: { userId: "123" }
});
console.log(code, token, new Date(expiresAt).toISOString());
// Validate (one-time)
const result = await otp.validate(code, token);
// { valid: true, metadata: { userId: "123" } }
-------------------------------------------------
š§ Options
length (4ā12), default 6
expirySeconds, default 300
charset: "numeric" | "alphanumeric" | "hex" (default "numeric")
metadata: any extra info to store & get back on validation
-------------------------------------------------------
š§± Custom Store (e.g., Redis)
import type { OtpStore, OtpRecord } from "otp-toolkit";
class RedisStore implements OtpStore {
constructor(private client: any) {}
async save(rec: OtpRecord) {
await this.client.set(rec.id, JSON.stringify(rec), "PX", rec.expiresAt - Date.now());
}
async get(id: string) {
const raw = await this.client.get(id);
return raw ? (JSON.parse(raw) as OtpRecord) : undefined;
}
async consume(id: string) {
const rec = await this.get(id);
if (!rec) return;
rec.consumed = true;
await this.client.set(id, JSON.stringify(rec), "PX", rec.expiresAt - Date.now());
}
async delete(id: string) { await this.client.del(id); }
}
Then:
import { OtpToolkit } from "otp-toolkit";
const otp = new OtpToolkit({ store: new RedisStore(redisClient) });
-----------------------------------------------------------
š Security Notes
OTP codes are hashed with PBKDF2 + salt in storage.
Validation uses timing-safe comparison.
Avoid logging raw OTP codes in production.
Secure,