mirror of
https://github.com/bitwarden/browser
synced 2026-02-20 11:24:07 +00:00
[PM-26732] Remove Chromium ABE importer feature flag (#19039)
This commit is contained in:
@@ -53,7 +53,6 @@ export enum FeatureFlag {
|
||||
|
||||
/* Tools */
|
||||
UseSdkPasswordGenerators = "pm-19976-use-sdk-password-generators",
|
||||
ChromiumImporterWithABE = "pm-25855-chromium-importer-abe",
|
||||
SendUIRefresh = "pm-28175-send-ui-refresh",
|
||||
SendEmailOTP = "pm-19051-send-email-verification",
|
||||
|
||||
@@ -120,7 +119,6 @@ export const DefaultFeatureFlagValue = {
|
||||
|
||||
/* Tools */
|
||||
[FeatureFlag.UseSdkPasswordGenerators]: FALSE,
|
||||
[FeatureFlag.ChromiumImporterWithABE]: FALSE,
|
||||
[FeatureFlag.SendUIRefresh]: FALSE,
|
||||
[FeatureFlag.SendEmailOTP]: FALSE,
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { combineLatest, map, Observable } from "rxjs";
|
||||
import { map, Observable } from "rxjs";
|
||||
|
||||
import { ClientType, DeviceType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { SemanticLogger } from "@bitwarden/common/tools/log";
|
||||
import { SystemServiceProvider } from "@bitwarden/common/tools/providers";
|
||||
|
||||
import { DataLoader, ImporterMetadata, Importers, ImportersMetadata, Loader } from "../metadata";
|
||||
import { ImporterMetadata, Importers, ImportersMetadata } from "../metadata";
|
||||
import { ImportType } from "../models/import-options";
|
||||
import { availableLoaders } from "../util";
|
||||
|
||||
@@ -15,13 +13,8 @@ export class DefaultImportMetadataService implements ImportMetadataServiceAbstra
|
||||
protected importers: ImportersMetadata = Importers;
|
||||
private logger: SemanticLogger;
|
||||
|
||||
private chromiumWithABE$: Observable<boolean>;
|
||||
|
||||
constructor(protected system: SystemServiceProvider) {
|
||||
this.logger = system.log({ type: "ImportMetadataService" });
|
||||
this.chromiumWithABE$ = this.system.configService.getFeatureFlag$(
|
||||
FeatureFlag.ChromiumImporterWithABE,
|
||||
);
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
@@ -30,13 +23,13 @@ export class DefaultImportMetadataService implements ImportMetadataServiceAbstra
|
||||
|
||||
metadata$(type$: Observable<ImportType>): Observable<ImporterMetadata> {
|
||||
const client = this.system.environment.getClientType();
|
||||
const capabilities$ = combineLatest([type$, this.chromiumWithABE$]).pipe(
|
||||
map(([type, enabled]) => {
|
||||
const capabilities$ = type$.pipe(
|
||||
map((type) => {
|
||||
if (!this.importers) {
|
||||
return { type, loaders: [] };
|
||||
}
|
||||
|
||||
const loaders = this.availableLoaders(this.importers, type, client, enabled);
|
||||
const loaders = availableLoaders(this.importers, type, client);
|
||||
|
||||
if (!loaders || loaders.length === 0) {
|
||||
return { type, loaders: [] };
|
||||
@@ -55,34 +48,4 @@ export class DefaultImportMetadataService implements ImportMetadataServiceAbstra
|
||||
|
||||
return capabilities$;
|
||||
}
|
||||
|
||||
/** Determine the available loaders for the given import type and client, considering feature flags and environments */
|
||||
private availableLoaders(
|
||||
importers: ImportersMetadata,
|
||||
type: ImportType,
|
||||
client: ClientType,
|
||||
withABESupport: boolean,
|
||||
): DataLoader[] | undefined {
|
||||
let loaders = availableLoaders(importers, type, client);
|
||||
|
||||
if (withABESupport) {
|
||||
return loaders;
|
||||
}
|
||||
|
||||
// Special handling for Brave and Chrome CSV imports on Windows Desktop
|
||||
if (type === "bravecsv" || type === "chromecsv") {
|
||||
try {
|
||||
const device = this.system.environment.getDevice();
|
||||
const isWindowsDesktop = device === DeviceType.WindowsDesktop;
|
||||
if (isWindowsDesktop) {
|
||||
// Exclude the Chromium loader if on Windows Desktop without ABE support
|
||||
loaders = loaders?.filter((loader) => loader !== Loader.chromium);
|
||||
}
|
||||
} catch {
|
||||
loaders = loaders?.filter((loader) => loader !== Loader.chromium);
|
||||
}
|
||||
}
|
||||
|
||||
return loaders;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { BehaviorSubject, Subject, firstValueFrom } from "rxjs";
|
||||
import { Subject, firstValueFrom } from "rxjs";
|
||||
|
||||
import { ClientType } from "@bitwarden/client-type";
|
||||
import { DeviceType } from "@bitwarden/common/enums";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SystemServiceProvider } from "@bitwarden/common/tools/providers";
|
||||
|
||||
@@ -17,13 +15,10 @@ describe("ImportMetadataService", () => {
|
||||
let systemServiceProvider: MockProxy<SystemServiceProvider>;
|
||||
|
||||
beforeEach(() => {
|
||||
const configService = mock<ConfigService>();
|
||||
|
||||
const environment = mock<PlatformUtilsService>();
|
||||
environment.getClientType.mockReturnValue(ClientType.Desktop);
|
||||
|
||||
systemServiceProvider = mock<SystemServiceProvider>({
|
||||
configService,
|
||||
environment,
|
||||
log: jest.fn().mockReturnValue({ debug: jest.fn() }),
|
||||
});
|
||||
@@ -34,7 +29,6 @@ describe("ImportMetadataService", () => {
|
||||
describe("metadata$", () => {
|
||||
let typeSubject: Subject<ImportType>;
|
||||
let mockLogger: { debug: jest.Mock };
|
||||
let featureFlagSubject: BehaviorSubject<boolean>;
|
||||
|
||||
const environment = mock<PlatformUtilsService>();
|
||||
environment.getClientType.mockReturnValue(ClientType.Desktop);
|
||||
@@ -42,13 +36,8 @@ describe("ImportMetadataService", () => {
|
||||
beforeEach(() => {
|
||||
typeSubject = new Subject<ImportType>();
|
||||
mockLogger = { debug: jest.fn() };
|
||||
featureFlagSubject = new BehaviorSubject<boolean>(false);
|
||||
|
||||
const configService = mock<ConfigService>();
|
||||
configService.getFeatureFlag$.mockReturnValue(featureFlagSubject);
|
||||
|
||||
systemServiceProvider = mock<SystemServiceProvider>({
|
||||
configService,
|
||||
environment,
|
||||
log: jest.fn().mockReturnValue(mockLogger),
|
||||
});
|
||||
@@ -78,7 +67,6 @@ describe("ImportMetadataService", () => {
|
||||
|
||||
afterEach(() => {
|
||||
typeSubject.complete();
|
||||
featureFlagSubject.complete();
|
||||
});
|
||||
|
||||
it("should emit metadata when type$ emits", async () => {
|
||||
@@ -129,86 +117,5 @@ describe("ImportMetadataService", () => {
|
||||
"capabilities updated",
|
||||
);
|
||||
});
|
||||
|
||||
it("should update when feature flag changes", async () => {
|
||||
environment.getDevice.mockReturnValue(DeviceType.WindowsDesktop);
|
||||
const testType: ImportType = "bravecsv"; // Use bravecsv which supports chromium loader
|
||||
const emissions: ImporterMetadata[] = [];
|
||||
|
||||
const subscription = sut.metadata$(typeSubject).subscribe((metadata) => {
|
||||
emissions.push(metadata);
|
||||
});
|
||||
|
||||
typeSubject.next(testType);
|
||||
featureFlagSubject.next(true);
|
||||
|
||||
// Wait for emissions
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(emissions).toHaveLength(2);
|
||||
// Disable ABE - chromium loader should be excluded
|
||||
expect(emissions[0].loaders).not.toContain(Loader.chromium);
|
||||
// Enabled ABE - chromium loader should be included
|
||||
expect(emissions[1].loaders).toContain(Loader.chromium);
|
||||
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
|
||||
it("should exclude chromium loader when ABE is disabled and on Windows Desktop", async () => {
|
||||
environment.getDevice.mockReturnValue(DeviceType.WindowsDesktop);
|
||||
const testType: ImportType = "bravecsv"; // bravecsv supports both file and chromium loaders
|
||||
featureFlagSubject.next(false);
|
||||
|
||||
const metadataPromise = firstValueFrom(sut.metadata$(typeSubject));
|
||||
typeSubject.next(testType);
|
||||
|
||||
const result = await metadataPromise;
|
||||
|
||||
expect(result.loaders).not.toContain(Loader.chromium);
|
||||
expect(result.loaders).toContain(Loader.file);
|
||||
});
|
||||
|
||||
it("should exclude chromium loader when ABE is disabled and getDevice throws error", async () => {
|
||||
environment.getDevice.mockImplementation(() => {
|
||||
throw new Error("Device detection failed");
|
||||
});
|
||||
const testType: ImportType = "bravecsv";
|
||||
featureFlagSubject.next(false);
|
||||
|
||||
const metadataPromise = firstValueFrom(sut.metadata$(typeSubject));
|
||||
typeSubject.next(testType);
|
||||
|
||||
const result = await metadataPromise;
|
||||
|
||||
expect(result.loaders).not.toContain(Loader.chromium);
|
||||
expect(result.loaders).toContain(Loader.file);
|
||||
});
|
||||
|
||||
it("should include chromium loader when ABE is disabled and not on Windows Desktop", async () => {
|
||||
environment.getDevice.mockReturnValue(DeviceType.MacOsDesktop);
|
||||
const testType: ImportType = "bravecsv"; // bravecsv supports both file and chromium loaders
|
||||
featureFlagSubject.next(false);
|
||||
|
||||
const metadataPromise = firstValueFrom(sut.metadata$(typeSubject));
|
||||
typeSubject.next(testType);
|
||||
|
||||
const result = await metadataPromise;
|
||||
|
||||
expect(result.loaders).toContain(Loader.chromium);
|
||||
expect(result.loaders).toContain(Loader.file);
|
||||
});
|
||||
|
||||
it("should include chromium loader when ABE is enabled regardless of device", async () => {
|
||||
environment.getDevice.mockReturnValue(DeviceType.MacOsDesktop);
|
||||
const testType: ImportType = "bravecsv"; // bravecsv supports both file and chromium loaders
|
||||
featureFlagSubject.next(true);
|
||||
|
||||
const metadataPromise = firstValueFrom(sut.metadata$(typeSubject));
|
||||
typeSubject.next(testType);
|
||||
|
||||
const result = await metadataPromise;
|
||||
|
||||
expect(result.loaders).toContain(Loader.chromium);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user