Подтверждение пароля в TypeScript с помощью `class-validator` - PullRequest
1 голос
/ 28 февраля 2020

Сегодня я пытаюсь выяснить, как проверить форму регистрации в серверной части (Nest JS) приложения. Мне просто интересно, существует ли способ проверки соответствия password и passwordConfirm, используя пакет class-validator для создания собственного средства проверки или использования предоставленных. Я думаю о валидаторе класса, а не о поле.

// Maybe validator here
export class SignUpDto {
    @IsString()
    @MinLength(4)
    @MaxLength(20)
    username: string;

    @IsString()
    @MinLength(4)
    @MaxLength(20)
    @Matches(/((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/, {message: 'password too weak'})
    password: string;

    @IsString()
    @MinLength(4)
    @MaxLength(20)
    passwordConfirm: string;
}

Что вы предлагаете?

Ответы [ 2 ]

3 голосов
/ 31 марта 2020

Наконец-то мне удалось решить проблему сопоставления паролей благодаря предложению @ ChristopheGeers в комментариях к моему вопросу:

@ piero: пока не поддерживается, как уже упоминалось , Но вот пример декоратора (@IsLongerThan): LINK .... он проверяет, является ли свойство длиннее другого. Таким образом, можно сравнить одно свойство с другим. Вы можете использовать этот пример для создания декоратора, который делает то, что вы хотите.

Вот решение, которое я предлагаю:

sign-up.dto.ts

export class SignUpDto {
    @IsString()
    @MinLength(4)
    @MaxLength(20)
    username: string;

    @IsString()
    @MinLength(4)
    @MaxLength(20)
    @Matches(/((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/, {message: 'password too weak'})
    password: string;

    @IsString()
    @MinLength(4)
    @MaxLength(20)
    @Match('password')
    passwordConfirm: string;
}

match.decorator.ts

import {registerDecorator, ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface} from 'class-validator';

export function Match(property: string, validationOptions?: ValidationOptions) {
    return (object: any, propertyName: string) => {
        registerDecorator({
            target: object.constructor,
            propertyName,
            options: validationOptions,
            constraints: [property],
            validator: MatchConstraint,
        });
    };
}

@ValidatorConstraint({name: 'Match'})
export class MatchConstraint implements ValidatorConstraintInterface {

    validate(value: any, args: ValidationArguments) {
        const [relatedPropertyName] = args.constraints;
        const relatedValue = (args.object as any)[relatedPropertyName];
        return value === relatedValue;
    }

}
1 голос
/ 13 апреля 2020

Вот расширенный пример, который вставляет валидатор и предоставляет ему сообщение по умолчанию. Таким образом, вам не нужно вводить сообщение каждый раз, когда вы используете декоратор @IsEqualTo.

import { 
    registerDecorator, 
    ValidationArguments, 
    ValidationOptions 
} from 'class-validator';

export function IsEqualTo(property: string, validationOptions?: ValidationOptions) {
    return (object: any, propertyName: string) => {
      registerDecorator({
        name: 'isEqualTo',
        target: object.constructor,
        propertyName,
        constraints: [property],
        options: validationOptions,
        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 `$property must match ${relatedPropertyName} exactly`;
        },
      },
    });
  };
}
...