diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2449b198..0b12ea1c 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -312,6 +312,7 @@ import {MatFormFieldModule} from "@angular/material/form-field"; import { PermissionsFilterPipe } from './components/permissions-management/permissions-filter.pipe'; import { DisplayPathPipe } from './components/permissions-management/display-path.pipe'; import {RolePermissionsComponent} from "@components/role-management/role-detail/role-permissions/role-permissions.component"; +import { ChangeUserPasswordComponent } from './components/user-management/user-detail/change-user-password/change-user-password.component'; @NgModule({ declarations: [ @@ -534,11 +535,9 @@ import {RolePermissionsComponent} from "@components/role-management/role-detail/ FilterCompletePipe, UserPermissionsComponent, PermissionsFilterPipe, - FilterCompletePipe, - DisplayPathPipe, RolePermissionsComponent, DisplayPathPipe, - PermissionsFilterPipe, + ChangeUserPasswordComponent, ], imports: [ BrowserModule, diff --git a/src/app/components/user-management/ConfirmPasswordValidator.ts b/src/app/components/user-management/ConfirmPasswordValidator.ts new file mode 100644 index 00000000..1e26eac3 --- /dev/null +++ b/src/app/components/user-management/ConfirmPasswordValidator.ts @@ -0,0 +1,10 @@ +import {AbstractControl, FormGroup, ValidationErrors, ValidatorFn} from '@angular/forms'; + + +export function matchingPassword(control: AbstractControl) : ValidationErrors | null { + if (control.get('password').value !== control.get('confirmPassword').value) { + control.get('confirmPassword').setErrors({confirmPasswordMatch: true}); + return; + } + return; +} diff --git a/src/app/components/user-management/add-user-dialog/add-user-dialog.component.html b/src/app/components/user-management/add-user-dialog/add-user-dialog.component.html index 478937c9..5b2c0391 100644 --- a/src/app/components/user-management/add-user-dialog/add-user-dialog.component.html +++ b/src/app/components/user-management/add-user-dialog/add-user-dialog.component.html @@ -26,7 +26,12 @@ A password between 6 and 100 characters is required. - + + + Password and Confirm password must be the same. + + Is active diff --git a/src/app/components/user-management/add-user-dialog/add-user-dialog.component.ts b/src/app/components/user-management/add-user-dialog/add-user-dialog.component.ts index 95d22b29..3bf5e6e1 100644 --- a/src/app/components/user-management/add-user-dialog/add-user-dialog.component.ts +++ b/src/app/components/user-management/add-user-dialog/add-user-dialog.component.ts @@ -25,6 +25,7 @@ import {GroupService} from "@services/group.service"; import {Observable} from "rxjs/Rx"; import {startWith} from "rxjs/operators"; import {map} from "rxjs//operators"; +import {matchingPassword} from "@components/user-management/ConfirmPasswordValidator"; @Component({ selector: 'app-add-user-dialog', @@ -58,7 +59,11 @@ export class AddUserDialogComponent implements OnInit { [userEmailAsyncValidator(this.server, this.userService)]), password: new FormControl(null, [Validators.required, Validators.minLength(6), Validators.maxLength(100)]), + confirmPassword: new FormControl(null, + [Validators.minLength(6), Validators.maxLength(100), Validators.required] ), is_active: new FormControl(true) + },{ + validators: [matchingPassword] }); this.groupService.getGroups(this.server) .subscribe((groups: Group[]) => { diff --git a/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.html b/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.html new file mode 100644 index 00000000..f61f5fa5 --- /dev/null +++ b/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.html @@ -0,0 +1,25 @@ +

Change password for user :

+
+
+ + + Password must be between 6 and 100 characters. + + + + + Password and Confirm password must be the same. + + + +
+ + +
+
+
diff --git a/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.scss b/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.scss new file mode 100644 index 00000000..a64b61ba --- /dev/null +++ b/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.scss @@ -0,0 +1,7 @@ +.input-field { + width: 100%; +} + +.button-div { + float: right; +} diff --git a/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.spec.ts b/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.spec.ts new file mode 100644 index 00000000..eaa343b8 --- /dev/null +++ b/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChangeUserPasswordComponent } from './change-user-password.component'; + +describe('ChangeUserPasswordComponent', () => { + let component: ChangeUserPasswordComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ChangeUserPasswordComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ChangeUserPasswordComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.ts b/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.ts new file mode 100644 index 00000000..192f2644 --- /dev/null +++ b/src/app/components/user-management/user-detail/change-user-password/change-user-password.component.ts @@ -0,0 +1,67 @@ +import {Component, Inject, OnInit} from '@angular/core'; +import {AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators} from "@angular/forms"; +import {User} from "@models/users/user"; +import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog"; +import {UserService} from "@services/user.service"; +import {Server} from "@models/server"; +import {ToasterService} from "@services/toaster.service"; +import {matchingPassword} from "@components/user-management/ConfirmPasswordValidator"; + +@Component({ + selector: 'app-change-user-password', + templateUrl: './change-user-password.component.html', + styleUrls: ['./change-user-password.component.scss'] +}) +export class ChangeUserPasswordComponent implements OnInit { + + editPasswordForm: FormGroup; + user: User; + + constructor(private dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: { user: User, server: Server }, + private userService: UserService, + private toasterService: ToasterService) { } + + ngOnInit(): void { + this.user = this.data.user; + this.editPasswordForm = new FormGroup({ + password: new FormControl(null, + [Validators.minLength(6), Validators.maxLength(100), Validators.required] ), + confirmPassword: new FormControl(null, + [Validators.minLength(6), Validators.maxLength(100), Validators.required] ), + },{ + validators: [matchingPassword] + }) + } + + get passwordForm() { + return this.editPasswordForm.controls; + } + + + onCancel() { + this.dialogRef.close(); + } + + onPasswordSave() { + if (!this.editPasswordForm.valid) { + return; + } + + const updatedUser = {}; + updatedUser['password'] = this.editPasswordForm.get('password').value; + updatedUser['user_id'] = this.user.user_id; + + console.log(updatedUser); + + this.userService.update(this.data.server, updatedUser) + .subscribe((user: User) => { + this.toasterService.success(`User ${user.username} password updated`); + this.editPasswordForm.reset(); + this.dialogRef.close(true); + }, + (error) => { + this.toasterService.error('Cannot update password for user : ' + error); + }) + } +} diff --git a/src/app/components/user-management/user-detail/user-detail.component.html b/src/app/components/user-management/user-detail/user-detail.component.html index f9d2db94..b4ba6cf0 100644 --- a/src/app/components/user-management/user-detail/user-detail.component.html +++ b/src/app/components/user-management/user-detail/user-detail.component.html @@ -44,15 +44,6 @@ - - - - Password must be between 6 and 100 characters - - - - Is active
Is Superadmin @@ -65,6 +56,11 @@
+ + +
Creation date: {{user.created_at}}
Last update Date: {{user.updated_at}}
diff --git a/src/app/components/user-management/user-detail/user-detail.component.ts b/src/app/components/user-management/user-detail/user-detail.component.ts index bf5931bc..9edbae10 100644 --- a/src/app/components/user-management/user-detail/user-detail.component.ts +++ b/src/app/components/user-management/user-detail/user-detail.component.ts @@ -10,6 +10,10 @@ import {userEmailAsyncValidator} from "@components/user-management/add-user-dial import {ActivatedRoute, Router} from "@angular/router"; import {Permission} from "@models/api/permission"; import {Role} from "@models/api/role"; +import {AddUserDialogComponent} from "@components/user-management/add-user-dialog/add-user-dialog.component"; +import {MatDialog} from "@angular/material/dialog"; +import {ChangeUserPasswordComponent} from "@components/user-management/user-detail/change-user-password/change-user-password.component"; +import {RemoveToGroupDialogComponent} from "@components/group-details/remove-to-group-dialog/remove-to-group-dialog.component"; @Component({ selector: 'app-user-detail', @@ -24,11 +28,13 @@ export class UserDetailComponent implements OnInit { server: Server; user_id: string; permissions: Permission[]; + changingPassword: boolean = false; constructor(public userService: UserService, private toasterService: ToasterService, private route: ActivatedRoute, - private router: Router) { + private router: Router, + public dialog: MatDialog) { } @@ -57,8 +63,6 @@ export class UserDetailComponent implements OnInit { email: new FormControl(this.user.email, [Validators.email, Validators.required], [userEmailAsyncValidator(this.server, this.userService, this.user.email)]), - password: new FormControl(null, - [Validators.minLength(6), Validators.maxLength(100)]), is_active: new FormControl(this.user.is_active) }); } @@ -91,7 +95,7 @@ export class UserDetailComponent implements OnInit { .forEach(key => { const currentControl = this.editUserForm.get(key); - if (currentControl.dirty && currentControl.value !== this.user[key] && currentControl.value !== '') { + if (currentControl.dirty && currentControl.value !== this.user[key]) { dirtyValues[key] = currentControl.value; } }); @@ -99,5 +103,8 @@ export class UserDetailComponent implements OnInit { return dirtyValues; } - + onChangePassword() { + this.dialog.open(ChangeUserPasswordComponent, + {width: '400px', height: '300px', data: {user: this.user, server: this.server}}); + } }