juice-shop/juice-shop

View on GitHub
frontend/src/app/register/register.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_REGISTRATION</h1>

    <div class="error" ng-if="error">{{ error }}</div>

    <div class="form-container" id="registration-form">

      <mat-form-field appearance="outline" color="accent">
        <mat-label translate>LABEL_EMAIL</mat-label>
        <input id="emailControl" [formControl]="emailControl" (focus)="this.error=null" type="text" matInput
               aria-label="Email address field">
        <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>

      <mat-form-field appearance="outline" color="accent">
        <mat-label translate>LABEL_PASSWORD</mat-label>
        <input #password id="passwordControl" [formControl]="passwordControl" (focus)="this.error=null" type="password"
               matInput aria-label="Field for the 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_PASSWORD
        </mat-error>
        <mat-error
          *ngIf="passwordControl.invalid && (passwordControl.errors.minlength || passwordControl.errors.maxlength)"
          translate [translateParams]="{length: '5-40'}">INVALID_PASSWORD_LENGTH
        </mat-error>
      </mat-form-field>

      <mat-form-field appearance="outline" color="accent">
        <mat-label translate>LABEL_PASSWORD_REPEAT</mat-label>
        <input #repeatPassword id="repeatPasswordControl" [formControl]="repeatPasswordControl"
               (focus)="this.error=null" type="password" matInput aria-label="Field to confirm the password">
        <mat-hint align="end">{{repeatPassword.value?.length || 0}}/40</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-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 class="security-container">

        <mat-form-field color="accent" appearance="outline">
          <mat-label>
            {{'LABEL_SECURITY_QUESTION' | translate}}
          </mat-label>
          <mat-select [formControl]="securityQuestionControl" placeholder="" [(value)]="selected"
                      (focus)="this.error=null" name="securityQuestion"
                      aria-label="Selection list for the security question">
            <mat-option *ngFor="let question of securityQuestions" [value]="question.id">
              {{question.question}}
            </mat-option>
          </mat-select>
          <mat-hint translate>
            <i class="fas fa-exclamation-circle"></i>
            <em style="margin-left:5px;" translate>CANNOT_BE_CHANGED_LATER</em>
          </mat-hint>
          <mat-error *ngIf="securityQuestionControl.invalid && securityQuestionControl.errors.required" translate>
            MANDATORY_SECURITY_QUESTION
          </mat-error>
        </mat-form-field>

        <mat-form-field appearance="outline" color="accent">
          <mat-label translate>SECURITY_ANSWER</mat-label>
          <input id="securityAnswerControl" [formControl]="securityAnswerControl" (focus)="this.error=null" type="text"
                 matInput [placeholder]="'SECURITY_ANSWER_PLACEHOLDER' | translate"
                 aria-label="Field for the answer to the security question">
          <mat-error *ngIf="securityAnswerControl.invalid && securityAnswerControl.errors.required" translate>
            MANDATORY_SECURITY_ANSWER
          </mat-error>
        </mat-form-field>
      </div>

      <button type="submit"
              id="registerButton"
              mat-raised-button color="primary"
              [disabled]="emailControl.invalid || passwordControl.invalid || repeatPasswordControl.invalid || securityQuestionControl.invalid || securityAnswerControl.invalid"
              (click)="save()"
              aria-label="Button to complete the registration">
        <i class="material-icons">
          person_add
        </i>
        {{'BTN_REGISTER' | translate}}
      </button>

      <div id="alreadyACustomerLink">
        <a class="primary-link" routerLink="/login" translate>ALREADY_A_CUSTOMER</a>
      </div>
    </div>
  </mat-card>
</div>