refactor: put the input password in a separate component
Some checks failed
Build and Deploy Angular App / build (push) Failing after 1m17s
Some checks failed
Build and Deploy Angular App / build (push) Failing after 1m17s
This commit is contained in:
@ -0,0 +1,45 @@
|
||||
<div [formGroup]="formGroup">
|
||||
<mat-form-field color="accent">
|
||||
<mat-label>Пароль</mat-label>
|
||||
<input matInput
|
||||
matTooltip="Укажите пароль"
|
||||
formControlName="password"
|
||||
required
|
||||
[type]="hidePass ? 'password' : 'text'"
|
||||
id="passwordNextFocus"
|
||||
focusNext="focusNext">
|
||||
|
||||
<button mat-icon-button matSuffix (click)="togglePassword($event)" [attr.aria-label]="'Hide password'"
|
||||
[attr.aria-pressed]="hidePass">
|
||||
<mat-icon>{{ hidePass ? 'visibility_off' : 'visibility' }}</mat-icon>
|
||||
</button>
|
||||
|
||||
@if (formGroup.get('password')?.hasError('required')) {
|
||||
<mat-error>
|
||||
Пароль является <i>обязательным</i>
|
||||
</mat-error>
|
||||
}
|
||||
|
||||
@if (formGroup.get('password')?.hasError('minlength')) {
|
||||
<mat-error>
|
||||
Пароль должен быть не менее {{ policy.minimumLength }} символов
|
||||
</mat-error>
|
||||
}
|
||||
|
||||
@if (formGroup.get('password')?.hasError('pattern')) {
|
||||
<mat-error>
|
||||
Пароль должен содержать:
|
||||
@if (policy.requireLettersDifferentCase) {
|
||||
Латинские символы разных регистров
|
||||
} @else if (policy.requireLetter) {
|
||||
Один латинский символ
|
||||
} @else if (policy.requireDigit) {
|
||||
Одну цифру
|
||||
}
|
||||
@if (policy.requireSpecialCharacter) {
|
||||
Специальный символ
|
||||
}
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
@ -0,0 +1,77 @@
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {MatFormFieldModule} from "@angular/material/form-field";
|
||||
import {MatInput} from "@angular/material/input";
|
||||
import {MatIconButton} from "@angular/material/button";
|
||||
import {FormGroup, ReactiveFormsModule, ValidatorFn, Validators} from "@angular/forms";
|
||||
import {MatSelectModule} from "@angular/material/select";
|
||||
import {MatTooltip} from "@angular/material/tooltip";
|
||||
import {MatIcon} from "@angular/material/icon";
|
||||
import {PasswordPolicy} from "@model/passwordPolicy";
|
||||
import SecurityService from "@api/v1/securityService";
|
||||
import {FocusNextDirective} from "@/directives/focus-next.directive";
|
||||
import SetupService from "@api/v1/setup.service";
|
||||
|
||||
@Component({
|
||||
selector: 'password-input',
|
||||
imports: [
|
||||
ReactiveFormsModule,
|
||||
MatFormFieldModule,
|
||||
MatSelectModule,
|
||||
MatInput,
|
||||
MatTooltip,
|
||||
MatIconButton,
|
||||
MatIcon,
|
||||
FocusNextDirective
|
||||
],
|
||||
templateUrl: './password-input.component.html',
|
||||
styleUrl: './password-input.component.css',
|
||||
providers: [SecurityService, SetupService]
|
||||
})
|
||||
export class PasswordInputComponent {
|
||||
protected hidePass = true;
|
||||
protected policy!: PasswordPolicy;
|
||||
@Input() formGroup!: FormGroup;
|
||||
@Input() focusNext: string | undefined;
|
||||
@Input() isSetupMode: boolean = false;
|
||||
|
||||
constructor(securityApi: SecurityService, setupApi: SetupService) {
|
||||
if (this.isSetupMode)
|
||||
setupApi.passwordPolicyConfiguration().subscribe(policy => {
|
||||
this.policy = policy;
|
||||
this.updateValueAndValidity(policy);
|
||||
});
|
||||
else
|
||||
securityApi.passwordPolicy().subscribe(policy => {
|
||||
this.policy = policy;
|
||||
this.updateValueAndValidity(policy);
|
||||
});
|
||||
}
|
||||
|
||||
private updateValueAndValidity(policy: PasswordPolicy): void {
|
||||
const validators: ValidatorFn[] = [Validators.required];
|
||||
|
||||
if (policy.minimumLength) {
|
||||
validators.push(Validators.minLength(policy.minimumLength));
|
||||
}
|
||||
|
||||
if (policy.requireLettersDifferentCase) {
|
||||
validators.push(Validators.pattern(/(?=.*[a-z])(?=.*[A-Z])/));
|
||||
} else if (policy.requireLetter) {
|
||||
validators.push(Validators.pattern(/[A-Za-z]/));
|
||||
} else if (policy.requireDigit) {
|
||||
validators.push(Validators.pattern(/\d/));
|
||||
}
|
||||
|
||||
if (policy.requireSpecialCharacter) {
|
||||
validators.push(Validators.pattern(/[!@#$%^&*(),.?":{}|<>]/));
|
||||
}
|
||||
|
||||
this.formGroup.get('password')?.setValidators(validators);
|
||||
this.formGroup.get('password')?.updateValueAndValidity();
|
||||
}
|
||||
|
||||
protected togglePassword(event: MouseEvent) {
|
||||
this.hidePass = !this.hidePass;
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user