Skip to content

Releases: tgenericx/nestjs-auth-module

v4.0.0

Choose a tag to compare

@tgenericx tgenericx released this 23 Dec 14:06

🚀 Release v4.0.0

Major Release - This version includes breaking changes.

🎯 Overview

Version 4.0.0 represents a significant evolution of the authentication module, introducing refresh token support, enhanced security, and a more flexible architecture. This release focuses on production-readiness and security best practices.


✨ New Features

🔄 Refresh Token Support

The headline feature of v4.0.0 is full refresh token support with a secure, production-ready implementation.

Key Features:

  • One-time use tokens - Refresh tokens are automatically deleted after use, preventing replay attacks
  • SHA-256 hashing - Tokens are stored as hashes for additional security
  • Configurable expiration - Set custom lifetimes for refresh tokens
  • Token rotation - New refresh token issued with each refresh operation
  • Revocation support - Revoke specific tokens or all tokens for a user (logout all devices)

Implementation:

// Enable by providing a refresh token repository
AuthModule.forRootAsync({
  refreshTokenRepository: RefreshTokenRepositoryService,
  useFactory: (config: ConfigService) => ({
    jwt: {
      accessToken: createSymmetricTokenConfig({ /* ... */ }),
      refreshToken: {
        expiresIn: 7 * 24 * 60 * 60, // 7 days in seconds
        tokenLength: 32, // Optional, defaults to 32 bytes
      },
    },
  }),
  // ...
})

New Service Methods:

// AuthJwtService
await authJwt.generateTokens(userId);        // Generate access + refresh
await authJwt.refreshTokens(refreshToken);   // Rotate tokens
await authJwt.revokeToken(tokenId);          // Revoke single token
await authJwt.revokeAllTokens(userId);       // Logout all devices

🏗️ Refactored Service Architecture

Services have been reorganized for better separation of concerns:

New Service: AuthJwtService

  • Central service for all JWT operations
  • Handles both access and refresh tokens
  • Optional refresh token support (gracefully degrades if not configured)

Enhanced: CredentialsAuthService

  • Now handles all email/password operations
  • Added verifyEmail() method
  • Added validateUser() method for token refresh flows
  • Improved error messages

Enhanced: GoogleAuthService

  • Added unlinkGoogleAccount() method
  • Added isGoogleLinked() method
  • Better error handling for OAuth flows

🔐 Enhanced Security

Improved Password Handling:

  • Extracted HashService for reusable hashing logic
  • Both passwords and refresh tokens use Argon2
  • Timing-safe comparison for refresh token validation
  • Prevention of password reuse in changePassword()

JWT Configuration Requirements:

  • expiresIn is now required in signOptions to prevent immortal tokens
  • Support for both symmetric (HS256) and asymmetric (RS256) keys
  • Explicit key type configuration

💥 Breaking Changes

1. JWT Configuration Changes

v4.0.0:

jwt: {
  accessToken: createSymmetricTokenConfig({
    secret: 'my-secret',
    signOptions: {
      expiresIn: '15m', // Now required
      algorithm: 'HS256',
    },
  }),
  refreshToken: { // Optional
    expiresIn: 7 * 24 * 60 * 60,
  },
}

Migration:

  • Wrap existing JWT config under accessToken key
  • Ensure expiresIn is specified in signOptions
  • Add algorithm to signOptions
  • Optionally add refreshToken configuration

2. Module Configuration Structure

Before (v3.x):

AuthModule.forRootAsync({
  useFactory: (config: ConfigService) => ({
    jwt: { /* ... */ },
    credentials: { /* ... */ },
    google: { /* ... */ },
  }),
  userRepository: UserRepositoryService,
})

After (v4.0.0):

AuthModule.forRootAsync({
  useFactory: (config: ConfigService) => ({
    jwt: { /* ... */ },
    credentials: { /* ... */ },
    google: { /* ... */ },
  }),
  userRepository: UserRepositoryService,
  refreshTokenRepository: RefreshTokenRepositoryService, // New
  enabledCapabilities: ['credentials', 'google'], // New
})

Migration:

  • Add enabledCapabilities array to specify which auth methods to enable
  • Optionally add refreshTokenRepository for refresh token support

Full Changelog: v3.0.1...v4.0.0

v3.0.2

Choose a tag to compare

@tgenericx tgenericx released this 20 Dec 14:14

Release Notes - v3.0.2

🔧 Bug Fixes

JWT Strategy & Token Validation

Fixed JWT verification key handling and configuration (656e788, cae46ff)

  • Resolved critical issue where JWT verification was not properly using the configured secret/key
  • Fixed mismatch between token generation and validation configurations
  • Improved key selection logic for asymmetric key pairs (RS256, ES256, etc.)

Enhanced JWT strategy validation (427c9db, fd6b9d4)

  • Simplified JWT strategy configuration by using secretOrKey instead of secretOrKeyProvider
  • Added validation for missing secret/public key in JWT strategy constructor
  • Added algorithm, issuer, and audience validation to JWT strategy configuration
  • Enhanced refresh token generation with proper conditional key selection (secret vs private key)
  • Ensured JWT strategy validates against the same algorithm used for signing

🔄 Refactoring

Configuration Structure

Improved JWT configuration interface (427c9db)

  • Renamed JwtConfig interface to JwtAuthConfig for better clarity
  • Restructured configuration from flat accessTokenSignOptions/refreshTokenSignOptions to nested structure:
    // Before (v3.0.1)
    jwt: {
      accessTokenSignOptions: { secret, expiresIn },
      refreshTokenSignOptions: { secret, expiresIn }
    }
    
    // After (v3.0.2)
    jwt: {
      accessToken: {
        secret,
        signOptions: { expiresIn }
      },
      refreshToken: {
        secret,
        signOptions: { expiresIn }
      }
    }
  • Better type safety and clarity for token configuration

Enhanced token type validation (427c9db)

  • Added token type validation ('access' | 'refresh') in JWT payload
  • Removed unused token verification methods from TokenService
  • Refactored token generation to explicitly use config properties

📖 Documentation

Updated configuration examples (b408ef8)

  • Updated README to reflect new JWT configuration structure
  • Removed deprecated passReqToCallback from Google OAuth configuration examples
  • Improved code formatting and indentation in examples

Added complete auth controller example (e3838ea)

  • Comprehensive controller example showing login, register, and OAuth flows
  • Demonstrates proper usage of guards, decorators, and services

🔨 Internal Improvements

  • Updated type definitions for better IDE support
  • Improved error messages when JWT configuration is missing
  • Enhanced type safety across token generation and validation

📦 Dependencies

  • Updated @types/express to latest version
  • Updated @types/passport-google-oauth20 to latest version

⚠️ Breaking Changes

Configuration Structure Change

The JWT configuration structure has been updated. If you're upgrading from v3.0.1, you'll need to update your configuration:

Before (v3.0.1):

AuthModule.forRootAsync({
  useFactory: (config: ConfigService) => ({
    jwt: {
      accessTokenSignOptions: {
        secret: config.get('JWT_SECRET'),
        expiresIn: '15m',
      },
      refreshTokenSignOptions: {
        secret: config.get('JWT_REFRESH_SECRET'),
        expiresIn: '7d',
      },
    },
  }),
})

After (v3.0.2):

AuthModule.forRootAsync({
  useFactory: (config: ConfigService) => ({
    jwt: {
      accessToken: {
        secret: config.get('JWT_SECRET'),
        signOptions: {
          expiresIn: '15m',
          algorithm: 'HS256', // Optional: specify algorithm
          issuer: 'your-app',  // Optional: add issuer
          audience: 'your-audience', // Optional: add audience
        },
      },
      refreshToken: {
        secret: config.get('JWT_REFRESH_SECRET'),
        signOptions: {
          expiresIn: '7d',
        },
      },
    },
  }),
})

Migration Steps

  1. Update your JWT configuration to use the new nested structure
  2. Move expiresIn and other signing options under signOptions
  3. Consider adding algorithm, issuer, and audience for enhanced security (optional but recommended)

Asymmetric Key Support

For RS256/ES256 (asymmetric keys), the configuration now properly distinguishes between signing and verification:

jwt: {
  accessToken: {
    privateKey: fs.readFileSync('private.key'), // For signing
    publicKey: fs.readFileSync('public.key'),   // For verification
    signOptions: {
      algorithm: 'RS256',
      expiresIn: '15m',
    },
  },
}

🙏 Notes

This release focuses on improving JWT configuration structure and fixing critical token validation issues. The configuration changes provide better type safety, clearer structure, and support for advanced JWT features like algorithm-specific validation and asymmetric keys.

All users are encouraged to upgrade and update their configuration to the new structure.


Full Changelog: v3.0.1...v3.0.2

v3.0.1

Choose a tag to compare

@tgenericx tgenericx released this 18 Dec 20:49

Full Changelog: v3.0.0...v3.0.1

v3.0.0

Choose a tag to compare

@tgenericx tgenericx released this 18 Dec 19:21

Release Notes: v3.0.0

🎉 Major Release: Authentication-First Architecture

Version 3.0.0 represents a fundamental shift in the module's philosophy: Authentication Only, Authorization Optional. We've removed all built-in authorization features to focus on doing one thing exceptionally well—secure authentication.

🚀 Breaking Changes

1. No More Built-in Authorization

· Removed: @roles() decorator and RolesGuard
· Removed: roles property from all interfaces (JwtPayload, BaseUser, RequestUser)
· Rationale: Authorization is highly application-specific. By removing it, we enable you to implement the exact authorization logic your business needs.

2. Simplified Token Generation

· Changed: TokenService.generateTokens() now accepts only userId instead of full user object
· Changed: All authentication services return simplified AuthResponse with just userId
· Benefit: Cleaner API, no unnecessary data exposure, better separation of concerns

3. Optional Dependencies

· New: argon2 and passport-google-oauth20 are now optional peer dependencies
· Benefit: Install only what you need. Use credentials auth, Google OAuth, or both.

🆕 New Features

1. Truly Modular Installation

# Just credentials auth
npm install @nahnah/nestjs-auth-module argon2

# Just Google OAuth  
npm install @nahnah/nestjs-auth-module passport-google-oauth20

# Both
npm install @nahnah/nestjs-auth-module argon2 passport-google-oauth20

2. Cleaner Public API

· Removed authorization-related exports
· Simplified type interfaces
· More focused module exports

📦 Updated Package Structure

Peer Dependencies (Required):

{
  "@nestjs/common": "^11.0.0",
  "@nestjs/core": "^11.0.0", 
  "@nestjs/jwt": "^11.0.0",
  "@nestjs/passport": "^11.0.0",
  "passport": "^0.7.0",
  "passport-jwt": "^4.0.1",
  "reflect-metadata": "^0.2.0",
  "rxjs": "^7.0.0"
}

Optional (Install as needed):

· argon2 (for password hashing in credentials auth)
· passport-google-oauth20 (for Google OAuth)

🔧 Migration Guide

From v2.x to v3.0:

  1. Remove Role-Based Code:
    // BEFORE (v2.x)
    @Roles('admin')
    @UseGuards(JwtAuthGuard, RolesGuard)
    
    // AFTER (v3.0) - implement your own authorization
    @UseGuards(JwtAuthGuard, YourCustomAuthorizationGuard)
  2. Update Token Usage:
    // BEFORE (v2.x)
    const tokens = tokenService.generateTokens(fullUser);
    
    // AFTER (v3.0)
    const tokens = tokenService.generateTokens(user.id);
  3. Simplify Response Handling:
    // BEFORE (v2.x)
    const { user: { id, email, roles }, tokens } = await authService.login();
    
    // AFTER (v3.0) 
    const { user: { userId }, tokens } = await authService.login();

🎯 Why This Change?

  1. Single Responsibility: Authentication ≠ Authorization. They're different concerns.
  2. Flexibility: Your authorization logic is unique to your business.
  3. Simplicity: Smaller API surface, easier to understand and maintain.
  4. Performance: No unnecessary role checks in authentication flow.

v2.0.0

Choose a tag to compare

@tgenericx tgenericx released this 18 Dec 01:29

🚀 Major Release — v2.0.0

This release introduces a new architecture for "@nahnah/nestjs-auth-module".
It is a breaking change and represents a shift from feature-bundled auth to a capability-driven authentication system designed for real-world production use.


✨ What’s New

🔌 Capability-Based Architecture

Enable only the authentication features your app needs.

enabledCapabilities: ['credentials', 'google'];

Supported capabilities:

  • "credentials" — Email/password authentication
  • "google" — Google OAuth 2.0

This reduces surface area, improves security, and keeps your auth layer lean.


🧠 Redesigned User Repository Contract

The user repository API has been simplified and made more flexible.

create(data: Partial)
update(id: string, data: Partial)

This design:

  • Works naturally with ORMs (Prisma, TypeORM, Mongoose)
  • Avoids rigid method explosion
  • Makes extending user models trivial

🧩 Interface-Driven, Domain-Friendly Design

Auth no longer owns your domain model.

  • Extend "AuthUser" freely
  • Bring your own database schema
  • No forced fields beyond what auth truly needs

⚙️ Improved Module Configuration

  • First-class async configuration support
  • Cleaner JWT configuration
  • Explicit credential & OAuth configuration blocks
  • Better TypeScript inference and safety

📘 Documentation Overhaul

  • Completely rewritten README
  • Clear Quick Start
  • Realistic examples
  • Strong focus on DX and architecture clarity

⚠️ Breaking Changes

  • v1 configuration API has been removed
  • Auth features must now be explicitly enabled via "enabledCapabilities"
  • User repository interface has changed
  • Internal service APIs are not backward compatible

👉 This release requires manual migration.


🗺️ Roadmap

  • Refresh token rotation & blacklisting
  • Magic link authentication
  • Email verification helpers
  • Password reset flow helpers
  • Additional OAuth providers (GitHub, Microsoft, etc.)

v1.1.0-alpha.0

v1.1.0-alpha.0 Pre-release
Pre-release

Choose a tag to compare

@tgenericx tgenericx released this 17 Dec 10:22

What's Changed

Full Changelog: alpha-1.0...v1.1.0-alpha.0

alpha-1.0

alpha-1.0 Pre-release
Pre-release

Choose a tag to compare

@tgenericx tgenericx released this 17 Dec 10:11

Full Changelog: alpha...alpha-1.0

alpha

alpha Pre-release
Pre-release

Choose a tag to compare

@tgenericx tgenericx released this 17 Dec 10:02
091c653

Release Notes - alpha

🎉 Major Architecture Redesign

We're excited to announce a complete redesign of the NestJS Auth Module! This release introduces a modern, modular architecture that provides better separation of concerns, improved security, and greater flexibility.

⚠️ BREAKING CHANGES

This is a major breaking release. The authentication system has been completely restructured from a monolithic module to a capability-based modular architecture.

Migration Required

  • Old approach: Single AuthModule with all features bundled
  • New approach: Explicit configuration via AuthModule.forRootAsync() with capability selection

You must now:

  1. Explicitly configure and import the auth capabilities you need (JWT, Credentials, Google OAuth)
  2. Provide required configuration objects for each capability
  3. Implement and provide user repository providers

✨ What's New

Modular Architecture

The authentication system is now split into three independent, composable modules:

  • 🔐 JWT Authentication Module - Token generation, validation, guards, and decorators
  • 👤 Credentials Authentication - Registration, login, and password management
  • 🔑 Google OAuth Module - Third-party authentication with Passport integration

Standardized Interfaces

New shared contracts provide consistency across the entire authentication flow:

  • Authentication responses and token structures
  • JWT payload definitions
  • User data interfaces (with separation of safe vs. sensitive fields)
  • Operation contracts for login, registration, OAuth callbacks, token refresh, and password changes
  • Extensible configuration interfaces for each auth strategy
  • Repository interfaces to decouple persistence layer

Enhanced Security

  • Argon2 Password Hashing - Industry-standard secure password storage
  • Improved Token Handling - Clearer error semantics for expired and invalid tokens
  • Better Access Control - Enhanced role-based guards and decorators
  • Reduced Exposure Risk - Explicit separation of sensitive user data

Better Developer Experience

  • Clearer API Surface - Narrowed public exports to prevent accidental coupling
  • Explicit Error Handling - Better error messages for invalid credentials, OAuth issues, and token problems
  • Decoupled Components - Each module can be used independently or combined as needed
  • Type Safety - Comprehensive TypeScript interfaces for all auth operations

Request-Level Improvements

Centralized request handling in the JWT module includes:

  • Public route decorators
  • Current user injection
  • Role-based access control guards
  • Standardized JWT payload validation

📋 Full Changelog

Added

  • JWT authentication module with guards and token utilities
  • Credentials authentication with secure Argon2 password hashing
  • Google OAuth integration with strategy and services
  • Shared authentication and configuration interfaces
  • Dependency injection tokens for clear capability separation
  • User and repository interface contracts
  • Reusable decorators for public routes and role-based access

Changed

  • Complete architectural redesign from monolithic to modular approach
  • Centralized request-level concerns in auth-jwt module
  • Improved error handling across all auth flows
  • Updated documentation to reflect new architecture
  • Narrowed public API surface to reduce coupling

Removed

  • Legacy monolithic AuthService
  • Tightly coupled auth logic
  • Direct export of internal injection tokens
  • Old DTOs and service implementations
  • Password policy configuration from core (moved to validation layer)

🚀 Getting Started

import { AuthModule } from '@nahnah/nestjs-auth-module';

@Module({
  imports: [
    AuthModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        jwt: {
          secret: config.get('JWT_SECRET'),
          expiresIn: '15m',
        },
        credentials: {
          enabled: true,
        },
        googleOauth: {
          clientID: config.get('GOOGLE_CLIENT_ID'),
          clientSecret: config.get('GOOGLE_CLIENT_SECRET'),
          callbackURL: config.get('GOOGLE_CALLBACK_URL'),
        },
      }),
    }),
  ],
  providers: [
    {
      provide: USER_REPOSITORY,
      useClass: YourUserRepository,
    },
  ],
})
export class AppModule {}

📝 Migration Guide

See our Migration Guide for detailed instructions on upgrading from v1.x to alpha.

🔮 What's Next

We have several improvements planned for upcoming releases:

  • Enhanced refresh token management
  • Email verification flows
  • Two-factor authentication support
  • Additional OAuth providers
  • Session management utilities

📚 Documentation

For complete documentation, visit our README.


Questions or issues? Please open an issue on GitHub or reach out to the maintainers.

v1.0.1

Choose a tag to compare

@tgenericx tgenericx released this 10 Dec 22:35

What's Changed

1.0.1 – 2025-12-10

  • Improved refresh token security by validating against stored hash before issuing new tokens.
  • Made Google OAuth strategy and guard optional, only enabled when Google config is provided.
  • Tightened config typing and DI for userRepository and emailService options.
  • Cleaned up public exports and minor internal packaging workflow tweaks.

1

Full Changelog: v1.0.0...v1.0.1

v1.0.0

Choose a tag to compare

@tgenericx tgenericx released this 08 Dec 19:16

What's Changed

Full Changelog: v0.0.8...v1.0.0