update user password + confirm password validator

This commit is contained in:
Lebeau Elise 2022-02-08 10:55:13 +00:00 committed by Sylvain MATHIEU
parent 8df255ebc3
commit b6b9d735f5
10 changed files with 164 additions and 18 deletions

View File

@ -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,

View File

@ -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;
}

View File

@ -26,7 +26,12 @@
<mat-error *ngIf="form.password?.touched && form.password?.errors"
>A password between 6 and 100 characters is required.</mat-error>
</mat-form-field>
<mat-form-field class="input-field">
<input matInput type="password" formControlName="confirmPassword" placeholder="Confirm Password"/>
<mat-error *ngIf="form.confirmPassword?.touched && form.confirmPassword?.errors"
>Password and Confirm password must be the same.
</mat-error>
</mat-form-field>
<mat-checkbox formControlName="is_active">Is active</mat-checkbox>
<mat-divider class="my-2"></mat-divider>

View File

@ -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[]) => {

View File

@ -0,0 +1,25 @@
<h1 mat-dialog-title>Change password for user : </h1>
<div>
<form [formGroup]="editPasswordForm" class="input-field">
<mat-form-field class="input-field">
<input matInput type="password" formControlName="password" placeholder="Password"/>
<mat-error *ngIf="passwordForm.password?.touched && passwordForm.password?.errors"
>Password must be between 6 and 100 characters.
</mat-error>
</mat-form-field>
<mat-form-field class="input-field">
<input matInput type="password" formControlName="confirmPassword" placeholder="Confirm Password"/>
<mat-error *ngIf="passwordForm.confirmPassword?.touched && passwordForm.confirmPassword?.errors"
>Password and Confirm password must be the same.
</mat-error>
</mat-form-field>
<div mat-dialog-actions class="button-div">
<button mat-button (click)="onCancel()" color="accent">Cancel</button>
<button mat-button (click)="onPasswordSave()" tabindex="2" class="add-project-button" mat-raised-button color="primary"
[disabled]="!editPasswordForm.valid">
Change password
</button>
</div>
</form>
</div>

View File

@ -0,0 +1,7 @@
.input-field {
width: 100%;
}
.button-div {
float: right;
}

View File

@ -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<ChangeUserPasswordComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChangeUserPasswordComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ChangeUserPasswordComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -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<ChangeUserPasswordComponent>,
@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);
})
}
}

View File

@ -44,15 +44,6 @@
</mat-error>
</mat-form-field>
<mat-form-field class="input-field">
<input matInput type="password" formControlName="password" placeholder="Password"/>
<mat-error *ngIf="form.password?.touched && form.password?.errors"
>Password must be between 6 and 100 characters
</mat-error>
</mat-form-field>
<mat-checkbox formControlName="is_active">Is active</mat-checkbox>
<div>
<mat-checkbox [checked]="user.is_superadmin" disabled>Is Superadmin</mat-checkbox>
@ -65,6 +56,11 @@
</button>
</div>
</form>
<button mat-button (click)="onChangePassword()" tabindex="2" mat-raised-button color="primary">
Change Password
</button>
<div>
<div>Creation date: {{user.created_at}}</div>
<div>Last update Date: {{user.updated_at}}</div>

View File

@ -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>(ChangeUserPasswordComponent,
{width: '400px', height: '300px', data: {user: this.user, server: this.server}});
}
}