Skip to content

Commit

Permalink
Merge pull request #841 from xkostka2/PT-128
Browse files Browse the repository at this point in the history
feat(user-profile): change password
  • Loading branch information
HejdaJakub authored Sep 13, 2021
2 parents f3b1ea4 + 0d0824b commit e8bff01
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 7 deletions.
15 changes: 15 additions & 0 deletions apps/user-profile/src/assets/i18n/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@
"PASSWORD_RESET": {
"TITLE": "Změna hesla",
"CHANGE_PASSWORD": "Změnit heslo",
"RESET_PASSWORD": "Resetovat heslo",
"NAMESPACE": "Jmenný prostor",
"LOGIN": "Přihlašovací jméno",
"NOT_SUPPORTED": "Zména hesla není podporována ve vašich jmených prostorech"
Expand All @@ -350,6 +351,20 @@
"CANCEL": "Zrušit",
"SEND": "Poslat",
"SUCCESS": "Chyba byla nahlášena a dostala lístek s číslem: "
},
"CHANGE_PASSWORD_DIALOG": {
"TITLE": "Změna hesla",
"CANCEL": "Zrušit",
"CHANGE": "Potvrdit",
"OLD_PASSWORD": "Staré heslo",
"NEW_PASSWORD": "Nové heslo",
"NEW_PASSWORD_AGAIN": "Znovu zadejte nové heslo",
"PWD_DONT_MATCH": "Hesla se neshodují.",
"PWD_WEAK": "Heslo nesplňuje požadavky.",
"PWD_SHORT": "Heslo je příliš krátké.",
"FIELD_EMPTY": "Tohle políčko musí být vyplněné.",
"PASSWORD_INFO": "Heslo musí:\n - obsahovat pouze tisknutelné znaky bez diakritiky \n - být alespoň 10 znaků dlouhé\n - obsahovat nejméně 3 ze 4 skupin znaků:\n - malá písmena\n - velká písmena\n - čísla\n - speciální znaky",
"SUCCESS": "Heslo bylo úspěšně změněno"
}
},
"ORGANIZATIONS": {
Expand Down
19 changes: 17 additions & 2 deletions apps/user-profile/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"PREFERRED_UNIX_GROUP_NAMES": "Preferred unix group names",
"SAMBA_PASSWORD": "Samba password",
"SSH_KEYS": "SSH keys",
"PASSWORD_RESET": "Password reset",
"PASSWORD_RESET": "Change password",
"AUTHENTICATION": "Authentication"
},
"ORGANIZATIONS": {
Expand Down Expand Up @@ -368,8 +368,9 @@
"SUCCESS": "User external source successfully removed"
},
"PASSWORD_RESET": {
"TITLE": "Password reset",
"TITLE": "Change password",
"CHANGE_PASSWORD": "Change password",
"RESET_PASSWORD": "Reset password",
"NAMESPACE": "Namespace",
"LOGIN": "Login",
"NOT_SUPPORTED": "Password reset is not supported for your current namespaces"
Expand Down Expand Up @@ -421,6 +422,20 @@
"CANCEL": "Cancel",
"SEND": "Send",
"SUCCESS": "Issue report was sent and got ticket number: "
},
"CHANGE_PASSWORD_DIALOG": {
"TITLE": "Change password",
"CANCEL": "Cancel",
"CHANGE": "Confirm",
"OLD_PASSWORD": "Old password",
"NEW_PASSWORD": "New password",
"NEW_PASSWORD_AGAIN": "Re-type new password",
"PWD_DONT_MATCH": "Passwords do not match",
"PWD_WEAK": "Password does not meet the requirements",
"PWD_SHORT": "Password is too short",
"FIELD_EMPTY": "This field cannot be empty",
"PASSWORD_INFO": "Password must:\n - contain only printing non-accented characters\n - be at least 10 characters long\n - consist of at least 3 of 4 character groups:\n - lower-case letters\n - upper-case letters\n - digits\n - special characters",
"SUCCESS": "Password has been changed successfully,"
}
},
"ORGANIZATIONS": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ <h1 class="page-subtitle">{{'SHARED_LIB.PERUN.COMPONENTS.PASSWORD_RESET.TITLE' |
<th *matHeaderCellDef mat-header-cell>{{'SHARED_LIB.PERUN.COMPONENTS.PASSWORD_RESET.LOGIN' | customTranslate | translate}}</th>
<td *matCellDef="let login" class="w-50" mat-cell>{{login.value}}</td>
</ng-container>
<ng-container matColumnDef="reset">
<th *matHeaderCellDef mat-header-cell></th>
<td *matCellDef="let login" mat-cell>
<button (click)="resetPassword(login.friendlyNameParameter)" [disabled]="!logins.includes(login)" color="accent" mat-flat-button>{{'SHARED_LIB.PERUN.COMPONENTS.PASSWORD_RESET.RESET_PASSWORD' | customTranslate | translate}}</button>
</td>
</ng-container>
<ng-container matColumnDef="change">
<th *matHeaderCellDef mat-header-cell></th>
<td *matCellDef="let login" mat-cell>
<button (click)="changePassword(login.friendlyNameParameter)" [disabled]="!logins.includes(login)" color="accent" mat-flat-button>{{'SHARED_LIB.PERUN.COMPONENTS.PASSWORD_RESET.CHANGE_PASSWORD' | customTranslate | translate}}</button>
<button (click)="changePassword(login)" [disabled]="!logins.includes(login)" color="accent" mat-flat-button>{{'SHARED_LIB.PERUN.COMPONENTS.PASSWORD_RESET.CHANGE_PASSWORD' | customTranslate | translate}}</button>
</td>
</ng-container>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { Component, OnInit } from '@angular/core';
import { Attribute, AttributesManagerService} from '@perun-web-apps/perun/openapi';
import { StoreService } from '@perun-web-apps/perun/services';
import { MatTableDataSource } from '@angular/material/table';
import { MatDialog } from '@angular/material/dialog';
import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils';
import { ChangePasswordDialogComponent } from '../../../../dialogs/src/lib/change-password-dialog/change-password-dialog.component';

@Component({
selector: 'perun-web-apps-password-reset',
Expand All @@ -15,11 +18,12 @@ export class PasswordResetComponent implements OnInit {
nameSpaces: string[] = [];
logins: Attribute[] = [];

displayedColumns: string[] = ['namespace', 'value', 'change'];
displayedColumns: string[] = ['namespace', 'value', 'reset', 'change'];
dataSource: MatTableDataSource<Attribute>;

constructor(private attributesManagerService: AttributesManagerService,
private store: StoreService) {
private store: StoreService,
private dialog: MatDialog) {
}

ngOnInit(): void {
Expand All @@ -36,8 +40,19 @@ export class PasswordResetComponent implements OnInit {
});
}

changePassword(login: string) {
resetPassword(login: string) {
const url = this.store.get('pwd_reset_base_url');
location.href = `${url}?login-namespace=${login}`;
}

changePassword(login){
const config = getDefaultDialogConfig();
config.width = '600px';
config.data = {
login: login.value,
namespace: login.friendlyName.split(':')[1]
};

this.dialog.open(ChangePasswordDialogComponent, config);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.display-flex {
display: flex;
flex-direction: column;
}

.white-space-pre {
white-space: pre;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<h1 mat-dialog-title>{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.TITLE' | translate}}</h1>
<div class="dialog-container user-theme" mat-dialog-content>
<form *ngIf="!loading" [formGroup]="formGroup">
<div class="display-flex">
<mat-form-field>
<mat-label>{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.OLD_PASSWORD' | translate}}</mat-label>
<input formControlName="oldPasswordCtrl" matInput required type="password">
<mat-error *ngIf="oldPwd.hasError('required')">{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.FIELD_EMPTY' | translate}}</mat-error>
</mat-form-field>

<mat-form-field>
<mat-label>{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.NEW_PASSWORD' | translate}}</mat-label>
<input formControlName="passwordCtrl" matInput required type="password">
<mat-error *ngIf="newPwd.hasError('required')">{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.FIELD_EMPTY' | translate}}</mat-error>
<mat-error *ngIf="newPwd.hasError('isWeak') && !newPwd.hasError('minlength')">{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.PWD_WEAK' | translate}}</mat-error>
<mat-error *ngIf="newPwd.hasError('minlength')">{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.PWD_SHORT' | translate}}</mat-error>
</mat-form-field>

<mat-form-field>
<mat-label>{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.NEW_PASSWORD_AGAIN' | translate}}</mat-label>
<input formControlName="passwordAgainCtrl" matInput required type="password">
<mat-error *ngIf="newPwdAgain.hasError('required')">{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.FIELD_EMPTY' | translate}}</mat-error>
<mat-error *ngIf="newPwdAgain.hasError('noPasswordMatch')">{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.PWD_DONT_MATCH' | translate}}</mat-error>
</mat-form-field>

<p class="white-space-pre">{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.PASSWORD_INFO' | translate}}</p>
</div>
</form>
<mat-spinner *ngIf="loading" class="ml-auto mr-auto"></mat-spinner>
</div>

<div *ngIf="!loading" mat-dialog-actions>
<div class="ml-auto">
<button (click)="close()" mat-button>
{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.CANCEL' | translate}}
</button>
<button
(click)="changePassword()"
[disabled]="formGroup.invalid"
class="ml-2"
color="accent"
mat-flat-button>
{{'SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.CHANGE' | translate}}
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UsersManagerService } from '@perun-web-apps/perun/openapi';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CustomValidators } from '@perun-web-apps/perun/utils';
import { NotificatorService } from '@perun-web-apps/perun/services';
import { TranslateService } from '@ngx-translate/core';

export interface ChangePasswordDialogData {
namespace: string;
login: string;
}

@Component({
selector: 'perun-web-apps-change-password-dialog',
templateUrl: './change-password-dialog.component.html',
styleUrls: ['./change-password-dialog.component.css']
})
export class ChangePasswordDialogComponent implements OnInit {

formGroup: FormGroup;
oldPwd: AbstractControl;
newPwd: AbstractControl;
newPwdAgain: AbstractControl;
successMessage: string;
loading: boolean;

constructor(private dialogRef: MatDialogRef<ChangePasswordDialogComponent>,
@Inject(MAT_DIALOG_DATA) private data: ChangePasswordDialogData,
private _formBuilder: FormBuilder,
private usersManagerService: UsersManagerService,
private notificator: NotificatorService,
private translate: TranslateService) {
translate.get('SHARED_LIB.PERUN.COMPONENTS.CHANGE_PASSWORD_DIALOG.SUCCESS').subscribe(m => this.successMessage = m);
}

ngOnInit(): void {
this.formGroup = this._formBuilder.group({
oldPasswordCtrl: ['', Validators.required],
passwordCtrl: ['', Validators.compose([
CustomValidators.patternValidator([/\d/, /[A-Z]/, /[a-z]/, /[$&+,:;=?@#|'<>.^*()%!-]/]),
Validators.minLength(10)])
],
passwordAgainCtrl: ['']
}, {
validator: CustomValidators.passwordMatchValidator
});
this.oldPwd = this.formGroup.get('oldPasswordCtrl');
this.newPwd = this.formGroup.get('passwordCtrl');
this.newPwdAgain = this.formGroup.get('passwordAgainCtrl');
}

close() {
this.dialogRef.close(false);
}

changePassword() {
this.loading = true;
this.usersManagerService.changePasswordForLogin(this.data.login, this.data.namespace, this.newPwd.value, this.oldPwd.value, true).subscribe(() => {
this.notificator.showSuccess(this.successMessage);
this.loading = false;
this.dialogRef.close(true);
});
}
}
4 changes: 3 additions & 1 deletion libs/perun/dialogs/src/lib/perun-dialogs.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { ChangeGroupExpirationDialogComponent } from './change-group-expiration-
import { ChangeVoExpirationDialogComponent } from './change-vo-expiration-dialog/change-vo-expiration-dialog.component';
import { ChangeSponsorshipExpirationDialogComponent } from './change-sponsorship-expiration-dialog/change-sponsorship-expiration-dialog.component';
import { ChangeGroupResourceAssigmentDialogComponent } from './change-group-resource-assigment-dialog/change-group-resource-assigment-dialog.component';
import { ChangePasswordDialogComponent } from './change-password-dialog/change-password-dialog.component';

@NgModule({
imports: [
Expand Down Expand Up @@ -80,7 +81,8 @@ import { ChangeGroupResourceAssigmentDialogComponent } from './change-group-reso
ChangeGroupExpirationDialogComponent,
ChangeVoExpirationDialogComponent,
ChangeSponsorshipExpirationDialogComponent,
ChangeGroupResourceAssigmentDialogComponent
ChangeGroupResourceAssigmentDialogComponent,
ChangePasswordDialogComponent
],
exports: [
ChangeExpirationDialogComponent,
Expand Down

0 comments on commit e8bff01

Please sign in to comment.