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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@katalysttech/auth

v1.0.48

Published

A flexible authentication module for NestJS applications with JWT and refresh token support

Readme

@katalyst/auth

A flexible and feature-rich authentication module for NestJS applications with support for JWT tokens, refresh tokens, multiple sessions, and various storage options.

cd existing_repo git remote add origin https://ntgitlab.novatechset.com/katalysttech-eco-system/auth-package.git git branch -M main git push -uf origin main

Features

  • 🔐 JWT-based authentication
  • 🔄 Refresh token support
  • 📱 Multiple device sessions
  • 💾 TypeORM and Redis storage support
  • 🔒 Password hashing utilities
  • 👥 Session management
  • 🛡️ Route protection
  • ⚙️ Highly configurable

Installation

npm install @katalyst/auth

Dependencies

Based on your storage choice, install the required dependencies:

For TypeORM storage:

npm install typeorm @nestjs/typeorm

For Redis storage:

npm install ioredis

Configuration

1. Module Setup

Synchronous Configuration

import { Module } from '@nestjs/common';
import { AuthModule } from '@katalyst/auth';
import { TypeOrmModule } from '@nestjs/typeorm';
import { RefreshToken } from './entities/refresh-token.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: 'localhost',
      port: 5432,
      username: 'your_username',
      password: 'your_password',
      database: 'your_database',
      entities: [RefreshToken],
      synchronize: true, // set to false in production
    }),
    AuthModule.register({
      jwt: {
        secret: process.env.JWT_SECRET,
        expiresIn: '15m',
      },
      refreshToken: {
        secret: process.env.REFRESH_TOKEN_SECRET,
        expiresIn: '7d',
        maxActiveSessions: 5, // Optional: limit active sessions per user
        storage: {
          type: 'typeorm',
          entity: RefreshToken,
        }
      },
      findUserById: async (id) => {
        // Implement your user lookup logic
        return await userRepository.findOne({ where: { id } });
      },
      findUserByUsername: async (username) => {
        // Implement your user lookup logic
        return await userRepository.findOne({ where: { username } });
      },
      userFields: {
        idField: 'id',
        usernameField: 'username',
        passwordField: 'password',
        tokenFields: ['role'] // Additional fields to include in JWT payload
      }
    }),
  ],
})
export class AppModule {}

Async Configuration

import { Module } from '@nestjs/common';
import { AuthModule } from '@katalyst/auth';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot(),
    AuthModule.registerAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        jwt: {
          secret: configService.get('JWT_SECRET'),
          expiresIn: configService.get('JWT_EXPIRES_IN'),
        },
        refreshToken: {
          secret: configService.get('REFRESH_TOKEN_SECRET'),
          expiresIn: configService.get('REFRESH_TOKEN_EXPIRES_IN'),
          maxActiveSessions: configService.get('MAX_ACTIVE_SESSIONS'),
          storage: {
            type: 'typeorm',
            entity: RefreshToken,
          }
        },
        // ... other config
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

2. Entity Setup (For TypeORM)

import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn } from 'typeorm';

@Entity('refresh_tokens')
export class RefreshToken {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  userId: string;

  @Column()
  tokenId: string;

  @Column()
  expiresAt: Date;

  @Column({ default: false })
  isRevoked: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @Column('json', { nullable: true })
  deviceInfo: any;
}

Important Notes About Entity Setup

  1. The id field must be of type string to match the package's requirements
  2. Use @PrimaryGeneratedColumn('uuid') for string IDs
  3. If you need to use numeric IDs, you'll need to convert them to strings in your entity

Example with Numeric ID (if required)

@Entity('refresh_tokens')
export class RefreshToken {
  @PrimaryGeneratedColumn('increment')
  @Transform(({ value }) => value.toString())
  id: string;

  // ... other fields
}

Troubleshooting

Common Issues

  1. ID Type Mismatch If you see the error: "The types of '(new refreshToken.storage.entity(...)).id' are incompatible between these types. Type 'number' is not assignable to type 'string'", you need to ensure your RefreshToken entity's id field is of type string. See the Entity Setup section above for solutions.

  2. Storage Configuration When using TypeORM storage, make sure to:

    • Pass the correct DataSource instance
    • Use the correct entity type
    • Configure the proper ID field type

Usage

1. Authentication Controller

import { Controller, Post, Body, Get, UseGuards, Request } from '@nestjs/common';
import { AuthService, AuthGuard } from '@katalyst/auth';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Post('login')
  async login(@Body() credentials: { username: string; password: string }) {
    return await this.authService.login(credentials.username, credentials.password);
  }

  @Post('refresh')
  async refresh(@Body() body: { refreshToken: string }) {
    return await this.authService.refreshToken(body.refreshToken);
  }

  @Get('sessions')
  @UseGuards(AuthGuard)
  async getSessions(@Request() req: any) {
    return await this.authService.getActiveSessions(req.user.sub);
  }

  @Post('logout')
  @UseGuards(AuthGuard)
  async logout(@Request() req: any) {
    await this.authService.logout(req.user.sub, req.user.tokenId);
    return { message: 'Logged out successfully' };
  }

  @Post('logout-all')
  @UseGuards(AuthGuard)
  async logoutAll(@Request() req: any) {
    await this.authService.logoutAll(req.user.sub);
    return { message: 'Logged out from all devices' };
  }
}

2. Protecting Routes

import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@katalyst/auth';

@Controller('protected')
@UseGuards(AuthGuard)
export class ProtectedController {
  @Get()
  getProtectedData() {
    return { message: 'This is protected data' };
  }
}

3. Password Utilities

import { Injectable } from '@nestjs/common';
import { PasswordService } from '@katalyst/auth';

@Injectable()
export class UserService {
  constructor(private readonly passwordService: PasswordService) {}

  async createUser(username: string, password: string) {
    const hashedPassword = await this.passwordService.hashPassword(password);
    // Save user with hashed password
  }

  async validatePassword(plainPassword: string, hashedPassword: string) {
    return await this.passwordService.comparePassword(plainPassword, hashedPassword);
  }
}

4. Session Management

import { Controller, Get, Post, UseGuards, Request, Param } from '@nestjs/common';
import { AuthService, AuthGuard } from '@katalyst/auth';

@Controller('sessions')
@UseGuards(AuthGuard)
export class SessionController {
  constructor(private readonly authService: AuthService) {}

  @Get()
  async getActiveSessions(@Request() req: any) {
    return await this.authService.getActiveSessions(req.user.sub);
  }

  @Post('revoke/:tokenId')
  async revokeSession(@Request() req: any, @Param('tokenId') tokenId: string) {
    await this.authService.revokeToken(req.user.sub, tokenId);
    return { message: 'Session revoked successfully' };
  }
}

Environment Variables

JWT_SECRET=your_jwt_secret_key
JWT_EXPIRES_IN=15m
REFRESH_TOKEN_SECRET=your_refresh_token_secret
REFRESH_TOKEN_EXPIRES_IN=7d
MAX_ACTIVE_SESSIONS=5

API Response Types

Login Response

interface AuthTokens {
  accessToken: string;
  refreshToken: string;
  expiresIn: number;
}

Active Session Response

interface Session {
  id: string;
  createdAt: Date;
  expiresAt: Date;
  deviceInfo?: {
    userAgent?: string;
    ip?: string;
    // ... other device info
  };
}

Error Handling

The module throws standard NestJS exceptions:

  • UnauthorizedException: Invalid credentials, invalid token, or revoked token
  • BadRequestException: Invalid refresh token or missing required fields
  • ForbiddenException: Token revoked or session limit exceeded

Best Practices

  1. Security

    • Store secrets in environment variables
    • Use strong secret keys
    • Set appropriate token expiration times
    • Implement rate limiting for auth endpoints
  2. Token Storage

    • Use secure storage for refresh tokens
    • Implement regular token cleanup
    • Monitor active sessions
  3. Error Handling

    • Implement proper error handling in your controllers
    • Log authentication failures
    • Provide clear error messages to users

Contributing

Contributions are welcome! Please read our contributing guidelines for details.

License

This project is licensed under the MIT License - see the LICENSE file for details.