1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 15:23:33 +00:00

[PM-7564] Move 2fa and login strategy service to popup and add state providers to 2fa service (#8820)

* remove 2fa from main.background

* remove login strategy service from main.background

* move 2fa and login strategy service to popup, init in browser

* add state providers to 2fa service
- add deserializer helpers

* use key definitions for global state

* fix calls to 2fa service

* remove extra await

* add delay to wait for active account emission in popup

* add and fix tests

* fix cli

* really fix cli

* remove timeout and wait for active account

* verify expected user is active account

* fix tests

* address feedback
This commit is contained in:
Jake Fink
2024-04-25 16:45:23 -04:00
committed by GitHub
parent cbf7c292f3
commit 8afe915be1
27 changed files with 217 additions and 152 deletions

View File

@@ -253,7 +253,7 @@ describe("SsoComponent", () => {
describe("2FA scenarios", () => {
beforeEach(() => {
const authResult = new AuthResult();
authResult.twoFactorProviders = new Map([[TwoFactorProviderType.Authenticator, {}]]);
authResult.twoFactorProviders = { [TwoFactorProviderType.Authenticator]: {} };
// use standard user with MP because this test is not concerned with password reset.
selectedUserDecryptionOptions.next(mockUserDecryptionOpts.withMasterPassword);

View File

@@ -2,7 +2,10 @@ import { Directive, EventEmitter, OnInit, Output } from "@angular/core";
import { Router } from "@angular/router";
import { firstValueFrom } from "rxjs";
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
import {
TwoFactorProviderDetails,
TwoFactorService,
} from "@bitwarden/common/auth/abstractions/two-factor.service";
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -24,11 +27,11 @@ export class TwoFactorOptionsComponent implements OnInit {
protected environmentService: EnvironmentService,
) {}
ngOnInit() {
this.providers = this.twoFactorService.getSupportedProviders(this.win);
async ngOnInit() {
this.providers = await this.twoFactorService.getSupportedProviders(this.win);
}
choose(p: any) {
async choose(p: TwoFactorProviderDetails) {
this.onProviderSelected.emit(p.type);
}

View File

@@ -102,7 +102,7 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
}
async ngOnInit() {
if (!(await this.authing()) || this.twoFactorService.getProviders() == null) {
if (!(await this.authing()) || (await this.twoFactorService.getProviders()) == null) {
// 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([this.loginRoute]);
@@ -145,7 +145,9 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
);
}
this.selectedProviderType = this.twoFactorService.getDefaultProvider(this.webAuthnSupported);
this.selectedProviderType = await this.twoFactorService.getDefaultProvider(
this.webAuthnSupported,
);
await this.init();
}
@@ -162,12 +164,14 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
this.cleanupWebAuthn();
this.title = (TwoFactorProviders as any)[this.selectedProviderType].name;
const providerData = this.twoFactorService.getProviders().get(this.selectedProviderType);
const providerData = await this.twoFactorService.getProviders().then((providers) => {
return providers.get(this.selectedProviderType);
});
switch (this.selectedProviderType) {
case TwoFactorProviderType.WebAuthn:
if (!this.webAuthnNewTab) {
setTimeout(() => {
this.authWebAuthn();
setTimeout(async () => {
await this.authWebAuthn();
}, 500);
}
break;
@@ -212,7 +216,7 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
break;
case TwoFactorProviderType.Email:
this.twoFactorEmail = providerData.Email;
if (this.twoFactorService.getProviders().size > 1) {
if ((await this.twoFactorService.getProviders()).size > 1) {
await this.sendEmail(false);
}
break;
@@ -474,8 +478,10 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
this.emailPromise = null;
}
authWebAuthn() {
const providerData = this.twoFactorService.getProviders().get(this.selectedProviderType);
async authWebAuthn() {
const providerData = await this.twoFactorService.getProviders().then((providers) => {
return providers.get(this.selectedProviderType);
});
if (!this.webAuthnSupported || this.webAuthn == null) {
return;