juice-shop/juice-shop

View on GitHub
frontend/src/app/forgot-password/forgot-password.component.html

Summary

Maintainability
Test Coverage
<!--
  ~ 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>