Как проверить силу пароля с помощью шаблона Validator

Мне нужно проверить силу поля формы ввода пароля.
Требования:
- по крайней мере, один строчный символ
- по крайней мере один символ верхнего регистра
- по крайней мере одно число
(независимо от порядка)

То, что я искал и пробовал до сих пор, ниже, результаты несовместимы. Кажется, что он проверяет порядок проверки регулярных выражений.
Мне нужно просто проверить, присутствует ли хотя бы один из "типов" символов.
Спасибо

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
    selector: 'signup',
    templateUrl: './signup.component.html',
    styleUrls: ['./signup.component.scss']
})
export class SignupComponent {

    form: FormGroup;

    constructor() {
        this.init();
    }

    init() {
        this.form = this.fb.group({
            name: ['', [Validators.required]],
            email: ['', [Validators.required, Validators.email],
            password: ['', [
                Validators.required, 
                Validators.pattern('((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,30})')
            ]]
        }); 
    }
}

Ответ 1

Я взял укол с помощью Углового встроенного шаблона валидатора и смог придумать следующее, которое проверяет:

  • Длина не менее 8 символов
  • Строчные буквы
  • Заглавные буквы
  • чисел
  • Специальные символы

    password: [
      '',
      [
        Validators.required,
        Validators.pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]$!%*?&])[A-Za-z\[email protected]$!%*?&].{8,}')
       ]
    ]
    

Я добавлю, что я не специалист по регулярному выражению. Это просто то, что сработало для меня в тесно связанном случае с ОП. Может быть, это поможет кому-то другому. Документация Mozilla очень помогла разобраться в этом, особенно в разделе " Написание регулярного выражения ".

Ответ 2

Я не смог правильно использовать шаблон Validator, поэтому я создал Custom Validator и проверил строку поля пароля с тремя простыми регулярными выражениями.
Во всяком случае, я с нетерпением жду, чтобы правильно использовать Угловой шаблон валидатора.

Пользовательский валидатор

// password.validator.ts

import { FormControl } from '@angular/forms';

export interface ValidationResult {
    [key: string]: boolean;
}

export class PasswordValidator {

    public static strong(control: FormControl): ValidationResult {
        let hasNumber = /\d/.test(control.value);
        let hasUpper = /[A-Z]/.test(control.value);
        let hasLower = /[a-z]/.test(control.value);
        // console.log('Num, Upp, Low', hasNumber, hasUpper, hasLower);
        const valid = hasNumber && hasUpper && hasLower;
        if (!valid) {
            // return what´s not valid
            return { strong: true };
        }
        return null;
    }
}

Заменен шаблон Validator с помощью моего настраиваемого валидатора

// signup.component.ts

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { PasswordValidator } from 'validators/password.validator';

@Component({
    selector: 'signup',
    templateUrl: './signup.component.html',
    styleUrls: ['./signup.component.scss']
})
export class SignupComponent {

    form: FormGroup;

    constructor() {
        this.init();
    }

    init() {
        this.form = this.fb.group({
            name: ['', [Validators.required]],
            email: ['', [Validators.required, Validators.email],
            password: ['', [
                Validators.required, 
                PasswordValidator.strong
            ]]
        }); 
    }
}

Ответ 3

Если вы посмотрите Validator.js, вы заметите, что можете передать как строковый, так и литерал регулярных выражений в Validators.pattern.

Регулярное выражение передается как строковый литерал

  • Вся строка должна соответствовать шаблону (то есть шаблон привязан с обеих сторон)
  • Обратная косая черта может образовывать escape-последовательности строк, и вы должны использовать двойную обратную косую черту для определения литеральной обратной косой черты, которая используется для определения escape-выражения регулярного выражения. Итак, чтобы определить шаблон сопоставления цифр, используйте '\\d', чтобы определить шаблон пробелов, используйте '\\s', чтобы определить обратную косую черту, используйте '\\\\'.

Регулярное выражение передано как буквальное выражение

  • Регулярное выражение не требует автоматического совпадения строк.
  • Используйте одиночные обратные слэши для определения экранирования регулярных выражений (например, /\s+/)

Итак, вы можете использовать один из двух:

this.form = this.fb.group({
    name: ['', [Validators.required]],
    email: ['', [Validators.required, Validators.email],
    password: ['', [
        Validators.required, 
        Validators.pattern('(?=\\D*\\d)(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z]).{8,30}')
 ]]
});

Или

this.form = this.fb.group({
    name: ['', [Validators.required]],
    email: ['', [Validators.required, Validators.email],
    password: ['', [
        Validators.required, 
        Validators.pattern(/^(?=\D*\d)(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z]).{8,30}$/)
 ]]
});

Детали регулярного выражения

Обратите внимание, что изменения шаблона, которые я предлагаю, это просто изменения, связанные с принципом контраста:

  • ^ - начало строки (неявно в шаблоне регулярного выражения строки)
  • (?=\D*\d) - должна быть 1 цифра
  • (?=[^a-z]*[a-z]) - должна быть 1 строчная буква ASCII
  • (?=[^A-Z]*[A-Z]) - должна быть 1 заглавная буква ASCII
  • .{8,30} - любые 8-30 символов, кроме символов разрыва строки
  • $ - конец строки (неявно в шаблоне регулярного выражения строки).