From 8b64087b32d9e44105e2d037e600514de46627ef Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Mon, 14 Apr 2025 14:41:08 +0200 Subject: [PATCH] [PM-18040] Inject ipc content script dynamically (#13674) * feat: add content script manager * feat: inject into all pages * feat: only inject if flag is enabled * fix: wrong constructor parameters --- .../browser/src/background/main.background.ts | 3 ++ .../ipc/ipc-content-script-manager.service.ts | 42 +++++++++++++++++++ libs/common/src/enums/feature-flag.enum.ts | 6 +++ 3 files changed, 51 insertions(+) create mode 100644 apps/browser/src/platform/ipc/ipc-content-script-manager.service.ts diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 709d64f2094..a5001e0c5b7 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -261,6 +261,7 @@ import VaultTimeoutService from "../key-management/vault-timeout/vault-timeout.s import { BrowserApi } from "../platform/browser/browser-api"; import { flagEnabled } from "../platform/flags"; import { IpcBackgroundService } from "../platform/ipc/ipc-background.service"; +import { IpcContentScriptManagerService } from "../platform/ipc/ipc-content-script-manager.service"; import { UpdateBadge } from "../platform/listeners/update-badge"; /* eslint-disable no-restricted-imports */ import { ChromeMessageSender } from "../platform/messaging/chrome-message.sender"; @@ -405,6 +406,7 @@ export default class MainBackground { inlineMenuFieldQualificationService: InlineMenuFieldQualificationService; taskService: TaskService; + ipcContentScriptManagerService: IpcContentScriptManagerService; ipcService: IpcService; onUpdatedRan: boolean; @@ -1314,6 +1316,7 @@ export default class MainBackground { this.inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService(); + this.ipcContentScriptManagerService = new IpcContentScriptManagerService(this.configService); this.ipcService = new IpcBackgroundService(this.logService); } diff --git a/apps/browser/src/platform/ipc/ipc-content-script-manager.service.ts b/apps/browser/src/platform/ipc/ipc-content-script-manager.service.ts new file mode 100644 index 00000000000..e5fe95e2018 --- /dev/null +++ b/apps/browser/src/platform/ipc/ipc-content-script-manager.service.ts @@ -0,0 +1,42 @@ +import { mergeMap } from "rxjs"; + +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; + +import { BrowserApi } from "../browser/browser-api"; + +const IPC_CONTENT_SCRIPT_ID = "ipc-content-script"; + +export class IpcContentScriptManagerService { + constructor(configService: ConfigService) { + if (!BrowserApi.isManifestVersion(3)) { + // IPC not supported on MV2 + return; + } + + configService + .getFeatureFlag$(FeatureFlag.IpcChannelFramework) + .pipe( + mergeMap(async (enabled) => { + if (!enabled) { + return; + } + + try { + await BrowserApi.unregisterContentScriptsMv3({ ids: [IPC_CONTENT_SCRIPT_ID] }); + } catch { + // Ignore errors + } + + await BrowserApi.registerContentScriptsMv3([ + { + id: IPC_CONTENT_SCRIPT_ID, + matches: ["https://*/*"], + js: ["content/ipc-content-script.js"], + }, + ]); + }), + ) + .subscribe(); + } +} diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index cd88a415caf..09708859ac8 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -55,6 +55,9 @@ export enum FeatureFlag { VaultBulkManagementAction = "vault-bulk-management-action", SecurityTasks = "security-tasks", CipherKeyEncryption = "cipher-key-encryption", + + /* Platform */ + IpcChannelFramework = "ipc-channel-framework", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -118,6 +121,9 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.PrivateKeyRegeneration]: FALSE, [FeatureFlag.UserKeyRotationV2]: FALSE, [FeatureFlag.PM4154_BulkEncryptionService]: FALSE, + + /* Platform */ + [FeatureFlag.IpcChannelFramework]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue;