All files / app/identity/validators/passwords firebase.validator.ts

100% Statements 8/8
100% Branches 3/3
100% Functions 2/2
100% Lines 8/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35                                  1x 42x   42x 18x     18x 2x       16x   16x      
import { inject } from '@angular/core';
import { Auth, validatePassword } from '@angular/fire/auth';
import type { AbstractControl, AsyncValidatorFn, ValidationErrors } from '@angular/forms';
 
import { getPasswordControlValue } from './util';
 
/**
 * Validate against the Firebase Project Authentication Password Policy.
 *
 * Note: This validator will be called on every InputEvent/Control.valueChange event after the sync
 * validators pass. But Firebase Auth caches the password policy fetch request so the first time is
 * the only remote request and so it is safe to not throttle this validator. Not that there is a
 * clean way to throttle AsyncValidatorFns :-(
 *
 * Note: at this time there is no actual need for this because the policy only enforces length and
 * other Validators already check for that. However it is nice to know how to do this.
 */
export const passwordFirebaseValidator = (): AsyncValidatorFn => {
  const auth: Auth = inject(Auth);
 
  return async (control: AbstractControl<unknown>): Promise<ValidationErrors | null> => {
    const value = getPasswordControlValue(control);
 
    // Like Validators.email, rely on Validators.required to check for blank passwords.
    if (value == undefined) {
      return null; // eslint-disable-line unicorn/no-null -- ValidatorFn returns null
    }
 
    // Opened an issue about this being necessary: https://github.com/angular/angularfire/issues/3614
    const { passwordPolicy: _, ...status } = await validatePassword(auth, value);
 
    return status.isValid ? null : { firebasevalidator: status }; // eslint-disable-line unicorn/no-null -- ValidatorFn returns null
  };
};