Skip to content

Repository files navigation

nestjs-xotp

XOTP Logo plus NestJS Logo

A Nest module wrapper for XOTP.

Overview

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.

Table of contents

Installation

npm i xotp nestjs-xotp

Usage

Integrate 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 {}

Asynchronous Configuration

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) {}
}

Examples

Runnable NestJS apps live under examples/.

Run with npm (recommended)

From the repository root:

npm run build
cd examples/2fa-basic
npm install
npm run start

The 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.

Run with Docker Compose (optional)

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 up

npm is the primary workflow for development and copying code into your own app. See examples/README.md for more detail.

Cookbook

Copy-paste patterns for common integrations. For runnable NestJS apps, see Examples above.

Verify a TOTP token

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,
    });
  }
}

Enroll a user (TOTP)

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 setup

Options

The 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"
}

Overriding Specific Options for TOTP/OTP servioces

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
  }
}

License

nestjs-xotp is MIT licensed

About

Powerful one-time password(OTP) library for NestJS to implement 2FA / MFA systems using Nestjs framework.

Topics

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages