diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 9959357d850..d2d712154f2 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -3302,12 +3302,6 @@ "loginWithMasterPassword": { "message": "Log in with master password" }, - "loggingInAs": { - "message": "Logging in as" - }, - "notYou": { - "message": "Not you?" - }, "newAroundHere": { "message": "New around here?" }, @@ -3470,9 +3464,6 @@ "requestAdminApproval": { "message": "Request admin approval" }, - "approveWithMasterPassword": { - "message": "Approve with master password" - }, "ssoIdentifierRequired": { "message": "Organization SSO identifier is required." }, diff --git a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.html b/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.html deleted file mode 100644 index e996f9a6ff4..00000000000 --- a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.html +++ /dev/null @@ -1,111 +0,0 @@ -
- -
- -
-

- {{ "loginInitiated" | i18n }} -

-
-
-
-
- -
- - - -
-

{{ "loginInitiated" | i18n }}

-
{{ "deviceApprovalRequired" | i18n }}
-
- -
-
- - -

{{ "uncheckIfPublicDevice" | i18n }}

-
-
- -
- - - -
-
- - -
-

{{ "loginInitiated" | i18n }}

-
- -
-
- - -

{{ "uncheckIfPublicDevice" | i18n }}

-
-
- -
- -
-
- -
- -
-

{{ "loggingInAs" | i18n }} {{ data.userEmail }}

- {{ - "notYou" | i18n - }} -
-
-
-
diff --git a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.ts b/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.ts deleted file mode 100644 index bd8f808c910..00000000000 --- a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Component } from "@angular/core"; -import { firstValueFrom } from "rxjs"; - -import { BaseLoginDecryptionOptionsComponentV1 } from "@bitwarden/angular/auth/components/base-login-decryption-options-v1.component"; - -import { postLogoutMessageListener$ } from "../utils/post-logout-message-listener"; - -@Component({ - selector: "browser-login-decryption-options", - templateUrl: "login-decryption-options-v1.component.html", -}) -export class LoginDecryptionOptionsComponentV1 extends BaseLoginDecryptionOptionsComponentV1 { - override async createUser(): Promise { - try { - await super.createUser(); - await this.router.navigate(["/tabs/vault"]); - } catch (error) { - this.validationService.showError(error); - } - } - - override async logOut(): Promise { - // start listening for "switchAccountFinish" or "doneLoggingOut" - const messagePromise = firstValueFrom(postLogoutMessageListener$); - super.logOut(); - // wait for messages - const command = await messagePromise; - - // We should be routed/routing very soon but just in case, turn loading back off. - this.loading = false; - - // doneLoggingOut already has a message handler that will navigate us - if (command === "switchAccountFinish") { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/"]); - } - } -} diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index 1fa6e8e3d89..80cffa03b17 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -20,7 +20,6 @@ import { AvatarModule, ButtonModule, FormFieldModule, ToastModule } from "@bitwa import { AccountComponent } from "../auth/popup/account-switching/account.component"; import { CurrentAccountComponent } from "../auth/popup/account-switching/current-account.component"; import { ExtensionAnonLayoutWrapperComponent } from "../auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component"; -import { LoginDecryptionOptionsComponentV1 } from "../auth/popup/login-decryption-options/login-decryption-options-v1.component"; import { RemovePasswordComponent } from "../auth/popup/remove-password.component"; import { SetPasswordComponent } from "../auth/popup/set-password.component"; import { AccountSecurityComponent } from "../auth/popup/settings/account-security.component"; @@ -91,7 +90,6 @@ import "../platform/popup/locales"; AppComponent, ColorPasswordPipe, ColorPasswordCountPipe, - LoginDecryptionOptionsComponentV1, SetPasswordComponent, SsoComponentV1, TabsV2Component, diff --git a/apps/browser/src/popup/scss/base.scss b/apps/browser/src/popup/scss/base.scss index 7a8d39c6f3e..59893b5050d 100644 --- a/apps/browser/src/popup/scss/base.scss +++ b/apps/browser/src/popup/scss/base.scss @@ -447,37 +447,3 @@ main:not(popup-page main) { .cdk-virtual-scroll-content-wrapper { width: 100%; } - -#login-initiated { - .margin-auto { - margin: auto; - } - .mb-20px { - margin-bottom: 20px; - } - - .mx-5px { - margin-left: 5px !important; - margin-right: 5px !important; - } - - .muted-hr { - margin-top: 1rem; - margin-bottom: 1rem; - border-top: 1px solid rgba(0, 0, 0, 0.1); - } - - .standard-x-margin { - margin-left: 5px; - margin-right: 5px; - } - - .btn-top-margin { - margin-top: 12px; - } - - #rememberThisDeviceHintText { - font-size: $font-size-small; - color: $text-muted; - } -} diff --git a/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.html b/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.html deleted file mode 100644 index d2abb2071d0..00000000000 --- a/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.html +++ /dev/null @@ -1,66 +0,0 @@ -
-
- Bitwarden - -
- -
- - -

{{ "loginInitiated" | i18n }}

-
- {{ "deviceApprovalRequired" | i18n }} -
- -
-
- -
- {{ "uncheckIfPublicDevice" | i18n }} -
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-

{{ "loggingInAs" | i18n }} {{ data.userEmail }}

- {{ "notYou" | i18n }} -
-
-
-
diff --git a/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.ts b/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.ts deleted file mode 100644 index d9cc07adb7e..00000000000 --- a/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component } from "@angular/core"; - -import { BaseLoginDecryptionOptionsComponentV1 } from "@bitwarden/angular/auth/components/base-login-decryption-options-v1.component"; - -@Component({ - selector: "desktop-login-decryption-options", - templateUrl: "login-decryption-options-v1.component.html", -}) -export class LoginDecryptionOptionsComponentV1 extends BaseLoginDecryptionOptionsComponentV1 { - override async createUser(): Promise { - try { - await super.createUser(); - this.messagingService.send("redrawMenu"); - await this.router.navigate(["/vault"]); - } catch (error) { - this.validationService.showError(error); - } - } -} diff --git a/apps/desktop/src/auth/login/login.module.ts b/apps/desktop/src/auth/login/login.module.ts index 6fe9f9b07d3..601c71e00b1 100644 --- a/apps/desktop/src/auth/login/login.module.ts +++ b/apps/desktop/src/auth/login/login.module.ts @@ -5,11 +5,9 @@ import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components import { SharedModule } from "../../app/shared/shared.module"; -import { LoginDecryptionOptionsComponentV1 } from "./login-decryption-options/login-decryption-options-v1.component"; - @NgModule({ imports: [SharedModule, RouterModule], - declarations: [EnvironmentSelectorComponent, LoginDecryptionOptionsComponentV1], + declarations: [EnvironmentSelectorComponent], exports: [], }) export class LoginModule {} diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 52e277beb23..f93db44aa69 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -2772,15 +2772,9 @@ "loginWithMasterPassword": { "message": "Log in with master password" }, - "loggingInAs": { - "message": "Logging in as" - }, "rememberEmail": { "message": "Remember email" }, - "notYou": { - "message": "Not you?" - }, "newAroundHere": { "message": "New around here?" }, @@ -3020,9 +3014,6 @@ "requestAdminApproval": { "message": "Request admin approval" }, - "approveWithMasterPassword": { - "message": "Approve with master password" - }, "region": { "message": "Region" }, diff --git a/apps/desktop/src/scss/pages.scss b/apps/desktop/src/scss/pages.scss index 5f8f501d420..b9559e13a26 100644 --- a/apps/desktop/src/scss/pages.scss +++ b/apps/desktop/src/scss/pages.scss @@ -1,11 +1,9 @@ @import "variables.scss"; -#login-page, #lock-page, #sso-page, #set-password-page, -#remove-password-page, -#login-decryption-options-page { +#remove-password-page { display: flex; justify-content: center; align-items: center; @@ -48,13 +46,11 @@ } #accessibility-cookie-page, -#login-page, #register-page, #hint-page, #two-factor-page, #lock-page, -#update-temp-password-page, -#login-decryption-options-page { +#update-temp-password-page { .content { width: 325px; transition: width 0.25s linear; @@ -189,37 +185,6 @@ } } -#login-page, -#login-decryption-options-page { - flex-direction: column; - justify-content: unset; - padding-top: 20px; - - .login-header { - align-self: flex-start; - padding: 1em; - font-size: 1.2em; - .environment-urls-settings-icon { - @include themify($themes) { - color: themed("mutedColor"); - } - - span { - visibility: hidden; - } - - &:hover, - &:focus { - text-decoration: none; - - @include themify($themes) { - color: themed("primaryColor"); - } - } - } - } -} - #login-approval-page { .section-title { padding: 20px; @@ -239,14 +204,3 @@ } } } - -#login-decryption-options-page { - .standard-bottom-margin { - margin-bottom: 20px; - } - - #rememberThisDeviceHintText { - font-size: $font-size-small; - color: $text-muted; - } -} diff --git a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.html b/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.html deleted file mode 100644 index 615edb82d0c..00000000000 --- a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.html +++ /dev/null @@ -1,105 +0,0 @@ -
-
-
- -
- - -

- - {{ "loading" | i18n }} -

-
- -
- -

{{ "loginInitiated" | i18n }}

- -

- {{ "deviceApprovalRequired" | i18n }} -

- -
- - - {{ "rememberThisDevice" | i18n }} - {{ "uncheckIfPublicDevice" | i18n }} - -
- -
- - - - - -
-
- - -

{{ "loggedInExclamation" | i18n }}

- -
- - - {{ "rememberThisDevice" | i18n }} - {{ "uncheckIfPublicDevice" | i18n }} - -
- - -
- -
- -
-

{{ "loggingInAs" | i18n }} {{ data.userEmail }}

- {{ "notYou" | i18n }} -
-
-
-
diff --git a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.ts b/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.ts deleted file mode 100644 index 5eb72503b90..00000000000 --- a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Component, inject } from "@angular/core"; - -import { BaseLoginDecryptionOptionsComponentV1 } from "@bitwarden/angular/auth/components/base-login-decryption-options-v1.component"; - -import { RouterService } from "../../../core"; -import { AcceptOrganizationInviteService } from "../../organization-invite/accept-organization.service"; -@Component({ - selector: "web-login-decryption-options", - templateUrl: "login-decryption-options-v1.component.html", -}) -export class LoginDecryptionOptionsComponentV1 extends BaseLoginDecryptionOptionsComponentV1 { - protected routerService = inject(RouterService); - protected acceptOrganizationInviteService = inject(AcceptOrganizationInviteService); - - override async createUser(): Promise { - try { - await super.createUser(); - - // Invites from TDE orgs go through here, but the invite is - // accepted while being enrolled in admin recovery. So we need to clear - // the redirect and stored org invite. - await this.routerService.getAndClearLoginRedirectUrl(); - await this.acceptOrganizationInviteService.clearOrganizationInvitation(); - - await this.router.navigate(["/vault"]); - } catch (error) { - this.validationService.showError(error); - } - } - - createUserAction = async (): Promise => { - return this.createUser(); - }; -} diff --git a/apps/web/src/app/auth/login/login.module.ts b/apps/web/src/app/auth/login/login.module.ts index 12f908324a3..9a99c84f727 100644 --- a/apps/web/src/app/auth/login/login.module.ts +++ b/apps/web/src/app/auth/login/login.module.ts @@ -4,12 +4,11 @@ import { CheckboxModule } from "@bitwarden/components"; import { SharedModule } from "../../../app/shared"; -import { LoginDecryptionOptionsComponentV1 } from "./login-decryption-options/login-decryption-options-v1.component"; import { LoginViaWebAuthnComponent } from "./login-via-webauthn/login-via-webauthn.component"; @NgModule({ imports: [SharedModule, CheckboxModule], - declarations: [LoginDecryptionOptionsComponentV1, LoginViaWebAuthnComponent], - exports: [LoginDecryptionOptionsComponentV1, LoginViaWebAuthnComponent], + declarations: [LoginViaWebAuthnComponent], + exports: [LoginViaWebAuthnComponent], }) export class LoginModule {} diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 0643861db1b..d7e0cf6c130 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -7329,12 +7329,6 @@ "numberOfUsers": { "message": "Number of users" }, - "loggingInAs": { - "message": "Logging in as" - }, - "notYou": { - "message": "Not you?" - }, "pickAnAvatarColor": { "message": "Pick an avatar color" }, @@ -8458,9 +8452,6 @@ "requestAdminApproval": { "message": "Request admin approval" }, - "approveWithMasterPassword": { - "message": "Approve with master password" - }, "trustedDeviceEncryption": { "message": "Trusted device encryption" }, diff --git a/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts b/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts deleted file mode 100644 index 32396c878d9..00000000000 --- a/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts +++ /dev/null @@ -1,307 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Directive, OnDestroy, OnInit } from "@angular/core"; -import { FormBuilder, FormControl } from "@angular/forms"; -import { ActivatedRoute, Router } from "@angular/router"; -import { - firstValueFrom, - switchMap, - Subject, - catchError, - from, - of, - finalize, - takeUntil, - defer, - throwError, - map, - Observable, - take, -} from "rxjs"; - -import { OrganizationUserApiService } from "@bitwarden/admin-console/common"; -import { - LoginEmailServiceAbstraction, - UserDecryptionOptions, - UserDecryptionOptionsServiceAbstraction, -} from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; -import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction"; -import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction"; -import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; -import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; -import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; -import { UserId } from "@bitwarden/common/types/guid"; -import { ToastService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; - -enum State { - NewUser, - ExistingUserUntrustedDevice, -} - -type NewUserData = { - readonly state: State.NewUser; - readonly organizationId: string; - readonly userEmail: string; -}; - -type ExistingUserUntrustedDeviceData = { - readonly state: State.ExistingUserUntrustedDevice; - readonly showApproveFromOtherDeviceBtn: boolean; - readonly showReqAdminApprovalBtn: boolean; - readonly showApproveWithMasterPasswordBtn: boolean; - readonly userEmail: string; -}; - -type Data = NewUserData | ExistingUserUntrustedDeviceData; - -@Directive() -export class BaseLoginDecryptionOptionsComponentV1 implements OnInit, OnDestroy { - private destroy$ = new Subject(); - - protected State = State; - - protected data?: Data; - protected loading = true; - - private email$: Observable; - - activeAccountId: UserId; - - // Remember device means for the user to trust the device - rememberDeviceForm = this.formBuilder.group({ - rememberDevice: [true], - }); - - get rememberDevice(): FormControl { - return this.rememberDeviceForm?.controls.rememberDevice; - } - - constructor( - protected formBuilder: FormBuilder, - protected devicesService: DevicesServiceAbstraction, - protected stateService: StateService, - protected router: Router, - protected activatedRoute: ActivatedRoute, - protected messagingService: MessagingService, - protected tokenService: TokenService, - protected loginEmailService: LoginEmailServiceAbstraction, - protected organizationApiService: OrganizationApiServiceAbstraction, - protected keyService: KeyService, - protected organizationUserApiService: OrganizationUserApiService, - protected apiService: ApiService, - protected i18nService: I18nService, - protected validationService: ValidationService, - protected deviceTrustService: DeviceTrustServiceAbstraction, - protected platformUtilsService: PlatformUtilsService, - protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction, - protected passwordResetEnrollmentService: PasswordResetEnrollmentServiceAbstraction, - protected ssoLoginService: SsoLoginServiceAbstraction, - protected accountService: AccountService, - protected toastService: ToastService, - ) {} - - async ngOnInit() { - this.loading = true; - this.activeAccountId = (await firstValueFrom(this.accountService.activeAccount$))?.id; - this.email$ = this.accountService.activeAccount$.pipe( - map((a) => a?.email), - catchError((err: unknown) => { - this.validationService.showError(err); - return of(undefined); - }), - takeUntil(this.destroy$), - ); - - this.setupRememberDeviceValueChanges(); - - // Persist user choice from state if it exists - await this.setRememberDeviceDefaultValue(); - - try { - const userDecryptionOptions = await firstValueFrom( - this.userDecryptionOptionsService.userDecryptionOptions$, - ); - - // see sso-login.strategy - to determine if a user is new or not it just checks if there is a key on the token response.. - // can we check if they have a user key or master key in crypto service? Would that be sufficient? - if ( - !userDecryptionOptions?.trustedDeviceOption?.hasAdminApproval && - !userDecryptionOptions?.hasMasterPassword - ) { - // We are dealing with a new account if: - // - User does not have admin approval (i.e. has not enrolled into admin reset) - // - AND does not have a master password - - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.loadNewUserData(); - } else { - this.loadUntrustedDeviceData(userDecryptionOptions); - } - - // Note: this is probably not a comprehensive write up of all scenarios: - - // If the TDE feature flag is enabled and TDE is configured for the org that the user is a member of, - // then new and existing users can be redirected here after completing the SSO flow (and 2FA if enabled). - - // First we must determine user type (new or existing): - - // New User - // - present user with option to remember the device or not (trust the device) - // - present a continue button to proceed to the vault - // - loadNewUserData() --> will need to load enrollment status and user email address. - - // Existing User - // - Determine if user is an admin with access to account recovery in admin console - // - Determine if user has a MP or not, if not, they must be redirected to set one (see PM-1035) - // - Determine if device is trusted or not via device crypto service (method not yet written) - // - If not trusted, present user with login decryption options (approve from other device, approve with master password, request admin approval) - // - loadUntrustedDeviceData() - } catch (err) { - this.validationService.showError(err); - } - } - - private async setRememberDeviceDefaultValue() { - const rememberDeviceFromState = await this.deviceTrustService.getShouldTrustDevice( - this.activeAccountId, - ); - - const rememberDevice = rememberDeviceFromState ?? true; - - this.rememberDevice.setValue(rememberDevice); - } - - private setupRememberDeviceValueChanges() { - this.rememberDevice.valueChanges - .pipe( - switchMap((value) => - defer(() => this.deviceTrustService.setShouldTrustDevice(this.activeAccountId, value)), - ), - takeUntil(this.destroy$), - ) - .subscribe(); - } - - async loadNewUserData() { - const autoEnrollStatus$ = defer(() => - this.ssoLoginService.getActiveUserOrganizationSsoIdentifier(this.activeAccountId), - ).pipe( - switchMap((organizationIdentifier) => { - if (organizationIdentifier == undefined) { - return throwError(() => new Error(this.i18nService.t("ssoIdentifierRequired"))); - } - - return from(this.organizationApiService.getAutoEnrollStatus(organizationIdentifier)); - }), - catchError((err: unknown) => { - this.validationService.showError(err); - return of(undefined); - }), - ); - - const autoEnrollStatus = await firstValueFrom(autoEnrollStatus$); - const email = await firstValueFrom(this.email$); - - this.data = { state: State.NewUser, organizationId: autoEnrollStatus.id, userEmail: email }; - this.loading = false; - } - - loadUntrustedDeviceData(userDecryptionOptions: UserDecryptionOptions) { - this.loading = true; - - this.email$ - .pipe( - take(1), - finalize(() => { - this.loading = false; - }), - ) - .subscribe((email) => { - const showApproveFromOtherDeviceBtn = - userDecryptionOptions?.trustedDeviceOption?.hasLoginApprovingDevice || false; - - const showReqAdminApprovalBtn = - !!userDecryptionOptions?.trustedDeviceOption?.hasAdminApproval || false; - - const showApproveWithMasterPasswordBtn = userDecryptionOptions?.hasMasterPassword || false; - - const userEmail = email; - - this.data = { - state: State.ExistingUserUntrustedDevice, - showApproveFromOtherDeviceBtn, - showReqAdminApprovalBtn, - showApproveWithMasterPasswordBtn, - userEmail, - }; - }); - } - - async approveFromOtherDevice() { - if (this.data.state !== State.ExistingUserUntrustedDevice) { - return; - } - - this.loginEmailService.setLoginEmail(this.data.userEmail); - await this.router.navigate(["/login-with-device"]); - } - - async requestAdminApproval() { - this.loginEmailService.setLoginEmail(this.data.userEmail); - await this.router.navigate(["/admin-approval-requested"]); - } - - async approveWithMasterPassword() { - await this.router.navigate(["/lock"], { queryParams: { from: "login-initiated" } }); - } - - async createUser() { - if (this.data.state !== State.NewUser) { - return; - } - - // this.loading to support clients without async-actions-support - this.loading = true; - // errors must be caught in child components to prevent navigation - try { - const { publicKey, privateKey } = await this.keyService.initAccount(); - const keysRequest = new KeysRequest(publicKey, privateKey.encryptedString); - await this.apiService.postAccountKeys(keysRequest); - - this.toastService.showToast({ - variant: "success", - title: null, - message: this.i18nService.t("accountSuccessfullyCreated"), - }); - - await this.passwordResetEnrollmentService.enroll(this.data.organizationId); - - if (this.rememberDeviceForm.value.rememberDevice) { - await this.deviceTrustService.trustDevice(this.activeAccountId); - } - } finally { - this.loading = false; - } - } - - logOut() { - this.loading = true; // to avoid an awkward delay in browser extension - this.messagingService.send("logout"); - } - - ngOnDestroy(): void { - this.destroy$.next(); - this.destroy$.complete(); - } -}