1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-13 06:43:35 +00:00

Auth/PM-8112 - UI refresh - Registration Components (#11353)

* PM-8112 - Update classes of existing registration icons

* PM-8112 - Add new icons

* PM-8112 - Export icons from libs/auth

* PM-8112 - RegistrationStart - Add new user icon as page icon

* PM-8112 - Replace RegistrationCheckEmailIcon with new icon so it displays properly

* PM-8112 - RegistrationFinish - Add new icon across clients

* PM-8112 - Registration start comp - update page icon and page title on state change to match figma

* PM-8112 - RegistrationFinish - adding most of framework for changing page title & subtitle when an org invite is in state.

* PM-8112 - Add joinOrganizationName to all clients translations

* PM-8112 - RegistrationFinish - Remove default page title & subtitle and let onInit logic figure out what to set based on flows.

* PM-8112 - RegistrationStart - Fix setAnonLayoutWrapperData calls

* PM-8112 - RegistrationFinish - simplify qParams init logic to make handling loading and page title and subtitle setting easier.

* PM-8112 - Registration Link expired - move icon to page icon out of main content

* PM-8112 - RegistrationFinish - Refactor init logic further into distinct flows.

* PM-8112 - Fix icons

* PM-8112 - Extension AppRoutingModule - move sign up start & finish routes under extension anon layout

* PM-8112 - Fix storybook

* PM-8112 - Clean up unused prop

* PM-8112 - RegistrationLockAltIcon tweaks

* PM-8112 - Update icons to have proper styling

* PM-8112 - RegistrationUserAddIcon - remove unnecessary svg class

* PM-8112 - Fix icons
This commit is contained in:
Jared Snider
2024-10-16 18:28:27 -04:00
committed by GitHub
parent e256bde1de
commit 4b67cd24b4
21 changed files with 336 additions and 141 deletions

View File

@@ -1,7 +1,7 @@
import { CommonModule } from "@angular/common";
import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute, Params, Router, RouterModule } from "@angular/router";
import { EMPTY, Subject, from, switchMap, takeUntil, tap } from "rxjs";
import { Subject, firstValueFrom } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
@@ -15,6 +15,7 @@ import { ValidationService } from "@bitwarden/common/platform/abstractions/valid
import { ToastService } from "@bitwarden/components";
import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "../../../common";
import { AnonLayoutWrapperDataService } from "../../anon-layout/anon-layout-wrapper-data.service";
import { InputPasswordComponent } from "../../input-password/input-password.component";
import { PasswordInputResult } from "../../input-password/password-input-result";
@@ -60,55 +61,72 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
private accountApiService: AccountApiService,
private loginStrategyService: LoginStrategyServiceAbstraction,
private logService: LogService,
private anonLayoutWrapperDataService: AnonLayoutWrapperDataService,
) {}
async ngOnInit() {
this.listenForQueryParamChanges();
this.masterPasswordPolicyOptions =
await this.registrationFinishService.getMasterPasswordPolicyOptsFromOrgInvite();
const qParams = await firstValueFrom(this.activatedRoute.queryParams);
this.handleQueryParams(qParams);
if (
qParams.fromEmail &&
qParams.fromEmail === "true" &&
this.email &&
this.emailVerificationToken
) {
await this.initEmailVerificationFlow();
} else {
// Org Invite flow OR registration with email verification disabled Flow
const orgInviteFlow = await this.initOrgInviteFlowIfPresent();
if (!orgInviteFlow) {
this.initRegistrationWithEmailVerificationDisabledFlow();
}
}
this.loading = false;
}
private listenForQueryParamChanges() {
this.activatedRoute.queryParams
.pipe(
tap((qParams: Params) => {
if (qParams.email != null && qParams.email.indexOf("@") > -1) {
this.email = qParams.email;
}
private handleQueryParams(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;
}
if (qParams.orgSponsoredFreeFamilyPlanToken != null) {
this.orgSponsoredFreeFamilyPlanToken = qParams.orgSponsoredFreeFamilyPlanToken;
}
if (qParams.orgSponsoredFreeFamilyPlanToken != null) {
this.orgSponsoredFreeFamilyPlanToken = qParams.orgSponsoredFreeFamilyPlanToken;
}
if (qParams.acceptEmergencyAccessInviteToken != null && qParams.emergencyAccessId) {
this.acceptEmergencyAccessInviteToken = qParams.acceptEmergencyAccessInviteToken;
this.emergencyAccessId = qParams.emergencyAccessId;
}
}),
switchMap((qParams: Params) => {
if (
qParams.fromEmail &&
qParams.fromEmail === "true" &&
this.email &&
this.emailVerificationToken
) {
return from(
this.registerVerificationEmailClicked(this.email, this.emailVerificationToken),
);
} else {
// org invite flow
this.loading = false;
return EMPTY;
}
}),
if (qParams.acceptEmergencyAccessInviteToken != null && qParams.emergencyAccessId) {
this.acceptEmergencyAccessInviteToken = qParams.acceptEmergencyAccessInviteToken;
this.emergencyAccessId = qParams.emergencyAccessId;
}
}
takeUntil(this.destroy$),
)
.subscribe();
private async initOrgInviteFlowIfPresent(): Promise<boolean> {
this.masterPasswordPolicyOptions =
await this.registrationFinishService.getMasterPasswordPolicyOptsFromOrgInvite();
const orgName = await this.registrationFinishService.getOrgNameFromOrgInvite();
if (orgName) {
// Org invite exists
// Set the page title and subtitle appropriately
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
pageTitle: {
key: "joinOrganizationName",
placeholders: [orgName],
},
pageSubtitle: {
key: "finishJoiningThisOrganizationBySettingAMasterPassword",
},
});
return true;
}
return false;
}
async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
@@ -162,9 +180,24 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
this.submitting = false;
}
private setDefaultPageTitleAndSubtitle() {
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
pageTitle: {
key: "setAStrongPassword",
},
pageSubtitle: {
key: "finishCreatingYourAccountBySettingAPassword",
},
});
}
private async initEmailVerificationFlow() {
this.setDefaultPageTitleAndSubtitle();
await this.registerVerificationEmailClicked(this.email, this.emailVerificationToken);
}
private async registerVerificationEmailClicked(email: string, emailVerificationToken: string) {
const request = new RegisterVerificationEmailClickedRequest(email, emailVerificationToken);
try {
const result = await this.accountApiService.registerVerificationEmailClicked(request);
@@ -174,11 +207,9 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
message: this.i18nService.t("emailVerifiedV2"),
variant: "success",
});
this.loading = false;
}
} catch (e) {
await this.handleRegisterVerificationEmailClickedError(e);
this.loading = false;
}
}
@@ -204,6 +235,10 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
}
}
private initRegistrationWithEmailVerificationDisabledFlow() {
this.setDefaultPageTitleAndSubtitle();
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();