5
votes

Comment empêcher les propriétés d'objets indésirables du client dans nestjs lors de la mise à jour d'une ligne existante dans mongodb

La création d'un nouvel utilisateur ignorera les objets non spécifiés de create-user.dto.ts

Cependant, lorsque je mets à jour l'utilisateur, il ajoutera des champs indésirables comme celui-ci:

XXX

Ceci est l'action de mise à jour du service utilisateur

// Unwanted junk from client
{
  "email": "newemail@gmail.com",
  "junk": "junk"
}

Et voici le user.controller.ts

  @Patch()
  @UsePipes(CustomValidationPipe)
  async update(@Body() data: UpdateUserDto) {
    return this.userService.update(data);
  }

Les données du correctif client:

// user.service.ts
  async update(data: UpdateUserDto) {
    try {
      this.logger.log(data);
      const id = '5c6dd9852d4f441638c2df86';
      const user = await this.userRepository.update(id, data);

      return { message: 'Updated your information' };
    } catch (error) {
      this.logger.log(error);
      throw new HttpException('', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

Le email sera mis à jour correctement mais la ligne aura une nouvelle propriété indésirable code> junk avec la valeur junk


0 commentaires

3 Réponses :


0
votes

J'ai trouvé la solution:

Voici à quoi devrait ressembler user.service.ts update ():

  async update(data: UpdateUserDto) {
    this.logger.log(data);

    // added for testing purposes (id should be based on active user)
    const id = '5c6ef2c823bf4e3414d65cd0';
    const user = await this.userRepository.create(data);
    await this.userRepository.update(id, user);

    return { message: 'Updated your information' };
  }

doit être ajouté avant

await this.userRepository.update(id, user);

Voici la mise à jour complète de user.service.ts ()

const user = await this.userRepository.create(data);

Désormais, aucune propriété indésirable ne sera ajoutée à la ligne


0 commentaires

7
votes

Je suppose que vous utilisez la méthode validate de class-transformer dans votre CustomValidationPipe .

Lorsque vous passez le whitelist , validate supprimera toutes les propriétés inconnues (-> aucune annotation dans votre classe DTO):

@IsString()
lastName: string;

@ValidateNested()
@Type(() => Address)
address: Address

Si vous souhaitez renvoyer une erreur de validation au lieu de simplement supprimer les propriétés inconnues, vous pouvez également passer l'option interditNonWhitelisted .

validate(userUpdate, { whitelist: true, forbidNonWhitelisted: true });

Dans le cas d'une mise à jour, vous voudrez probablement aussi utiliser skipMissingProperties: true , afin que validate ne lève pas d'erreur, lorsque par exemple lastName ne fait pas partie de la mise à jour.


Notez que vous devez annoter toutes les propriétés de votre classe dto, pour que la validation fonctionne correctement:

XXX


1 commentaires

Excellente réponse. Exactement ce que je cherchais!



2
votes

Je ne sais pas quand ce comportement / cette option a été ajouté à NestJS (peut-être a-t-il été ajouté après la question d'origine et la réponse acceptée), mais le meilleur moyen de supprimer les propriétés inconnues serait que:

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);

C'est ça. En vous assurant simplement d'avoir whitelist: true dans votre configuration, vous n'obtiendrez aucune propriété inconnue / invalide.

Vous pouvez également arrêter complètement la demande en définissant une autre propriété appelé interditNonWhitelisted à true.

Pour en savoir plus: https://docs.nestjs.com/techniques/validation#stripping-properties


0 commentaires