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

@flusys/nestjs-auth

v1.1.0

Published

Authentication and authorization infrastructure for NestJS applications

Downloads

891

Readme

Authentication Package Guide

Package: @flusys/nestjs-auth Version: 1.1.0 Type: Authentication system with JWT, email verification, multi-tenant, and company/branch support

Table of Contents


Installation

npm install @flusys/nestjs-auth @flusys/nestjs-shared @flusys/nestjs-core

Quick Start

Basic Setup (Single Database, No Company Feature)

import { Module } from '@nestjs/common';
import { AuthModule } from '@flusys/nestjs-auth';

@Module({
  imports: [
    AuthModule.forRoot({
      global: true,
      includeController: true,
      bootstrapAppConfig: {
        databaseMode: 'single',
        enableCompanyFeature: false,
      },
      config: {
        defaultDatabaseConfig: {
          type: 'postgres',
          host: 'localhost',
          port: 5432,
          username: 'postgres',
          password: 'password',
          database: 'myapp',
        },
        jwtSecret: process.env.JWT_SECRET,
        jwtExpiration: '1h',
      },
    }),
  ],
})
export class AppModule {}

With Company Feature

AuthModule.forRoot({
  global: true,
  includeController: true,
  bootstrapAppConfig: {
    databaseMode: 'single',
    enableCompanyFeature: true,
  },
  config: {
    defaultDatabaseConfig: { /* ... */ },
    jwtSecret: process.env.JWT_SECRET,
    refreshTokenSecret: process.env.REFRESH_TOKEN_SECRET,
    refreshTokenExpiration: '7d',
    refreshTokenCookieName: 'fsn_refresh_token',
  },
})

Multi-Tenant Mode

AuthModule.forRoot({
  global: true,
  includeController: true,
  bootstrapAppConfig: {
    databaseMode: 'multi-tenant',
    enableCompanyFeature: true,
  },
  config: {
    tenantDefaultDatabaseConfig: {
      type: 'postgres',
      host: 'localhost',
      port: 5432,
      username: 'postgres',
      password: 'password',
    },
    tenants: [
      { id: 'tenant1', database: 'tenant1_db', name: 'Tenant 1', isActive: true },
      { id: 'tenant2', database: 'tenant2_db', name: 'Tenant 2', isActive: true },
    ],
    jwtSecret: process.env.JWT_SECRET,
  },
})

With Email Provider (Password Reset, Email Verification)

import { AUTH_EMAIL_PROVIDER } from '@flusys/nestjs-auth';
import { EmailSendService } from '@flusys/nestjs-email';

AuthModule.forRoot({
  // ... config
  providers: [
    {
      provide: AUTH_EMAIL_PROVIDER,
      useFactory: (emailService: EmailSendService) => ({
        sendPasswordResetEmail: async (email, token, resetUrl) => {
          await emailService.sendTemplateEmail({
            templateSlug: 'password-reset',
            to: email,
            variables: { resetUrl, token },
          });
        },
        sendVerificationEmail: async (email, token, verifyUrl) => {
          await emailService.sendTemplateEmail({
            templateSlug: 'email-verification',
            to: email,
            variables: { verifyUrl, token },
          });
        },
      }),
      inject: [EmailSendService],
    },
  ],
})

Configuration

Configuration Options

interface AuthModuleOptions {
  global?: boolean;                    // Make module global
  includeController?: boolean;         // Include default controllers
  bootstrapAppConfig?: {
    databaseMode: 'single' | 'multi-tenant';
    enableCompanyFeature: boolean;
    enableEmailVerification?: boolean; // Default: true
  };
  config?: {
    defaultDatabaseConfig?: IDatabaseConfig;
    tenantDefaultDatabaseConfig?: IDatabaseConfig;
    tenants?: ITenantDatabaseConfig[];
    jwtSecret?: string;
    jwtExpiration?: string;             // Default: '1h'
    refreshTokenSecret?: string;
    refreshTokenExpiration?: string;    // Default: '7d'
    refreshTokenCookieName?: string;    // Default: 'fsn_refresh_token'
    frontendUrl?: string;               // For email links
  };
  providers?: Provider[];               // Additional providers (AUTH_EMAIL_PROVIDER, USER_ENRICHER)
}

Bootstrap Configuration Flags:

| Flag | Type | Default | Effect | |------|------|---------|--------| | enableCompanyFeature | boolean | false | Enables company/branch entities and APIs | | enableEmailVerification | boolean | true | When false: excludes AuthEmailService, hides email-related APIs (forgot-password, reset-password, verify-email, resend-verification), and excludes PendingRegistration entity from migrations |

Constants

// Injection Tokens
export const AUTH_MODULE_OPTIONS = 'AUTH_MODULE_OPTIONS';
export const USER_ENRICHER = 'USER_ENRICHER';

// Security
export const BCRYPT_SALT_ROUNDS = 12;

// Cookie
export const DEFAULT_COOKIE_NAME = 'fsn_refresh_token';
export const MAX_COOKIE_BYTES = 3500;

// Cache Key Prefixes
export const SESSION_CACHE_PREFIX = 'auth:session';
export const TOKEN_REVOKED_PREFIX = 'auth:revoked';

Entities

Entity Groups

The auth module organizes entities into groups based on feature flags:

// Internal entity groups (not exported directly)
// Base entities: User, UserToken
// Email entities: PendingRegistration
// Company entities: Company, CompanyBranch, UserCompanyPermission

// Exported interface for configuration
export interface IAuthEntitiesConfig {
  enableCompanyFeature?: boolean;
  enableEmailVerification?: boolean;  // Default: true
}

// Get entities based on feature flags (exported)
export function getEntitiesByConfig(config: IAuthEntitiesConfig): any[] {
  const { enableCompanyFeature = false, enableEmailVerification = true } = config;

  const entities = [User, UserToken];
  if (enableEmailVerification) entities.push(PendingRegistration);
  if (enableCompanyFeature) entities.push(Company, CompanyBranch, UserCompanyPermission);
  return entities;
}

Usage:

import { getEntitiesByConfig } from '@flusys/nestjs-auth/entities';

// Get entities for single database without company feature
const entities = getEntitiesByConfig({ enableCompanyFeature: false });
// Returns: [User, UserToken, PendingRegistration]

// Get entities with company feature, no email verification
const entities = getEntitiesByConfig({ enableCompanyFeature: true, enableEmailVerification: false });
// Returns: [User, UserToken, Company, CompanyBranch, UserCompanyPermission]

Entity Selection by Feature Flags:

| enableEmailVerification | enableCompanyFeature | Entities | |------------------------|---------------------|----------| | true (default) | false | User, UserToken, PendingRegistration | | true | true | All entities | | false | false | User, UserToken only | | false | true | User, UserToken, Company, CompanyBranch, UserCompanyPermission |

User Entity

Extends UserRoot from @flusys/nestjs-shared:

| Field | Type | Description | |-------|------|-------------| | id | uuid | Primary key | | name | varchar(255) | User's name | | email | varchar(255) | Unique email address | | password | text | Bcrypt hashed password | | phone | varchar(255) | Phone number | | isActive | boolean | Account status | | emailVerified | boolean | Email verification status | | phoneVerified | boolean | Phone verification status | | profilePictureId | uuid | Reference to storage file | | lastLoginAt | timestamp | Last login timestamp | | additionalFields | json | Extensible JSON fields | | createdAt | timestamp | Auto-generated | | updatedAt | timestamp | Auto-updated | | deletedAt | timestamp | Soft delete timestamp |

UserToken Entity

Stores tokens for existing user actions:

enum TokenType {
  PASSWORD_RESET = 'password_reset',
  EMAIL_VERIFICATION = 'email_verification',
  EMAIL_CHANGE = 'email_change',
}

| Field | Type | Description | |-------|------|-------------| | id | uuid | Primary key | | userId | uuid | Reference to user | | type | TokenType | Token purpose | | token | varchar(64) | SHA-256 hashed token | | expiresAt | timestamp | Expiration time | | usedAt | timestamp | When token was used | | metadata | varchar(255) | Additional data (e.g., new email for EMAIL_CHANGE) | | createdAt | timestamp | Auto-generated |

Indexes:

  • IDX_user_token_token - Unique on token
  • IDX_user_token_user_type - userId + type
  • IDX_user_token_expires - For cleanup queries

PendingRegistration Entity

Stores registration data until email verification (prevents garbage accounts):

| Field | Type | Description | |-------|------|-------------| | id | uuid | Primary key | | email | varchar(255) | Unique pending email | | name | varchar(255) | User's name | | phone | varchar(255) | Phone number | | passwordHash | text | Pre-hashed password | | token | varchar(64) | SHA-256 hashed verification token | | expiresAt | timestamp | Expiration (24 hours) | | companyData | json | Company registration data | | createdAt | timestamp | Auto-generated |

Indexes:

  • IDX_pending_reg_email - Unique
  • IDX_pending_reg_token - Unique
  • IDX_pending_reg_expires - For cleanup

Company Entity (when company feature enabled)

| Field | Type | Description | |-------|------|-------------| | id | uuid | Primary key | | name | varchar(255) | Company name | | slug | varchar(255) | URL-friendly identifier | | phone | varchar(255) | Contact phone | | address | text | Address | | logoId | uuid | Reference to storage file | | isActive | boolean | Company status |

CompanyBranch Entity

| Field | Type | Description | |-------|------|-------------| | id | uuid | Primary key | | name | varchar(255) | Branch name | | slug | varchar(255) | URL-friendly identifier | | companyId | uuid | Parent company | | parentId | uuid | Parent branch (hierarchical) | | serial | int | Display order | | logoId | uuid | Reference to storage file | | isActive | boolean | Branch status |

UserCompanyPermission Entity (Polymorphic)

enum PermissionType {
  COMPANY = 'company',
  BRANCH = 'branch',
}

| Field | Type | Description | |-------|------|-------------| | id | uuid | Primary key | | userId | uuid | Reference to user | | permissionType | PermissionType | company or branch | | targetId | uuid | Company ID or Branch ID | | isActive | boolean | Permission status |

Provider Interfaces

AUTH_EMAIL_PROVIDER

Allows auth to work independently of the email module:

interface IAuthEmailProvider {
  /** Send password reset email */
  sendPasswordResetEmail(email: string, token: string, resetUrl: string): Promise<void>;

  /** Send email verification email */
  sendVerificationEmail(email: string, token: string, verifyUrl: string): Promise<void>;

  /** Send welcome email after registration (optional) */
  sendWelcomeEmail?(email: string, name: string): Promise<void>;
}

Example Implementation:

{
  provide: AUTH_EMAIL_PROVIDER,
  useFactory: (emailSendService: EmailSendService) => ({
    sendPasswordResetEmail: async (email, token, resetUrl) => {
      await emailSendService.sendTemplateEmail({
        templateSlug: 'password-reset',
        to: email,
        variables: { resetUrl, token },
      });
    },
    sendVerificationEmail: async (email, token, verifyUrl) => {
      await emailSendService.sendTemplateEmail({
        templateSlug: 'email-verification',
        to: email,
        variables: { verifyUrl, token },
      });
    },
  }),
  inject: [EmailSendService],
}

USER_ENRICHER

Extends user list and profile without modifying base package:

interface IUserEnricher {
  /** Enrich user list query with extra joins/selects */
  enrichListQuery?(
    query: SelectQueryBuilder<User>,
    user: ILoggedUserInfo | null,
  ): Promise<{ extraFields: string[] }>;

  /** Transform user list items with extra computed data */
  enrichListItems?(
    users: IUser[],
    user: ILoggedUserInfo | null,
  ): Promise<IEnrichedUser[]>;

  /** Get extra profile data (roles, permissions, sections) */
  getProfileExtras?(
    userId: string,
    user: ILoggedUserInfo,
  ): Promise<IProfileExtras>;

  /** Handle profile update with extra fields */
  updateProfileExtras?(
    userId: string,
    extras: Record<string, any>,
    queryRunner: QueryRunner,
  ): Promise<void>;

  /** Validate extra fields before profile update */
  validateProfileExtras?(
    userId: string,
    extras: Record<string, any>,
    user: ILoggedUserInfo,
  ): Promise<void>;

  // Multi-Step Profile Methods (LEADPRO-style)
  getProfileSections?(): IProfileSection[];
  getProfileSectionData?(userId, sectionId, user): Promise<IProfileSectionData>;
  updateProfileSection?(userId, sectionId, data, queryRunner): Promise<void>;
  handleSectionFileUpload?(userId, sectionId, field, fileInfo, queryRunner): Promise<IProfileFile>;
  handleSectionFileDelete?(userId, sectionId, field, fileId, queryRunner): Promise<void>;
  calculateProfileCompletion?(userId, user): Promise<number>;
}

Profile Section Interface (for multi-step profiles):

interface IProfileSection {
  id: string;              // Unique identifier
  name: string;            // Display name
  order: number;           // Stepper order
  icon?: string;           // PrimeNG icon class
  required?: boolean;      // Required for completion
  hasFileUpload?: boolean; // Has file fields
  editPermission?: string; // Required permission
}

interface IProfileExtras {
  roles?: IProfileRole[];
  actions?: IProfileAction[];
  sections?: IProfileSectionData[];
  completionPercentage?: number;
}

Services

| Service | Scope | Description | |---------|-------|-------------| | AuthenticationService | REQUEST | Login, register, token management, company selection | | AuthEmailService | REQUEST | Email verification, password reset, pending registrations | | UserService | REQUEST | User CRUD, extends RequestScopedApiService | | CompanyService | REQUEST | Company CRUD (when company feature enabled) | | BranchService | REQUEST | Branch CRUD with company filtering | | UserPermissionService | REQUEST | User-company/branch permission management | | AuthDataSourceProvider | REQUEST | Dynamic datasource for single/multi-tenant | | AuthConfigService | SINGLETON | JWT and module configuration access | | CompanySelectionSessionService | SINGLETON | Session management for company selection |

AuthEmailService

Token Security: All tokens are stored as SHA-256 hashes. Raw tokens are sent to users via email, but only hashes are stored in the database.

| Method | Description | |--------|-------------| | isEmailEnabled() | Check if email provider is configured | | hasPendingRegistration(email) | Check for pending registration | | createPendingRegistration(data) | Create pending registration with verification email | | forgotPassword(email, resetUrlBase) | Send password reset email | | resetPassword(token, newPassword) | Reset password using token | | verifyEmail(token) | Verify email (pending registration or existing user) | | resendVerificationEmail(email, verifyUrlBase) | Resend verification email | | cleanupExpired() | Clean up expired tokens and pending registrations |

Token Expiry:

  • Password Reset: 1 hour
  • Email Verification: 24 hours

API Endpoints

Authentication Endpoints

| Endpoint | Method | Description | |----------|--------|-------------| | /auth/login | POST | Login with email/password | | /auth/register | POST | Register new user | | /auth/refresh | POST | Refresh access token | | /auth/logout | POST | Logout (revokes all tokens) | | /auth/change-password | POST | Change user password | | /auth/me | GET | Get current user info |

Email Authentication Endpoints

| Endpoint | Method | Description | |----------|--------|-------------| | /auth/forgot-password | POST | Request password reset email | | /auth/reset-password | POST | Reset password using token | | /auth/verify-email | POST | Verify email using token | | /auth/resend-verification | POST | Resend email verification link |

Note: Email endpoints require AUTH_EMAIL_PROVIDER to be configured.

Company Selection Endpoints (when company feature enabled)

| Endpoint | Method | Description | |----------|--------|-------------| | /auth/select | POST | Select company and branch after login | | /auth/switch-company | POST | Switch to different company/branch | | /auth/companies | GET | Get user's available companies | | /auth/companies/:companyId/branches | GET | Get branches for a company |

User Management Endpoints

| Endpoint | Method | Description | |----------|--------|-------------| | /administration/users/insert | POST | Create user | | /administration/users/insert-many | POST | Bulk create users | | /administration/users/get/:id | POST | Get user by ID | | /administration/users/get-all | POST | Get paginated user list | | /administration/users/update | POST | Update user | | /administration/users/update-many | POST | Bulk update users | | /administration/users/delete | POST | Delete/restore/permanent delete | | /administration/users/profile | POST | Update own profile | | /administration/users/:id/verify-email | POST | Mark email as verified | | /administration/users/:id/verify-phone | POST | Mark phone as verified | | /administration/users/:id/status | PUT | Update user active status |

User Permission Endpoints (when company feature enabled)

| Endpoint | Method | Description | |----------|--------|-------------| | /administration/permissions/user-company/assign | POST | Batch assign/revoke user-company permissions | | /administration/permissions/user-company | GET | Get user's assigned companies | | /administration/permissions/user-branch/assign | POST | Batch assign/revoke user-branch permissions | | /administration/permissions/user-branch | GET | Get user's assigned branches |

Company/Branch Management Endpoints (when company feature enabled)

| Resource | Endpoints | |----------|-----------| | Companies | /administration/company - CRUD operations | | Branches | /administration/branch - CRUD operations |

Login Flows

Simple Mode (Company Feature Disabled)

POST /auth/login { email, password }
              │
              ▼
┌─────────────────────────┐
│  AuthenticationService  │
│  .login()               │
└────────────┬────────────┘
             │
             │ 1. Check pending registration
             │ 2. Verify credentials
             │ 3. Check email verified (if email enabled)
             │ 4. Generate JWT tokens
             ▼
    { accessToken, refreshToken, user }

Company Mode - Auto-Select (Single Company/Branch)

POST /auth/login { email, password }
              │
              ▼
┌─────────────────────────┐
│  AuthenticationService  │
│  .login()               │
└────────────┬────────────┘
             │
             │ 1. Verify credentials
             │ 2. Check UserCompanyPermission
             │ 3. Found: 1 company, 1 branch → Auto-select
             ▼
    { accessToken, refreshToken, user, company, branch }

Company Mode - Selection Required (Multiple Options)

POST /auth/login { email, password }
              │
              ▼
    { requiresSelection: true, sessionId, companies: [...] }
              │
              │ User selects company & branch
              ▼
POST /auth/select { sessionId, companyId, branchId }
              │
              ▼
    { accessToken, refreshToken, user, company, branch }

Login with Email Verification Required

POST /auth/login { email, password }
              │
              ▼
    If pending registration OR email not verified:
    { requiresEmailVerification: true, email, message }

Email Verification Flow

New User Registration (with email enabled)

┌─────────────────────────────────────────────────────────────────┐
│ POST /auth/register { email, password, name }                   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. Check existing user (must not exist)                         │
│ 2. Hash password with bcrypt (SALT_ROUNDS = 12)                 │
│ 3. Generate verification token                                  │
│ 4. Hash token with SHA-256 for storage                          │
│ 5. Create PendingRegistration record                            │
│ 6. Send verification email via AUTH_EMAIL_PROVIDER              │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
    { requiresEmailVerification: true, message: "Check your email" }
                              │
                              │ User clicks email link
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│ POST /auth/verify-email { token }                               │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. Hash incoming token with SHA-256                             │
│ 2. Find PendingRegistration by hashed token                     │
│ 3. Check expiration                                             │
│ 4. Delete PendingRegistration record                            │
│ 5. Create User with emailVerified: true                         │
│ 6. Process company assignment if companyData present            │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
    { accessToken, refreshToken, user, company?, branch? }

Password Reset Flow

POST /auth/forgot-password { email }
              │
              ▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. Find user by email                                           │
│ 2. Delete existing PASSWORD_RESET tokens for user               │
│ 3. Generate new token, hash with SHA-256                        │
│ 4. Create UserToken record (expires in 1 hour)                  │
│ 5. Send reset email via AUTH_EMAIL_PROVIDER                     │
│ 6. Return success (same response even if user not found)        │
└─────────────────────────────────────────────────────────────────┘
              │
              ▼
    { success: true, message: "If email exists, reset link sent" }
              │
              │ User clicks email link
              ▼
POST /auth/reset-password { token, newPassword }
              │
              ▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. Hash incoming token with SHA-256                             │
│ 2. Find UserToken by hashed token + type: PASSWORD_RESET        │
│ 3. Validate not expired, not used                               │
│ 4. Update user password                                         │
│ 5. Mark token as used (usedAt = now)                            │
└─────────────────────────────────────────────────────────────────┘
              │
              ▼
    { success: true, message: "Password reset successfully" }

User Management

Company Permission Assignment Flow

When creating users with enableCompanyFeature: true, permissions are automatically assigned:

User Creation (with companyId/branchId)
                │
                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. Insert user record                                           │
└─────────────────────────────────────────────────────────────────┘
                │
                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 2. Check if company permission exists                           │
│    - Lookup UserCompanyPermission for user + company            │
│    - If not exists: create { userId, targetId: companyId,       │
│                              permissionType: 'company' }        │
└─────────────────────────────────────────────────────────────────┘
                │
                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 3. Check if branch permission exists                            │
│    - Lookup UserCompanyPermission for user + branch             │
│    - If not exists: create { userId, targetId: branchId,        │
│                              permissionType: 'branch' }         │
└─────────────────────────────────────────────────────────────────┘

User Active Status

When company feature is disabled:

  • Updates User.isActive directly

When company feature is enabled:

  • Updates UserCompanyPermission.isActive for the logged user's company
  • User can be active in Company A but inactive in Company B

Registration Flows

Simple registration:

{ "name": "John Doe", "email": "[email protected]", "password": "password123" }

Join existing company:

{
  "name": "John Doe",
  "email": "[email protected]",
  "password": "password123",
  "companySlug": "acme-corp",
  "branchSlug": "main-branch"
}

Create new company:

{
  "name": "John Doe",
  "email": "[email protected]",
  "password": "password123",
  "newCompanyName": "My Company",
  "newCompanyPhone": "+1234567890",
  "newCompanyAddress": "123 Main St"
}

No-IAM Mode

When not using @flusys/nestjs-iam but controllers use level: 'permission' security, set wildcard permissions after login:

import { HybridCache, CACHE_INSTANCE, PERMISSIONS_CACHE_PREFIX } from '@flusys/nestjs-shared';

@Injectable()
export class AuthenticationService {
  constructor(
    @Inject(CACHE_INSTANCE) private readonly cache: HybridCache,
  ) {}

  async login(dto: LoginDto): Promise<LoginResponse> {
    // ... validate credentials, generate tokens

    // When IAM is NOT used, grant all permissions via wildcard
    await this.setWildcardPermissions(user.id);

    return { accessToken, user };
  }

  private async setWildcardPermissions(userId: string): Promise<void> {
    const cacheKey = `${PERMISSIONS_CACHE_PREFIX}:user:${userId}`;
    await this.cache.set(cacheKey, ['*'], 86400000); // 24 hours TTL
  }
}

With Company Feature Enabled

private async setWildcardPermissions(
  userId: string,
  companyId?: string,
  branchId?: string,
): Promise<void> {
  if (companyId) {
    const cacheKey = `${PERMISSIONS_CACHE_PREFIX}:company:${companyId}:branch:${branchId || 'null'}:user:${userId}`;
    await this.cache.set(cacheKey, ['*'], 86400000);
  } else {
    const cacheKey = `${PERMISSIONS_CACHE_PREFIX}:user:${userId}`;
    await this.cache.set(cacheKey, ['*'], 86400000);
  }
}

Wildcard Permission Patterns

| Pattern | Meaning | |---------|---------| | * | Full access to everything | | user.* | All user permissions | | branch.* | All branch permissions |

API Reference

Exports

// Config
export { AUTH_MODULE_OPTIONS, BCRYPT_SALT_ROUNDS, DEFAULT_COOKIE_NAME, MAX_COOKIE_BYTES, SESSION_CACHE_PREFIX, TOKEN_REVOKED_PREFIX } from './config';

// Entities
export { User } from './entities/user.entity';
export { UserToken, TokenType } from './entities/user-token.entity';
export { PendingRegistration } from './entities/pending-registration.entity';
export { Company } from './entities/company.entity';
export { CompanyBranch } from './entities/company-branch.entity';
export { UserCompanyPermission, PermissionType } from './entities/user-company-permission.entity';
export { getEntitiesByConfig, IAuthEntitiesConfig } from './entities';

// Enums
export { PermissionType } from './enums';

// Interfaces
export { IAuthEmailProvider, AUTH_EMAIL_PROVIDER } from './interfaces/auth-email-provider.interface';
export { IUserEnricher, IProfileSection, IProfileExtras, IEnrichedUser } from './interfaces/user-enricher.interface';
export { AuthModuleOptions, AuthModuleAsyncOptions, AuthOptionsFactory } from './interfaces/auth-module-options.interface';
export { TokenPayload, TokenPayloadWithCompany, LoginResponse, MeResponse, RegistrationResponse } from './interfaces/authentication.interface';

// Services
export { AuthenticationService } from './services/authentication.service';
export { AuthEmailService } from './services/auth-email.service';
export { AuthConfigService } from './services/auth-config.service';
export { AuthDataSourceProvider } from './services/auth-datasource.provider';
export { UserService } from './services/user.service';
export { CompanyService } from './services/company.service';
export { BranchService } from './services/branch.service';
export { UserPermissionService } from './services/user-permission.service';
export { CompanySelectionSessionService } from './services/company-selection-session.service';

// Modules
export { AuthModule } from './modules/auth.module';

// Strategies
export { JwtStrategy } from './strategies/jwt.strategy';

// Interceptors
export { SetToken } from './interceptors/set-token.interceptor';
export { ClearToken } from './interceptors/clear-token.interceptor';

// DTOs
export * from './dtos';

// Swagger Config
export { authSwaggerConfig } from './docs/auth-swagger.config';

Module Static Methods

// Get entities based on feature flags
// Supports both boolean (legacy) and config object signatures
AuthModule.getEntities(config?: boolean | IBootstrapAppConfig): any[]

// Examples:
AuthModule.getEntities()                                    // BaseEntities + EmailEntities
AuthModule.getEntities(true)                                // All entities (backward compat)
AuthModule.getEntities(false)                               // BaseEntities + EmailEntities
AuthModule.getEntities(bootstrapAppConfig)                  // Based on config flags
AuthModule.getEntities({ enableCompanyFeature: true, enableEmailVerification: false })

// Configure module
AuthModule.forRoot(options: AuthModuleOptions): DynamicModule
AuthModule.forRootAsync(options: AuthModuleAsyncOptions): DynamicModule

Swagger Schema Behavior

When enableCompanyFeature: false, the following are automatically hidden from Swagger:

Excluded Tags: Companies, Branches, User Permissions, Company Selection

Excluded DTO Properties:

| DTO | Hidden Fields | |-----|---------------| | RegistrationDto | companySlug, branchSlug, newCompanyName, newCompanyPhone, newCompanyAddress | | RegistrationResponseDto | company, branch, companyFeatureEnabled | | LoginResponseDto | company, branch, companyFeatureEnabled | | MeResponseDto | company, branch |


Last Updated: 2026-02-22