1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 13:23:34 +00:00

Auth/PM-6198 - Registration with Email Verification - Call email clicked endpoint (#10139)

* PM-6198 - Majority of client work done; WIP on registration finish comp

* PM-6198 - Registration Finish - Add registerVerificationEmailClicked logic

* PM-6198 - RegistrationLinkExpired component; added translations on other clients just in case we use the component on other clients in the future.

* PM-6198 - Clean up comment
This commit is contained in:
Jared Snider
2024-07-18 17:37:22 -04:00
committed by GitHub
parent 158da35008
commit 56f5dba444
12 changed files with 264 additions and 17 deletions

View File

@@ -1,10 +1,14 @@
import { CommonModule } from "@angular/common";
import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute, Params, Router, RouterModule } from "@angular/router";
import { Subject, takeUntil } from "rxjs";
import { Subject, from, switchMap, takeUntil, tap } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
import { RegisterVerificationEmailClickedRequest } from "@bitwarden/common/auth/models/request/registration/register-verification-email-clicked.request";
import { HttpStatusCode } from "@bitwarden/common/enums";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
import { ToastService } from "@bitwarden/components";
@@ -41,33 +45,43 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
private i18nService: I18nService,
private registrationFinishService: RegistrationFinishService,
private validationService: ValidationService,
private accountApiService: AccountApiService,
) {}
async ngOnInit() {
this.listenForQueryParamChanges();
this.masterPasswordPolicyOptions =
await this.registrationFinishService.getMasterPasswordPolicyOptsFromOrgInvite();
this.loading = false;
}
private listenForQueryParamChanges() {
this.activatedRoute.queryParams.pipe(takeUntil(this.destroy$)).subscribe((qParams: Params) => {
if (qParams.email != null && qParams.email.indexOf("@") > -1) {
this.email = qParams.email;
}
this.activatedRoute.queryParams
.pipe(
tap((qParams: Params) => {
if (qParams.email != null && qParams.email.indexOf("@") > -1) {
this.email = qParams.email;
}
if (qParams.token != null) {
this.emailVerificationToken = qParams.token;
}
if (qParams.token != null) {
this.emailVerificationToken = qParams.token;
}
}),
switchMap((qParams: Params) => {
if (
qParams.fromEmail &&
qParams.fromEmail === "true" &&
this.email &&
this.emailVerificationToken
) {
return from(
this.registerVerificationEmailClicked(this.email, this.emailVerificationToken),
);
}
}),
if (qParams.fromEmail && qParams.fromEmail === "true") {
this.toastService.showToast({
title: null,
message: this.i18nService.t("emailVerifiedV2"),
variant: "success",
});
}
});
takeUntil(this.destroy$),
)
.subscribe();
}
async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
@@ -94,6 +108,48 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
await this.router.navigate(["/login"], { queryParams: { email: this.email } });
}
private async registerVerificationEmailClicked(email: string, emailVerificationToken: string) {
const request = new RegisterVerificationEmailClickedRequest(email, emailVerificationToken);
try {
const result = await this.accountApiService.registerVerificationEmailClicked(request);
if (result == null) {
this.toastService.showToast({
title: null,
message: this.i18nService.t("emailVerifiedV2"),
variant: "success",
});
this.loading = false;
}
} catch (e) {
await this.handleRegisterVerificationEmailClickedError(e);
this.loading = false;
}
}
private async handleRegisterVerificationEmailClickedError(e: unknown) {
if (e instanceof ErrorResponse) {
const errorResponse = e as ErrorResponse;
switch (errorResponse.statusCode) {
case HttpStatusCode.BadRequest: {
if (errorResponse.message.includes("Expired link")) {
await this.router.navigate(["/signup-link-expired"]);
} else {
this.validationService.showError(errorResponse);
}
break;
}
default:
this.validationService.showError(errorResponse);
break;
}
} else {
this.validationService.showError(e);
}
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();