Nestjs Starter

It can take time to create a new nestjs project and make all settings and install the packages. That's why I made this starter kit.

Features

  • Authentication
  • Role based authorization
  • Refresh token operations
  • Session verify and token management from database
  • Logout function for killing session
  • Mysql connection (another driver can be used easily)
  • Auto load & sync entities
  • Eslint
  • Swagger (persistAuthorization)
  • Env settings (local and dev)
  • Debug settings
  • Validation setted up and contains sample codes
  • Response Format
  • Access token, username are indexed for quick access

Installation

The project is using the current lts version node.js 18.12.1 and nestjs 9.1.5. First of all, if you have nvm, let's make sure you are using version 18.12.1

  nvm install 18.12.1
  nvm use 18.12.1

To install all packages

  npm install

To upgrade all packages to current versions

  npm update
  npm i -g npm-check-updates && ncu -u && npm i

Usages & Examples

Authorization

To enable bearer token sending with Swagger, you must put the following tag at the beginning of the controller

@ApiBearerAuth()

Using the Roles decorator, you can specify the user roles that can access those controls.

@Roles(Role.Admin, Role.User)
  @Get('me')
  async getProfile(@Req() req) {
    const response = await this.usersService.findMeById(req.user.id);
    return new ResponseDto(response);
  }

All remaining functions are public. You don't need to use @public decorator.

Response Format

You can return responseDto when returning data in the controller to have a uniform response format

const response = await this.authService.getAccessToken(
  req.params['refreshToken'],
);
return new ResponseDto(response, 'Access token retrieved');

return new ResponseDto(response); // returns 'ok' message and statusCode:200

return new ResponseDto(response, 'Access token retrieved'); // returns custom message and statusCode:200

return new ResponseDto(null, 'Access token cannot retrieved', HttpStatus.BAD_REQUEST); // returns custom message and statusCode:400

Response Example:

{
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InN0cmluZyIsInN1YiI6MSwiY3JlYXRlZEF0IjoiMjAyMi0xMS0xMFQxMDo1MDo1MS41MzBaIiwiaWF0IjoxNjY4MTU1MTQ0LCJleHAiOjE2NjgyNDUxNDR9.Xf6AKBTgx6NPXtP7WsqvUJMYdvpUZ_9zZvTTfZpxJyA",
    "refreshToken": "c1cb305691112804f045af444fc39a41876bfec25aa544d4cb1ab4e94b05693f743d9c2548afc9c92a8e555777c6bbc50a97fe3bf8fab30eac581e8c42031b0f",
    "expiresAt": "2022-11-12T09:25:44.918Z",
    "expiresRefreshAt": "2022-12-11T08:25:44.918Z"
  },
  "message": "Login informations are retrived",
  "statusCode": 200
}

Mapping response object

Sometimes you may not need to return all objects of a data (Ex. password). In such a case, create a response object and use '?' for allow null.

const result: User = await this.usersRepository.findOne({ where: { id: id } });
return new MeResponseDto(result);
export class MeResponseDto {
  constructor(payload: any) {
    this.id = payload?.id;
    this.username = payload?.username;
    this.role = payload?.role;
  }

  id: number;
  username: string;
  role: string;
}

Validations

More info: https://github.com/typestack/class-validator

Typeorm Lazy Loading

It is not efficient to constantly call up data that is not always needed (Eager loading). In such cases lazy loading can be used

More info: https://orkhan.gitbook.io/typeorm/docs/eager-and-lazy-relations#lazy-relations