From 287d18e04693c503db91a140f0d1bf4b2858f9d9 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Tue, 28 Jun 2022 22:37:51 +0300 Subject: [PATCH 1/4] Fix #12999 --- .../src/lib/constants/validation.ts | 4 ++ .../src/lib/utils/validation-utils.ts | 41 +++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/constants/validation.ts b/npm/ng-packs/packages/theme-shared/src/lib/constants/validation.ts index 463a7b01dc..65b759a21e 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/constants/validation.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/constants/validation.ts @@ -13,4 +13,8 @@ export const DEFAULT_VALIDATION_BLUEPRINTS = { range: 'AbpValidation::ThisFieldMustBeBetween{0}And{1}[{{ min }},{{ max }}]', required: 'AbpValidation::ThisFieldIsRequired.', url: 'AbpValidation::ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl', + passwordRequiresLower: 'AbpIdentity::Volo.Abp.Identity:PasswordRequiresLower', + passwordRequiresUpper: 'AbpIdentity::Volo.Abp.Identity:PasswordRequiresUpper', + passwordRequiresDigit: 'AbpIdentity::Volo.Abp.Identity:PasswordRequiresDigit', + passwordRequiresNonAlphanumeric: 'AbpIdentity::Volo.Abp.Identity:PasswordRequiresNonAlphanumeric', }; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts index a9ec1d4270..b7d8d23376 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts @@ -1,7 +1,7 @@ import { ABP, ConfigStateService } from '@abp/ng.core'; import { Injector } from '@angular/core'; -import { ValidatorFn, Validators } from '@angular/forms'; -import { PasswordRules, validatePassword } from '@ngx-validate/core'; +import { AbstractControl, ValidatorFn, Validators } from '@angular/forms'; +import { PasswordRules, normalizeDiacritics } from '@ngx-validate/core'; const { minLength, maxLength } = Validators; @@ -31,7 +31,8 @@ export function getPasswordValidators(injector: Injector): ValidatorFn[] { requiredLength = +getRule('RequiredLength'); } - return [validatePassword(passwordRulesArr), minLength(requiredLength), maxLength(128)]; + const passwordValidators = passwordRulesArr.map(rule => validatePassword(rule)); + return [...passwordValidators, minLength(requiredLength), maxLength(128)]; } function getRuleFn(injector: Injector) { @@ -43,3 +44,37 @@ function getRuleFn(injector: Injector) { return (passwordRules[`Abp.Identity.Password.${key}`] || '').toLowerCase(); }; } +const errorMessageMap = { + small: 'passwordRequiresLower', + capital: 'passwordRequiresUpper', + number: 'passwordRequiresDigit', + special: 'passwordRequiresNonAlphanumeric', +}; + +function validatePassword(shouldContain: 'small' | 'capital' | 'number' | 'special'): ValidatorFn { + return (control: AbstractControl) => { + if (!control.value) return null; + + const value = normalizeDiacritics(control.value); + + const regexMap = { + small: /.*[a-z].*/, + capital: /.*[A-Z].*/, + number: /.*[0-9].*/, + special: /.*[^0-9a-zA-Z].*/, + }; + const regex = regexMap[shouldContain]; + + const hasError = regex[shouldContain].test(value); + + if (!hasError) { + return null; + } + + const error = errorMessageMap[shouldContain]; + + return { + [error]: true, + }; + }; +} From da0fe2246a76784cc9f94fdb5457327d24917077 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Wed, 29 Jun 2022 10:46:08 +0300 Subject: [PATCH 2/4] Update npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts Co-authored-by: Qingxiao Ren --- .../packages/theme-shared/src/lib/utils/validation-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts index b7d8d23376..eb9d21c192 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts @@ -65,7 +65,7 @@ function validatePassword(shouldContain: 'small' | 'capital' | 'number' | 'speci }; const regex = regexMap[shouldContain]; - const hasError = regex[shouldContain].test(value); + const hasError = regex.test(value); if (!hasError) { return null; From 2b28c0f44f38d53d13fc45217ef1dfea33667133 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Wed, 29 Jun 2022 10:53:44 +0300 Subject: [PATCH 3/4] Revert if condition validatePassword func on validation-utils.ts --- .../packages/theme-shared/src/lib/utils/validation-utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts index eb9d21c192..0d0faf4211 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts @@ -65,9 +65,9 @@ function validatePassword(shouldContain: 'small' | 'capital' | 'number' | 'speci }; const regex = regexMap[shouldContain]; - const hasError = regex.test(value); + const isValid = regex.test(value); - if (!hasError) { + if (isValid) { return null; } From adcb457f8f9348af54ffed325e0513d036091e60 Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Wed, 29 Jun 2022 10:59:45 +0300 Subject: [PATCH 4/4] update tests --- .../packages/theme-shared/src/lib/models/index.ts | 1 + .../packages/theme-shared/src/lib/models/validation.ts | 1 + .../src/lib/tests/validation-utils.spec.ts | 10 +++++++--- .../theme-shared/src/lib/utils/validation-utils.ts | 7 +++++-- 4 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/models/validation.ts diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts index ca6aa74124..4cb240e9ab 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts @@ -4,3 +4,4 @@ export * from './nav-item'; export * from './statistics'; export * from './toaster'; export * from './user-menu'; +export * from './validation'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/validation.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/validation.ts new file mode 100644 index 0000000000..bcc53a34e7 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/validation.ts @@ -0,0 +1 @@ +export type PasswordRule = 'small' | 'capital' | 'number' | 'special'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/validation-utils.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/validation-utils.spec.ts index fe7577477c..435afb76e6 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tests/validation-utils.spec.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/validation-utils.spec.ts @@ -4,10 +4,11 @@ import { HttpClient } from '@angular/common/http'; import { Component, Injector } from '@angular/core'; import { Validators } from '@angular/forms'; import { createComponentFactory, Spectator } from '@ngneat/spectator/jest'; -import { validatePassword } from '@ngx-validate/core'; import { OAuthService } from 'angular-oauth2-oidc'; import { of } from 'rxjs'; -import { getPasswordValidators } from '../utils'; +import { getPasswordValidators, validatePassword } from '../utils'; +import { PasswordRule } from '../models/validation'; + @Component({ template: '', selector: 'abp-dummy' }) class DummyComponent {} @@ -47,8 +48,11 @@ describe('ValidationUtils', () => { configState.refreshAppState(); const validators = getPasswordValidators(spectator.inject(Injector)); + const passwordValidators = ['number', 'small', 'capital', 'special'].map( + (rule: PasswordRule) => validatePassword(rule), + ); const expectedValidators = [ - validatePassword(['number', 'small', 'capital', 'special']), + ...passwordValidators, Validators.minLength(6), Validators.maxLength(128), ]; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts index b7d8d23376..4d3f4a1f15 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts @@ -1,7 +1,8 @@ import { ABP, ConfigStateService } from '@abp/ng.core'; import { Injector } from '@angular/core'; import { AbstractControl, ValidatorFn, Validators } from '@angular/forms'; -import { PasswordRules, normalizeDiacritics } from '@ngx-validate/core'; +import { normalizeDiacritics, PasswordRules } from '@ngx-validate/core'; +import { PasswordRule } from "../models/validation"; const { minLength, maxLength } = Validators; @@ -51,7 +52,9 @@ const errorMessageMap = { special: 'passwordRequiresNonAlphanumeric', }; -function validatePassword(shouldContain: 'small' | 'capital' | 'number' | 'special'): ValidatorFn { +export function validatePassword( + shouldContain: PasswordRule +): ValidatorFn { return (control: AbstractControl) => { if (!control.value) return null;