Creating a new user will ignore non-specified objects from create-user.dto.ts
However when I update the user it will add unwanted fields like this:
// update-user.dto.ts
import { IsEmail } from 'class-validator';
import { Address } from '../model/address';
export class UpdateUserDto {
firstName: string;
lastName: string;
@IsEmail(undefined, { message: 'Not a valid e-mail' })
email: string;
username: string;
password: string;
addresses: Address[];
}
This is the update action from the user service
// 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);
}
}
And here is the user.controller.ts
@Patch()
@UsePipes(CustomValidationPipe)
async update(@Body() data: UpdateUserDto) {
return this.userService.update(data);
}
The client patch data:
// Unwanted junk from client
{
"email": "[email protected]",
"junk": "junk"
}
The email
will update properly but the row will have a new unwanted property junk
with the value junk
I'm assuming you are using class-transformer
's validate
method in your CustomValidationPipe
.
When you pass the whitelist
option to it, validate
will strip away all unknown (-> no annotation in your DTO class) properties:
validate(userUpdate, { whitelist: true })
If you want to throw a validation error instead of just stripping away unknown properties, you can additionally pass the forbidNonWhitelisted
option.
validate(userUpdate, { whitelist: true, forbidNonWhitelisted: true });
In the case of an update, you probably also want to use skipMissingProperties: true
, so that validate will not throw an error, when e.g. lastName
is not part of the update.
Note, that you should annotate all properties in your dto class, for the validation to work properly:
@IsString()
lastName: string;
@ValidateNested()
@Type(() => Address)
address: Address
Not sure when this behavior/option was added to NestJS (perhaps it was added after the original question and accepted answer), but the best way to achieve unknown property stripping would be that:
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
}),
);
That is it. By just making sure you have whitelist: true
in your config, you won't be getting any unknown/invalid property.
You can also completely stop the request by setting another property called forbidNonWhitelisted
to true
.
More on that here: https://docs.nestjs.com/techniques/validation#stripping-properties
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With