npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nest-native/lockout

v0.1.0

Published

Thin NestJS adapter over @authlock/core — a LockoutGuard, LockoutService, and DynamicModule for django-axes-style login lockout in NestJS apps

Readme

@nest-native/lockout

[!NOTE] Unreleased (0.0.0). The module, guard, and service are implemented and tested; the package has not been published to npm yet. The first release will be 0.1.0.

Honest by design: NestJS has no login-failure signal

Django's django-axes hooks into the framework's ambient user_login_failed signal, so it can be install-and-forget. NestJS has no equivalent signal bus, so this adapter cannot be. It gives you explicit wiring instead:

  • LockoutGuard — applied before your authentication guard, it rejects a request whose identity is currently locked (HTTP 429 + Retry-After).
  • LockoutService — you call reportFailure(...) / reportSuccess(...) from your own login handler (or a Passport strategy) so the engine can count failures and reset on success. A documented Passport recipe ships with it.
  • LockoutModule.forRoot(...) / forRootAsync(...) — configure the policy, the store (in-memory or Drizzle), the identity extractors, and failMode ('open' by default, 'closed' for high-security).

All of it builds on stable Nest primitives (CanActivate, DynamicModule, HttpException), so the package supports NestJS 10, 11, and 12.

Usage

Install the adapter and the core (the core carries the stores and policy types):

npm install @nest-native/lockout @authlock/core

Register the module once:

import { Module } from '@nestjs/common';
import { LockoutModule } from '@nest-native/lockout';
import { InMemoryLockoutStore } from '@authlock/core';

@Module({
  imports: [
    LockoutModule.forRoot({
      store: new InMemoryLockoutStore(), // swap for a Drizzle store in production
      limit: 5,
      cooloffMs: 15 * 60_000,
      parameters: [['username'], ['ip']],
      // failMode: 'closed', // deny on store errors (default is 'open')
    }),
  ],
})
export class AppModule {}

Guard the login route (place LockoutGuard before your auth guard) and report the outcome from the handler — NestJS won't tell the engine about failures, so you make the two calls yourself:

import { Controller, Post, Body, Req, UseGuards } from '@nestjs/common';
import { LockoutGuard, LockoutService } from '@nest-native/lockout';

@Controller('auth')
export class AuthController {
  constructor(private readonly lockout: LockoutService) {}

  @Post('login')
  @UseGuards(LockoutGuard) // 429 + Retry-After if already locked
  async login(@Body() dto: { username: string }, @Req() req: Request) {
    const identity = { username: dto.username, ip: req.ip };
    const user = await this.verify(dto); // your credential check
    if (!user) {
      await this.lockout.reportFailure(identity); // count the failure
      throw new UnauthorizedException();
    }
    await this.lockout.reportSuccess(identity); // reset on success
    return this.issueSession(user);
  }
}

Passport recipe

With passport-local the failure happens inside the strategy, so report it there (or in the controller after AuthGuard throws). Put LockoutGuard first so a locked identity is rejected before Passport runs:

@UseGuards(LockoutGuard, AuthGuard('local'))
@Post('login')
login(@Req() req) {
  // AuthGuard populated req.user; report success here, and report failure from
  // LocalStrategy.validate() (or a catch around AuthGuard) where the check fails.
}

Relationship to @authlock/core

This package is a thin DI shell. All the lockout logic — failure counting, tiered cooloff, the pluggable store, fail-open/closed — lives in the framework-agnostic @authlock/core engine, which you can also use directly from Express or any other framework. If you want request-rate limiting rather than failed-auth lockout, use @nestjs/throttler instead.

MIT licensed. Part of the nest-native family. Not affiliated with the NestJS core team or the django-axes project.