I have created a custom validator that checks whether an email already exists in MySQL database. It works in that when a user types in an email that already exists in a database, an appropriate warning message will appear and not allow the admin to insert an existing user.
However, after testing it a few times, it looks like this validation can be easily broken by simply copying the email address from the database and pasting it in the form field. It is worth to note that when pasting in the email the first time round, it doesnt validate the email but when I then delete it and paste it in the second time, it then recognises it. I have shown the process in the attached photos below:
My custom validator:
import { Directive } from '@angular/core';
import { AsyncValidator, AbstractControl, ValidationErrors, NG_ASYNC_VALIDATORS, AsyncValidatorFn } from '@angular/forms';
import { Observable } from 'rxjs';
import { PatientsService } from './patients.service';
import { map } from 'rxjs/operators';
export function uniqueUsernameValidator(patientService: PatientsService): AsyncValidatorFn {
return (c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
return patientService.checkUserEmail(c.value).pipe(
map(users => {
return users && users.length > 0 ? { 'uniqueUsername': true } : null;
})
);
};
}
@Directive({
selector: '[uniqueUsername]',
providers: [{ provide: NG_ASYNC_VALIDATORS, useExisting: UniqueUsernameValidatorDirective, multi: true }]
})
export class UniqueUsernameValidatorDirective implements AsyncValidator {
constructor(private patientService: PatientsService) { }
validate(c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
return uniqueUsernameValidator(this.patientService)(c);
}
}
component I am using it in:
email: [
null,
[Validators.required,Validators.maxLength(30),Validators.email],
[this.usernameService.usernameValidator()]
]
Referenced in my html
<div class="form-group col-md-6">
<label for="inputemail"id="label">Email</label>
<input type="email" formControlName="email" name="email" class="form-control" id="inputEmail4"placeholder="Email">
<div class="alert alert-danger" *ngIf="addForm.get('email').hasError('maxlength') && addForm.get('email').touched">
Please enter maximum 30 characters.
</div>
<div class="alert alert-danger" *ngIf="addForm.get('email').hasError('required') && addForm.get('email').touched">
Please enter an email address.
</div>
<div class="alert alert-danger"*ngIf="addForm.get('email').hasError('email') && addForm.get('email').touched">
Please insert a valid email address.
</div>
<!--If same email exists...-->
<div class="alert alert-danger"*ngIf=" addForm.controls['email']?.errors?.emailExists">
Email already exists
</div>
</div>
Could someone please advise ? I am trying for it to also validate clipboard events (copy and paste) the first time round.

