Skip to content

Commit

Permalink
Strongest password policy
Browse files Browse the repository at this point in the history
  • Loading branch information
Jose Alberto Hernandez authored and alberto-art3ch committed May 7, 2024
1 parent 9b17a6c commit 8fdf8fb
Show file tree
Hide file tree
Showing 35 changed files with 283 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class ChartOfAccountsComponent implements AfterViewInit, OnInit {
/** Selected GL Account. */
glAccount: GLAccountNode;
/** Flag to check if tree is expanded or collapsed. */
isTreeExpanded: boolean = true;
isTreeExpanded = true;

/** Paginator for chart of accounts table. */
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
Expand Down Expand Up @@ -182,9 +182,9 @@ export class ChartOfAccountsComponent implements AfterViewInit, OnInit {
this.router.navigate(['/accounting']);
}

/**
/**
* Expand and Collapse the tree
*/
*/
toggleExpandCollapse() {
this.isTreeExpanded = this.treeControlService.toggleExpandCollapse(this.nestedTreeControl, this.isTreeExpanded);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,39 @@
<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>

<mat-form-field fxFlex="48%">
<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>

<mat-form-field fxFlex="48%">
<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>

<mat-form-field fxFlex="48%">
<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>

Expand All @@ -53,26 +58,43 @@
{{"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>

<mat-form-field fxFlex="48%" *ngIf="!hidePasswordField">
<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>

Expand All @@ -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>
Expand All @@ -95,4 +120,4 @@

</mat-card>

</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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;
});
Expand All @@ -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')]));
}
});
}
Expand Down Expand Up @@ -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;
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ <h3>{{"labels.heading.Loan Accounts" | translate}}</h3>

<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">
Expand Down Expand Up @@ -195,7 +197,9 @@ <h3>{{"labels.heading.Loan Accounts" | translate}}</h3>

<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">
Expand Down Expand Up @@ -260,7 +264,9 @@ <h3>{{"labels.heading.Saving Accounts" | translate}}</h3>

<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">
Expand Down Expand Up @@ -320,7 +326,9 @@ <h3>{{"labels.heading.Saving Accounts" | translate}}</h3>

<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">
Expand Down Expand Up @@ -415,7 +423,9 @@ <h3>{{"labels.heading.Fixed Deposit Accounts" | translate}}</h3>

<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">
Expand Down Expand Up @@ -458,7 +468,9 @@ <h3>{{"labels.heading.Recurring Deposit Accounts" | translate}}</h3>

<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">
Expand Down Expand Up @@ -515,7 +527,9 @@ <h3>{{"labels.heading.Recurring Deposit Accounts" | translate}}</h3>

<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">
Expand Down Expand Up @@ -556,7 +570,9 @@ <h3>{{"labels.inputs.Shares Accounts" | translate}}</h3>

<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">
Expand Down
37 changes: 37 additions & 0 deletions src/app/core/utils/passwords-utility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Injectable } from '@angular/core';
import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { Subscription } from 'rxjs';


@Injectable({
providedIn: 'root'
})

export class PasswordsUtility {
// password regex pattern
public static PASSWORD_REGEX = '^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*[#$@$!%*?&])[A-Za-z\d#$@$!%*?&].{8,}$';

public getPasswordValidators(): ValidatorFn[] {
return [Validators.required, Validators.pattern(PasswordsUtility.PASSWORD_REGEX), Validators.maxLength(50), Validators.minLength(8)];
}

/**
* Confirm Change Password of Users
* @param controlNameToCompare Form Control Name to be compared.
*/
public 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;
};
}
}
5 changes: 3 additions & 2 deletions src/app/loans/loans-view/loans-view.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
<h3>
<i class="fa fa-stop" matTooltip="{{'labels.status.' + loanDetailsData.status.value | translate}}"
[ngClass]="loanDetailsData.inArrears?'status-active-overdue':( iconLoanStatusColor() | statusLookup)"></i>
<span class="m-r-10">{{'labels.heading.Loan Product' | translate}}:</span> {{loanDetailsData.loanProductName}}
<mifosx-account-number accountNo="{{loanDetailsData.accountNo}}"></mifosx-account-number>
<span class="m-r-5">{{'labels.heading.Loan Product' | translate}} :</span>
<span class="m-r-5"><mifosx-long-text textValue="{{loanDetailsData.loanProductName}}"></mifosx-long-text></span>
<mifosx-account-number accountNo="{{loanDetailsData.accountNo}}" display="left"></mifosx-account-number>
</h3>
<span class="loans-overview">
<span class="m-r-10">{{'labels.text.' + entityType | translate}} {{"labels.inputs.name" | translate}} :</span> {{loanDetailsData.clientName ||
Expand Down
Loading

0 comments on commit 8fdf8fb

Please sign in to comment.