Strongest password policy

This commit is contained in:
Jose Alberto Hernandez
2024-05-06 21:09:31 -06:00
committed by Jose Alberto Hernandez
parent 9b17a6c4f8
commit 8fdf8fb10c
35 changed files with 283 additions and 79 deletions
@@ -12,7 +12,8 @@
<mat-label> {{"labels.inputs.User Name" | translate}} </mat-label>
<input matInput required formControlName="username">
<mat-error *ngIf="createSelfServiceForm.controls.username.hasError('required')">
{{"labels.inputs.User Name" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
{{"labels.inputs.User Name" | translate}} {{"labels.commons.is" | translate}}
<strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
</mat-form-field>
@@ -20,7 +21,8 @@
<mat-label> {{"labels.inputs.First Name" | translate}} </mat-label>
<input matInput required formControlName="firstname">
<mat-error *ngIf="createSelfServiceForm.controls.firstname.hasError('required')">
{{"labels.inputs.First Name" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
{{"labels.inputs.First Name" | translate}} {{"labels.commons.is" | translate}}
<strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
</mat-form-field>
@@ -28,7 +30,8 @@
<mat-label> {{"labels.inputs.Last Name" | translate}} </mat-label>
<input matInput required formControlName="lastname">
<mat-error *ngIf="createSelfServiceForm.controls.lastname.hasError('required')">
{{"labels.inputs.Last Name" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
{{"labels.inputs.Last Name" | translate}} {{"labels.commons.is" | translate}}
<strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
</mat-form-field>
@@ -36,10 +39,12 @@
<mat-label> {{"labels.inputs.Email" | translate}} </mat-label>
<input matInput required formControlName="email">
<mat-error *ngIf="createSelfServiceForm.controls.email.hasError('required')">
{{"labels.inputs.Email" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
{{"labels.inputs.Email" | translate}} {{"labels.commons.is" | translate}}
<strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
<mat-error *ngIf="createSelfServiceForm.controls.email.hasError('email')">
{{"labels.inputs.Email should be a" | translate}} <strong>{{"labels.inputs.valid" | translate}}</strong> {{"labels.inputs.email" | translate}}.
{{"labels.inputs.Email should be a" | translate}} <strong>{{"labels.inputs.valid" |
translate}}</strong> {{"labels.inputs.email" | translate}}.
</mat-error>
</mat-form-field>
@@ -53,15 +58,30 @@
{{"labels.inputs.Override Password Expire Policy" | translate}} ?
</mat-checkbox>
<i class="fa fa-question-circle fa fa-align-left" title="Determines if passwords do not expire for this user even if global configuration for password expiry is enabled"></i>
<i class="fa fa-question-circle fa fa-align-left"
title="Determines if passwords do not expire for this user even if global configuration for password expiry is enabled"></i>
</div>
<mat-form-field fxFlex="48%" *ngIf="!hidePasswordField">
<mat-label> {{"labels.inputs.Password" | translate}} </mat-label>
<input matInput required formControlName="password" type="password">
<mat-label>{{ 'labels.inputs.Password' | translate }}</mat-label>
<input matInput formControlName="password" type="password">
<mat-error *ngIf="createSelfServiceForm.controls.password.hasError('required')">
{{"labels.inputs.Password" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
{{ 'labels.inputs.Password' | translate }} <strong>{{'labels.commons.is required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="createSelfServiceForm.controls.password.hasError('minlength')">
{{'labels.commons.Password should be at least' | translate }} <strong>{{'labels.commons.8 characters long' | translate }}</strong>
</mat-error>
<mat-error *ngIf="createSelfServiceForm.controls.password.hasError('maxlength')">
{{'labels.commons.Password should not be more than' | translate }}
<strong>{{'labels.commons.50 characters long' | translate }}</strong>
</mat-error>
<mat-error
*ngIf="createSelfServiceForm.controls.password.hasError('pattern') && !(createSelfServiceForm.controls.password.hasError('minlength') || createSelfServiceForm.controls.password.hasError('maxlength'))">
{{'labels.commons.Password should include a' | translate }}
<strong>{{'labels.commons.numeral' | translate }}</strong> {{'labels.commons.and at' | translate }}
<strong>{{'labels.commons.least one uppercase' | translate }}</strong>
,<strong>{{'labels.commons.lowercase and special character' | translate }}</strong>
</mat-error>
</mat-form-field>
@@ -69,10 +89,12 @@
<mat-label> {{"labels.inputs.Repeat Password" | translate}} </mat-label>
<input matInput required formControlName="repeatPassword" type="password">
<mat-error *ngIf="createSelfServiceForm.controls.repeatPassword.hasError('required')">
{{"labels.inputs.Repeat password" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
{{"labels.inputs.Repeat password" | translate}} {{"labels.commons.is" | translate}}
<strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
<mat-error *ngIf="createSelfServiceForm.controls.repeatPassword.hasError('notequal')">
{{"labels.inputs.Passwords should be" | translate}} <strong>{{"labels.inputs.matched" | translate}}</strong>
{{"labels.inputs.Passwords should be" | translate}} <strong>{{"labels.inputs.matched" |
translate}}</strong>
</mat-error>
</mat-form-field>
@@ -84,9 +106,12 @@
</div>
<mat-card-actions fxLayoutGap="5px" fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center">
<button type="button" mat-raised-button [routerLink]="['../../']">{{"labels.buttons.Cancel" | translate}}</button>
<button mat-raised-button color="primary" [disabled]="!createSelfServiceForm.valid">{{"labels.buttons.Activate Self Service User" | translate}}</button>
<i class="fa fa-question-circle fa-2x" title="Activate Self Service User Help"></i>
<button type="button" mat-raised-button [routerLink]="['../../']">{{"labels.buttons.Cancel" |
translate}}</button>
<button mat-raised-button color="primary"
[disabled]="!createSelfServiceForm.valid">{{"labels.buttons.Activate Self Service User" |
translate}}</button>
<i class="fa fa-question-circle fa-2x" title="Activate Self Service User Help"></i>
</mat-card-actions>
</mat-card-content>
@@ -95,4 +120,4 @@
</mat-card>
</div>
</div>
@@ -6,6 +6,7 @@ import { Subscription } from 'rxjs';
/** Client Services. */
import { ClientsService } from 'app/clients/clients.service';
import { PasswordsUtility } from 'app/core/utils/passwords-utility';
@Component({
selector: 'mifosx-create-self-service-user',
@@ -21,7 +22,8 @@ export class CreateSelfServiceUserComponent implements OnInit {
constructor(private formBuilder: UntypedFormBuilder,
private route: ActivatedRoute,
private clientService: ClientsService,
private router: Router) {
private router: Router,
private passwordsUtility: PasswordsUtility) {
this.route.data.subscribe((data: { clientActionData: any}) => {
this.clientData = data.clientActionData;
});
@@ -43,8 +45,8 @@ export class CreateSelfServiceUserComponent implements OnInit {
this.createSelfServiceForm.removeControl('repeatPassword');
} else {
this.hidePasswordField = false;
this.createSelfServiceForm.addControl('password', new UntypedFormControl('', [Validators.required]));
this.createSelfServiceForm.addControl('repeatPassword', new UntypedFormControl('', [Validators.required, this.confirmPassword('password')]));
this.createSelfServiceForm.addControl('password', new UntypedFormControl('', this.passwordsUtility.getPasswordValidators()));
this.createSelfServiceForm.addControl('repeatPassword', new UntypedFormControl('', [Validators.required, this.passwordsUtility.confirmPassword('password')]));
}
});
}
@@ -83,24 +85,4 @@ export class CreateSelfServiceUserComponent implements OnInit {
});
}
/**
* Confirm Change Password of Users
* @param controlNameToCompare Form Control Name to be compared.
*/
confirmPassword(controlNameToCompare: string): ValidatorFn {
return (c: AbstractControl): ValidationErrors|null => {
if (c.value == null || c.value.length === 0) {
return null;
}
const controlToCompare = c.root.get(controlNameToCompare);
if (controlToCompare) {
const subscription: Subscription = controlToCompare.valueChanges.subscribe(() => {
c.updateValueAndValidity();
subscription.unsubscribe();
});
}
return controlToCompare && controlToCompare.value !== c.value ? {'notequal': true} : null;
};
}
}
@@ -121,7 +121,9 @@
<ng-container matColumnDef="Loan Account">
<th mat-header-cell *matHeaderCellDef> {{"labels.inputs.Loan Product" | translate}} </th>
<td mat-cell *matCellDef="let element"> {{element.productName}} </td>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{element.productName}}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Original Loan">
@@ -195,7 +197,9 @@
<ng-container matColumnDef="Loan Account">
<th mat-header-cell *matHeaderCellDef> {{"labels.inputs.Loan Product" | translate}} </th>
<td mat-cell *matCellDef="let element"> {{element.productName}} </td>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{element.productName}}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Original Loan">
@@ -260,7 +264,9 @@
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef> {{"labels.inputs.Savings Product" | translate}} </th>
<td mat-cell *matCellDef="let element"> {{element.productName}} </td>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{element.productName}}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Last Active">
@@ -320,7 +326,9 @@
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef> {{"labels.inputs.Saving Product" | translate}} </th>
<td mat-cell *matCellDef="let element"> {{element.productName}} </td>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{element.productName}}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Closed Date">
@@ -415,7 +423,9 @@
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef> {{"labels.inputs.Fixed Deposit Product" | translate}} </th>
<td mat-cell *matCellDef="let element"> {{element.productName}} </td>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{element.productName}}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Closed Date">
@@ -458,7 +468,9 @@
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef> {{"labels.inputs.Recurring Deposit Product" | translate}} </th>
<td mat-cell *matCellDef="let element"> {{element.productName}} </td>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{element.productName}}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Last Active">
@@ -515,7 +527,9 @@
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef> {{"labels.inputs.Recurring Deposit Product" | translate}} </th>
<td mat-cell *matCellDef="let element"> {{element.productName}} </td>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{element.productName}}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Closed Date">
@@ -556,7 +570,9 @@
<ng-container matColumnDef="Share Account">
<th mat-header-cell *matHeaderCellDef> {{"labels.inputs.Share Product" | translate}} </th>
<td mat-cell *matCellDef="let element"> {{element.productName}} </td>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{element.productName}}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Approved Shares">