From 654c887f0e3ce9264c8fb36f27bb4b5bc0db6b55 Mon Sep 17 00:00:00 2001
From: Artem Dzhereleiko
Date: Thu, 7 Dec 2023 12:52:13 +0200
Subject: [PATCH 1/7] UI: Add max password length with validation
---
.../admin/security-settings.component.html | 59 ++++++++++++-------
.../admin/security-settings.component.ts | 27 ++++++++-
.../pages/security/security.component.html | 7 +++
.../home/pages/security/security.component.ts | 5 ++
.../src/app/shared/models/settings.models.ts | 2 +
.../assets/locale/locale.constant-en_US.json | 9 ++-
6 files changed, 83 insertions(+), 26 deletions(-)
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
index ef29248767..f49b2b25e8 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
@@ -51,24 +51,36 @@
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
index cdaf0747af..9e969bf8e0 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
@@ -19,7 +19,14 @@ import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { PageComponent } from '@shared/components/page.component';
import { Router } from '@angular/router';
-import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
+import {
+ AbstractControl,
+ UntypedFormBuilder,
+ UntypedFormControl,
+ UntypedFormGroup, ValidationErrors,
+ ValidatorFn,
+ Validators
+} from '@angular/forms';
import { JwtSettings, SecuritySettings } from '@shared/models/settings.models';
import { AdminService } from '@core/http/admin.service';
import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard';
@@ -67,14 +74,16 @@ export class SecuritySettingsComponent extends PageComponent implements HasConfi
userLockoutNotificationEmail: ['', []],
passwordPolicy: this.fb.group(
{
- minimumLength: [null, [Validators.required, Validators.min(5), Validators.max(50)]],
+ minimumLength: [null, [Validators.required, Validators.min(6), Validators.max(50)]],
+ maximumLength: [null, [Validators.min(6), this.maxPasswordValidation()]],
minimumUppercaseLetters: [null, Validators.min(0)],
minimumLowercaseLetters: [null, Validators.min(0)],
minimumDigits: [null, Validators.min(0)],
minimumSpecialCharacters: [null, Validators.min(0)],
passwordExpirationPeriodDays: [null, Validators.min(0)],
passwordReuseFrequencyDays: [null, Validators.min(0)],
- allowWhitespaces: [true]
+ allowWhitespaces: [true],
+ forceUserToResetPasswordIfNotValid: [false]
}
)
});
@@ -113,6 +122,18 @@ export class SecuritySettingsComponent extends PageComponent implements HasConfi
})).subscribe(() => {});
}
+ private maxPasswordValidation(): ValidatorFn {
+ return (control: AbstractControl): ValidationErrors | null => {
+ const value: string = control.value;
+ if (value) {
+ if (value < this.securitySettingsFormGroup.get('passwordPolicy.minimumLength').value) {
+ return {lessMin: true};
+ }
+ }
+ return null;
+ };
+ }
+
discardSetting() {
this.securitySettingsFormGroup.reset(this.securitySettings);
}
diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.html b/ui-ngx/src/app/modules/home/pages/security/security.component.html
index 45460e086d..9d40e0786b 100644
--- a/ui-ngx/src/app/modules/home/pages/security/security.component.html
+++ b/ui-ngx/src/app/modules/home/pages/security/security.component.html
@@ -105,6 +105,13 @@
{{ 'security.password-requirement.character' | translate : {count: passwordPolicy.minimumLength} }}
+
0">
+
security.password-requirement.at-most
+
+
+ {{ 'security.password-requirement.character' | translate : {count: passwordPolicy.maximumLength} }}
+
+
diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.ts b/ui-ngx/src/app/modules/home/pages/security/security.component.ts
index 9a99e7d6d4..d79a6c59b4 100644
--- a/ui-ngx/src/app/modules/home/pages/security/security.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/security/security.component.ts
@@ -213,6 +213,11 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro
errors.minLength = true;
}
+ if (this.passwordPolicy?.maximumLength > 0 &&
+ (value.length > this.passwordPolicy?.maximumLength || value.length < this.passwordPolicy.minimumLength)) {
+ errors.maxLength = true;
+ }
+
return isEqual(errors, {}) ? null : errors;
};
}
diff --git a/ui-ngx/src/app/shared/models/settings.models.ts b/ui-ngx/src/app/shared/models/settings.models.ts
index 9238dae197..9dd599d49b 100644
--- a/ui-ngx/src/app/shared/models/settings.models.ts
+++ b/ui-ngx/src/app/shared/models/settings.models.ts
@@ -99,12 +99,14 @@ export type DeviceConnectivitySettings = Record
Date: Thu, 7 Dec 2023 16:45:37 +0200
Subject: [PATCH 2/7] UI: Refactoring validation func
---
.../app/modules/home/pages/admin/security-settings.component.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
index 9e969bf8e0..5c64d78049 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
@@ -126,7 +126,7 @@ export class SecuritySettingsComponent extends PageComponent implements HasConfi
return (control: AbstractControl): ValidationErrors | null => {
const value: string = control.value;
if (value) {
- if (value < this.securitySettingsFormGroup.get('passwordPolicy.minimumLength').value) {
+ if (value < control.parent.value?.minimumLength) {
return {lessMin: true};
}
}
From 793639a87798203499f5cdc68da70cf9f66cd3a7 Mon Sep 17 00:00:00 2001
From: Artem Dzhereleiko
Date: Fri, 8 Dec 2023 15:09:36 +0200
Subject: [PATCH 3/7] UI: Refactoring
---
.../home/pages/admin/security-settings.component.html | 9 ++++++++-
.../home/pages/admin/security-settings.component.scss | 6 ++++++
.../home/pages/admin/security-settings.component.ts | 7 ++++++-
.../app/modules/login/pages/login/login.component.html | 3 ++-
.../src/app/modules/login/pages/login/login.component.ts | 4 ++++
ui-ngx/src/app/shared/models/constants.ts | 3 ++-
ui-ngx/src/assets/locale/locale.constant-en_US.json | 1 +
7 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
index f49b2b25e8..189d75d56d 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
@@ -157,7 +157,14 @@
admin.allow-whitespace
- admin.force-reset-password-if-no-valid
+
+ {{'admin.force-reset-password-if-no-valid' | translate}}
+
+
+
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.scss b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.scss
index d9300a5504..fcafcb9c95 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.scss
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.scss
@@ -32,4 +32,10 @@
color: rgba(0, 0, 0, .7);
}
}
+
+ .hint-icon {
+ width: 15px;
+ height: 15px;
+ vertical-align: top;
+ }
}
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
index 5c64d78049..4ca662763a 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
@@ -35,7 +35,10 @@ import { randomAlphanumeric } from '@core/utils';
import { AuthService } from '@core/auth/auth.service';
import { DialogService } from '@core/services/dialog.service';
import { TranslateService } from '@ngx-translate/core';
-import { Observable, of } from 'rxjs';
+import { forkJoin, Observable, of } from 'rxjs';
+import { MatCheckboxChange } from '@angular/material/checkbox';
+import { AlarmInfo } from '@shared/models/alarm.models';
+import { QueueProcessingStrategyTypes, QueueProcessingStrategyTypesMap } from '@shared/models/queue.models';
@Component({
selector: 'tb-security-settings',
@@ -211,4 +214,6 @@ export class SecuritySettingsComponent extends PageComponent implements HasConfi
return this.securitySettingsFormGroup.dirty ? this.securitySettingsFormGroup : this.jwtSecuritySettingsFormGroup;
}
+ protected readonly queueProcessingStrategyTypes = QueueProcessingStrategyTypes;
+ protected readonly queueProcessingStrategyTypesMap = QueueProcessingStrategyTypesMap;
}
diff --git a/ui-ngx/src/app/modules/login/pages/login/login.component.html b/ui-ngx/src/app/modules/login/pages/login/login.component.html
index f5797ae574..8748917ee7 100644
--- a/ui-ngx/src/app/modules/login/pages/login/login.component.html
+++ b/ui-ngx/src/app/modules/login/pages/login/login.component.html
@@ -56,7 +56,8 @@
lock
-
diff --git a/ui-ngx/src/app/modules/login/pages/login/login.component.ts b/ui-ngx/src/app/modules/login/pages/login/login.component.ts
index 2fc1c7c50d..e61322b653 100644
--- a/ui-ngx/src/app/modules/login/pages/login/login.component.ts
+++ b/ui-ngx/src/app/modules/login/pages/login/login.component.ts
@@ -32,6 +32,8 @@ import { OAuth2ClientInfo } from '@shared/models/oauth2.models';
})
export class LoginComponent extends PageComponent implements OnInit {
+ passwordViolation = false;
+
loginFormGroup = this.fb.group({
username: '',
password: ''
@@ -57,6 +59,8 @@ export class LoginComponent extends PageComponent implements OnInit {
if (error && error.error && error.error.errorCode) {
if (error.error.errorCode === Constants.serverErrorCode.credentialsExpired) {
this.router.navigateByUrl(`login/resetExpiredPassword?resetToken=${error.error.resetToken}`);
+ } else if (error.error.errorCode === Constants.serverErrorCode.passwordViolation) {
+ this.passwordViolation = true;
}
}
}
diff --git a/ui-ngx/src/app/shared/models/constants.ts b/ui-ngx/src/app/shared/models/constants.ts
index 4f904a4bf3..c119ae327f 100644
--- a/ui-ngx/src/app/shared/models/constants.ts
+++ b/ui-ngx/src/app/shared/models/constants.ts
@@ -30,7 +30,8 @@ export const Constants = {
badRequestParams: 31,
itemNotFound: 32,
tooManyRequests: 33,
- tooManyUpdates: 34
+ tooManyUpdates: 34,
+ passwordViolation: 45
},
entryPoints: {
login: '/api/auth/login',
diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json
index 8e9433e6d2..93ec444fea 100644
--- a/ui-ngx/src/assets/locale/locale.constant-en_US.json
+++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json
@@ -200,6 +200,7 @@
"password-reuse-frequency-days-range": "Password reuse frequency in days can't be negative",
"allow-whitespace": "Allow whitespace",
"force-reset-password-if-no-valid": "Force to reset password if not valid",
+ "force-reset-password-if-no-valid-hint": "Please, take into it can affect all users with passwords that violate current policy.",
"general-policy": "General policy",
"max-failed-login-attempts": "Maximum number of failed login attempts, before account is locked",
"minimum-max-failed-login-attempts-range": "Maximum number of failed login attempts can't be negative",
From 515c7e1b07b28d32ab76ac09ba627f228150f217 Mon Sep 17 00:00:00 2001
From: Artem Dzhereleiko
Date: Fri, 8 Dec 2023 16:06:46 +0200
Subject: [PATCH 4/7] UI: Refactoring
---
.../home/pages/admin/security-settings.component.html | 8 ++------
.../home/pages/admin/security-settings.component.ts | 3 ---
.../modules/home/pages/security/security.component.html | 5 +++--
.../app/modules/home/pages/security/security.component.ts | 4 ++--
4 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
index 189d75d56d..886dd79ef6 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.html
@@ -73,6 +73,7 @@
admin.maximum-password-length
+
{{ 'admin.maximum-password-length-min' | translate }}
@@ -157,13 +158,8 @@
admin.allow-whitespace
-
+
{{'admin.force-reset-password-if-no-valid' | translate}}
-
-
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
index 4ca662763a..a2d43e1a8f 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.ts
@@ -213,7 +213,4 @@ export class SecuritySettingsComponent extends PageComponent implements HasConfi
confirmForm(): UntypedFormGroup {
return this.securitySettingsFormGroup.dirty ? this.securitySettingsFormGroup : this.jwtSecuritySettingsFormGroup;
}
-
- protected readonly queueProcessingStrategyTypes = QueueProcessingStrategyTypes;
- protected readonly queueProcessingStrategyTypesMap = QueueProcessingStrategyTypesMap;
}
diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.html b/ui-ngx/src/app/modules/home/pages/security/security.component.html
index 9d40e0786b..b87507f957 100644
--- a/ui-ngx/src/app/modules/home/pages/security/security.component.html
+++ b/ui-ngx/src/app/modules/home/pages/security/security.component.html
@@ -44,10 +44,11 @@
{{ 'security.password-requirement.incorrect-password-try-again' | translate }}
-
+
login.new-password
+
{{ 'security.password-requirement.character' | translate : {count: passwordPolicy.minimumLength} }}
- 0">
+
0">
security.password-requirement.at-most
diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.ts b/ui-ngx/src/app/modules/home/pages/security/security.component.ts
index d79a6c59b4..0f9b9cef2c 100644
--- a/ui-ngx/src/app/modules/home/pages/security/security.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/security/security.component.ts
@@ -171,6 +171,7 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro
private loadPasswordPolicy() {
this.authService.getUserPasswordPolicy().subscribe(policy => {
this.passwordPolicy = policy;
+ this.passwordPolicy.maximumLength = 7;
this.changePassword.get('newPassword').setValidators([
this.passwordStrengthValidator(),
this.samePasswordValidation(true, 'currentPassword'),
@@ -213,8 +214,7 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro
errors.minLength = true;
}
- if (this.passwordPolicy?.maximumLength > 0 &&
- (value.length > this.passwordPolicy?.maximumLength || value.length < this.passwordPolicy.minimumLength)) {
+ if (!value.length || this.passwordPolicy.maximumLength > 0 && value.length > this.passwordPolicy.maximumLength) {
errors.maxLength = true;
}
From e83fb9e58803569a1228d9a70deefd320873f6d6 Mon Sep 17 00:00:00 2001
From: Artem Dzhereleiko
Date: Fri, 8 Dec 2023 16:07:38 +0200
Subject: [PATCH 5/7] UI: Clear
---
ui-ngx/src/app/modules/home/pages/security/security.component.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.ts b/ui-ngx/src/app/modules/home/pages/security/security.component.ts
index 0f9b9cef2c..c49ba464d4 100644
--- a/ui-ngx/src/app/modules/home/pages/security/security.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/security/security.component.ts
@@ -171,7 +171,6 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro
private loadPasswordPolicy() {
this.authService.getUserPasswordPolicy().subscribe(policy => {
this.passwordPolicy = policy;
- this.passwordPolicy.maximumLength = 7;
this.changePassword.get('newPassword').setValidators([
this.passwordStrengthValidator(),
this.samePasswordValidation(true, 'currentPassword'),
From 81403e872bf70db16a27681efee3572bbb981ceb Mon Sep 17 00:00:00 2001
From: Artem Dzhereleiko
Date: Fri, 8 Dec 2023 16:08:50 +0200
Subject: [PATCH 6/7] UI: Clean css style
---
.../home/pages/admin/security-settings.component.scss | 6 ------
1 file changed, 6 deletions(-)
diff --git a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.scss b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.scss
index fcafcb9c95..d9300a5504 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.scss
+++ b/ui-ngx/src/app/modules/home/pages/admin/security-settings.component.scss
@@ -32,10 +32,4 @@
color: rgba(0, 0, 0, .7);
}
}
-
- .hint-icon {
- width: 15px;
- height: 15px;
- vertical-align: top;
- }
}
From 3c41eb765cf3e69688fc148830ad428c4b919bb5 Mon Sep 17 00:00:00 2001
From: Artem Dzhereleiko
Date: Fri, 8 Dec 2023 16:49:48 +0200
Subject: [PATCH 7/7] UI: Update hint translate
---
ui-ngx/src/assets/locale/locale.constant-en_US.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json
index 93ec444fea..cb09328d45 100644
--- a/ui-ngx/src/assets/locale/locale.constant-en_US.json
+++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json
@@ -200,7 +200,7 @@
"password-reuse-frequency-days-range": "Password reuse frequency in days can't be negative",
"allow-whitespace": "Allow whitespace",
"force-reset-password-if-no-valid": "Force to reset password if not valid",
- "force-reset-password-if-no-valid-hint": "Please, take into it can affect all users with passwords that violate current policy.",
+ "force-reset-password-if-no-valid-hint": "Please be careful when enabling this feature: it will require users with not valid password to reset their password via email.",
"general-policy": "General policy",
"max-failed-login-attempts": "Maximum number of failed login attempts, before account is locked",
"minimum-max-failed-login-attempts-range": "Maximum number of failed login attempts can't be negative",