【问题标题】:TypeORM / NestJS - @BeforeUpdate hook not workingTypeORM / NestJS - @BeforeUpdate 挂钩不起作用
【发布时间】:2022-03-28 19:16:16
【问题描述】:

我在使用 TypeOrm 挂钩“BeforeUpdate”时遇到问题

我正在尝试更新用户实体密码,方法是传递一个简单的字符串并调用 save 方法来触发 beforeUpdate 钩子,然后对密码进行哈希处理,但是在调用 save 方法时这个钩子不起作用。

这就是我所拥有的

user.service.ts

  async update(id: number, updateUserDto: UpdateUserDto) {
    const roles =
      updateUserDto.roles &&
      (await Promise.all(
        updateUserDto.roles.map((name) => this.preloadRoleByName(name))
      ));
    const user = await this.userRepository.findOneOrFail(id);
    if (!user) {
      throw new NotFoundException(`User with ID #${id} not found`);
    }
    const toSaveUser = {
      ...user,
      ...updateUserDto,
      roles,
    };
    return await this.userRepository.save(toSaveUser);
  }

user.entity.ts

.
.
.
@Column()
@Exclude()
password: string;

@BeforeInsert()
@BeforeUpdate()
private async hashPassword() {
  const rounds = 10;
  const salt = await bcrypt.genSalt(rounds);
  this.password = await bcrypt.hash(this.password, salt);
}

user.controller.ts

@Patch(":id")
@UseInterceptors(ClassSerializerInterceptor)
async update(@Param("id") id: string, @Body() updateUserDto: UpdateUserDto) {
 return await this.usersService.update(+id, updateUserDto);
}

我做错了什么?

BeforeInsert 钩子有效,或者如果我调用 userRepository.preload() 方法来更新它,但它不会取代角色关系,这就是我采用这种方法的原因。

有什么想法吗?

【问题讨论】:

    标签: nestjs typeorm nestjs-config node.js-typeorm


    【解决方案1】:

    您需要先创建 DTO(Data Transfer Object),然后再更新。此代码用于更新临时密码。

    如何创建 DTO:

    this..create()

    例子:

    async updatePassword(id: number, tempPassword: string): Promise<boolean> {
        let newUser = { tempPassword: tempPassword };
        const userDto = this.userAccountRepository.create(newUser)
        const userAccount = this.userAccountRepository.update(
          {
            userAccountId: id,
          },
          userDto 
        );
        if (userAccount) {
          return true;
        } else {
          return false;
        }
      }
    

    这是我的实体:

    import {BeforeInsert, BeforeUpdate,Column,Entity,JoinColumn,OneToMany,OneToOne,PrimaryColumn,} from 'typeorm';
    import { Users } from '../users/users.entity';
    const crypto = require('crypto');
    
        @Entity()
        export class UserAccount {
          @PrimaryColumn()
          userAccountId: number;
          @OneToOne(() => Users, { cascade: true })
          @JoinColumn({ name: 'userAccountId' })
          @Column({ nullable: true })
          tempPassword: string;
          @BeforeInsert()
          @BeforeUpdate()
          async hashPassword(): Promise<void> {
            if (!!this.password) {
              this.password = crypto.createHmac('sha256', this.password).digest('hex');
            }
            if (!!this.tempPassword) {
              this.tempPassword = crypto
                .createHmac('sha256', this.tempPassword)
                .digest('hex');
            }
          }
        }
    

    【讨论】:

      【解决方案2】:

      在 TypeOrm 中使用这些触发器有一个奇怪的缺点,您必须使用存储库 api 来创建您调用 .save 的实例。

          const toSaveUser = this.userRepository.create({
            ...user,
            ...updateUserDto,
            roles,
          });
          return await this.userRepository.save(toSaveUser);
      
      

      而且你应该很好。在 DTO 对象或不是从 repository.create 创建的实体实例上调用 .save 不会触发事件函数。

      【讨论】:

        【解决方案3】:

        我这边的两个输入,

        1. 用于加密更新密码的单独功能 -
          @BeforeUpdate()
          async hashPasswordBeforeUpdate() {
            this.password = await bcrypt.hash(this.password, 10);
          }
        
        1. 尝试创建 PUT 请求而不是 PATCH 请求

        我能够生成有效的更新查询,仅供参考-

        query: UPDATE `users` SET `levelId` = ?, `updatedAt` = ?, `password` = ? WHERE `id` IN (?) -- PARAMETERS: [null,"2021-05-07T07:27:47.198Z","$2b$10$uQOMNv57BZLB/W/9SWPbke6/OMdIDWxv3i25A8rUhA0/vEMloWb2W",1]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多