import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { ApplicantService } from '@core/services/auth-user/applicant.service'; import { AuthService } from '@core/services/auth.service'; import { DeepLinkingService } from '@core/services/deep-linking.service'; import { PortalDeterminationService } from '@core/services/portal-determination.service'; import { SpinnerService } from '@core/services/spinner.service'; import { SSOService } from '@core/services/sso.service'; import { ClientUserService } from '@features/client-user/client-user.service'; import { PasswordService, PasswordValidator, TypeSafeFormBuilder, TypeSafeFormGroup } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { LogService } from '@yourcause/common/logging'; import { NotifierService } from '@yourcause/common/notifier'; interface ConfirmGroup { password: string; } @Component({ selector: 'gc-confirm-email', templateUrl: './confirm-email.component.html', styleUrls: ['./confirm-email.component.scss'] }) export class ConfirmEmailComponent implements OnInit { isApplicant = false; formGroup: TypeSafeFormGroup; passwordVisible = false; token: string; errorMessage = ''; ssoLoginUrl: string; isSSO: boolean; loaded = false; programGuid: string; errorOnSubmit = false; containsUserInfo = false; isPreviousPassword = false; constructor ( private logger: LogService, private activatedRoute: ActivatedRoute, private router: Router, private applicantService: ApplicantService, private formBuilder: TypeSafeFormBuilder, private authService: AuthService, private clientUserService: ClientUserService, private notifier: NotifierService, private i18n: I18nService, private determinationService: PortalDeterminationService, private spinnerService: SpinnerService, private passwordService: PasswordService, private ssoService: SSOService, private portal: PortalDeterminationService, private deepLinkingService: DeepLinkingService ) { this.handleSubmit = this.handleSubmit.bind(this); } async ngOnInit () { this.spinnerService.startSpinner(); this.setIsSSO(); this.token = decodeURIComponent( this.activatedRoute.snapshot.queryParamMap.get('cet') ); this.programGuid = this.activatedRoute.snapshot.queryParamMap.get('grantProgramGuid'); await this.checkIfTokenExpired(); this.spinnerService.stopSpinner(); } setIsSSO () { this.isSSO = this.activatedRoute.snapshot.queryParams.isSso === 'True'; } async checkIfTokenExpired () { const token = encodeURIComponent(this.token).replace(/%20/g, '%2B'); try { const func = this.determinationService.isManager ? 'checkIfTokenExpiredManager' : 'checkIfTokenExpiredApplicant'; const response = await this.authService[func](token); if (!response.isValid) { this.setTokenExpiredMessage(); } else { if (this.isSSO) { await this.handleIsSSO(); } else { if (this.determinationService.isManager) { await this.handleManagerInit(); } else { await this.handleApplicantInit(); } } } } catch (e) { this.logger.error(e); this.setTokenExpiredMessage(); } } async handleIsSSO () { const prefix = this.portal.getCurrentPrefix(); if (!this.ssoService.ssoConfig) { if (prefix && prefix !== 'apply') { await this.ssoService.getSSOConfigurationBySubDomain(prefix); } } this.ssoLoginUrl = this.ssoService.generateUrl( this.ssoService.ssoConfig.affiliateId, prefix ); const passed = await this.clientUserService.confirmUser(this.token); if (passed) { this.loginWithSSO(); } else { this.setCantConfirmEmailMessage(); } } loginWithSSO () { setTimeout(() => { location.href = this.ssoLoginUrl; }, 50); } async handleApplicantInit () { this.isApplicant = true; try { await this.applicantService.confirmApplicantEmail(this.token); this.notifier.success(this.i18n.translate( 'GLOBAL:notificationEmailConfirmed', {}, 'Email confirmed' )); this.goToApplicantSignIn(); } catch (err) { const e = err as HttpErrorResponse; this.logger.error(e); if (e.error && e.error.message === 'Unable to find applicant') { this.setTokenExpiredMessage(); } else { this.notifier.error(this.i18n.translate( 'AUTH:textErrorConfirmingEmail', {}, 'There was an error confirming your email' )); this.goToApplicantSignIn(); } } } async handleManagerInit () { this.formGroup = this.formBuilder.group({ password: [ '', [ Validators.required, PasswordValidator(this.passwordService) ] ] }); } passwordChanged () { this.errorOnSubmit = false; this.containsUserInfo = false; this.isPreviousPassword = false; } setTokenExpiredMessage () { this.errorMessage = this.i18n.translate( 'AUTH:textTheConfirmationEmailYouUsedIsExpired', {}, 'The confirmation email you used has expired. In order to proceed with confirming your account, you will need to click the link below to resend the email.' ); } setCantConfirmEmailMessage () { this.errorMessage = this.i18n.translate( 'AUTH:textThereWasAProblemConfirmingYourEmail', {}, 'We could not confirm your email. Try again by clicking the link below to resend the email.' ); } async handleSubmit () { this.spinnerService.startSpinner(); const payload = { token: this.token, password: this.formGroup.value.password, confirmPassword: this.formGroup.value.password }; try { const response = await this.clientUserService.setPassword(payload); if (response.validPassword) { this.router.navigate(['/management/auth/signin']); this.notifier.success(this.i18n.translate( 'GLOBAL:notificationPasswordSaved', {}, 'Password saved' )); } else { this.containsUserInfo = response.containsUserInfo; this.isPreviousPassword = response.passwordPreviouslyUsed; this.errorOnSubmit = this.containsUserInfo || this.isPreviousPassword; } } catch (e) { this.logger.error(e); this.notifier.error(this.i18n.translate( 'GLOBAL:notificationErrorSettingPassword', {}, 'There was an error saving your password' )); this.spinnerService.stopSpinner(); throw e; } this.spinnerService.stopSpinner(); } goToResendVerification () { const routeSlice = this.determinationService.isManager ? 'management' : 'apply'; this.router.navigate([`/${routeSlice}/auth/resend-verification`]); } goToApplicantSignIn () { if (this.programGuid) { this.deepLinkingService.setAttemptedRouteApplicant( `/apply/programs/${this.programGuid}` ); } this.router.navigate(['/apply/auth/signin']); } togglePasswordVisible = () => { this.passwordVisible = !this.passwordVisible; }; }