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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 1x 10x 10x 10x 10x 10x 3x 3x 1x 2x 2x 2x 2x 1x 1x 2x | import {
ChangeDetectionStrategy,
Component,
inject,
signal,
} from '@angular/core';
import type { Signal, WritableSignal } from '@angular/core';
import { Auth, sendPasswordResetEmail } from '@angular/fire/auth';
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
import type { FormControl, ValidationErrors } from '@angular/forms';
import { RouterLink } from '@angular/router';
import { SpinnerComponent } from '~/app/shared/spinner/spinner.component';
import { AuthErrorMessagesComponent } from '../auth-error-messages/auth-error-messages.component';
import { getErrorCode } from '../error-code';
import { createEmailControl } from '../identity-forms';
/** FormGroup allows the use of (ngSubmit) on the Form element. */
type ForgotFormGroup = FormGroup<{ email: FormControl<string | null> }>;
/**
* Sends email to reset password for a user's account.
*/
@Component({
selector: 'app-forgot-password',
imports: [
AuthErrorMessagesComponent,
ReactiveFormsModule,
RouterLink,
SpinnerComponent,
],
templateUrl: './forgot-password.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ForgotPasswordComponent {
/** Errors specific to the email field. */
public readonly $emailCntrlErrors: Signal<ValidationErrors | undefined>;
/** Aria-invalid attribute for the email field. */
public readonly $emailCntrlInvalid: Signal<boolean>;
/** Form submission errors from Firebase Authentication response. */
public readonly $errorCode: WritableSignal<string>;
/** Toggle the HTML form and spinner. */
public readonly $showForm: WritableSignal<boolean>;
public readonly emailCntrl: FormControl<string | null>;
public readonly forgotForm: ForgotFormGroup;
private readonly _auth: Auth;
constructor() {
this._auth = inject(Auth);
({ $errors: this.$emailCntrlErrors, $invalid: this.$emailCntrlInvalid, control: this.emailCntrl } = createEmailControl());
this.forgotForm = new FormGroup({ email: this.emailCntrl });
this.$errorCode = signal<string>('');
this.$showForm = signal<boolean>(true);
}
/**
* Sends password reset email to submitted email address, if it exists in Firebase Authentication.
*
* Email enumeration protection is enabled in production, so errors should not indicate if an
* account exists with the submitted email address.
*/
public async onSubmit(): Promise<void> {
const { email } = this.forgotForm.value;
// Validators prevent email being falsy, but TypeScript doesn't know that.
if (this.forgotForm.invalid || !email) {
throw new Error('Invalid form submitted');
}
this.$showForm.set(false);
this.$errorCode.set(''); // Clear out any existing errors
try {
await sendPasswordResetEmail(this._auth, email);
} catch (err: unknown) {
const code = getErrorCode(err);
this.$errorCode.set(code);
}
this.$showForm.set(true);
}
}
|