Search code examples
node.jstypescriptnestjsdtotypeorm

How to hash password before inserting?


I am using Nest.Js with TypeORM and I want to hash my password before persisting into the DB.

I tried using the event decorator @BeforeInsert() however it wasn't working for me but later I found that it was not working because I was taking an DTO as an input.

user.controller.ts

  @Post()
  async create(@Body() data: CreateUserDto, @Res() res) {

    // if user already exist
    const isUserExist = await this.service.findByEmail(data.email);
    if (isUserExist) {
      throw new BadRequestException('Email already exist');
    }

    // insert user
    this.service.create(data);

    // send response
    return res.status(201).json({
      statusCode: 201,
      message: 'User added Successfully',
    });
  }


user.service.ts

    create(data: CreateUserDto) {
        return this.userRepository.save(data)
    }

So, I was basically using an DTO to save the data. That's why it was not working.

But what I want to do is map the DTO to user object. So, This is what I did.

  @Post()
  async create(@Body() data: CreateUserDto, @Res() res) {

    // Create User object
    const user = new User();

    // Map DTO to User object
    for (const [key, value] of Object.entries(data)) {
      user[key] = value;
    }

    // if user already exist
    const isUserExist = await this.service.findByEmail(user.email);
    if (isUserExist) {
      throw new BadRequestException('Email already exist');
    }

    // insert user
    this.service.create(user);

    // send response
    return res.status(201).json({
      statusCode: 201,
      message: 'User added Successfully',
    });
  }

create-user.dto.ts

import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly firstName: string;
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly lastName: string;
    @IsNotEmpty()
    @IsString()
    @IsEmail()
    @ApiProperty()
    readonly email: string;
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly password: string;
}

Is there any better approach for this? Because currently I have to write the code in every method to map it.


Solution

  • We can easily map Plain Object Literal to Class Instances by using 'class-transformer' package

    Answer:

    async create(@Body() data: CreateUserDto, @Res() res) {
    
    const user = plainToClass(User, data)
    
    }