Class-validator: Deep nested validation broken

Created on 20 May 2020  路  14Comments  路  Source: typestack/class-validator

Description

When trying to validate nested objects using @ValidateNested(), whitelist: true and forbidNonWhitelisted: true, error "property XY should not exist" gets thrown for no apparent reason.

Reproduction

Here a vastly simplified version of my use case:

class ProductPricing {
    @Type(() => ProductPricingOptionsDTO)
    options: ProductPricingOptionsDTO;
}
class ProductPricingOptionsDTO{
    @ValidateNested()
    @Type(() => OnlineUserPricingOptionsDTO)
    onlineUserPrices: OnlineUserPricingOptionsDTO;
}



md5-a0958fc4778dd0b00617aaa166cdc454



class OnlineUserPricingOptionsDTO{
    @IsNumber()
    @Min(2)
    price: number;
}



md5-2423009a39f75b49cb1b947056fbcdcf



{
    "options": {
        "onlineUserPrices": {
            "price": 2
        }
    }
}



md5-4429c47492cdac6fe03394825f60a785



"constraints": {
    "whitelistValidation": "property price should not exist"            }
}

Environment

  • [x] nodejs:
  • [ ] browser:
  • [x] typeorm:

class-validator version: ^0.12.1

Most helpful comment

Cheers! We have found out that adding @Type(() => NestedType) was the thing. It works without adding that parameter which you suggested.
Adding comment for "future generations".

All 14 comments

Setting only forbidNonWhitelisted: true is necessary to reproduce this problem, that will throw the property X should not exist message

For setting only forbidUnknownValues: true, the class-validator will throw with an unknown value was passed to the validate

If both options are enabled, it will give an error in the first check rule

For example:
If my PipeValidation is

new ValidationPipe({
   whitelist: true,
   forbidUnknownValues: true,
   forbidNonWhitelisted: true,
})

It will throw the forbidUnknownValues message because it's the first rule checked at ValidationPipe, the same occurs if forbidNonWhitelisted is above forbidUnknown but it will throw property X should not exist message instead

Any updates on this?

Just hit this issue...

Hi!
I had the same issue but I managed to resolve it by using:

transformOptions: {
    enableImplicitConversion: true,
},

Please let me know if it helped also in your cases.

It works in terms of passing the validation, but... It does not validate the nested objects at all now :/

@IsNotEmpty()
  @IsArray()
  @ArrayNotEmpty()
  @ValidateNested({ each: true })
myNestedObjects!: NestedObjectType[]
export class NestedObjectType{
  @IsNotEmpty()
  @IsString()
  firstName!: string;

  @IsNotEmpty()
  @IsString()
  lastName!: string; 
}

I can miss fields or pass wrong values - validation still passes without any issue :/

I tested such example

export class Address {
    @IsString()
    public street!: string;
}

export class CreateParams {
    @IsString()
    public name!: string;

    @IsIn(Object.values(Gender))
    @ApiProperty({ enum: Gender, enumName: GENDER_ENUM_NAME })
    public gender!: Gender;

    @IsPositive()
    public age!: number;

    @ValidateNested()
    @Type(() => Address)
    public address!: Address;
}

And it validated address correctly for optimistic/pessimistic paths.

Cheers! We have found out that adding @Type(() => NestedType) was the thing. It works without adding that parameter which you suggested.
Adding comment for "future generations".

Ok. Update on my case. @Type decorator didn't work as should when used yarn link along with class-transformer in peerDependency. So option enableImplicitConversion: true helped me because of not working @Type but when not linked everything works as it should 馃憤 .

@murbanowicz adding @Type(() => NestedType) seems to only be working on second level objects. If you go down one more level like in the OP validation doesn't work on the third level object. I will try @gabrieloczkowski suggestion for enableImplicitConversion: true today and see if it works.

@gabrieloczkowski enableImplicitConversion: true did not work for me. Could you share an example of your implementation?

@gabrieloczkowski enableImplicitConversion: true did not work for me. Could you share an example of your implementation?

@rbiggers
https://github.com/typestack/class-validator/issues/614#issuecomment-698336485

{
    whitelist: true,
    forbidNonWhitelisted: true,
    forbidUnknownValues: true,
    transform: true,
    transformOptions: {
        enableImplicitConversion: true,
    },
}

@gabrieloczkowski Where did you enable these attributes? I can only find the first three attributes in the configuration when validating with validate() of class-validator.

@jpabeem configurations which @gabrieloczkowski wrote are forValidationPipe which is used in nestjs

Thanks! Makes sense. Hope we can get support for deeply-nested validation in a future release :-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NoNameProvided picture NoNameProvided  路  3Comments

st-clair-clarke picture st-clair-clarke  路  3Comments

otbe picture otbe  路  5Comments

twittwer picture twittwer  路  6Comments

binaryangel-noa picture binaryangel-noa  路  3Comments