totem-otp-validation-receipt-jose
v0.0.4
Published
Validation Receipt implementation for TotemOTP using Jose
Maintainers
Readme
TotemOTP Validation Receipt JOSE
A JWT-based validation receipt generator for TotemOTP using the JOSE (JSON Object Signing and Encryption) library.
Installation
npm install totem-otp-validation-receipt-joseThe jose library is included as a dependency and will be installed automatically.
Usage
import { TotemOTP } from 'totem-otp'
import { JoseValidationReceiptGenerator } from 'totem-otp-validation-receipt-jose'
// Create the validation receipt generator
const validationReceiptGenerator = new JoseValidationReceiptGenerator({
sharedSecret: 'your-secret-key-at-least-32-characters-long',
expirationTimeMs: 60 * 60 * 1000, // 1 hour (optional)
issuer: 'your-app-name', // optional
audience: 'your-client-app' // optional
})
// Configure TotemOTP with validation receipt support
const totem = new TotemOTP({
storage: () => yourStorageInstance,
schemas: [yourSchema],
deliveryAgents: [yourDeliveryAgent],
validationReceipt: () => validationReceiptGenerator
})
// Validate OTP and get JWT receipt
const jwtReceipt = await totem.validate('REF123', '123456', ['login', 'transfer'])
// Later, validate the JWT receipt
const validationResult = await totem.validateReceipt('REF123', jwtReceipt, 'login')Configuration Options
JoseValidationReceiptGeneratorOptions
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| sharedSecret | string | ✅ | - | Secret key for signing and verifying JWTs. Should be at least 32 characters long for security |
| expirationTimeMs | number | ❌ | 3600000 (1 hour) | JWT expiration time in milliseconds |
| issuer | string | ❌ | 'totem-otp' | JWT issuer claim |
| audience | string | ❌ | 'totem-otp-client' | JWT audience claim |
JWT Structure
The generated JWT contains the following claims:
{
"target": {
"type": "email",
"value": "[email protected]",
"uniqueIdentifier": "optional-id"
},
"purpose": ["login", "transfer"],
"ref": "REF123",
"iss": "your-app-name",
"aud": "your-client-app",
"sub": "email:[email protected]",
"iat": 1638360000,
"exp": 1638363600
}Claims Description
target: The OTP target information (email/msisdn with value and optional unique identifier)purpose: Array of purposes this receipt is valid forref: The OTP reference this receipt was generated foriss: Issuer (configurable)aud: Audience (configurable)sub: Subject in format{type}:{value}iat: Issued at timestampexp: Expiration timestamp
Security Features
- HMAC SHA-256 Signing: Uses HS256 algorithm for JWT signing
- Reference Binding: JWTs are bound to specific OTP references
- Expiration: Built-in JWT expiration handling
- Issuer/Audience Validation: Prevents token misuse across different applications
- Purpose Validation: Ensures receipts are used for intended purposes only
Error Handling
The generator throws errors in the following scenarios:
- Invalid JWT format or signature
- JWT signed with different secret
- Expired JWT
- Wrong issuer or audience
- Reference mismatch between JWT and validation call
- Purpose not included in JWT claims
All errors are wrapped in a descriptive format: "Invalid JWT receipt: {specific error message}"
Examples
Basic Usage
const generator = new JoseValidationReceiptGenerator({
sharedSecret: 'my-super-secret-key-32-chars-min'
})Advanced Configuration
const generator = new JoseValidationReceiptGenerator({
sharedSecret: process.env.JWT_SECRET,
expirationTimeMs: 30 * 60 * 1000, // 30 minutes
issuer: 'my-banking-app',
audience: 'mobile-client'
})Error Handling
try {
const result = await totem.validateReceipt(reference, receipt, purpose)
console.log('Valid receipt:', result)
} catch (error) {
if (error.message.includes('Invalid JWT receipt')) {
console.log('Receipt validation failed:', error.message)
}
}Best Practices
- Use a strong shared secret: At least 32 characters long, randomly generated
- Store secrets securely: Use environment variables or secure configuration management
- Set appropriate expiration: Balance security with user experience
- Validate purposes strictly: Only grant access to explicitly requested purposes
- Use HTTPS: Always transmit JWTs over secure connections
- Monitor for abuse: Log validation failures and monitor for suspicious patterns
Dependencies
License
ISC
