I am working on a change password endpoint using nestjs , I want to be able to validate if the two password match
The class-validator library doesn't seem to have that on how to validate two properties within the DTO
How do I achieve this
This is my current code
export class CreatePasswordDTO {
@MaxLength(6)
@IsString()
@Matches(/^\d{6}$/, { message: "Password must be a 6-digit number" })
password: string;
@MaxLength(6)
@IsString()
@Matches(/^\d{6}$/, { message: "Confirm Password must be a 6-digit number" })
// I check that the password and confirmPassword are the same
confirmPassword: string;
}
If there is no default solution, what you usually do is come up with a custom implementation. I would create custom validator to check related fields at the same time:
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator';
export function Match(property: string, validationOptions?: ValidationOptions) {
return (object: any, propertyName: string) => {
registerDecorator({
name: 'Match',
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
constraints: [property],
validator: {
validate(value: any, args: ValidationArguments) {
const [relatedPropertyName] = args.constraints;
const relatedValue = (args.object as any)[relatedPropertyName];
return value === relatedValue;
},
defaultMessage(args: ValidationArguments) {
const [relatedPropertyName] = args.constraints;
return `${args.property} must match ${relatedPropertyName}`;
},
},
});
};
}
And use your custom validator on confirmPassword
field:
import { IsString, MaxLength, Matches } from 'class-validator';
import { Match } from './match.decorator'; // Adjust the import path as needed
export class CreatePasswordDTO {
@MaxLength(6)
@IsString()
@Matches(/^\d{6}$/, { message: 'Password must be a 6-digit number' })
password: string;
@MaxLength(6)
@IsString()
@Matches(/^\d{6}$/, { message: 'Confirm Password must be a 6-digit number' })
@Match('password', { message: 'Passwords do not match' })
confirmPassword: string;
}