molana-otp
v1.0.0
Published
A secure OTP (One-Time Password) generator with JWT-like expiry functionality
Maintainers
Readme
Molana OTP
A secure OTP (One-Time Password) generator with JWT-like expiry functionality for Node.js applications.
Features
- 🔐 Secure 6-digit OTP generation - Cryptographically secure random code generation
- ⏰ JWT-like expiry - Built-in token expiration with configurable timeouts
- 🔒 Token-based verification - Secure token format with signature verification
- 📱 TypeScript support - Full TypeScript definitions included
- 🧪 Comprehensive testing - Well-tested with Jest
- 🚀 Zero dependencies - No external dependencies for core functionality
Installation
npm install molana-otpQuick Start
import { MolanaOTP } from 'molana-otp';
// Create an instance
const otp = new MolanaOTP('your-secret-key');
// Generate an OTP token
const token = otp.generate({
expiryMinutes: 5,
issuer: 'your-app',
subject: '[email protected]'
});
// Get the code from the token (for display to user)
const tokenInfo = otp.getTokenInfo(token);
console.log('Your OTP code is:', tokenInfo?.code);
// Verify the OTP
const result = otp.verify(token, '123456');
if (result.valid) {
console.log('OTP verified successfully!');
} else {
console.log('Verification failed:', result.error);
}API Reference
MolanaOTP Class
Constructor
new MolanaOTP(secret?: string)secret(optional): Custom secret key for token signing. If not provided, a random secret will be generated.
Methods
generate(options?: OTPOptions): string
Generates a new OTP token with a 6-digit code.
Parameters:
options(optional): Configuration optionsexpiryMinutes?: number- Token expiry time in minutes (default: 5)issuer?: string- Token issuer identifier (default: 'molana-otp')subject?: string- Token subject identifier (default: 'user')
Returns: Base64 encoded OTP token
Example:
const token = otp.generate({
expiryMinutes: 10,
issuer: 'my-app',
subject: 'user123'
});verify(token: string, providedCode: string): OTPVerificationResult
Verifies an OTP token against a provided code.
Parameters:
token: The OTP token to verifyprovidedCode: The 6-digit code provided by the user
Returns: Verification result object
Example:
const result = otp.verify(token, '123456');
if (result.valid) {
// OTP is valid
} else if (result.expired) {
// Token has expired
} else if (result.invalidCode) {
// Code is incorrect
}getTokenInfo(token: string): OTPPayload | null
Extracts information from an OTP token without verification.
Parameters:
token: The OTP token to inspect
Returns: Token payload or null if invalid
Example:
const info = otp.getTokenInfo(token);
if (info) {
console.log('Code:', info.code);
console.log('Expires at:', new Date(info.expiresAt));
console.log('Issuer:', info.issuer);
}isExpired(token: string): boolean
Checks if a token has expired.
Parameters:
token: The OTP token to check
Returns: True if expired, false otherwise
Example:
if (otp.isExpired(token)) {
console.log('Token has expired');
}Interfaces
OTPPayload
interface OTPPayload {
code: string; // 6-digit OTP code
issuedAt: number; // Timestamp when token was issued
expiresAt: number; // Timestamp when token expires
issuer?: string; // Token issuer
subject?: string; // Token subject
}OTPOptions
interface OTPOptions {
expiryMinutes?: number; // Token expiry time in minutes
issuer?: string; // Token issuer identifier
subject?: string; // Token subject identifier
secret?: string; // Custom secret key
}OTPVerificationResult
interface OTPVerificationResult {
valid: boolean; // Whether the verification was successful
expired: boolean; // Whether the token has expired
invalidCode: boolean; // Whether the provided code is incorrect
error?: string; // Error message if verification failed
}Usage Examples
Basic Authentication Flow
import { MolanaOTP } from 'molana-otp';
const otp = new MolanaOTP(process.env.OTP_SECRET);
// Step 1: Generate OTP for user
app.post('/auth/request-otp', (req, res) => {
const { email } = req.body;
const token = otp.generate({
expiryMinutes: 5,
issuer: 'my-app',
subject: email
});
const tokenInfo = otp.getTokenInfo(token);
// Send OTP code to user via SMS/Email
sendOTPCode(email, tokenInfo.code);
// Store token securely (in session, database, etc.)
req.session.otpToken = token;
res.json({ message: 'OTP sent successfully' });
});
// Step 2: Verify OTP
app.post('/auth/verify-otp', (req, res) => {
const { code } = req.body;
const token = req.session.otpToken;
if (!token) {
return res.status(400).json({ error: 'No OTP token found' });
}
const result = otp.verify(token, code);
if (result.valid) {
// OTP verified successfully
req.session.otpToken = null; // Clear token
res.json({ message: 'OTP verified successfully' });
} else {
res.status(400).json({
error: result.error,
expired: result.expired,
invalidCode: result.invalidCode
});
}
});Two-Factor Authentication (2FA)
import { MolanaOTP } from 'molana-otp';
const otp = new MolanaOTP();
// Generate 2FA OTP
function generate2FAOTP(userId: string): string {
return otp.generate({
expiryMinutes: 2, // Short expiry for 2FA
issuer: '2fa-system',
subject: userId
});
}
// Verify 2FA OTP
function verify2FAOTP(token: string, code: string): boolean {
const result = otp.verify(token, code);
return result.valid && !result.expired;
}Password Reset Flow
import { MolanaOTP } from 'molana-otp';
const otp = new MolanaOTP();
// Generate password reset OTP
function generatePasswordResetOTP(email: string): string {
return otp.generate({
expiryMinutes: 15, // Longer expiry for password reset
issuer: 'password-reset',
subject: email
});
}
// Verify password reset OTP
function verifyPasswordResetOTP(token: string, code: string): boolean {
const result = otp.verify(token, code);
return result.valid && !result.expired;
}Security Considerations
Secret Key Management: Always use a strong, unique secret key for your application. Store it securely in environment variables.
Token Storage: Store OTP tokens securely and ensure they are cleared after successful verification.
Rate Limiting: Implement rate limiting to prevent brute force attacks on OTP verification.
Expiry Times: Use appropriate expiry times based on your use case:
- 2FA: 2-5 minutes
- Password reset: 10-15 minutes
- Account verification: 5-10 minutes
Code Delivery: Ensure OTP codes are delivered securely via SMS or email.
Development
Building the Package
npm run buildRunning Tests
npm testRunning Tests in Watch Mode
npm run test:watchLicense
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
If you encounter any issues or have questions, please open an issue on the GitHub repository.
