From dbad9ee1ffc4fc25939174c603dca08f80092c2f Mon Sep 17 00:00:00 2001 From: Thiago Ramalho Date: Tue, 25 Jun 2024 13:24:41 -0300 Subject: [PATCH 1/2] chore: improve documentation for nests-jet --- packages/nestjs-jwt/README.md | 428 ++++++++++++++++++++++++++++++++-- 1 file changed, 412 insertions(+), 16 deletions(-) diff --git a/packages/nestjs-jwt/README.md b/packages/nestjs-jwt/README.md index 393aa60e3..3d3f6c71f 100644 --- a/packages/nestjs-jwt/README.md +++ b/packages/nestjs-jwt/README.md @@ -12,27 +12,147 @@ This module extends/wraps the [@nestjs/jwt](https://www.npmjs.com/package/@nestj [![GH Contrib](https://img.shields.io/github/contributors/conceptadev/rockets?logo=github)](https://github.com/conceptadev/rockets/graphs/contributors) [![NestJS Dep](https://img.shields.io/github/package-json/dependency-version/conceptadev/rockets/@nestjs/common?label=NestJS&logo=nestjs&filename=packages%2Fnestjs-core%2Fpackage.json)](https://www.npmjs.com/package/@nestjs/common) -## Overview +# JWT Module Documentation -The module exports three services: `JwtSignService`, `JwtIssueService`, and `JwtVerifyService`. +## Project + +[![NPM Latest](https://img.shields.io/npm/v/@concepta/nestjs-jwt)](https://www.npmjs.com/package/@concepta/nestjs-jwt) +[![NPM Downloads](https://img.shields.io/npm/dw/@conceptadev/nestjs-jwt)](https://www.npmjs.com/package/@concepta/nestjs-jwt) +[![GH Last Commit](https://img.shields.io/github/last-commit/conceptadev/rockets?logo=github)](https://github.com/conceptadev/rockets) +[![GH Contrib](https://img.shields.io/github/contributors/conceptadev/rockets?logo=github)](https://github.com/conceptadev/rockets/graphs/contributors) +[![NestJS Dep](https://img.shields.io/github/package-json/dependency-version/conceptadev/rockets/@nestjs/common?label=NestJS&logo=nestjs&filename=packages%2Fnestjs-core%2Fpackage.json)](https://www.npmjs.com/package/@nestjs/common) + +## Table of Contents + +- [Tutorials](#tutorials) + - [Introduction](#introduction) + - [Overview of the Library](#overview-of-the-library) + - [Purpose and Key Features](#purpose-and-key-features) + - [Installation](#installation) + - [Basic Setup](#basic-setup) + - [Creating custom jwtIssueService](#creating-custom-jwtIssueService) + - [Environment Variables](#environment-variables) +- [How to Guides](#how-to-guides) + - [1. How to Set Up JwtModule with forRoot](#1-how-to-set-up-jwtmodule-with-forroot) + - [2. How to Configure JwtModule Settings](#2-how-to-configure-jwtmodule-settings) + - [3. Overriding Defaults](#3-overriding-defaults) + - [JwtAccessService](#jwtaccessservice) + - [JwtRefreshService](#jwtrefreshservice) + - [JwtIssueService](#jwtissueservice) + - [JwtVerifyService](#jwtverifyservice) + - [JwtSignService](#jwtsignservice) +- [Explanation](#explanation) + - [Conceptual Overview](#conceptual-overview) + - [What is This Library?](#what-is-this-library) + - [Benefits of Using This Library](#benefits-of-using-this-library) + - [Design Choices](#design-choices) + - [Global, Synchronous vs Asynchronous Registration](#global-synchronous-vs-asynchronous-registration) + - [Integration Details](#integration-details) + - [Integrating with Other Modules](#integrating-with-other-modules) +- [References](#references) + +# Tutorials + +## Introduction + +### Overview of the Library + +This module is designed to manage JWT authentication processes within a NestJS +application. It includes services for issuing JWTs, validating user credentials, +and verifying tokens. The services handle the generation of access and refresh +tokens, ensure users are active and meet authentication criteria, and perform +token validity checks, including additional validations if necessary. This +comprehensive approach ensures secure user authentication and efficient token +management. + +### Purpose and Key Features + +- **Secure Token Management**: Provides robust mechanisms for issuing and + managing access and refresh tokens, ensuring secure and efficient token + lifecycle management. +- **Abstract User Validation Service**: Offers an abstract service to validate + user credentials and check user activity status, ensuring that only eligible + users can authenticate. This abstract nature requires implementations to + define specific validation logic, allowing flexibility across different user + models and authentication requirements. +- **Token Verification**: Includes capabilities to verify the authenticity and + validity of tokens, with support for additional custom validations to meet + specific security requirements. +- **Customizable and Extensible**: Designed to be flexible, allowing + customization of token generation, user validation, and token verification + processes to suit different application needs. +- **Integration with NestJS Ecosystem**: Seamlessly integrates with other + NestJS modules and services, leveraging the framework's features for enhanced + functionality and performance. + +### Installation + +To get started, install the `JwtModule` package: + +**sh-begin** +yarn add @concepta/nestjs-jwt +**sh-end** + +## Basic Setup + +To set up the `JwtModule`, follow the basic setup tutorial in the +[nestjs-authentication README](https://github.com/conceptadev/nestjs-authentication). + +## Creating custom jwtIssueService -The `JwtSignService` maintains two separate `JwtService` instances from the `@nestjs/jwt` module, -one for managing _access_ tokens and one for managing _refresh_ tokens. -Each one can be configured separately at registration time for maximum flexibility. +Here we will cover how to override the default services in `JwtModule`. +For example, to override the `JwtIssueService`, follow the steps below: -The `JwtIssueService` and `JwtVerifyService` use the `JwtSignService` internally for generating -and validating tokens. +1. Create a custom implementation of `JwtIssueService`: -## Installation +```ts +import { Injectable } from '@nestjs/common'; +import { JwtIssueServiceInterface } from './interfaces/jwt-issue-service.interface'; +import { JwtSignService } from './jwt-sign.service'; -`yarn add @concepta/nestjs-jwt` +@Injectable() +export class CustomJwtIssueService implements JwtIssueServiceInterface { + constructor(private readonly jwtSignService: JwtSignService) {} -## Configuration + async accessToken(...args: Parameters) { + return this.jwtSignService.signAsync('access', ...args); + } -- [ENV](#env) -- [Advanced](#advanced) + async refreshToken(...args: Parameters) { + return this.jwtSignService.signAsync('refresh', ...args); + } +} +``` -### ENV +2. Provide the custom implementation in your module configuration: + +```ts +import { Module } from '@nestjs/common'; +import { JwtModule } from '@concepta/nestjs-jwt'; +import { CustomJwtIssueService } from './custom-jwt-issue.service'; + +@Module({ + imports: [ + JwtModule.forRoot({ + jwtIssueService: CustomJwtIssueService, + settings: { + access: { + secret: 'your-secret-key', + signOptions: { expiresIn: '60s' }, + }, + }, + }), + ], + providers: [CustomJwtIssueService], +}) +export class AppModule {} +``` + +This example shows how to customize the `JwtIssueService` with a custom +implementation. Similar steps can be followed to override other services in +`JwtModule`. + +### environment variables Configurations available via environment. @@ -45,7 +165,283 @@ Configurations available via environment. > \* For security reasons, a random UUID will only be generated for the default secret when `NODE_ENV !== 'production'`. -### Advanced +# How to Guides + +### 1. How to Set Up JwtModule with forRoot + +To set up the `JwtModule`, follow these steps: + +```ts +import { Module } from '@nestjs/common'; +import { JwtModule } from '@concepta/nestjs-jwt'; + +@Module({ + imports: [ + JwtModule.forRoot({}), + ], +}) +export class AppModule {} +``` + +This setup configures the `JwtModule` with global settings and integrates the +`JwtModule` for JWT-based authentication. + +### 2. How to Configure JwtModule Settings + +The `JwtModule` provides several configurable settings to customize its +behavior. Each setting can be defined in the module configuration and will +create default services to be used in other modules. + +#### Settings Example + +Here is an example of how to configure each property of the settings: + +```ts +import { Module } from '@nestjs/common'; +import { JwtModule } from '@concepta/nestjs-jwt'; + +@Module({ + imports: [ + JwtModule.forRoot({ + settings: { + access: { + secret: 'your-secret-key', + signOptions: { expiresIn: '60s' }, + }, + }, + }), + ], +}) +export class AppModule {} +``` + +### 3. Overriding Defaults + +To override the default services, you can provide custom implementations for +any of the services. + +#### JwtAccessService +```ts +@Injectable() +import { JwtService, JwtSignOptions } from '@nestjs/jwt'; +class CustomJwtAccessService extends JwtService { + sign(_payload: string, _options?: JwtSignOptions): string { + return 'foo'; + } +} +``` + +#### jwtRefreshService + +```ts +@Injectable() +import { JwtService, JwtSignOptions } from '@nestjs/jwt'; +class CustomRefreshJwtAccessService extends JwtService { + sign(_payload: string, _options?: JwtSignOptions): string { + return 'foo'; + } +} +``` + +#### JwtIssueService + +```ts +import { Injectable } from '@nestjs/common'; +import { JwtIssueServiceInterface } from './interfaces/jwt-issue-service.interface'; +import { JwtSignService } from './jwt-sign.service'; + +@Injectable() +export class CustomJwtIssueService implements JwtIssueServiceInterface { + constructor(private readonly jwtSignService: JwtSignService) {} + + async accessToken(...args: Parameters) { + // Custom implementation + return this.jwtSignService.signAsync('access', ...args); + } + + async refreshToken(...args: Parameters) { + // Custom implementation + return this.jwtSignService.signAsync('refresh', ...args); + } +} +``` + +#### JwtVerifyService. + +```ts +import { Injectable } from '@nestjs/common'; +import { JwtVerifyServiceInterface } from './interfaces/jwt-verify-service.interface'; +import { JwtSignService } from './jwt-sign.service'; + +@Injectable() +export class CustomJwtVerifyService implements JwtVerifyServiceInterface { + constructor(private readonly jwtSignService: JwtSignService) {} + + async accessToken(...args: Parameters) { + // Custom implementation + return this.jwtSignService.verifyAsync('access', ...args); + } + + async refreshToken(...args: Parameters) { + // Custom implementation + return this.jwtSignService.verifyAsync('refresh', ...args); + } +} +``` + +#### JwtSignService + +```ts +import { Inject, Injectable } from '@nestjs/common'; +import { JwtService } from '@nestjs/jwt'; +import { JwtSignServiceInterface } from '../interfaces/jwt-sign-service.interface'; +import { + JWT_MODULE_JWT_ACCESS_SERVICE_TOKEN, + JWT_MODULE_JWT_REFRESH_SERVICE_TOKEN, +} from '../jwt.constants'; +import { JwtTokenType } from '../jwt.types'; + +@Injectable() +export class CustomJwtSignService implements JwtSignServiceInterface { + constructor( + @Inject(JWT_MODULE_JWT_ACCESS_SERVICE_TOKEN) + protected readonly jwtAccessService: JwtService, + @Inject(JWT_MODULE_JWT_REFRESH_SERVICE_TOKEN) + protected readonly jwtRefreshService: JwtService, + ) {} + + async signAsync( + tokenType: JwtTokenType, + ...rest: Parameters + ) { + return this.service(tokenType).signAsync(...rest); + } + + async verifyAsync( + tokenType: JwtTokenType, + ...rest: Parameters + ) { + return this.service(tokenType).verifyAsync(...rest); + } + + decode(tokenType: JwtTokenType, ...rest: Parameters) { + return this.service(tokenType).decode(...rest); + } + + private service(tokenType: JwtTokenType): JwtService { + switch (tokenType) { + case 'access': + return this.jwtAccessService; + case 'refresh': + return this.jwtRefreshService; + } + } +} + +``` + +2. Provide the custom implementations in your module configuration: + +```ts +import { Module } from '@nestjs/common'; +import { JwtModule } from '@concepta/nestjs-jwt'; +import { CustomJwtIssueService } from './custom-jwt-issue.service'; +import { CustomJwtVerifyService } from './custom-jwt-verify.service'; + +@Module({ + imports: [ + JwtModule.forRoot({ + jwtIssueService: CustomJwtIssueService, + jwtVerifyService: CustomJwtVerifyService, + settings: { + access: { + secret: 'your-secret-key', + signOptions: { expiresIn: '60s' }, + }, + }, + }), + ], + providers: [CustomJwtIssueService, CustomJwtVerifyService], +}) +export class AppModule {} +``` + +This example shows how to customize the `JwtIssueService` and `JwtVerifyService` +with custom implementations. Similar steps can be followed to override other +services in `JwtModule`. + + +# Explanation + +### Conceptual Overview + +#### What is This Library? + +The `nestjs-jwt` library is a comprehensive solution for managing authentication +processes within a NestJS application. It provides services for issuing JWTs, +validating user credentials, and verifying tokens. The library integrates +seamlessly with other modules in the `nestjs-auth` suite, making it a versatile +choice for various authentication needs. + +#### Benefits of Using This Library + +- **Secure Token Management**: Robust mechanisms for issuing and managing access + and refresh tokens. +- **Abstract User Validation Service**: Flexible user validation service that + can be customized to meet specific requirements. +- **Token Verification**: Capabilities to verify the authenticity and validity + of tokens, with support for additional custom validations. +- **Customizable and Extensible**: Designed to be flexible, allowing + customization of token generation, user validation, and token verification + processes. +- **Integration with NestJS Ecosystem**: Seamlessly integrates with other + NestJS modules and services, leveraging the framework's features for enhanced + functionality and performance. + +### Design Choices + +#### Global, Synchronous vs Asynchronous Registration + +The `nestjs-jwt` module supports both synchronous and asynchronous registration: + +- **Global Registration**: Makes the module available throughout the entire + application. This approach is useful when JWT authentication is required + across all or most routes in the application. +- **Synchronous Registration**: This method is used when the configuration + options are static and available at application startup. It simplifies the + setup process and is suitable for most use cases where configuration values do + not depend on external services. +- **Asynchronous Registration**: This method is beneficial when configuration + options need to be retrieved from external sources, such as a database or an + external API, at runtime. It allows for more flexible and dynamic configuration + but requires an asynchronous factory function. + +### Integration Details + +#### Integrating with Other Modules + +The `nestjs-jwt` module integrates smoothly with other modules in the +`nestjs-auth` suite. Here are some integration details: + +- **@concepta/nestjs-auth-jwt**: Use `@concepta/nestjs-auth-jwt` for JWT-based + authentication. Configure it to handle the issuance and verification of JWT + tokens. +- **@concepta/nestjs-auth-local**: Use `@concepta/nestjs-auth-local` for local + authentication strategies such as username and password. +- **@concepta/nestjs-auth-recovery**: Use `@concepta/nestjs-auth-recovery` for + account recovery processes like password reset. +- **@concepta/nestjs-auth-refresh**: Use `@concepta/nestjs-auth-refresh` for + handling token refresh mechanisms. + +By combining these modules, you can create a comprehensive authentication system +that meets various security requirements and user needs. + +## References + +For further details and external references, please visit the following link: + +[External Authentication References](#) + +This link provides additional information and resources related to the +authentication processes and best practices in NestJS applications. -It is possible to override all services at registration time with a custom service that -meets their respective interfaces. From 19d3683e551ef8e3e3c5ca944d91f14de339413c Mon Sep 17 00:00:00 2001 From: Marshall Sorenson Date: Mon, 8 Jul 2024 17:40:23 -0400 Subject: [PATCH 2/2] chore: doc cleanup --- packages/nestjs-auth-jwt/README.md | 246 +++++++++++++++++------------ 1 file changed, 143 insertions(+), 103 deletions(-) diff --git a/packages/nestjs-auth-jwt/README.md b/packages/nestjs-auth-jwt/README.md index f7b66ec07..6e7419c0f 100644 --- a/packages/nestjs-auth-jwt/README.md +++ b/packages/nestjs-auth-jwt/README.md @@ -1,6 +1,7 @@ # Rockets NestJS JWT Authentication -Authenticate requests using JWT tokens passed via the request (headers, cookies, body, query, etc). +Authenticate requests using JWT tokens passed via the +request (headers, cookies, body, query, etc). ## Project @@ -65,7 +66,7 @@ Authenticate requests using JWT tokens passed via the request (headers, cookies, - [How AuthJwtModule Works with AuthLocalModule](#how-authjwtmodule-works-with-authlocalmodule) - [Integrating with AuthRefreshModule](#integrating-with-authrefreshmodule) -# Tutorials +## Tutorials ### 1. Getting Started with AuthJwtModule @@ -98,9 +99,10 @@ application or tailor it for specific features. ### 1.2 Installation -#### Install the AuthJwtModule package: +#### Install the AuthJwtModule package -To get started, install the `@concepta/nestjs-auth-jwt` packages and some other dependencies from npm or yarn: +To get started, install the `@concepta/nestjs-auth-jwt` packages and some other +dependencies from npm or yarn: ```bash npm install class-transformer @@ -111,7 +113,9 @@ npm install @concepta/nestjs-authentication npm install @concepta/nestjs-jwt npm install @concepta/nestjs-auth-jwt ``` + or + ```bash yarn add class-transformer yarn add class-validator @@ -122,7 +126,7 @@ yarn add @concepta/nestjs-jwt yarn add @concepta/nestjs-auth-jwt ``` -#### Add the AuthJwtModule to Your NestJS Application: +#### Add the AuthJwtModule to Your NestJS Application Import the `AuthJwtModule` and required services in your application module. Ensure to import `JwtModule` and provide the necessary configuration options, @@ -132,16 +136,18 @@ including the required `userLookupService`. #### Scenario: Users have a list of pets -To demonstrate this scenario, we will set up an application where users can have a list of pets. -We will create the necessary entities, services, module configurations to simulate the environment. +To demonstrate this scenario, we will set up an application where users can +have a list of pets. We will create the necessary entities, services, module +configurations to simulate the environment. -> Note: The `@concepta/nestjs-user` module can be used in place of our example `User` related prerequisites. +> Note: The `@concepta/nestjs-user` module can be used in place of our +> example `User` related prerequisites. #### Step 1: Create Entities First, create the `User` and `Pet` entities. -```typescript +```ts // user.entity.ts import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'; import { Pet } from './pet.entity'; @@ -159,7 +165,7 @@ export class User { } ``` -```typescript +```ts // pet.entity.ts import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'; import { User } from './user.entity'; @@ -181,7 +187,7 @@ export class Pet { Next, create services for `User` and `Pet` to handle the business logic. -```typescript +```ts // user.service.ts import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; @@ -208,7 +214,7 @@ export class UserService { } ``` -```typescript +```ts // user-lookup.service.ts import { AuthJwtUserLookupServiceInterface } from '@concepta/nestjs-auth-jwt'; import { ReferenceIdInterface, ReferenceSubject } from '@concepta/ts-core'; @@ -226,7 +232,7 @@ export class UserLookupService implements AuthJwtUserLookupServiceInterface { } ``` -```typescript +```ts // pet.service.ts import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; @@ -254,10 +260,11 @@ export class PetService { Create a controller to handle the HTTP requests. -> Use `@AuthPublic` decorator from `@concepta/nestjs-authentication` on the controller or -individual routes if you want to override the global JWT guard to make the route public. +> Use `@AuthPublic` decorator from `@concepta/nestjs-authentication` +on the controller or individual routes if you want to override the +global JWT guard to make the route public. -```typescript +```ts // user.controller.ts import { Controller, Get, Param } from '@nestjs/common'; import { UserService } from './user.service'; @@ -282,7 +289,7 @@ export class UserController { Configure the module to include the necessary services, controllers, and guards. -```typescript +```ts import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthJwtModule } from '@concepta/nestjs-auth-jwt'; @@ -316,10 +323,12 @@ export class UserModule {}; #### Validating the Setup -To validate the setup, you can use `curl` commands to simulate frontend requests. +To validate the setup, you can use `curl` commands to simulate +frontend requests. -By following these steps, you can validate that the setup is working correctly and that -authenticated requests to the `user/:id/pets` endpoint return the expected list of pets for a given user. +By following these steps, you can validate that the setup is +working correctly and that authenticated requests to the `user/:id/pets` +endpoint return the expected list of pets for a given user. Here are the steps to test the `user/:id/pets` endpoint: @@ -335,23 +344,25 @@ curl -X POST [auth-url] \ -d '{"username": "[username]", "password": "[password]"}' ``` -This should return a response with a JWT token, which you'll use for authenticated requests. +This should return a response with a JWT token, which you'll use for +authenticated requests. #### Step 2: Make an Authenticated Request -Use the JWT token obtained in the previous step to make an authenticated request to -the `user/:id/pets` endpoint. Replace `[jwt-token]` with the actual token and `[user-id]` with a valid user ID. +Use the JWT token obtained in the previous step to make an authenticated +request to the `user/:id/pets` endpoint. Replace `[jwt-token]` with the actual +token and `[user-id]` with a valid user ID. ```bash curl -X GET http://localhost:3000/user/[user-id]/pets \ -H "Authorization: Bearer [jwt-token]" ``` -#### Example Curl Calls: +#### Example Curl Calls Here is an example sequence of curl commands: -##### Obtain a JWT token: +##### Obtain a JWT token ```bash curl -X POST http://localhost:3000/auth/login \ @@ -359,7 +370,7 @@ curl -X POST http://localhost:3000/auth/login \ -d '{"username": "testuser", "password": "testpassword"}' ``` -##### Example JWT response: +##### Example JWT response ```json { @@ -367,14 +378,15 @@ curl -X POST http://localhost:3000/auth/login \ } ``` -##### Make an authenticated request using the token: +##### Make an authenticated request using the token ```bash curl -X GET http://localhost:3000/user/1/pets \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` -##### Example authenticated response: +##### Example authenticated response + ```json [ { @@ -389,7 +401,7 @@ curl -X GET http://localhost:3000/user/1/pets \ ] ``` -# How-To Guides +## How-To Guides ### Setting Up a Custom Module for Providers @@ -400,7 +412,7 @@ includes the necessary providers and exports for `UserLookupService`, This will ensure that our asynchronous registration examples can inject these services correctly. -```typescript +```ts import { Module } from '@nestjs/common'; import { UserLookupService } from './user-lookup.service'; import { MyVerifyTokenService } from './verify-token.service'; @@ -416,7 +428,7 @@ export class MyProviderModule {}; ### 1. Registering AuthJwtModule Synchronously -```typescript +```ts import * as jwt from 'jsonwebtoken'; import { Module } from '@nestjs/common'; import { AuthJwtModule } from '@concepta/nestjs-auth-jwt'; @@ -455,7 +467,7 @@ export class AppModule {} ### 2. Registering AuthJwtModule Asynchronously -```typescript +```ts import * as jwt from 'jsonwebtoken'; import { Module } from '@nestjs/common'; import { AuthJwtModule } from '@concepta/nestjs-auth-jwt'; @@ -506,7 +518,7 @@ export class AppModule {}; ### 3. Global Registering AuthJwtModule Asynchronously -```typescript +```ts import * as jwt from 'jsonwebtoken'; import { Module } from '@nestjs/common'; import { AuthJwtModule } from '@concepta/nestjs-auth-jwt'; @@ -557,10 +569,11 @@ export class AppModule {}; ### 4. Using Custom User Lookup Service -This service is responsible for looking up user information based on the JWT payload. -It implements the `AuthJwtUserLookupServiceInterface` and must be provided to the module. +This service is responsible for looking up user information based +on the JWT payload. It implements the `AuthJwtUserLookupServiceInterface` +and must be provided to the module. -```typescript +```ts import { AuthJwtUserLookupServiceInterface } from '@concepta/nestjs-auth-jwt'; import { ReferenceIdInterface, ReferenceSubject } from '@concepta/ts-core'; @@ -573,9 +586,10 @@ export class UserLookupService implements AuthJwtUserLookupServiceInterface { #### 5. Implementing and Using Custom Token Verification Service -This service verifies JWT tokens. If not provided, the default verification logic will be used. It extends the `VerifyTokenServiceInterface`. +This service verifies JWT tokens. If not provided, the default verification +logic will be used. It extends the `VerifyTokenServiceInterface`. -```typescript +```ts import { JwtService } from '@nestjs/jwt'; import { Injectable } from '@nestjs/common'; import { VerifyTokenServiceInterface } from '@concepta/nestjs-authentication'; @@ -615,14 +629,14 @@ from NestJS and provide it in the module configuration. To take advantage of the ability to enable/disable guards via configuration settings or with the `@AuthPublic` decorator, it is highly recommended that -you extend `AuthJwtGuard` class or call the `AuthGuard()` class factory from the -`@concepta/nestjs-authentication` module. +you extend `AuthJwtGuard` class or call the `AuthGuard()` class factory from +the `@concepta/nestjs-authentication` module. #### Step 1: Implement the Custom Guard Create a custom guard by extending the `AuthJwtGuard`. -```typescript +```ts import { Injectable, ExecutionContext } from '@nestjs/common'; import { AuthGuard } from '@concepta/nestjs-authentication'; @@ -644,7 +658,7 @@ export class MyAppGuard extends AuthJwtGuard { Update the module configuration to use the custom guard. -```typescript +```ts // ... AuthJwtModule.registerAsync({ useFactory: async (userLookupService: UserService) => ({ @@ -658,13 +672,14 @@ AuthJwtModule.registerAsync({ ### 7. Disabling the Guard -To completely disable the global guard for all routes, you can set the appGuard option to false. +To completely disable the global guard for all routes, you can set the +`appGuard` option to false. #### Disable the Guard in Module Configuration Update the module configuration to disable the global `APP_GUARD`. -```typescript +```ts // ... AuthJwtModule.registerAsync({ useFactory: async (userLookupService: UserService) => ({ @@ -678,7 +693,7 @@ AuthJwtModule.registerAsync({ ### 8. Overwriting the settings -```typescript +```ts import { ExtractJwt, JwtStrategyOptionsInterface } from "@concepta/nestjs-jwt"; const settings: JwtStrategyOptionsInterface = { @@ -711,8 +726,9 @@ AuthJwtModule.registerAsync({ ### 9. Integration with Other NestJS Modules Integrate `@concepta/nestjs-auth-jwt` with other NestJS modules like -`@concepta/nestjs-user`, `@concepta/nestjs-auth-local`, `@concepta/nestjs-auth-refresh`, -and more for a comprehensive authentication system. +`@concepta/nestjs-user`, `@concepta/nestjs-auth-local`, +`@concepta/nestjs-auth-refresh`, and more for a comprehensive +authentication system. # Reference @@ -720,41 +736,54 @@ Detailed Descriptions of All Classes, Methods, and Properties ## 1. AuthJwtModule API Reference -- ### register(options: AuthJwtOptions): +- ### register(options: AuthJwtOptions) + - Registers the module with synchronous options. -- ### registerAsync(options: AuthJwtAsyncOptions): +- ### registerAsync(options: AuthJwtAsyncOptions) + - Registers the module with asynchronous options. -- ### forRoot(options: AuthJwtOptions): +- ### forRoot(options: AuthJwtOptions) + - Registers the module globally with synchronous options. -- ### forRootAsync(options: AuthJwtAsyncOptions): +- ### forRootAsync(options: AuthJwtAsyncOptions) + - Registers the module globally with asynchronous options. -- ### forFeature(options: AuthJwtOptions): +- ### forFeature(options: AuthJwtOptions) + - Registers the module for specific features with custom options. ## 2. AuthJwtOptionsInterface -The `AuthJwtOptionsInterface` provides various configuration options to customize the behavior of the `AuthJwtModule`. Below is a summary of the key options: +The `AuthJwtOptionsInterface` provides various configuration options +to customize the behavior of the `AuthJwtModule`. + +Below is a summary of the key options: + +- ### userLookupService (required) + + - Service for looking up user information based on JWT payload. -- ### userLookupService (required): - - Service for looking up user information based on JWT payload. +- ### verifyTokenService (optional) -- ### verifyTokenService (optional): - - Service for verifying JWT tokens. + - Service for verifying JWT tokens. -- ### appGuard (optional): - - Custom guard to protect routes; can be set to a custom guard or `false`. +- ### appGuard (optional) -- ### settings (optional): - - JWT strategy settings, including token extraction and verification logic. + - Custom guard to protect routes; can be set to a custom guard or `false`. + +- ### settings (optional) + + - JWT strategy settings, including token extraction and verification logic. ## 3. AuthJwtModule Classes and Interfaces - - AuthJwtUserLookupServiceInterface - - VerifyTokenServiceInterface - - JwtStrategyOptionsInterface + +- AuthJwtUserLookupServiceInterface +- VerifyTokenServiceInterface +- JwtStrategyOptionsInterface # Engineering Concepts @@ -766,29 +795,33 @@ JSON Web Tokens (JWT) are a compact, URL-safe means of representing claims to be transferred between two parties. The token is composed of three parts: the header, payload, and signature. -The header typically consists of the token type (JWT) and the signing algorithm (e.g., HMAC SHA256). +The header typically consists of the token type (JWT) and the signing +algorithm (e.g., HMAC SHA256). The payload contains the claims, which are statements about an entity -(typically, the user) and additional data. The signature is used to verify that the -sender of the JWT is who it says it is and to ensure that the message wasn't changed along the way. +(typically, the user) and additional data. The signature is used to verify +that the sender of the JWT is who it says it is and to ensure that the message +wasn't changed along the way. -For more details on JWT, see the [JWT Introduction](https://jwt.io/introduction/). +For more details on JWT, see the +[JWT Introduction](https://jwt.io/introduction/). ### Benefits of Using JWT JWTs offer several benefits for authentication and authorization: -- **Stateless**: JWTs do not require storing user session information on the server, -which makes them ideal for scalable applications. +- **Stateless**: JWTs do not require storing user session information on +the server, which makes them ideal for scalable applications. -- **Compact**: Their small size allows them to be easily passed in URLs, POST parameters, -or inside HTTP headers. +- **Compact**: Their small size allows them to be easily passed in URLs, +POST parameters, or inside HTTP headers. -- **Self-contained**: JWTs contain all the necessary information about the user, avoiding -the need to query the database for each request once the user is authenticated. +- **Self-contained**: JWTs contain all the necessary information about the +user, avoiding the need to query the database for each request once the user +is authenticated. -- **Security**: JWTs can be signed using a secret (with HMAC algorithm) or a public/private -key pair (with RSA or ECDSA), ensuring the data integrity. +- **Security**: JWTs can be signed using a secret (with HMAC algorithm) or +a public/private key pair (with RSA or ECDSA), ensuring the data integrity. For more benefits, see the [JWT Handbook](https://auth0.com/learn/json-web-tokens/). @@ -796,12 +829,14 @@ For more benefits, see the [JWT Handbook](https://auth0.com/learn/json-web-token ### Why Use NestJS Guards? -Description: NestJS guards provide a way to control the access to various parts -of the application by checking certain conditions before the route handler is executed. +Description: NestJS guards provide a way to control the access to various +parts of the application by checking certain conditions before the route +handler is executed. -In `AuthJwtModule`, guards are used to implement authentication and authorization logic. -By using guards, developers can apply security policies across routes efficiently, ensuring -that only authenticated and authorized users can access protected resources. +In `AuthJwtModule`, guards are used to implement authentication and +authorization logic. By using guards, developers can apply security policies +across routes efficiently, ensuring that only authenticated and authorized +users can access protected resources. Read more about [NestJS Guards](https://docs.nestjs.com/guards). @@ -809,14 +844,15 @@ Read more about [NestJS Guards](https://docs.nestjs.com/guards). The `AuthJwtModule` supports both synchronous and asynchronous registration: -- **Synchronous Registration**: This method is used when the configuration options -are static and available at application startup. It simplifies the setup process and -is suitable for most use cases where configuration values do not depend on external services. +- **Synchronous Registration**: This method is used when the configuration +options are static and available at application startup. It simplifies the +setup process and is suitable for most use cases where configuration values +do not depend on external services. -- **Asynchronous Registration**: This method is beneficial when configuration options -need to be retrieved from external sources, such as a database or an external API, -at runtime. It allows for more flexible and dynamic configuration but requires an -asynchronous factory function. +- **Asynchronous Registration**: This method is beneficial when configuration +options need to be retrieved from external sources, such as a database or an +external API, at runtime. It allows for more flexible and dynamic configuration +but requires an asynchronous factory function. For more on module registration, see the [NestJS Documentation](https://docs.nestjs.com/modules). @@ -824,12 +860,14 @@ For more on module registration, see the [NestJS Documentation](https://docs.nes The `AuthJwtModule` can be registered globally or for specific features: -- **Global Registration**: Makes the module available throughout the entire application. -This approach is useful when JWT authentication is required across all or most routes in the application. +- **Global Registration**: Makes the module available throughout the entire +application. This approach is useful when JWT authentication is required across +all or most routes in the application. -- **Feature-Specific Registration**: Allows the module to be registered only for specific -features or modules within the application. This provides more granular control, enabling -different parts of the application to have distinct authentication and authorization requirements. +- **Feature-Specific Registration**: Allows the module to be registered only +for specific features or modules within the application. This provides more +granular control, enabling different parts of the application to have distinct +authentication and authorization requirements. To understand more about global and feature-specific registration, refer to the [NestJS Module Documentation](https://docs.nestjs.com/modules#global-modules). @@ -839,19 +877,21 @@ To understand more about global and feature-specific registration, refer to the ### How AuthJwtModule Works with AuthLocalModule The `AuthJwtModule` can be seamlessly integrated with the -`AuthLocalModule` to provide a comprehensive authentication solution. `AuthLocalModule` -handles the initial authentication using local strategies such as username and password. +`AuthLocalModule` to provide a comprehensive authentication solution. +`AuthLocalModule` handles the initial authentication using local strategies +such as username and password. -Once the user is authenticated, `AuthJwtModule` can issue a JWT that the user can use for -subsequent requests. This integration allows for secure and efficient authentication -processes combining the strengths of both modules. +Once the user is authenticated, `AuthJwtModule` can issue a JWT that the +user can use for subsequent requests. This integration allows for secure and +efficient authentication processes combining the strengths of both modules. ### Integrating with AuthRefreshModule Integrating `AuthJwtModule` with `AuthRefreshModule` enables the -application to handle token refresh logic. Refresh tokens are used to obtain new access -tokens without requiring the user to re-authenticate. +application to handle token refresh logic. Refresh tokens are used to obtain +new access tokens without requiring the user to re-authenticate. -This setup enhances the user experience by maintaining sessions securely and seamlessly. -The integration involves configuring both modules to use the same token issuance and -verification mechanisms, ensuring smooth interoperability and security. +This setup enhances the user experience by maintaining sessions securely and +seamlessly. The integration involves configuring both modules to use the same +token issuance and verification mechanisms, ensuring smooth interoperability +and security.