mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 21:33:27 +00:00
chore(feature-flag) [PM-22604] Remove 2FA persistence feature flag
* Removed flag. * Fixed tests to no longer reference flag. * Fixed test. * Removed duplicate test class. * Moved files into folders for yubikey and authenticator * Removed TwoFactorAuthEmailComponentService since it is no longer needed * Removed export * Fixed export
This commit is contained in:
@@ -1,112 +0,0 @@
|
|||||||
import { MockProxy, mock } from "jest-mock-extended";
|
|
||||||
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
|
||||||
import { DialogService } from "@bitwarden/components";
|
|
||||||
|
|
||||||
// Must mock modules before importing
|
|
||||||
jest.mock("../popup/utils/auth-popout-window", () => {
|
|
||||||
const originalModule = jest.requireActual("../popup/utils/auth-popout-window");
|
|
||||||
|
|
||||||
return {
|
|
||||||
...originalModule, // avoid losing the original module's exports
|
|
||||||
openTwoFactorAuthEmailPopout: jest.fn(),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock("../../platform/browser/browser-popup-utils", () => ({
|
|
||||||
inPopup: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// FIXME (PM-22628): Popup imports are forbidden in background
|
|
||||||
// eslint-disable-next-line no-restricted-imports
|
|
||||||
import { openTwoFactorAuthEmailPopout } from "../../auth/popup/utils/auth-popout-window";
|
|
||||||
import BrowserPopupUtils from "../../platform/browser/browser-popup-utils";
|
|
||||||
|
|
||||||
import { ExtensionTwoFactorAuthEmailComponentService } from "./extension-two-factor-auth-email-component.service";
|
|
||||||
|
|
||||||
describe("ExtensionTwoFactorAuthEmailComponentService", () => {
|
|
||||||
let extensionTwoFactorAuthEmailComponentService: ExtensionTwoFactorAuthEmailComponentService;
|
|
||||||
|
|
||||||
let dialogService: MockProxy<DialogService>;
|
|
||||||
let window: MockProxy<Window>;
|
|
||||||
let configService: MockProxy<ConfigService>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
|
|
||||||
dialogService = mock<DialogService>();
|
|
||||||
window = mock<Window>();
|
|
||||||
configService = mock<ConfigService>();
|
|
||||||
|
|
||||||
extensionTwoFactorAuthEmailComponentService = new ExtensionTwoFactorAuthEmailComponentService(
|
|
||||||
dialogService,
|
|
||||||
window,
|
|
||||||
configService,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("openPopoutIfApprovedForEmail2fa", () => {
|
|
||||||
it("should open a popout if the user confirms the warning to popout the extension when in the popup", async () => {
|
|
||||||
// Arrange
|
|
||||||
configService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
dialogService.openSimpleDialog.mockResolvedValue(true);
|
|
||||||
|
|
||||||
jest.spyOn(BrowserPopupUtils, "inPopup").mockReturnValue(true);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await extensionTwoFactorAuthEmailComponentService.openPopoutIfApprovedForEmail2fa();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(dialogService.openSimpleDialog).toHaveBeenCalledWith({
|
|
||||||
title: { key: "warning" },
|
|
||||||
content: { key: "popup2faCloseMessage" },
|
|
||||||
type: "warning",
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(openTwoFactorAuthEmailPopout).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not open a popout if the user cancels the warning to popout the extension when in the popup", async () => {
|
|
||||||
// Arrange
|
|
||||||
configService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
dialogService.openSimpleDialog.mockResolvedValue(false);
|
|
||||||
|
|
||||||
jest.spyOn(BrowserPopupUtils, "inPopup").mockReturnValue(true);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await extensionTwoFactorAuthEmailComponentService.openPopoutIfApprovedForEmail2fa();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(dialogService.openSimpleDialog).toHaveBeenCalledWith({
|
|
||||||
title: { key: "warning" },
|
|
||||||
content: { key: "popup2faCloseMessage" },
|
|
||||||
type: "warning",
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(openTwoFactorAuthEmailPopout).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not open a popout if not in the popup", async () => {
|
|
||||||
// Arrange
|
|
||||||
configService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
jest.spyOn(BrowserPopupUtils, "inPopup").mockReturnValue(false);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await extensionTwoFactorAuthEmailComponentService.openPopoutIfApprovedForEmail2fa();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(dialogService.openSimpleDialog).not.toHaveBeenCalled();
|
|
||||||
expect(openTwoFactorAuthEmailPopout).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("does not prompt or open a popout if the feature flag is enabled", async () => {
|
|
||||||
configService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
jest.spyOn(BrowserPopupUtils, "inPopup").mockReturnValue(true);
|
|
||||||
|
|
||||||
await extensionTwoFactorAuthEmailComponentService.openPopoutIfApprovedForEmail2fa();
|
|
||||||
|
|
||||||
expect(dialogService.openSimpleDialog).not.toHaveBeenCalled();
|
|
||||||
expect(openTwoFactorAuthEmailPopout).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import {
|
|
||||||
DefaultTwoFactorAuthEmailComponentService,
|
|
||||||
TwoFactorAuthEmailComponentService,
|
|
||||||
} from "@bitwarden/auth/angular";
|
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
|
||||||
import { DialogService } from "@bitwarden/components";
|
|
||||||
|
|
||||||
// FIXME (PM-22628): Popup imports are forbidden in background
|
|
||||||
// eslint-disable-next-line no-restricted-imports
|
|
||||||
import { openTwoFactorAuthEmailPopout } from "../../auth/popup/utils/auth-popout-window";
|
|
||||||
import BrowserPopupUtils from "../../platform/browser/browser-popup-utils";
|
|
||||||
|
|
||||||
// TODO: popup state persistence should eventually remove the need for this service
|
|
||||||
export class ExtensionTwoFactorAuthEmailComponentService
|
|
||||||
extends DefaultTwoFactorAuthEmailComponentService
|
|
||||||
implements TwoFactorAuthEmailComponentService
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
private dialogService: DialogService,
|
|
||||||
private window: Window,
|
|
||||||
private configService: ConfigService,
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
async openPopoutIfApprovedForEmail2fa(): Promise<void> {
|
|
||||||
const isTwoFactorFormPersistenceEnabled = await this.configService.getFeatureFlag(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isTwoFactorFormPersistenceEnabled) {
|
|
||||||
// If the feature flag is enabled, we don't need to prompt the user to open the popout
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BrowserPopupUtils.inPopup(this.window)) {
|
|
||||||
const confirmed = await this.dialogService.openSimpleDialog({
|
|
||||||
title: { key: "warning" },
|
|
||||||
content: { key: "popup2faCloseMessage" },
|
|
||||||
type: "warning",
|
|
||||||
});
|
|
||||||
if (confirmed) {
|
|
||||||
await openTwoFactorAuthEmailPopout();
|
|
||||||
this.window.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,6 @@ import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.
|
|||||||
import {
|
import {
|
||||||
LoginComponentService,
|
LoginComponentService,
|
||||||
TwoFactorAuthComponentService,
|
TwoFactorAuthComponentService,
|
||||||
TwoFactorAuthEmailComponentService,
|
|
||||||
TwoFactorAuthDuoComponentService,
|
TwoFactorAuthDuoComponentService,
|
||||||
TwoFactorAuthWebAuthnComponentService,
|
TwoFactorAuthWebAuthnComponentService,
|
||||||
SsoComponentService,
|
SsoComponentService,
|
||||||
@@ -147,7 +146,6 @@ import { ExtensionSsoComponentService } from "../../auth/popup/login/extension-s
|
|||||||
import { ExtensionLogoutService } from "../../auth/popup/logout/extension-logout.service";
|
import { ExtensionLogoutService } from "../../auth/popup/logout/extension-logout.service";
|
||||||
import { ExtensionTwoFactorAuthComponentService } from "../../auth/services/extension-two-factor-auth-component.service";
|
import { ExtensionTwoFactorAuthComponentService } from "../../auth/services/extension-two-factor-auth-component.service";
|
||||||
import { ExtensionTwoFactorAuthDuoComponentService } from "../../auth/services/extension-two-factor-auth-duo-component.service";
|
import { ExtensionTwoFactorAuthDuoComponentService } from "../../auth/services/extension-two-factor-auth-duo-component.service";
|
||||||
import { ExtensionTwoFactorAuthEmailComponentService } from "../../auth/services/extension-two-factor-auth-email-component.service";
|
|
||||||
import { ExtensionTwoFactorAuthWebAuthnComponentService } from "../../auth/services/extension-two-factor-auth-webauthn-component.service";
|
import { ExtensionTwoFactorAuthWebAuthnComponentService } from "../../auth/services/extension-two-factor-auth-webauthn-component.service";
|
||||||
import { AutofillService as AutofillServiceAbstraction } from "../../autofill/services/abstractions/autofill.service";
|
import { AutofillService as AutofillServiceAbstraction } from "../../autofill/services/abstractions/autofill.service";
|
||||||
import AutofillService from "../../autofill/services/autofill.service";
|
import AutofillService from "../../autofill/services/autofill.service";
|
||||||
@@ -560,11 +558,6 @@ const safeProviders: SafeProvider[] = [
|
|||||||
useClass: ExtensionTwoFactorAuthComponentService,
|
useClass: ExtensionTwoFactorAuthComponentService,
|
||||||
deps: [WINDOW],
|
deps: [WINDOW],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
|
||||||
provide: TwoFactorAuthEmailComponentService,
|
|
||||||
useClass: ExtensionTwoFactorAuthEmailComponentService,
|
|
||||||
deps: [DialogService, WINDOW, ConfigService],
|
|
||||||
}),
|
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: TwoFactorAuthWebAuthnComponentService,
|
provide: TwoFactorAuthWebAuthnComponentService,
|
||||||
useClass: ExtensionTwoFactorAuthWebAuthnComponentService,
|
useClass: ExtensionTwoFactorAuthWebAuthnComponentService,
|
||||||
|
|||||||
@@ -24,14 +24,12 @@ import {
|
|||||||
DefaultRegistrationFinishService,
|
DefaultRegistrationFinishService,
|
||||||
DefaultSetPasswordJitService,
|
DefaultSetPasswordJitService,
|
||||||
DefaultTwoFactorAuthComponentService,
|
DefaultTwoFactorAuthComponentService,
|
||||||
DefaultTwoFactorAuthEmailComponentService,
|
|
||||||
DefaultTwoFactorAuthWebAuthnComponentService,
|
DefaultTwoFactorAuthWebAuthnComponentService,
|
||||||
LoginComponentService,
|
LoginComponentService,
|
||||||
LoginDecryptionOptionsService,
|
LoginDecryptionOptionsService,
|
||||||
RegistrationFinishService as RegistrationFinishServiceAbstraction,
|
RegistrationFinishService as RegistrationFinishServiceAbstraction,
|
||||||
SetPasswordJitService,
|
SetPasswordJitService,
|
||||||
TwoFactorAuthComponentService,
|
TwoFactorAuthComponentService,
|
||||||
TwoFactorAuthEmailComponentService,
|
|
||||||
TwoFactorAuthWebAuthnComponentService,
|
TwoFactorAuthWebAuthnComponentService,
|
||||||
} from "@bitwarden/auth/angular";
|
} from "@bitwarden/auth/angular";
|
||||||
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
|
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
|
||||||
@@ -1471,11 +1469,6 @@ const safeProviders: SafeProvider[] = [
|
|||||||
useClass: DefaultTwoFactorAuthWebAuthnComponentService,
|
useClass: DefaultTwoFactorAuthWebAuthnComponentService,
|
||||||
deps: [],
|
deps: [],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
|
||||||
provide: TwoFactorAuthEmailComponentService,
|
|
||||||
useClass: DefaultTwoFactorAuthEmailComponentService,
|
|
||||||
deps: [],
|
|
||||||
}),
|
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: ViewCacheService,
|
provide: ViewCacheService,
|
||||||
useExisting: NoopViewCacheService,
|
useExisting: NoopViewCacheService,
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
export * from "./two-factor-auth-email";
|
|
||||||
export * from "./two-factor-auth-duo";
|
export * from "./two-factor-auth-duo";
|
||||||
export * from "./two-factor-auth-webauthn";
|
export * from "./two-factor-auth-webauthn";
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
import { TwoFactorAuthEmailComponentService } from "./two-factor-auth-email-component.service";
|
|
||||||
|
|
||||||
export class DefaultTwoFactorAuthEmailComponentService
|
|
||||||
implements TwoFactorAuthEmailComponentService {
|
|
||||||
// no default implementation
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
export * from "./default-two-factor-auth-email-component.service";
|
|
||||||
export * from "./two-factor-auth-email-component.service";
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
import { TestBed } from "@angular/core/testing";
|
|
||||||
import { mock, MockProxy } from "jest-mock-extended";
|
|
||||||
import { BehaviorSubject } from "rxjs";
|
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
|
||||||
|
|
||||||
import {
|
|
||||||
TwoFactorAuthEmailComponentCache,
|
|
||||||
TwoFactorAuthEmailComponentCacheService,
|
|
||||||
} from "./two-factor-auth-email-component-cache.service";
|
|
||||||
|
|
||||||
describe("TwoFactorAuthEmailCache", () => {
|
|
||||||
describe("fromJSON", () => {
|
|
||||||
it("returns null when input is null", () => {
|
|
||||||
const result = TwoFactorAuthEmailComponentCache.fromJSON(null as any);
|
|
||||||
expect(result).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("creates a TwoFactorAuthEmailCache instance from valid JSON", () => {
|
|
||||||
const jsonData = { emailSent: true };
|
|
||||||
const result = TwoFactorAuthEmailComponentCache.fromJSON(jsonData);
|
|
||||||
|
|
||||||
expect(result).not.toBeNull();
|
|
||||||
expect(result).toBeInstanceOf(TwoFactorAuthEmailComponentCache);
|
|
||||||
expect(result?.emailSent).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("TwoFactorAuthEmailComponentCacheService", () => {
|
|
||||||
let service: TwoFactorAuthEmailComponentCacheService;
|
|
||||||
let mockViewCacheService: MockProxy<ViewCacheService>;
|
|
||||||
let mockConfigService: MockProxy<ConfigService>;
|
|
||||||
let cacheData: BehaviorSubject<TwoFactorAuthEmailComponentCache | null>;
|
|
||||||
let mockSignal: any;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
mockViewCacheService = mock<ViewCacheService>();
|
|
||||||
mockConfigService = mock<ConfigService>();
|
|
||||||
cacheData = new BehaviorSubject<TwoFactorAuthEmailComponentCache | null>(null);
|
|
||||||
mockSignal = jest.fn(() => cacheData.getValue());
|
|
||||||
mockSignal.set = jest.fn((value: TwoFactorAuthEmailComponentCache | null) =>
|
|
||||||
cacheData.next(value),
|
|
||||||
);
|
|
||||||
mockViewCacheService.signal.mockReturnValue(mockSignal);
|
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [
|
|
||||||
TwoFactorAuthEmailComponentCacheService,
|
|
||||||
{ provide: ViewCacheService, useValue: mockViewCacheService },
|
|
||||||
{ provide: ConfigService, useValue: mockConfigService },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
service = TestBed.inject(TwoFactorAuthEmailComponentCacheService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("creates the service", () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("init", () => {
|
|
||||||
it("sets featureEnabled to true when flag is enabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
expect(mockConfigService.getFeatureFlag).toHaveBeenCalledWith(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
|
|
||||||
service.cacheData({ emailSent: true });
|
|
||||||
expect(mockSignal.set).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("sets featureEnabled to false when flag is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
expect(mockConfigService.getFeatureFlag).toHaveBeenCalledWith(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
|
|
||||||
service.cacheData({ emailSent: true });
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("cacheData", () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("caches email sent state when feature is enabled", () => {
|
|
||||||
service.cacheData({ emailSent: true });
|
|
||||||
|
|
||||||
expect(mockSignal.set).toHaveBeenCalledWith({
|
|
||||||
emailSent: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("does not cache data when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
service.cacheData({ emailSent: true });
|
|
||||||
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("clearCachedData", () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("clears cached data when feature is enabled", () => {
|
|
||||||
service.clearCachedData();
|
|
||||||
|
|
||||||
expect(mockSignal.set).toHaveBeenCalledWith(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("does not clear cached data when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
service.clearCachedData();
|
|
||||||
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("getCachedData", () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns cached data when feature is enabled", () => {
|
|
||||||
const testData = new TwoFactorAuthEmailComponentCache();
|
|
||||||
testData.emailSent = true;
|
|
||||||
cacheData.next(testData);
|
|
||||||
|
|
||||||
const result = service.getCachedData();
|
|
||||||
|
|
||||||
expect(result).toEqual(testData);
|
|
||||||
expect(mockSignal).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns null when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
const result = service.getCachedData();
|
|
||||||
|
|
||||||
expect(result).toBeNull();
|
|
||||||
expect(mockSignal).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -3,7 +3,6 @@ import { mock, MockProxy } from "jest-mock-extended";
|
|||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -61,87 +60,26 @@ describe("TwoFactorAuthEmailComponentCacheService", () => {
|
|||||||
expect(service).toBeTruthy();
|
expect(service).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("init", () => {
|
|
||||||
it("sets featureEnabled to true when flag is enabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
expect(mockConfigService.getFeatureFlag).toHaveBeenCalledWith(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
|
|
||||||
service.cacheData({ emailSent: true });
|
|
||||||
expect(mockSignal.set).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("sets featureEnabled to false when flag is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
expect(mockConfigService.getFeatureFlag).toHaveBeenCalledWith(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
|
|
||||||
service.cacheData({ emailSent: true });
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("cacheData", () => {
|
describe("cacheData", () => {
|
||||||
beforeEach(async () => {
|
it("caches email sent state", () => {
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("caches email sent state when feature is enabled", () => {
|
|
||||||
service.cacheData({ emailSent: true });
|
service.cacheData({ emailSent: true });
|
||||||
|
|
||||||
expect(mockSignal.set).toHaveBeenCalledWith({
|
expect(mockSignal.set).toHaveBeenCalledWith({
|
||||||
emailSent: true,
|
emailSent: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not cache data when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
service.cacheData({ emailSent: true });
|
|
||||||
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("clearCachedData", () => {
|
describe("clearCachedData", () => {
|
||||||
beforeEach(async () => {
|
it("clears cached data", () => {
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("clears cached data when feature is enabled", () => {
|
|
||||||
service.clearCachedData();
|
service.clearCachedData();
|
||||||
|
|
||||||
expect(mockSignal.set).toHaveBeenCalledWith(null);
|
expect(mockSignal.set).toHaveBeenCalledWith(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not clear cached data when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
service.clearCachedData();
|
|
||||||
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getCachedData", () => {
|
describe("getCachedData", () => {
|
||||||
beforeEach(async () => {
|
it("returns cached data", () => {
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns cached data when feature is enabled", () => {
|
|
||||||
const testData = new TwoFactorAuthEmailComponentCache();
|
const testData = new TwoFactorAuthEmailComponentCache();
|
||||||
testData.emailSent = true;
|
testData.emailSent = true;
|
||||||
cacheData.next(testData);
|
cacheData.next(testData);
|
||||||
@@ -151,15 +89,5 @@ describe("TwoFactorAuthEmailComponentCacheService", () => {
|
|||||||
expect(result).toEqual(testData);
|
expect(result).toEqual(testData);
|
||||||
expect(mockSignal).toHaveBeenCalled();
|
expect(mockSignal).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns null when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
const result = service.getCachedData();
|
|
||||||
|
|
||||||
expect(result).toBeNull();
|
|
||||||
expect(mockSignal).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ import { inject, Injectable, WritableSignal } from "@angular/core";
|
|||||||
import { Jsonify } from "type-fest";
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The key for the email two factor auth component cache.
|
* The key for the email two factor auth component cache.
|
||||||
@@ -34,10 +32,6 @@ export class TwoFactorAuthEmailComponentCache {
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class TwoFactorAuthEmailComponentCacheService {
|
export class TwoFactorAuthEmailComponentCacheService {
|
||||||
private viewCacheService: ViewCacheService = inject(ViewCacheService);
|
private viewCacheService: ViewCacheService = inject(ViewCacheService);
|
||||||
private configService: ConfigService = inject(ConfigService);
|
|
||||||
|
|
||||||
/** True when the feature flag is enabled */
|
|
||||||
private featureEnabled: boolean = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signal for the cached email state.
|
* Signal for the cached email state.
|
||||||
@@ -49,23 +43,10 @@ export class TwoFactorAuthEmailComponentCacheService {
|
|||||||
deserializer: TwoFactorAuthEmailComponentCache.fromJSON,
|
deserializer: TwoFactorAuthEmailComponentCache.fromJSON,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Must be called once before interacting with the cached data.
|
|
||||||
*/
|
|
||||||
async init() {
|
|
||||||
this.featureEnabled = await this.configService.getFeatureFlag(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache the email sent state.
|
* Cache the email sent state.
|
||||||
*/
|
*/
|
||||||
cacheData(data: { emailSent: boolean }): void {
|
cacheData(data: { emailSent: boolean }): void {
|
||||||
if (!this.featureEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.emailCache.set({
|
this.emailCache.set({
|
||||||
emailSent: data.emailSent,
|
emailSent: data.emailSent,
|
||||||
} as TwoFactorAuthEmailComponentCache);
|
} as TwoFactorAuthEmailComponentCache);
|
||||||
@@ -75,10 +56,6 @@ export class TwoFactorAuthEmailComponentCacheService {
|
|||||||
* Clear the cached email data.
|
* Clear the cached email data.
|
||||||
*/
|
*/
|
||||||
clearCachedData(): void {
|
clearCachedData(): void {
|
||||||
if (!this.featureEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.emailCache.set(null);
|
this.emailCache.set(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,10 +63,6 @@ export class TwoFactorAuthEmailComponentCacheService {
|
|||||||
* Get whether the email has been sent.
|
* Get whether the email has been sent.
|
||||||
*/
|
*/
|
||||||
getCachedData(): TwoFactorAuthEmailComponentCache | null {
|
getCachedData(): TwoFactorAuthEmailComponentCache | null {
|
||||||
if (!this.featureEnabled) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.emailCache();
|
return this.emailCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* A service that manages all cross client functionality for the email 2FA component.
|
|
||||||
*/
|
|
||||||
export abstract class TwoFactorAuthEmailComponentService {
|
|
||||||
/**
|
|
||||||
* Optionally shows a warning to the user that they might need to popout the
|
|
||||||
* window to complete email 2FA.
|
|
||||||
*/
|
|
||||||
abstract openPopoutIfApprovedForEmail2fa?(): Promise<void>;
|
|
||||||
}
|
|
||||||
@@ -25,7 +25,6 @@ import {
|
|||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
|
|
||||||
import { TwoFactorAuthEmailComponentCacheService } from "./two-factor-auth-email-component-cache.service";
|
import { TwoFactorAuthEmailComponentCacheService } from "./two-factor-auth-email-component-cache.service";
|
||||||
import { TwoFactorAuthEmailComponentService } from "./two-factor-auth-email-component.service";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-two-factor-auth-email",
|
selector: "app-two-factor-auth-email",
|
||||||
@@ -66,14 +65,10 @@ export class TwoFactorAuthEmailComponent implements OnInit {
|
|||||||
protected apiService: ApiService,
|
protected apiService: ApiService,
|
||||||
protected appIdService: AppIdService,
|
protected appIdService: AppIdService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
private twoFactorAuthEmailComponentService: TwoFactorAuthEmailComponentService,
|
|
||||||
private cacheService: TwoFactorAuthEmailComponentCacheService,
|
private cacheService: TwoFactorAuthEmailComponentCacheService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
await this.twoFactorAuthEmailComponentService.openPopoutIfApprovedForEmail2fa?.();
|
|
||||||
await this.cacheService.init();
|
|
||||||
|
|
||||||
// Check if email was already sent
|
// Check if email was already sent
|
||||||
const cachedData = this.cacheService.getCachedData();
|
const cachedData = this.cacheService.getCachedData();
|
||||||
if (cachedData?.emailSent) {
|
if (cachedData?.emailSent) {
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import { BehaviorSubject } from "rxjs";
|
|||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TwoFactorAuthComponentCache,
|
TwoFactorAuthComponentCache,
|
||||||
@@ -40,13 +38,11 @@ describe("TwoFactorAuthCache", () => {
|
|||||||
describe("TwoFactorAuthComponentCacheService", () => {
|
describe("TwoFactorAuthComponentCacheService", () => {
|
||||||
let service: TwoFactorAuthComponentCacheService;
|
let service: TwoFactorAuthComponentCacheService;
|
||||||
let mockViewCacheService: MockProxy<ViewCacheService>;
|
let mockViewCacheService: MockProxy<ViewCacheService>;
|
||||||
let mockConfigService: MockProxy<ConfigService>;
|
|
||||||
let cacheData: BehaviorSubject<TwoFactorAuthComponentCache | null>;
|
let cacheData: BehaviorSubject<TwoFactorAuthComponentCache | null>;
|
||||||
let mockSignal: any;
|
let mockSignal: any;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockViewCacheService = mock<ViewCacheService>();
|
mockViewCacheService = mock<ViewCacheService>();
|
||||||
mockConfigService = mock<ConfigService>();
|
|
||||||
cacheData = new BehaviorSubject<TwoFactorAuthComponentCache | null>(null);
|
cacheData = new BehaviorSubject<TwoFactorAuthComponentCache | null>(null);
|
||||||
mockSignal = jest.fn(() => cacheData.getValue());
|
mockSignal = jest.fn(() => cacheData.getValue());
|
||||||
mockSignal.set = jest.fn((value: TwoFactorAuthComponentCache | null) => cacheData.next(value));
|
mockSignal.set = jest.fn((value: TwoFactorAuthComponentCache | null) => cacheData.next(value));
|
||||||
@@ -56,7 +52,6 @@ describe("TwoFactorAuthComponentCacheService", () => {
|
|||||||
providers: [
|
providers: [
|
||||||
TwoFactorAuthComponentCacheService,
|
TwoFactorAuthComponentCacheService,
|
||||||
{ provide: ViewCacheService, useValue: mockViewCacheService },
|
{ provide: ViewCacheService, useValue: mockViewCacheService },
|
||||||
{ provide: ConfigService, useValue: mockConfigService },
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -67,41 +62,8 @@ describe("TwoFactorAuthComponentCacheService", () => {
|
|||||||
expect(service).toBeTruthy();
|
expect(service).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("init", () => {
|
|
||||||
it("sets featureEnabled to true when flag is enabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
expect(mockConfigService.getFeatureFlag).toHaveBeenCalledWith(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
|
|
||||||
service.cacheData({ token: "123456" });
|
|
||||||
expect(mockSignal.set).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("sets featureEnabled to false when flag is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
expect(mockConfigService.getFeatureFlag).toHaveBeenCalledWith(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
|
|
||||||
service.cacheData({ token: "123456" });
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("cacheData", () => {
|
describe("cacheData", () => {
|
||||||
beforeEach(async () => {
|
it("caches complete data", () => {
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("caches complete data when feature is enabled", () => {
|
|
||||||
const testData: TwoFactorAuthComponentData = {
|
const testData: TwoFactorAuthComponentData = {
|
||||||
token: "123456",
|
token: "123456",
|
||||||
remember: true,
|
remember: true,
|
||||||
@@ -117,7 +79,7 @@ describe("TwoFactorAuthComponentCacheService", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("caches partial data when feature is enabled", () => {
|
it("caches partial data", () => {
|
||||||
service.cacheData({ token: "123456" });
|
service.cacheData({ token: "123456" });
|
||||||
|
|
||||||
expect(mockSignal.set).toHaveBeenCalledWith({
|
expect(mockSignal.set).toHaveBeenCalledWith({
|
||||||
@@ -126,46 +88,18 @@ describe("TwoFactorAuthComponentCacheService", () => {
|
|||||||
selectedProviderType: undefined,
|
selectedProviderType: undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not cache data when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
service.cacheData({ token: "123456" });
|
|
||||||
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("clearCachedData", () => {
|
describe("clearCachedData", () => {
|
||||||
beforeEach(async () => {
|
it("clears cached data", () => {
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("clears cached data when feature is enabled", () => {
|
|
||||||
service.clearCachedData();
|
service.clearCachedData();
|
||||||
|
|
||||||
expect(mockSignal.set).toHaveBeenCalledWith(null);
|
expect(mockSignal.set).toHaveBeenCalledWith(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not clear cached data when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
service.clearCachedData();
|
|
||||||
|
|
||||||
expect(mockSignal.set).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getCachedData", () => {
|
describe("getCachedData", () => {
|
||||||
beforeEach(async () => {
|
it("returns cached data", () => {
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
|
||||||
await service.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns cached data when feature is enabled", () => {
|
|
||||||
const testData = new TwoFactorAuthComponentCache();
|
const testData = new TwoFactorAuthComponentCache();
|
||||||
testData.token = "123456";
|
testData.token = "123456";
|
||||||
testData.remember = true;
|
testData.remember = true;
|
||||||
@@ -177,15 +111,5 @@ describe("TwoFactorAuthComponentCacheService", () => {
|
|||||||
expect(result).toEqual(testData);
|
expect(result).toEqual(testData);
|
||||||
expect(mockSignal).toHaveBeenCalled();
|
expect(mockSignal).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns null when feature is disabled", async () => {
|
|
||||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
|
||||||
await service.init();
|
|
||||||
|
|
||||||
const result = service.getCachedData();
|
|
||||||
|
|
||||||
expect(result).toBeNull();
|
|
||||||
expect(mockSignal).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import { Jsonify } from "type-fest";
|
|||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
|
||||||
|
|
||||||
const TWO_FACTOR_AUTH_COMPONENT_CACHE_KEY = "two-factor-auth-component-cache";
|
const TWO_FACTOR_AUTH_COMPONENT_CACHE_KEY = "two-factor-auth-component-cache";
|
||||||
|
|
||||||
@@ -40,10 +38,6 @@ export interface TwoFactorAuthComponentData {
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class TwoFactorAuthComponentCacheService {
|
export class TwoFactorAuthComponentCacheService {
|
||||||
private viewCacheService: ViewCacheService = inject(ViewCacheService);
|
private viewCacheService: ViewCacheService = inject(ViewCacheService);
|
||||||
private configService: ConfigService = inject(ConfigService);
|
|
||||||
|
|
||||||
/** True when the `PM9115_TwoFactorExtensionDataPersistence` flag is enabled */
|
|
||||||
private featureEnabled: boolean = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signal for the cached TwoFactorAuthData.
|
* Signal for the cached TwoFactorAuthData.
|
||||||
@@ -57,23 +51,10 @@ export class TwoFactorAuthComponentCacheService {
|
|||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Must be called once before interacting with the cached data.
|
|
||||||
*/
|
|
||||||
async init() {
|
|
||||||
this.featureEnabled = await this.configService.getFeatureFlag(
|
|
||||||
FeatureFlag.PM9115_TwoFactorExtensionDataPersistence,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the cache with the new TwoFactorAuthData.
|
* Update the cache with the new TwoFactorAuthData.
|
||||||
*/
|
*/
|
||||||
cacheData(data: TwoFactorAuthComponentData): void {
|
cacheData(data: TwoFactorAuthComponentData): void {
|
||||||
if (!this.featureEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.twoFactorAuthComponentCache.set({
|
this.twoFactorAuthComponentCache.set({
|
||||||
token: data.token,
|
token: data.token,
|
||||||
remember: data.remember,
|
remember: data.remember,
|
||||||
@@ -85,10 +66,6 @@ export class TwoFactorAuthComponentCacheService {
|
|||||||
* Clears the cached TwoFactorAuthData.
|
* Clears the cached TwoFactorAuthData.
|
||||||
*/
|
*/
|
||||||
clearCachedData(): void {
|
clearCachedData(): void {
|
||||||
if (!this.featureEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.twoFactorAuthComponentCache.set(null);
|
this.twoFactorAuthComponentCache.set(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,10 +73,6 @@ export class TwoFactorAuthComponentCacheService {
|
|||||||
* Returns the cached TwoFactorAuthData (when available).
|
* Returns the cached TwoFactorAuthData (when available).
|
||||||
*/
|
*/
|
||||||
getCachedData(): TwoFactorAuthComponentCache | null {
|
getCachedData(): TwoFactorAuthComponentCache | null {
|
||||||
if (!this.featureEnabled) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.twoFactorAuthComponentCache();
|
return this.twoFactorAuthComponentCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ describe("TwoFactorAuthComponent", () => {
|
|||||||
|
|
||||||
mockTwoFactorAuthCompCacheService = mock<TwoFactorAuthComponentCacheService>();
|
mockTwoFactorAuthCompCacheService = mock<TwoFactorAuthComponentCacheService>();
|
||||||
mockTwoFactorAuthCompCacheService.getCachedData.mockReturnValue(null);
|
mockTwoFactorAuthCompCacheService.getCachedData.mockReturnValue(null);
|
||||||
mockTwoFactorAuthCompCacheService.init.mockResolvedValue();
|
|
||||||
|
|
||||||
mockUserDecryptionOpts = {
|
mockUserDecryptionOpts = {
|
||||||
noMasterPassword: new UserDecryptionOptions({
|
noMasterPassword: new UserDecryptionOptions({
|
||||||
|
|||||||
@@ -60,11 +60,11 @@ import {
|
|||||||
TwoFactorAuthDuoIcon,
|
TwoFactorAuthDuoIcon,
|
||||||
} from "../icons/two-factor-auth";
|
} from "../icons/two-factor-auth";
|
||||||
|
|
||||||
import { TwoFactorAuthAuthenticatorComponent } from "./child-components/two-factor-auth-authenticator.component";
|
import { TwoFactorAuthAuthenticatorComponent } from "./child-components/two-factor-auth-authenticator/two-factor-auth-authenticator.component";
|
||||||
import { TwoFactorAuthDuoComponent } from "./child-components/two-factor-auth-duo/two-factor-auth-duo.component";
|
import { TwoFactorAuthDuoComponent } from "./child-components/two-factor-auth-duo/two-factor-auth-duo.component";
|
||||||
import { TwoFactorAuthEmailComponent } from "./child-components/two-factor-auth-email/two-factor-auth-email.component";
|
import { TwoFactorAuthEmailComponent } from "./child-components/two-factor-auth-email/two-factor-auth-email.component";
|
||||||
import { TwoFactorAuthWebAuthnComponent } from "./child-components/two-factor-auth-webauthn/two-factor-auth-webauthn.component";
|
import { TwoFactorAuthWebAuthnComponent } from "./child-components/two-factor-auth-webauthn/two-factor-auth-webauthn.component";
|
||||||
import { TwoFactorAuthYubikeyComponent } from "./child-components/two-factor-auth-yubikey.component";
|
import { TwoFactorAuthYubikeyComponent } from "./child-components/two-factor-auth-yubikey/two-factor-auth-yubikey.component";
|
||||||
import {
|
import {
|
||||||
TwoFactorAuthComponentCacheService,
|
TwoFactorAuthComponentCacheService,
|
||||||
TwoFactorAuthComponentData,
|
TwoFactorAuthComponentData,
|
||||||
@@ -180,9 +180,6 @@ export class TwoFactorAuthComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.listenForAuthnSessionTimeout();
|
this.listenForAuthnSessionTimeout();
|
||||||
|
|
||||||
// Initialize the cache
|
|
||||||
await this.twoFactorAuthComponentCacheService.init();
|
|
||||||
|
|
||||||
// Load cached form data if available
|
// Load cached form data if available
|
||||||
let loadedCachedProviderType = false;
|
let loadedCachedProviderType = false;
|
||||||
const cachedData = this.twoFactorAuthComponentCacheService.getCachedData();
|
const cachedData = this.twoFactorAuthComponentCacheService.getCachedData();
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ export enum FeatureFlag {
|
|||||||
/* Auth */
|
/* Auth */
|
||||||
PM16117_SetInitialPasswordRefactor = "pm-16117-set-initial-password-refactor",
|
PM16117_SetInitialPasswordRefactor = "pm-16117-set-initial-password-refactor",
|
||||||
PM16117_ChangeExistingPasswordRefactor = "pm-16117-change-existing-password-refactor",
|
PM16117_ChangeExistingPasswordRefactor = "pm-16117-change-existing-password-refactor",
|
||||||
PM9115_TwoFactorExtensionDataPersistence = "pm-9115-two-factor-extension-data-persistence",
|
|
||||||
PM14938_BrowserExtensionLoginApproval = "pm-14938-browser-extension-login-approvals",
|
PM14938_BrowserExtensionLoginApproval = "pm-14938-browser-extension-login-approvals",
|
||||||
|
|
||||||
/* Autofill */
|
/* Autofill */
|
||||||
@@ -107,7 +106,6 @@ export const DefaultFeatureFlagValue = {
|
|||||||
/* Auth */
|
/* Auth */
|
||||||
[FeatureFlag.PM16117_SetInitialPasswordRefactor]: FALSE,
|
[FeatureFlag.PM16117_SetInitialPasswordRefactor]: FALSE,
|
||||||
[FeatureFlag.PM16117_ChangeExistingPasswordRefactor]: FALSE,
|
[FeatureFlag.PM16117_ChangeExistingPasswordRefactor]: FALSE,
|
||||||
[FeatureFlag.PM9115_TwoFactorExtensionDataPersistence]: FALSE,
|
|
||||||
[FeatureFlag.PM14938_BrowserExtensionLoginApproval]: FALSE,
|
[FeatureFlag.PM14938_BrowserExtensionLoginApproval]: FALSE,
|
||||||
|
|
||||||
/* Billing */
|
/* Billing */
|
||||||
|
|||||||
Reference in New Issue
Block a user