totp-native
Version:
High-performance TOTP library using native Web Crypto API
290 lines (217 loc) • 7.71 kB
Markdown
//img.shields.io/npm/v/totp-native)


**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
```bash
npm install totp-native
```
```bash
yarn add totp-native
```
```bash
pnpm add totp-native
```
## 📖 Quick Start
### Class-based API (Recommended)
```typescript
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}`);
```
```typescript
import { Totp } from 'totp-native';
// Generate token directly
const token = await Totp.generate('JBSWY3DPEHPK3PXP');
// Verify token directly
const isValid = await Totp.verify('JBSWY3DPEHPK3PXP', '123456');
```
```typescript
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)
}
```
```typescript
// 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);
```
```typescript
// 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);
```
```typescript
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);
```
```typescript
// 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);
```
```typescript
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
```typescript
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
```typescript
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}`);
}
}
```
- `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
- **Node.js**: 16.0.0+
- **Browsers**: Modern browsers with Web Crypto API support
- **TypeScript**: 4.0+
- **Minified**: ~15KB
- **Gzipped**: ~5KB
- **Zero dependencies**
```bash
npm test
npm run test:coverage
npm run test:watch
```
```bash
npm run build
npm run dev
npm run lint
npm run lint:fix
```
```typescript
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}`);
```
```typescript
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' });
});
}
```
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see [LICENSE](LICENSE) file for details.
- [totp-turbo](https://www.npmjs.com/package/totp-turbo) - Rust + WASM implementation
- [RFC 6238](https://tools.ietf.org/html/rfc6238) - TOTP specification
---
**Built with ❤️ using Web Crypto API**
![npm version](https: