import { Directive , Input , forwardRef } from '@angular/core' ; import { AbstractControl , NG_VALIDATORS , Validator } from '@angular/forms' ; @ Directive ( { selector : '[requireDigit],[requireLowercase],[requireNonAlphanumeric],[requireUppercase],[requiredLength]' , providers : [ { provide : NG_VALIDATORS , useExisting : forwardRef ( ( ) => PasswordComplexityValidator ) , multi : true } ] } ) export class PasswordComplexityValidator implements Validator { @ Input ( 'requireDigit' ) requireDigit : boolean ; @ Input ( 'requireUppercase' ) requireUppercase : boolean ; @ Input ( 'requireLowercase' ) requireLowercase : boolean ; @ Input ( 'requireNonAlphanumeric' ) requireNonAlphanumeric : boolean ; @ Input ( 'requiredLength' ) requiredLength : number ; validate ( control ) { const givenPassword = control . value ; let validationResult = null ; const requireDigit = this . requireDigit ; if ( requireDigit && givenPassword && ! /[0-9]/ . test ( givenPassword ) ) { validationResult = validationResult || { } ; validationResult . requireDigit = true ; } const requireUppercase = this . requireUppercase ; if ( requireUppercase && givenPassword && ! /[A-Z]/ . test ( givenPassword ) ) { validationResult = validationResult || { } ; validationResult . requireUppercase = true ; } const requireLowercase = this . requireLowercase ; if ( requireLowercase && givenPassword && ! /[a-z]/ . test ( givenPassword ) ) { validationResult = validationResult || { } ; validationResult . requireLowercase = true ; } const requiredLength = this . requiredLength ; if ( requiredLength && givenPassword && givenPassword . length < requiredLength ) { validationResult = validationResult || { } ; validationResult . requiredLength = true ; } const requireNonAlphanumeric = this . requireNonAlphanumeric ; if ( requireNonAlphanumeric && givenPassword && /^[0-9a-zA-Z]+$/ . test ( givenPassword ) ) { validationResult = validationResult || { } ; validationResult . requireNonAlphanumeric = true ; } return validationResult ; } }