frontend/src/app/forgot-password/forgot-password.component.html
<!--
~ Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors.
~ SPDX-License-Identifier: MIT
-->
<div fxLayoutAlign="center">
<mat-card class="mat-elevation-z6">
<h1 translate>TITLE_FORGOT_PASSWORD</h1>
<div class="confirmation"
[hidden]="!(confirmation && !emailControl.dirty && !securityQuestionControl.dirty && !passwordControl.dirty && !repeatPasswordControl.dirty)">
{{ confirmation }}
</div>
<div class="error"
[hidden]="!(error && !emailControl.dirty && !securityQuestionControl.dirty && !passwordControl.dirty && !repeatPasswordControl.dirty)">
{{ error }}
</div>
<div class="form-container">
<mat-form-field appearance="outline" color="accent">
<mat-label translate>LABEL_EMAIL</mat-label>
<input id="email" [formControl]="emailControl" (ngModelChange)="findSecurityQuestion()"
type="email" matInput placeholder="Enter your email" aria-label="Email address field">
<mat-icon matSuffix matTooltip="{{ 'MANDATORY_EMAIL' | translate }}"
matTooltipPosition=right aria-label="Please enter your email address to proceed">help_outline
</mat-icon>
<mat-error *ngIf="emailControl.invalid && emailControl.errors.required" translate>MANDATORY_EMAIL</mat-error>
<mat-error *ngIf="emailControl.invalid && emailControl.errors.email" translate>INVALID_EMAIL</mat-error>
</mat-form-field>
</div>
<div class="form-container" id="forgot-form">
<mat-form-field appearance="outline" color="accent">
<mat-label translate>LABEL_SECURITY_QUESTION</mat-label>
<input id="securityAnswer" [formControl]="securityQuestionControl" type="password" matInput
placeholder="{{ securityQuestion }}"
aria-label="Field for the answer to the security question">
<mat-icon matSuffix matTooltip="{{ 'MANDATORY_SECURITY_ANSWER' | translate }}"
matTooltipPosition=right aria-label="Please answer your selected security question">help_outline
</mat-icon>
<mat-error *ngIf="securityQuestionControl.invalid && securityQuestionControl.errors.required" translate>
MANDATORY_SECURITY_ANSWER
</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" color="accent">
<mat-label translate>LABEL_NEW_PASSWORD</mat-label>
<input #password id="newPassword" [formControl]="passwordControl" type="password" matInput placeholder=""
aria-label="Field for New Password">
<mat-hint translate>
<i class="fas fa-exclamation-circle"></i>
<em style="margin-left:5px;" translate>{{ 'INVALID_PASSWORD_LENGTH' | translate: {length: '5-40'} }}</em>
</mat-hint>
<mat-hint align="end">{{password.value?.length || 0}}/20</mat-hint>
<mat-error *ngIf="passwordControl.invalid && passwordControl.errors.required" translate>MANDATORY_NEW_PASSWORD
</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" color="accent">
<mat-label translate>LABEL_REPEAT_NEW_PASSWORD</mat-label>
<input #repeatPassword id="newPasswordRepeat" [formControl]="repeatPasswordControl" type="password" matInput
placeholder=""
aria-label="Field to confirm the new password">
<mat-hint align="end">{{repeatPassword.value?.length || 0}}/20</mat-hint>
<mat-error *ngIf="repeatPasswordControl.invalid && repeatPasswordControl.errors.required" translate>
MANDATORY_PASSWORD_REPEAT
</mat-error>
<mat-error *ngIf="repeatPasswordControl.invalid && repeatPasswordControl.errors.notSame" translate>
PASSWORDS_NOT_MATCHING
</mat-error>
<mat-error *ngIf="repeatPasswordControl.invalid && (repeatPasswordControl?.errors.minlength || repeatPasswordControl?.errors.maxlength)" translate
[translateParams]="{length: '5-40'}">INVALID_PASSWORD_LENGTH
</mat-error>
</mat-form-field>
<mat-slide-toggle #passwordInfoToggle [color]="passwordStrength.color">{{'SHOW_PASSWORD_ADVICE' | translate}}</mat-slide-toggle>
<mat-password-strength #passwordStrength [password]="password.value"></mat-password-strength>
<mat-password-strength-info *ngIf="passwordInfoToggle.checked" [passwordComponent]="passwordStrength"
[lowerCaseCriteriaMsg]="'LOWER_CASE_CRITERIA_MSG' | translate"
[upperCaseCriteriaMsg]="'UPPER_CASE_CRITERIA_MSG'| translate"
[digitsCriteriaMsg]="'DIGITS_CRITERIA_MSG'| translate"
[specialCharsCriteriaMsg]="'SPECIAL_CHARS_CRITERIA_MSG' | translate"
[minCharsCriteriaMsg]="'MIN_CHARS_CRITERIA_MSG' | translate:{value: 8}">
</mat-password-strength-info>
</div>
<button type="submit" id="resetButton"
[disabled]="emailControl.invalid || securityQuestionControl.invalid || passwordControl.invalid || repeatPasswordControl.invalid || repeatPasswordControl.disabled"
(click)="resetPassword()" mat-raised-button color="primary" aria-label="Button to confirm the changes">
<i class="far fa-edit fa-lg" aria-hidden="true"></i>
{{'BTN_CHANGE' | translate}}
</button>
</mat-card>
</div>