A Nest module wrapper for XOTP.
nestjs-xotp provides a convenient way to use the XOTP library within your NestJS applications. It fully leverages NestJS's powerful dependency injection system, making it easy to manage, generate, and validate OTPs (Time-based One-Time Passwords - TOTP, and HMAC-based One-Time Passwords - HOTP) for robust security within your services.
npm i xotp nestjs-xotpIntegrate XOTPModule into your NestJS application by importing it into your AppModule and configuring it using the forRoot() method.
See the options reference section for the options with which you can customize the module!
import { Module } from '@nestjs/common';
import { XOTPModule } from 'nestjs-xotp';
@Module({
imports: [
XOTPModule.forRoot({
// Optional: Your XOTP configuration options go here
}),
],
})
export class AppModule {}If your configuration depends on dynamic values, like environment variables or data from another module, use forRootAsync():
import { Module } from '@nestjs/common';
import { XOTPModule } from 'nestjs-xotp';
@Module({
imports: [
XOTPModule.forRootAsync({
useFactory: () => ({
// Your XOTP configuration options, dynamically provided
}),
}),
],
})
export class AppModule {}Once XOTPModule is configured, you can easily inject XOTPService into any of your NestJS services or controllers:
import { Injectable } from '@nestjs/common';
import { XOTPService } from 'nestjs-xotp';
@Injectable()
export class MyService {
constructor(private readonly xotpService: XOTPService) {}
}Runnable NestJS apps live under examples/.
From the repository root:
npm run build
cd examples/2fa-basic
npm install
npm run startThe app listens on http://localhost:3000. See examples/2fa-basic/README.md for enroll and verify requests.
| Example | Description |
|---|---|
2fa-basic |
TOTP enrollment and verification |
async-config |
forRootAsync with environment-based options |
hotp-counter |
Counter-based HOTP generate and verify |
Each example depends on the local package ("nestjs-xotp": "file:../.."), so run npm run build at the repo root before npm install inside an example.
Requires Docker. No local npm install or npm run build is needed — the image builds the library and example from source.
From the repository root:
# Build and run one example (foreground)
docker compose -f examples/docker-compose.yml up 2fa-basic
# Build and run in the background
docker compose -f examples/docker-compose.yml up -d 2fa-basic
# Build images only
docker compose -f examples/docker-compose.yml build
# Stop containers
docker compose -f examples/docker-compose.yml down| Service | URL | Per-example docs |
|---|---|---|
2fa-basic |
http://localhost:3000 | README |
async-config |
http://localhost:3001 | README |
hotp-counter |
http://localhost:3002 | README |
Run every example at once:
docker compose -f examples/docker-compose.yml upnpm is the primary workflow for development and copying code into your own app. See examples/README.md for more detail.
Copy-paste patterns for common integrations. For runnable NestJS apps, see Examples above.
Inject XOTPTOTPService (or XOTPService) and pass each user's secret per call:
import { Injectable } from '@nestjs/common';
import { XOTPTOTPService } from 'nestjs-xotp';
import { Secret } from 'xotp';
@Injectable()
export class AuthService {
constructor(private readonly totp: XOTPTOTPService) {}
verify(userSecretBase32: string, token: string): boolean {
return this.totp.validate({
secret: Secret.from(userSecretBase32, 'base32'),
token,
});
}
}For enrollment, create a bound instance and export the key URI:
const enrollment = XOTPTOTPService.create({
account: 'user@example.com',
issuer: 'MyApp',
});
const secret = enrollment.secret!.toString(); // persist (base32)
const keyUri = enrollment.toKeyUri(); // QR / authenticator setupThe nestjs-xotp module accepts an optional configuration object. These options mirror those available in the underlying XOTP library and apply globally to both TOTP and HOTP services. If you don't know what each one does, refer to the main xotp options!
{
"digits": 6,
"window": 1,
"algorithm": "sha1",
"duration": 30,
"issuer": "xotp"
}You can set distinct options for TOTP or HOTP services individually. For instance, to change only the digit length for HOTP tokens:
{
"digits": 6,
"hotp": {
"digits": 4
}
}nestjs-xotp is MIT licensed