diff --git a/src/app/shared/change-password-dialog/change-password-dialog.component.html b/src/app/shared/change-password-dialog/change-password-dialog.component.html new file mode 100644 index 000000000..2f72b23b2 --- /dev/null +++ b/src/app/shared/change-password-dialog/change-password-dialog.component.html @@ -0,0 +1,50 @@ +

Change Password

+ +
+ +
+ +
+ + + Password + + + Password is required + + + Password should be at least 8 characters long + + + Password should not be more than 50 characters long + + + Password should include a numeral and at least one uppercase ,lowercase and special character + + + +
+ +
+ + + Repeat Password + + + Password required + + + Password does not match + + + +
+ +
+ +
+ + + + + diff --git a/src/app/shared/change-password-dialog/change-password-dialog.component.scss b/src/app/shared/change-password-dialog/change-password-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/shared/change-password-dialog/change-password-dialog.component.spec.ts b/src/app/shared/change-password-dialog/change-password-dialog.component.spec.ts new file mode 100644 index 000000000..1ba6fd2da --- /dev/null +++ b/src/app/shared/change-password-dialog/change-password-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChangePasswordDialogComponent } from './change-password-dialog.component'; + +describe('ChangePasswordDialogComponent', () => { + let component: ChangePasswordDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ChangePasswordDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChangePasswordDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/change-password-dialog/change-password-dialog.component.ts b/src/app/shared/change-password-dialog/change-password-dialog.component.ts new file mode 100644 index 000000000..c2fc827ec --- /dev/null +++ b/src/app/shared/change-password-dialog/change-password-dialog.component.ts @@ -0,0 +1,60 @@ +/** Angular Imports */ +import { Component, OnInit, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { FormBuilder, Validators, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms'; +import { Subscription } from 'rxjs'; + +/** + * Change Password Dialog component. + */ +@Component({ + selector: 'mifosx-change-password-dialog', + templateUrl: './change-password-dialog.component.html', + styleUrls: ['./change-password-dialog.component.scss'] +}) +export class ChangePasswordDialogComponent implements OnInit { + + /** Change Password Form */ + changePasswordForm: any; + + /** + * @param {MatDialogRef} dialogRef Component reference to dialog. + * @param {any} data Provides any data. + */ + constructor(public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private formBuilder: FormBuilder) { } + + ngOnInit() { + this.createChangePasswordForm(); + } + + /** Change Password form */ + createChangePasswordForm() { + this.changePasswordForm = this.formBuilder.group({ + 'password': ['', [Validators.required, Validators.pattern('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&].{8,}$'), Validators.maxLength(50), Validators.minLength(8)]], + 'repeatPassword': ['', [Validators.required, this.confirmPassword('password')]] + }); + } + + /** + * 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; + }; + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index aead29200..d25935ea1 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -11,6 +11,7 @@ import { FileUploadComponent } from './file-upload/file-upload.component'; import { FooterComponent } from './footer/footer.component'; import { LanguageSelectorComponent } from './language-selector/language-selector.component'; import { ThemePickerComponent } from './theme-picker/theme-picker.component'; +import { ChangePasswordDialogComponent } from './change-password-dialog/change-password-dialog.component'; /** Custom Modules */ import { IconsModule } from './icons.module'; @@ -36,6 +37,7 @@ import { MaterialModule } from './material.module'; FooterComponent, LanguageSelectorComponent, ThemePickerComponent, + ChangePasswordDialogComponent ], exports: [ FileUploadComponent, @@ -50,7 +52,8 @@ import { MaterialModule } from './material.module'; ], entryComponents: [ FormDialogComponent, - DeleteDialogComponent + DeleteDialogComponent, + ChangePasswordDialogComponent ] }) export class SharedModule { } diff --git a/src/app/users/users.service.ts b/src/app/users/users.service.ts index a1bd0d26d..cd58b9088 100644 --- a/src/app/users/users.service.ts +++ b/src/app/users/users.service.ts @@ -48,6 +48,16 @@ export class UsersService { return this.http.get(`/users/${userId}`); } + /** + * Change User Password + * @param userId User Id of users + * @param password New Password of the user + * @returns {Observable} + */ + changePassword(userId: string, passwordObj: any) { + return this.http.put(`/users/${userId}`, passwordObj); + } + /** * @param {string} userId user ID of user. * @returns {Observable} diff --git a/src/app/users/view-user/view-user.component.html b/src/app/users/view-user/view-user.component.html index 622b2a614..747af8820 100644 --- a/src/app/users/view-user/view-user.component.html +++ b/src/app/users/view-user/view-user.component.html @@ -7,7 +7,7 @@    Delete - diff --git a/src/app/users/view-user/view-user.component.ts b/src/app/users/view-user/view-user.component.ts index 54293172b..1590adb5c 100644 --- a/src/app/users/view-user/view-user.component.ts +++ b/src/app/users/view-user/view-user.component.ts @@ -8,6 +8,7 @@ import { UsersService } from '../users.service'; /** Custom Components */ import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; +import { ChangePasswordDialogComponent } from 'app/shared/change-password-dialog/change-password-dialog.component'; /** * View user component. @@ -58,4 +59,25 @@ export class ViewUserComponent implements OnInit { }); } + /** + * Change Password of the Users. + */ + changeUserPassword() { + const changeUserPasswordDialogRef = this.dialog.open(ChangePasswordDialogComponent, { + width: '400px', + height: '300px' + }); + changeUserPasswordDialogRef.afterClosed().subscribe((response: any) => { + if (response.password && response.repeatPassword) { + const password = response.password; + const repeatPassword = response.repeatPassword; + const firstname = this.userData.firstname; + const data = {password: password, repeatPassword: repeatPassword, firstname: firstname}; + this.usersService.changePassword(this.userData.id, data).subscribe(() => { + this.router.navigate(['/users']); + }); + } + }); + } + }