frontend/src/app/register/register.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_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>