From c21b66f0fbf38b0104f7a2ce11dded734cad29bf Mon Sep 17 00:00:00 2001 From: gbrodman Date: Fri, 1 Aug 2025 15:53:20 -0400 Subject: [PATCH] Add reset-EPP-password frontend component (#2786) --- .../security/eppPasswordEdit.component.html | 13 ++++ .../security/eppPasswordEdit.component.scss | 41 +++++++++---- .../security/eppPasswordEdit.component.ts | 61 ++++++++++++++++++- .../app/shared/services/backend.service.ts | 7 +++ 4 files changed, 109 insertions(+), 13 deletions(-) diff --git a/console-webapp/src/app/settings/security/eppPasswordEdit.component.html b/console-webapp/src/app/settings/security/eppPasswordEdit.component.html index 6bd1ba11d..97a9c7120 100644 --- a/console-webapp/src/app/settings/security/eppPasswordEdit.component.html +++ b/console-webapp/src/app/settings/security/eppPasswordEdit.component.html @@ -77,4 +77,17 @@ Save + @if(userDataService.userData()?.isAdmin) { +
+

Need to reset your EPP password?

+ +
+ } diff --git a/console-webapp/src/app/settings/security/eppPasswordEdit.component.scss b/console-webapp/src/app/settings/security/eppPasswordEdit.component.scss index aaaacf125..7b77a5e57 100644 --- a/console-webapp/src/app/settings/security/eppPasswordEdit.component.scss +++ b/console-webapp/src/app/settings/security/eppPasswordEdit.component.scss @@ -1,16 +1,35 @@ -.settings-security__edit-password { - max-width: 616px; - &-field { - width: 100%; - mat-form-field { - margin-bottom: 20px; +// Copyright 2025 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +.settings-security { + &__edit-password { + max-width: 616px; + &-field { width: 100%; + mat-form-field { + margin-bottom: 20px; + width: 100%; + } + } + &-form { + margin-top: 30px; + } + &-save { + margin-top: 30px; } } - &-form { - margin-top: 30px; - } - &-save { - margin-top: 30px; + &__reset-password-field { + margin-top: 60px; } } diff --git a/console-webapp/src/app/settings/security/eppPasswordEdit.component.ts b/console-webapp/src/app/settings/security/eppPasswordEdit.component.ts index 5675da747..73221b829 100644 --- a/console-webapp/src/app/settings/security/eppPasswordEdit.component.ts +++ b/console-webapp/src/app/settings/security/eppPasswordEdit.component.ts @@ -24,11 +24,43 @@ import { import { MatSnackBar } from '@angular/material/snack-bar'; import { RegistrarService } from 'src/app/registrar/registrar.service'; import { SecurityService } from './security.service'; +import { UserDataService } from 'src/app/shared/services/userData.service'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { CommonModule } from '@angular/common'; +import { MaterialModule } from 'src/app/material.module'; +import { filter, switchMap, take } from 'rxjs'; +import { BackendService } from 'src/app/shared/services/backend.service'; type errorCode = 'required' | 'maxlength' | 'minlength' | 'passwordsDontMatch'; type errorFriendlyText = { [type in errorCode]: String }; +@Component({ + selector: 'app-reset-epp-password-dialog', + template: ` +

Please confirm the password reset:

+ + This will send an EPP password reset email to the admin POC. + + + + + + `, + imports: [CommonModule, MaterialModule], +}) +export class ResetEppPasswordComponent { + constructor(public dialogRef: MatDialogRef) {} + + onSave(): void { + this.dialogRef.close(true); + } + + onCancel(): void { + this.dialogRef.close(false); + } +} + @Component({ selector: 'app-epp-password-edit', templateUrl: './eppPasswordEdit.component.html', @@ -48,9 +80,12 @@ export default class EppPasswordEditComponent { }; constructor( + public registrarService: RegistrarService, public securityService: SecurityService, - private _snackBar: MatSnackBar, - public registrarService: RegistrarService + protected userDataService: UserDataService, + private backendService: BackendService, + private resetPasswordDialog: MatDialog, + private _snackBar: MatSnackBar ) {} hasError(controlName: string) { @@ -120,4 +155,26 @@ export default class EppPasswordEditComponent { goBack() { this.securityService.isEditingPassword = false; } + + sendEppPasswordResetRequest() { + return this.backendService.requestEppPasswordReset( + this.registrarService.registrarId() + ); + } + + requestEppPasswordReset() { + const dialogRef = this.resetPasswordDialog.open(ResetEppPasswordComponent); + dialogRef + .afterClosed() + .pipe( + take(1), + filter((result) => !!result) + ) + .pipe(switchMap((_) => this.sendEppPasswordResetRequest())) + .subscribe({ + next: (_) => this.goBack(), + error: (err: HttpErrorResponse) => + this._snackBar.open(err.error || err.message), + }); + } } diff --git a/console-webapp/src/app/shared/services/backend.service.ts b/console-webapp/src/app/shared/services/backend.service.ts index 2d17eb981..99247b377 100644 --- a/console-webapp/src/app/shared/services/backend.service.ts +++ b/console-webapp/src/app/shared/services/backend.service.ts @@ -291,4 +291,11 @@ export class BackendService { registryLockEmail, }); } + + requestEppPasswordReset(registrarId: string) { + return this.http.post('/console-api/password-reset-request', { + type: 'EPP', + registrarId, + }); + } }