6
votes

In typeorm, I am trying to use a subscriber decorator to hash users password before persisting to the database. Unfortunately, I can't find a reference in the docs.

In sequelizejs, I use the following code,

User.hashPassword = (user, options) => {
    if (!user.changed('password')) {
      return null;
    }
    // hash password
    return Bcrypt.hash(user.get('password'), SALT_ROUNDS)
      .then(hash => user.set('password', hash));
  };

Right now, I am trying to migrate the code to typeorm and my translation is roughly

@BeforeInsert()
@BeforeUpdate()
hashPassword() {
    // conditional to detect if password has changed goes here
    this.password = bcrypt.hashSync(this.password, SALT_ROUNDS);
}

The issue is, I stuck at !user.changed('password'). Is there an equivalent function in typeorm to do this without rolling out my own solution?

4
Did you find some solution for this?Hammerbot
@Hammerbot No, I did not. What I did was to check if the user.password property is present in the update request. If it is present, confirm that it is a plain string to prevent a double hash. Then manually run the bcrypt.hash() on the plain string before persisting.adetoola
Have you tried using a subscriber? github.com/typeorm/typeorm/blob/master/docs/…bashleigh

4 Answers

5
votes

The solution to this question was found in @adetoola's own issue. You can use @AfterLoad to load the user password and check if the current password is different:

@Entity()
export class User extends BaseEntity {
    @PrimaryColumn()
    public username: string;

    @Column()
    public password: string;

    @Column({ nullable: true })
    public jwtToken: string;

    private tempPassword: string;


    @AfterLoad()
    private loadTempPassword(): void {
        this.tempPassword = this.password;
    }

    @BeforeUpdate()
    private encryptPassword(): void {
        if (this.tempPassword !== this.password) {
            //
        }
    }
1
votes

You can try this:

@BeforeInsert()
@BeforeUpdate()
hashPassword() {
  if (this.password) {
    this.password = createHmac('sha256', this.password).digest('hex');
  }
}

I just check if a password is present in the DTO (before update and insert). If it is present, I should hash it.

0
votes
----------

    private tempPassword: string

  /// commit to handle the password if i not change it it will be  not encription


  @AfterLoad()
  private loadTempPassword(): void {
    this.tempPassword = this.password;
  }




  @BeforeInsert()
  @BeforeUpdate()
  async hashPassword(): Promise<void> {
    // cheack if that password changing or not
    if (this.tempPassword !== this.password) {

      try {
        this.password = await bcrypt.hash(this.password, 10)

      } catch (e) {
        throw new InternalServerErrorException('there are some issiue in the hash')

      }
    }


  }
0
votes

we can make the selection of password from the Column

 @Column('string', { select: false })
   password:string

then we try to hash

we check if the password is found or not 
 if (this.password) {
//make hash 
}

or another way it should make private tempPassword: string

   @AfterLoad()
  private loadTempPassword(): void {
    this.tempPassword = this.password;
  }

or

@BeforeInsert()
  @BeforeUpdate()
  async hashPassword(): Promise<void> {
    // cheack if that password changing or not
    if (this.password) {
      if (this.tempPassword !== this.password) {

        try {
          this.password = await bcrypt.hash(this.password, 10)

        } catch (e) {
          throw new InternalServerErrorException('there are some issiue in the hash')

        }
      }
    }