From 2d27de8d949ce754e0bfd001c0ae04f6b10efcc1 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 10:05:31 +0100 Subject: [PATCH 01/22] feat: add foreground ipc service --- .../platform/ipc/ipc-foreground.service.ts | 47 +++++++++++++++++++ apps/browser/src/platform/ipc/ipc-link.ts | 26 ++++++++++ apps/browser/src/platform/ipc/ipc-message.ts | 3 ++ 3 files changed, 76 insertions(+) create mode 100644 apps/browser/src/platform/ipc/ipc-foreground.service.ts create mode 100644 apps/browser/src/platform/ipc/ipc-link.ts create mode 100644 apps/browser/src/platform/ipc/ipc-message.ts diff --git a/apps/browser/src/platform/ipc/ipc-foreground.service.ts b/apps/browser/src/platform/ipc/ipc-foreground.service.ts new file mode 100644 index 00000000000..3c091f5a012 --- /dev/null +++ b/apps/browser/src/platform/ipc/ipc-foreground.service.ts @@ -0,0 +1,47 @@ +import { Injectable, OnDestroy } from "@angular/core"; +import { Observable, Subject, switchMap, takeUntil } from "rxjs"; + +import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; +import { Destination } from "@bitwarden/sdk-internal"; + +import { IpcLink } from "./ipc-link"; +import { IpcMessage } from "./ipc-message"; + +@Injectable() +export class IpcForegroundService implements OnDestroy { + private destroy$ = new Subject(); + + private linkToBackground = new IpcLink( + async (data) => { + await chrome.runtime.sendMessage({ payload: data } as IpcMessage); + }, + new Observable((subscriber) => { + const listener = (message: IpcMessage) => { + subscriber.next(message.payload); + }; + chrome.runtime.onMessage.addListener(listener); + + return () => chrome.runtime.onMessage.removeListener(listener); + }), + [Destination.BrowserBackground], + ); + + constructor(private sdkService: SdkService) {} + + init() { + this.sdkService.client$ + .pipe( + switchMap(async (client) => { + const manager = client.ipc().create_manager(); + await manager.register_link(this.linkToBackground); + }), + takeUntil(this.destroy$), + ) + .subscribe(); + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } +} diff --git a/apps/browser/src/platform/ipc/ipc-link.ts b/apps/browser/src/platform/ipc/ipc-link.ts new file mode 100644 index 00000000000..61352a58d1c --- /dev/null +++ b/apps/browser/src/platform/ipc/ipc-link.ts @@ -0,0 +1,26 @@ +import { firstValueFrom, Observable } from "rxjs"; + +import { Destination, Link } from "@bitwarden/sdk-internal"; + +/** + * A caching wrapper around JS transports + */ +export class IpcLink implements Link { + constructor( + private _send: (data: Uint8Array) => Promise, + private _receive: Observable, + private destinations: Destination[], + ) {} + + send(data: Uint8Array): Promise { + return this._send(data); + } + + receive(): Promise { + return firstValueFrom(this._receive); + } + + availableDestinations(): Destination[] { + return this.destinations; + } +} diff --git a/apps/browser/src/platform/ipc/ipc-message.ts b/apps/browser/src/platform/ipc/ipc-message.ts new file mode 100644 index 00000000000..3eb9cb1f550 --- /dev/null +++ b/apps/browser/src/platform/ipc/ipc-message.ts @@ -0,0 +1,3 @@ +export interface IpcMessage { + payload: Uint8Array; +} From 940689b7593afd9ed82b62ef02621b0da99f734a Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 10:22:14 +0100 Subject: [PATCH 02/22] refactor: create abstract ipc service in libs --- .../platform/ipc/ipc-foreground.service.ts | 36 ++++--------------- libs/platform/src/index.ts | 1 + libs/platform/src/ipc/index.ts | 3 ++ .../platform/src}/ipc/ipc-link.ts | 0 .../platform/src}/ipc/ipc-message.ts | 0 libs/platform/src/ipc/ipc.service.ts | 11 ++++++ 6 files changed, 22 insertions(+), 29 deletions(-) create mode 100644 libs/platform/src/ipc/index.ts rename {apps/browser/src/platform => libs/platform/src}/ipc/ipc-link.ts (100%) rename {apps/browser/src/platform => libs/platform/src}/ipc/ipc-message.ts (100%) create mode 100644 libs/platform/src/ipc/ipc.service.ts diff --git a/apps/browser/src/platform/ipc/ipc-foreground.service.ts b/apps/browser/src/platform/ipc/ipc-foreground.service.ts index 3c091f5a012..35de0d3c2bc 100644 --- a/apps/browser/src/platform/ipc/ipc-foreground.service.ts +++ b/apps/browser/src/platform/ipc/ipc-foreground.service.ts @@ -1,17 +1,10 @@ -import { Injectable, OnDestroy } from "@angular/core"; -import { Observable, Subject, switchMap, takeUntil } from "rxjs"; +import { Observable } from "rxjs"; -import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; -import { Destination } from "@bitwarden/sdk-internal"; +import { IpcLink, IpcMessage, IpcService } from "@bitwarden/platform"; +import { Destination, Manager } from "@bitwarden/sdk-internal"; -import { IpcLink } from "./ipc-link"; -import { IpcMessage } from "./ipc-message"; - -@Injectable() -export class IpcForegroundService implements OnDestroy { - private destroy$ = new Subject(); - - private linkToBackground = new IpcLink( +export class IpcForegroundService extends IpcService { + private static LinkToBackground = new IpcLink( async (data) => { await chrome.runtime.sendMessage({ payload: data } as IpcMessage); }, @@ -26,22 +19,7 @@ export class IpcForegroundService implements OnDestroy { [Destination.BrowserBackground], ); - constructor(private sdkService: SdkService) {} - - init() { - this.sdkService.client$ - .pipe( - switchMap(async (client) => { - const manager = client.ipc().create_manager(); - await manager.register_link(this.linkToBackground); - }), - takeUntil(this.destroy$), - ) - .subscribe(); - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); + protected override async registerLinks(manager: Manager): Promise { + await manager.register_link(IpcForegroundService.LinkToBackground); } } diff --git a/libs/platform/src/index.ts b/libs/platform/src/index.ts index f11ec102845..0fe353d86c9 100644 --- a/libs/platform/src/index.ts +++ b/libs/platform/src/index.ts @@ -1 +1,2 @@ export * from "./services/browser-service"; +export * from "./ipc"; diff --git a/libs/platform/src/ipc/index.ts b/libs/platform/src/ipc/index.ts new file mode 100644 index 00000000000..5c42d33bad5 --- /dev/null +++ b/libs/platform/src/ipc/index.ts @@ -0,0 +1,3 @@ +export * from "./ipc-link"; +export * from "./ipc-message"; +export * from "./ipc.service"; diff --git a/apps/browser/src/platform/ipc/ipc-link.ts b/libs/platform/src/ipc/ipc-link.ts similarity index 100% rename from apps/browser/src/platform/ipc/ipc-link.ts rename to libs/platform/src/ipc/ipc-link.ts diff --git a/apps/browser/src/platform/ipc/ipc-message.ts b/libs/platform/src/ipc/ipc-message.ts similarity index 100% rename from apps/browser/src/platform/ipc/ipc-message.ts rename to libs/platform/src/ipc/ipc-message.ts diff --git a/libs/platform/src/ipc/ipc.service.ts b/libs/platform/src/ipc/ipc.service.ts new file mode 100644 index 00000000000..5f07d16c15a --- /dev/null +++ b/libs/platform/src/ipc/ipc.service.ts @@ -0,0 +1,11 @@ +import { Manager } from "@bitwarden/sdk-internal"; + +export abstract class IpcService { + protected manager = new Manager(); + + async init() { + await this.registerLinks(this.manager); + } + + protected abstract registerLinks(manager: Manager): Promise; +} From d02350a732edb54bb96d2539c4a52db106530bf4 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 10:36:56 +0100 Subject: [PATCH 03/22] wip: remove IPC service complexity The code was making some wrong assumptions about how IPC is going to work. I'm removing everything and starting the content-script instead --- .../platform/ipc/ipc-background.service.ts | 3 +++ .../platform/ipc/ipc-foreground.service.ts | 25 ------------------- libs/platform/src/ipc/ipc.service.ts | 6 +---- 3 files changed, 4 insertions(+), 30 deletions(-) create mode 100644 apps/browser/src/platform/ipc/ipc-background.service.ts delete mode 100644 apps/browser/src/platform/ipc/ipc-foreground.service.ts diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts new file mode 100644 index 00000000000..914f9b0e4a2 --- /dev/null +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -0,0 +1,3 @@ +import { IpcService } from "@bitwarden/platform"; + +export class IpcForegroundService extends IpcService {} diff --git a/apps/browser/src/platform/ipc/ipc-foreground.service.ts b/apps/browser/src/platform/ipc/ipc-foreground.service.ts deleted file mode 100644 index 35de0d3c2bc..00000000000 --- a/apps/browser/src/platform/ipc/ipc-foreground.service.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Observable } from "rxjs"; - -import { IpcLink, IpcMessage, IpcService } from "@bitwarden/platform"; -import { Destination, Manager } from "@bitwarden/sdk-internal"; - -export class IpcForegroundService extends IpcService { - private static LinkToBackground = new IpcLink( - async (data) => { - await chrome.runtime.sendMessage({ payload: data } as IpcMessage); - }, - new Observable((subscriber) => { - const listener = (message: IpcMessage) => { - subscriber.next(message.payload); - }; - chrome.runtime.onMessage.addListener(listener); - - return () => chrome.runtime.onMessage.removeListener(listener); - }), - [Destination.BrowserBackground], - ); - - protected override async registerLinks(manager: Manager): Promise { - await manager.register_link(IpcForegroundService.LinkToBackground); - } -} diff --git a/libs/platform/src/ipc/ipc.service.ts b/libs/platform/src/ipc/ipc.service.ts index 5f07d16c15a..7e99e17abf2 100644 --- a/libs/platform/src/ipc/ipc.service.ts +++ b/libs/platform/src/ipc/ipc.service.ts @@ -3,9 +3,5 @@ import { Manager } from "@bitwarden/sdk-internal"; export abstract class IpcService { protected manager = new Manager(); - async init() { - await this.registerLinks(this.manager); - } - - protected abstract registerLinks(manager: Manager): Promise; + async init() {} } From 3e829e01297aca6b0bafd2f32418a48968d6b6af Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 13:33:28 +0100 Subject: [PATCH 04/22] feat: working message sending from page to background --- .../browser/src/background/main.background.ts | 7 ++++++ apps/browser/src/manifest.json | 6 +++++ apps/browser/src/manifest.v3.json | 6 +++++ .../ipc/content/bitwarden-ipc-web-api.ts | 25 +++++++++++++++++++ .../ipc/content/ipc-content-script.ts | 23 +++++++++++++++++ .../platform/ipc/content/ipc-page-script.ts | 10 ++++++++ .../platform/ipc/ipc-background.service.ts | 18 ++++++++++++- apps/browser/webpack.config.js | 1 + libs/platform/src/ipc/ipc.service.ts | 4 +-- 9 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts create mode 100644 apps/browser/src/platform/ipc/content/ipc-content-script.ts create mode 100644 apps/browser/src/platform/ipc/content/ipc-page-script.ts diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 4bec3d6cc0a..02c95655884 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -209,6 +209,7 @@ import { KdfConfigService, KeyService as KeyServiceAbstraction, } from "@bitwarden/key-management"; +import { IpcService } from "@bitwarden/platform"; import { IndividualVaultExportService, IndividualVaultExportServiceAbstraction, @@ -244,6 +245,7 @@ import { SafariApp } from "../browser/safariApp"; import { BackgroundBrowserBiometricsService } from "../key-management/biometrics/background-browser-biometrics.service"; import { BrowserApi } from "../platform/browser/browser-api"; import { flagEnabled } from "../platform/flags"; +import { IpcBackgroundService } from "../platform/ipc/ipc-background.service"; import { UpdateBadge } from "../platform/listeners/update-badge"; /* eslint-disable no-restricted-imports */ import { ChromeMessageSender } from "../platform/messaging/chrome-message.sender"; @@ -383,6 +385,8 @@ export default class MainBackground { cipherAuthorizationService: CipherAuthorizationService; inlineMenuFieldQualificationService: InlineMenuFieldQualificationService; + ipcService: IpcService; + onUpdatedRan: boolean; onReplacedRan: boolean; loginToAutoFill: CipherView = null; @@ -1260,6 +1264,8 @@ export default class MainBackground { ); this.inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService(); + + this.ipcService = new IpcBackgroundService(); } async bootstrap() { @@ -1323,6 +1329,7 @@ export default class MainBackground { } await this.initOverlayAndTabsBackground(); + await this.ipcService.init(); return new Promise((resolve) => { setTimeout(async () => { diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index 9e4eb78291a..c4daaef18bf 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -35,6 +35,12 @@ "js": ["content/lp-fileless-importer.js"], "matches": ["https://lastpass.com/export.php"], "run_at": "document_start" + }, + { + "all_frames": false, + "js": ["content/ipc-content-script.js"], + "matches": ["https://vault.bitwarden.com/*"], + "run_at": "document_start" } ], "background": { diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index ef7ede6b056..b016e6a806d 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -36,6 +36,12 @@ "js": ["content/lp-fileless-importer.js"], "matches": ["https://lastpass.com/export.php"], "run_at": "document_start" + }, + { + "all_frames": false, + "js": ["content/ipc-content-script.js"], + "matches": ["https://vault.bitwarden.com/*"], + "run_at": "document_start" } ], "background": { diff --git a/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts b/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts new file mode 100644 index 00000000000..6e8dce94fe3 --- /dev/null +++ b/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts @@ -0,0 +1,25 @@ +export interface BitwardenIpcWebApi { + /** + * Sends a message to the content script. + * @param payload The message to send. + */ + postMessage(payload: Uint8Array): void; + + /** + * The callback to be called when a message is received. + */ + onMessage?: (payload: Uint8Array) => void; +} + +export interface IpcMessage { + type: "bitwarden-ipc-message"; + payload: Uint8Array; +} + +export function getBitwardenIpcWebApi(): BitwardenIpcWebApi | undefined { + return (window as any).Bitwarden; +} + +export function isIpcMessage(message: any): message is IpcMessage { + return message.type === "bitwarden-ipc-message"; +} diff --git a/apps/browser/src/platform/ipc/content/ipc-content-script.ts b/apps/browser/src/platform/ipc/content/ipc-content-script.ts new file mode 100644 index 00000000000..804a59ab027 --- /dev/null +++ b/apps/browser/src/platform/ipc/content/ipc-content-script.ts @@ -0,0 +1,23 @@ +import { isIpcMessage } from "./bitwarden-ipc-web-api"; + +// TODO: This content script should be dynamically reloaded when the extension is updated, +// to avoid "Extension context invalidated." errors. + +export function sendExtensionMessage(message: unknown) { + if ( + typeof browser !== "undefined" && + typeof browser.runtime !== "undefined" && + typeof browser.runtime.sendMessage !== "undefined" + ) { + void browser.runtime.sendMessage(message); + return; + } + + void chrome.runtime.sendMessage(message); +} + +window.addEventListener("message", (event) => { + if (isIpcMessage(event.data)) { + sendExtensionMessage(event.data); + } +}); diff --git a/apps/browser/src/platform/ipc/content/ipc-page-script.ts b/apps/browser/src/platform/ipc/content/ipc-page-script.ts new file mode 100644 index 00000000000..d4c837c331a --- /dev/null +++ b/apps/browser/src/platform/ipc/content/ipc-page-script.ts @@ -0,0 +1,10 @@ +import { BitwardenIpcWebApi, IpcMessage } from "./bitwarden-ipc-web-api"; + +(window as any).Bitwarden = { + postMessage: (payload) => + window.postMessage( + { type: "bitwarden-ipc-message", payload } as IpcMessage, + window.location.origin, + ), + onMessage: undefined, +} as BitwardenIpcWebApi; diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index 914f9b0e4a2..25458fd51a6 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -1,3 +1,19 @@ import { IpcService } from "@bitwarden/platform"; -export class IpcForegroundService extends IpcService {} +import { BrowserApi } from "../browser/browser-api"; + +import { isIpcMessage } from "./content/bitwarden-ipc-web-api"; + +export class IpcBackgroundService extends IpcService { + override async init() { + await super.init(); + + BrowserApi.messageListener("platform.ipc", (message) => { + if (!isIpcMessage(message)) { + return; + } + + console.log("Received IPC message", message); + }); + } +} diff --git a/apps/browser/webpack.config.js b/apps/browser/webpack.config.js index 6ba74d7df43..4f7de756cc1 100644 --- a/apps/browser/webpack.config.js +++ b/apps/browser/webpack.config.js @@ -194,6 +194,7 @@ const mainConfig = { "content/content-message-handler": "./src/autofill/content/content-message-handler.ts", "content/fido2-content-script": "./src/autofill/fido2/content/fido2-content-script.ts", "content/fido2-page-script": "./src/autofill/fido2/content/fido2-page-script.ts", + "content/ipc-content-script": "./src/platform/ipc/content/ipc-content-script.ts", "notification/bar": "./src/autofill/notification/bar.ts", "overlay/menu-button": "./src/autofill/overlay/inline-menu/pages/button/bootstrap-autofill-inline-menu-button.ts", diff --git a/libs/platform/src/ipc/ipc.service.ts b/libs/platform/src/ipc/ipc.service.ts index 7e99e17abf2..c53fae3faa8 100644 --- a/libs/platform/src/ipc/ipc.service.ts +++ b/libs/platform/src/ipc/ipc.service.ts @@ -1,7 +1,7 @@ -import { Manager } from "@bitwarden/sdk-internal"; +// import { Manager } from "@bitwarden/sdk-internal"; export abstract class IpcService { - protected manager = new Manager(); + // protected manager = new Manager(); async init() {} } From 80c4cce1ce58ddc54eed035a064ac47c58642057 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 14:02:59 +0100 Subject: [PATCH 05/22] refactor: move into common --- apps/browser/src/background/main.background.ts | 2 +- .../ipc/content/bitwarden-ipc-web-api.ts | 13 ------------- .../platform/ipc/content/ipc-content-script.ts | 4 ++-- .../src/platform/ipc/content/ipc-page-script.ts | 10 ---------- .../src/platform/ipc/ipc-background.service.ts | 4 +--- apps/web/src/app/platform/ipc/web-ipc.service.ts | 16 ++++++++++++++++ .../src => common/src/platform}/ipc/index.ts | 0 .../src => common/src/platform}/ipc/ipc-link.ts | 0 libs/common/src/platform/ipc/ipc-message.ts | 8 ++++++++ .../src/platform}/ipc/ipc.service.ts | 4 ++++ libs/platform/src/index.ts | 1 - libs/platform/src/ipc/ipc-message.ts | 3 --- 12 files changed, 32 insertions(+), 33 deletions(-) delete mode 100644 apps/browser/src/platform/ipc/content/ipc-page-script.ts create mode 100644 apps/web/src/app/platform/ipc/web-ipc.service.ts rename libs/{platform/src => common/src/platform}/ipc/index.ts (100%) rename libs/{platform/src => common/src/platform}/ipc/ipc-link.ts (100%) create mode 100644 libs/common/src/platform/ipc/ipc-message.ts rename libs/{platform/src => common/src/platform}/ipc/ipc.service.ts (57%) delete mode 100644 libs/platform/src/ipc/ipc-message.ts diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 02c95655884..555c02b1274 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -100,6 +100,7 @@ import { } from "@bitwarden/common/platform/abstractions/storage.service"; import { SystemService as SystemServiceAbstraction } from "@bitwarden/common/platform/abstractions/system.service"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; +import { IpcService } from "@bitwarden/common/platform/ipc"; import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging"; // eslint-disable-next-line no-restricted-imports -- Used for dependency creation import { SubjectMessageSender } from "@bitwarden/common/platform/messaging/internal"; @@ -209,7 +210,6 @@ import { KdfConfigService, KeyService as KeyServiceAbstraction, } from "@bitwarden/key-management"; -import { IpcService } from "@bitwarden/platform"; import { IndividualVaultExportService, IndividualVaultExportServiceAbstraction, diff --git a/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts b/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts index 6e8dce94fe3..29a27c7053c 100644 --- a/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts +++ b/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts @@ -10,16 +10,3 @@ export interface BitwardenIpcWebApi { */ onMessage?: (payload: Uint8Array) => void; } - -export interface IpcMessage { - type: "bitwarden-ipc-message"; - payload: Uint8Array; -} - -export function getBitwardenIpcWebApi(): BitwardenIpcWebApi | undefined { - return (window as any).Bitwarden; -} - -export function isIpcMessage(message: any): message is IpcMessage { - return message.type === "bitwarden-ipc-message"; -} diff --git a/apps/browser/src/platform/ipc/content/ipc-content-script.ts b/apps/browser/src/platform/ipc/content/ipc-content-script.ts index 804a59ab027..dbb963cd87f 100644 --- a/apps/browser/src/platform/ipc/content/ipc-content-script.ts +++ b/apps/browser/src/platform/ipc/content/ipc-content-script.ts @@ -1,8 +1,8 @@ -import { isIpcMessage } from "./bitwarden-ipc-web-api"; - // TODO: This content script should be dynamically reloaded when the extension is updated, // to avoid "Extension context invalidated." errors. +import { isIpcMessage } from "@bitwarden/common/platform/ipc/ipc-message"; + export function sendExtensionMessage(message: unknown) { if ( typeof browser !== "undefined" && diff --git a/apps/browser/src/platform/ipc/content/ipc-page-script.ts b/apps/browser/src/platform/ipc/content/ipc-page-script.ts deleted file mode 100644 index d4c837c331a..00000000000 --- a/apps/browser/src/platform/ipc/content/ipc-page-script.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BitwardenIpcWebApi, IpcMessage } from "./bitwarden-ipc-web-api"; - -(window as any).Bitwarden = { - postMessage: (payload) => - window.postMessage( - { type: "bitwarden-ipc-message", payload } as IpcMessage, - window.location.origin, - ), - onMessage: undefined, -} as BitwardenIpcWebApi; diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index 25458fd51a6..6c7183bddac 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -1,9 +1,7 @@ -import { IpcService } from "@bitwarden/platform"; +import { IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc"; import { BrowserApi } from "../browser/browser-api"; -import { isIpcMessage } from "./content/bitwarden-ipc-web-api"; - export class IpcBackgroundService extends IpcService { override async init() { await super.init(); diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts new file mode 100644 index 00000000000..daf2630904f --- /dev/null +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -0,0 +1,16 @@ +import { IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc"; + +export class WebIpcService extends IpcService { + override async init() { + await super.init(); + + window.addEventListener("message", (event) => { + const message = event.data; + if (!isIpcMessage(message)) { + return; + } + + console.log("WEB Received IPC message", message); + }); + } +} diff --git a/libs/platform/src/ipc/index.ts b/libs/common/src/platform/ipc/index.ts similarity index 100% rename from libs/platform/src/ipc/index.ts rename to libs/common/src/platform/ipc/index.ts diff --git a/libs/platform/src/ipc/ipc-link.ts b/libs/common/src/platform/ipc/ipc-link.ts similarity index 100% rename from libs/platform/src/ipc/ipc-link.ts rename to libs/common/src/platform/ipc/ipc-link.ts diff --git a/libs/common/src/platform/ipc/ipc-message.ts b/libs/common/src/platform/ipc/ipc-message.ts new file mode 100644 index 00000000000..7fff419edcd --- /dev/null +++ b/libs/common/src/platform/ipc/ipc-message.ts @@ -0,0 +1,8 @@ +export interface IpcMessage { + type: "bitwarden-ipc-message"; + payload: Uint8Array; +} + +export function isIpcMessage(message: any): message is IpcMessage { + return message.type === "bitwarden-ipc-message"; +} diff --git a/libs/platform/src/ipc/ipc.service.ts b/libs/common/src/platform/ipc/ipc.service.ts similarity index 57% rename from libs/platform/src/ipc/ipc.service.ts rename to libs/common/src/platform/ipc/ipc.service.ts index c53fae3faa8..75b8b5ada6a 100644 --- a/libs/platform/src/ipc/ipc.service.ts +++ b/libs/common/src/platform/ipc/ipc.service.ts @@ -1,7 +1,11 @@ // import { Manager } from "@bitwarden/sdk-internal"; +import { SdkService } from "../abstractions/sdk/sdk.service"; + export abstract class IpcService { // protected manager = new Manager(); + constructor(private sdkService: SdkService) {} + async init() {} } diff --git a/libs/platform/src/index.ts b/libs/platform/src/index.ts index 0fe353d86c9..f11ec102845 100644 --- a/libs/platform/src/index.ts +++ b/libs/platform/src/index.ts @@ -1,2 +1 @@ export * from "./services/browser-service"; -export * from "./ipc"; diff --git a/libs/platform/src/ipc/ipc-message.ts b/libs/platform/src/ipc/ipc-message.ts deleted file mode 100644 index 3eb9cb1f550..00000000000 --- a/libs/platform/src/ipc/ipc-message.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IpcMessage { - payload: Uint8Array; -} From 6c620a39a42f75b1d45f87ad0b64a31298ab9684 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 14:33:34 +0100 Subject: [PATCH 06/22] feat: somewhat complete web <-> browser link --- .../browser/src/background/main.background.ts | 2 +- .../platform/ipc/ipc-background.service.ts | 34 +++++++++++++++++-- apps/web/src/app/core/core.module.ts | 7 ++++ apps/web/src/app/core/init.service.ts | 2 ++ .../src/app/platform/ipc/web-ipc.service.ts | 31 ++++++++++++----- libs/common/src/platform/ipc/ipc.service.ts | 12 +++++-- 6 files changed, 72 insertions(+), 16 deletions(-) diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 555c02b1274..6445a45a507 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -1265,7 +1265,7 @@ export default class MainBackground { this.inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService(); - this.ipcService = new IpcBackgroundService(); + this.ipcService = new IpcBackgroundService(this.sdkService); } async bootstrap() { diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index 6c7183bddac..6c4510fc0ec 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -1,17 +1,45 @@ -import { IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc"; +import { Observable } from "rxjs"; + +import { IpcLink, IpcMessage, IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc"; import { BrowserApi } from "../browser/browser-api"; export class IpcBackgroundService extends IpcService { + private links = new Map(); + override async init() { await super.init(); - BrowserApi.messageListener("platform.ipc", (message) => { + BrowserApi.messageListener("platform.ipc", (message, sender) => { if (!isIpcMessage(message)) { return; } - console.log("Received IPC message", message); + if (!this.links.has(sender.documentId)) { + this.links.set( + sender.documentId, + new IpcLink( + async (data) => + BrowserApi.sendMessage("platform.ipc", { + type: "bitwarden-ipc-message", + payload: data, + } satisfies IpcMessage), + new Observable((subscriber) => { + const handler = (message: unknown) => { + if (!isIpcMessage(message)) { + return; + } + subscriber.next(message.payload); + }; + + BrowserApi.addListener(chrome.runtime.onMessage, handler); + + return () => BrowserApi.removeListener(chrome.runtime.onMessage, handler); + }), + [{ Web: sender.documentId }], + ), + ); + } }); } } diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 8f21dfa2c8b..2af718914fd 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -68,6 +68,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; +import { IpcService } from "@bitwarden/common/platform/ipc"; import { AppIdService as DefaultAppIdService } from "@bitwarden/common/platform/services/app-id.service"; import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service"; // eslint-disable-next-line import/no-restricted-paths -- Implementation for memory storage @@ -108,6 +109,7 @@ import { I18nService } from "../core/i18n.service"; import { WebLockComponentService } from "../key-management/lock/services/web-lock-component.service"; import { WebProcessReloadService } from "../key-management/services/web-process-reload.service"; import { WebBiometricsService } from "../key-management/web-biometric.service"; +import { WebIpcService } from "../platform/ipc/web-ipc.service"; import { WebEnvironmentService } from "../platform/web-environment.service"; import { WebMigrationRunner } from "../platform/web-migration-runner"; import { WebSdkClientFactory } from "../platform/web-sdk-client-factory"; @@ -313,6 +315,11 @@ const safeProviders: SafeProvider[] = [ useClass: WebLoginDecryptionOptionsService, deps: [MessagingService, RouterService, AcceptOrganizationInviteService], }), + safeProvider({ + provide: IpcService, + useClass: WebIpcService, + deps: [SdkService], + }), ]; @NgModule({ diff --git a/apps/web/src/app/core/init.service.ts b/apps/web/src/app/core/init.service.ts index b3e6d691f75..1397955f5f3 100644 --- a/apps/web/src/app/core/init.service.ts +++ b/apps/web/src/app/core/init.service.ts @@ -15,6 +15,7 @@ import { ContainerService } from "@bitwarden/common/platform/services/container. import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service"; import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service"; import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service"; +import { IpcService } from "@bitwarden/common/src/platform/ipc"; import { KeyService as KeyServiceAbstraction } from "@bitwarden/key-management"; import { VersionService } from "../platform/version.service"; @@ -58,6 +59,7 @@ export class InitService { htmlEl.classList.add("locale_" + this.i18nService.translationLocale); this.themingService.applyThemeChangesTo(this.document); this.versionService.applyVersionToWindow(); + void this.ipcService.init(); const containerService = new ContainerService(this.keyService, this.encryptService); containerService.attachToGlobal(this.win); diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index daf2630904f..92046979830 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -1,16 +1,29 @@ -import { IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc"; +import { Observable } from "rxjs"; + +import { IpcLink, IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc"; export class WebIpcService extends IpcService { + private static LinkToExtensionBackground = new IpcLink( + async (data) => window.postMessage(data, window.location.origin), + new Observable((subscriber) => { + const listener = (event: MessageEvent) => { + const message = event.data; + if (!isIpcMessage(message)) { + return; + } + + subscriber.next(message.payload); + }; + window.addEventListener("message", listener); + + return () => window.removeEventListener("message", listener); + }), + ["BrowserBackground"], + ); + override async init() { await super.init(); - window.addEventListener("message", (event) => { - const message = event.data; - if (!isIpcMessage(message)) { - return; - } - - console.log("WEB Received IPC message", message); - }); + this.manager.register_link(WebIpcService.LinkToExtensionBackground); } } diff --git a/libs/common/src/platform/ipc/ipc.service.ts b/libs/common/src/platform/ipc/ipc.service.ts index 75b8b5ada6a..121c6f954a9 100644 --- a/libs/common/src/platform/ipc/ipc.service.ts +++ b/libs/common/src/platform/ipc/ipc.service.ts @@ -1,11 +1,17 @@ -// import { Manager } from "@bitwarden/sdk-internal"; +import { firstValueFrom, map } from "rxjs"; + +import { Manager } from "@bitwarden/sdk-internal"; import { SdkService } from "../abstractions/sdk/sdk.service"; export abstract class IpcService { - // protected manager = new Manager(); + protected manager: Manager; constructor(private sdkService: SdkService) {} - async init() {} + async init() { + await firstValueFrom( + this.sdkService.client$.pipe(map((client) => client.ipc().create_manager())), + ); + } } From 4e39a8073f403a3528b4c6ecba1437dd9cb38b39 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 15:19:12 +0100 Subject: [PATCH 07/22] wip: ping command from web --- apps/browser/src/manifest.json | 2 +- apps/browser/src/manifest.v3.json | 2 +- .../src/app/platform/ipc/web-ipc.service.ts | 20 ++++++++++++++++++- libs/common/src/platform/ipc/index.ts | 1 + libs/common/src/platform/ipc/ping.message.ts | 2 ++ 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 libs/common/src/platform/ipc/ping.message.ts diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index c4daaef18bf..50ae1f3c5cc 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -39,7 +39,7 @@ { "all_frames": false, "js": ["content/ipc-content-script.js"], - "matches": ["https://vault.bitwarden.com/*"], + "matches": ["https://vault.bitwarden.com/*", "https://localhost:4200/*"], "run_at": "document_start" } ], diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index b016e6a806d..b2fef94a5dd 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -40,7 +40,7 @@ { "all_frames": false, "js": ["content/ipc-content-script.js"], - "matches": ["https://vault.bitwarden.com/*"], + "matches": ["https://vault.bitwarden.com/*", "https://localhost:4200/*"], "run_at": "document_start" } ], diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index 92046979830..88bc8fd9c73 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -1,6 +1,12 @@ import { Observable } from "rxjs"; -import { IpcLink, IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc"; +import { + IpcLink, + IpcService, + isIpcMessage, + PingMessagePayload, + PongMessagePayload, +} from "@bitwarden/common/platform/ipc"; export class WebIpcService extends IpcService { private static LinkToExtensionBackground = new IpcLink( @@ -25,5 +31,17 @@ export class WebIpcService extends IpcService { await super.init(); this.manager.register_link(WebIpcService.LinkToExtensionBackground); + + void this.ping(); + } + + async ping() { + await this.manager.send("BrowserBackground", PingMessagePayload); + const message = await this.manager.receive("BrowserBackground"); + + if (message[0] === PongMessagePayload[0]) { + // eslint-disable-next-line no-console + console.log("Connected to extension background"); + } } } diff --git a/libs/common/src/platform/ipc/index.ts b/libs/common/src/platform/ipc/index.ts index 5c42d33bad5..5126e9c3141 100644 --- a/libs/common/src/platform/ipc/index.ts +++ b/libs/common/src/platform/ipc/index.ts @@ -1,3 +1,4 @@ export * from "./ipc-link"; export * from "./ipc-message"; export * from "./ipc.service"; +export * from "./ping.message"; diff --git a/libs/common/src/platform/ipc/ping.message.ts b/libs/common/src/platform/ipc/ping.message.ts new file mode 100644 index 00000000000..5be064628a3 --- /dev/null +++ b/libs/common/src/platform/ipc/ping.message.ts @@ -0,0 +1,2 @@ +export const PingMessagePayload = new Uint8Array([9001]); +export const PongMessagePayload = new Uint8Array([9002]); From cae769ad29c004a30b61fcd0bb938eab6ecd190a Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 15:27:07 +0100 Subject: [PATCH 08/22] fix: import path --- apps/web/src/app/core/init.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/app/core/init.service.ts b/apps/web/src/app/core/init.service.ts index 1397955f5f3..df2d6806112 100644 --- a/apps/web/src/app/core/init.service.ts +++ b/apps/web/src/app/core/init.service.ts @@ -11,11 +11,11 @@ import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/comm import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service"; +import { IpcService } from "@bitwarden/common/platform/ipc"; import { ContainerService } from "@bitwarden/common/platform/services/container.service"; import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service"; import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service"; import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service"; -import { IpcService } from "@bitwarden/common/src/platform/ipc"; import { KeyService as KeyServiceAbstraction } from "@bitwarden/key-management"; import { VersionService } from "../platform/version.service"; From 381f79384d8d9f3d57abb660fa0e274dac9aa4b1 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 15:33:28 +0100 Subject: [PATCH 09/22] fix: wip urls --- apps/browser/src/manifest.json | 2 +- apps/browser/src/manifest.v3.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index 50ae1f3c5cc..3b8a7add1e6 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -39,7 +39,7 @@ { "all_frames": false, "js": ["content/ipc-content-script.js"], - "matches": ["https://vault.bitwarden.com/*", "https://localhost:4200/*"], + "matches": ["https://vault.bitwarden.com/*", "https://localhost:8080/*"], "run_at": "document_start" } ], diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index b2fef94a5dd..c961afe2ddb 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -40,7 +40,7 @@ { "all_frames": false, "js": ["content/ipc-content-script.js"], - "matches": ["https://vault.bitwarden.com/*", "https://localhost:4200/*"], + "matches": ["https://vault.bitwarden.com/*", "https://localhost:8080/*"], "run_at": "document_start" } ], From a4fca331f9bd49f736f7648189ba5f04cee2892f Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 17 Dec 2024 15:33:45 +0100 Subject: [PATCH 10/22] wip: add console log --- apps/browser/src/platform/ipc/ipc-background.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index 6c4510fc0ec..f07e083459d 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -16,6 +16,8 @@ export class IpcBackgroundService extends IpcService { } if (!this.links.has(sender.documentId)) { + // eslint-disable-next-line no-console + console.log("New link", message, sender); this.links.set( sender.documentId, new IpcLink( From 452f185496c51c78fc73baeac75e92839d1f661e Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 18 Dec 2024 08:52:32 +0100 Subject: [PATCH 11/22] feat: successfull message sending (not receiving) --- .../src/app/platform/ipc/web-ipc.service.ts | 27 ++++++++++++++----- libs/common/src/platform/ipc/ipc.service.ts | 2 +- libs/common/src/platform/ipc/ping.message.ts | 4 +-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index 88bc8fd9c73..d5ec5bd19e8 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -2,6 +2,7 @@ import { Observable } from "rxjs"; import { IpcLink, + IpcMessage, IpcService, isIpcMessage, PingMessagePayload, @@ -10,7 +11,12 @@ import { export class WebIpcService extends IpcService { private static LinkToExtensionBackground = new IpcLink( - async (data) => window.postMessage(data, window.location.origin), + async (data) => { + window.postMessage( + { type: "bitwarden-ipc-message", payload: data } satisfies IpcMessage, + window.location.origin, + ); + }, new Observable((subscriber) => { const listener = (event: MessageEvent) => { const message = event.data; @@ -36,12 +42,21 @@ export class WebIpcService extends IpcService { } async ping() { - await this.manager.send("BrowserBackground", PingMessagePayload); - const message = await this.manager.receive("BrowserBackground"); - - if (message[0] === PongMessagePayload[0]) { + try { + // eslint-disable-next-line no-console + console.log("[IPC] Pinging"); + await this.manager.send("BrowserBackground", PingMessagePayload); + // eslint-disable-next-line no-console + console.log("[IPC] Sent ping"); + const message = await this.manager.receive("BrowserBackground"); + + if (message[0] === PongMessagePayload[0]) { + // eslint-disable-next-line no-console + console.log("[IPC] Received pong"); + } + } catch (error) { // eslint-disable-next-line no-console - console.log("Connected to extension background"); + console.error("[IPC] Ping failed", error); } } } diff --git a/libs/common/src/platform/ipc/ipc.service.ts b/libs/common/src/platform/ipc/ipc.service.ts index 121c6f954a9..e09c5a5a4bc 100644 --- a/libs/common/src/platform/ipc/ipc.service.ts +++ b/libs/common/src/platform/ipc/ipc.service.ts @@ -10,7 +10,7 @@ export abstract class IpcService { constructor(private sdkService: SdkService) {} async init() { - await firstValueFrom( + this.manager = await firstValueFrom( this.sdkService.client$.pipe(map((client) => client.ipc().create_manager())), ); } diff --git a/libs/common/src/platform/ipc/ping.message.ts b/libs/common/src/platform/ipc/ping.message.ts index 5be064628a3..7ae81922572 100644 --- a/libs/common/src/platform/ipc/ping.message.ts +++ b/libs/common/src/platform/ipc/ping.message.ts @@ -1,2 +1,2 @@ -export const PingMessagePayload = new Uint8Array([9001]); -export const PongMessagePayload = new Uint8Array([9002]); +export const PingMessagePayload = new Uint8Array([90, 1]); +export const PongMessagePayload = new Uint8Array([90, 2]); From d76bf955702531f146f304200a0d909face7f036 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 15 Jan 2025 12:41:14 +0100 Subject: [PATCH 12/22] feat: implement IPC using new refactored framework --- .../ipc/background-communication-provider.ts | 35 ++++++++++ .../platform/ipc/ipc-background.service.ts | 69 +++++++++---------- .../ipc/web-communication-provider.ts | 34 +++++++++ .../src/app/platform/ipc/web-ipc.service.ts | 57 +++++---------- libs/common/src/platform/ipc/index.ts | 1 - libs/common/src/platform/ipc/ipc-link.ts | 26 ------- libs/common/src/platform/ipc/ipc-message.ts | 4 +- libs/common/src/platform/ipc/ipc.service.ts | 34 ++++++--- libs/common/src/platform/ipc/message-queue.ts | 20 ++++++ 9 files changed, 168 insertions(+), 112 deletions(-) create mode 100644 apps/browser/src/platform/ipc/background-communication-provider.ts create mode 100644 apps/web/src/app/platform/ipc/web-communication-provider.ts delete mode 100644 libs/common/src/platform/ipc/ipc-link.ts create mode 100644 libs/common/src/platform/ipc/message-queue.ts diff --git a/apps/browser/src/platform/ipc/background-communication-provider.ts b/apps/browser/src/platform/ipc/background-communication-provider.ts new file mode 100644 index 00000000000..755d0e95360 --- /dev/null +++ b/apps/browser/src/platform/ipc/background-communication-provider.ts @@ -0,0 +1,35 @@ +import { IpcMessage, isIpcMessage } from "@bitwarden/common/platform/ipc"; +import { MessageQueue } from "@bitwarden/common/platform/ipc/message-queue"; +import { CommunicationProvider, Message } from "@bitwarden/sdk-internal"; + +import { BrowserApi } from "../browser/browser-api"; + +export class BackgroundCommunicationProvider implements CommunicationProvider { + private queue = new MessageQueue(); + + constructor() { + // Web listener + BrowserApi.messageListener("platform.ipc", (message, sender) => { + if (!isIpcMessage(message)) { + return; + } + + void this.queue.enqueue({ ...message.message, source: { Web: sender.documentId } }); + }); + } + + async send(message: Message): Promise { + if (typeof message.destination === "object") { + await BrowserApi.sendMessage("platform.ipc", { + type: "bitwarden-ipc-message", + message, + } satisfies IpcMessage); + } + + throw new Error("Destination not supported."); + } + + receive(): Promise { + return this.queue.dequeue(); + } +} diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index f07e083459d..f4ff4885665 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -1,47 +1,44 @@ -import { Observable } from "rxjs"; +import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; +import { IpcService, PingMessagePayload, PongMessagePayload } from "@bitwarden/common/platform/ipc"; +import { Destination, Manager } from "@bitwarden/sdk-internal"; -import { IpcLink, IpcMessage, IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc"; - -import { BrowserApi } from "../browser/browser-api"; +import { BackgroundCommunicationProvider } from "./background-communication-provider"; export class IpcBackgroundService extends IpcService { - private links = new Map(); - - override async init() { - await super.init(); + private communicationProvider: BackgroundCommunicationProvider; - BrowserApi.messageListener("platform.ipc", (message, sender) => { - if (!isIpcMessage(message)) { - return; - } + constructor(sdkService: SdkService) { + super(); + } - if (!this.links.has(sender.documentId)) { - // eslint-disable-next-line no-console - console.log("New link", message, sender); - this.links.set( - sender.documentId, - new IpcLink( - async (data) => - BrowserApi.sendMessage("platform.ipc", { - type: "bitwarden-ipc-message", - payload: data, - } satisfies IpcMessage), - new Observable((subscriber) => { - const handler = (message: unknown) => { - if (!isIpcMessage(message)) { - return; - } - subscriber.next(message.payload); - }; + async init() { + this.communicationProvider = new BackgroundCommunicationProvider(); + this.manager = new Manager(this.communicationProvider); - BrowserApi.addListener(chrome.runtime.onMessage, handler); + await super.init(); - return () => BrowserApi.removeListener(chrome.runtime.onMessage, handler); - }), - [{ Web: sender.documentId }], - ), - ); + this.messages$.subscribe((message) => { + if (message.data[0] === PingMessagePayload[0] && message.data[1] === PingMessagePayload[1]) { + void this.pong(message.source); } }); } + + async pong(destination: Destination) { + try { + // eslint-disable-next-line no-console + console.log("[IPC] Pinging"); + await this.manager.send({ + destination, + // TODO: Fix hacky hack + data: PongMessagePayload as any as number[], + source: undefined, + }); + // eslint-disable-next-line no-console + console.log("[IPC] Sent ping"); + } catch (error) { + // eslint-disable-next-line no-console + console.error("[IPC] Ping failed", error); + } + } } diff --git a/apps/web/src/app/platform/ipc/web-communication-provider.ts b/apps/web/src/app/platform/ipc/web-communication-provider.ts new file mode 100644 index 00000000000..14aacc6ab2e --- /dev/null +++ b/apps/web/src/app/platform/ipc/web-communication-provider.ts @@ -0,0 +1,34 @@ +import { IpcMessage, isIpcMessage } from "@bitwarden/common/platform/ipc"; +import { MessageQueue } from "@bitwarden/common/platform/ipc/message-queue"; +import { CommunicationProvider, Message } from "@bitwarden/sdk-internal"; + +export class WebCommunicationProvider implements CommunicationProvider { + private queue = new MessageQueue(); + + constructor() { + // Background listener + window.addEventListener("message", async (event: MessageEvent) => { + const message = event.data; + if (!isIpcMessage(message)) { + return; + } + + await this.queue.enqueue(message.message); + }); + } + + async send(message: Message): Promise { + if (message.destination === "BrowserBackground") { + window.postMessage( + { type: "bitwarden-ipc-message", message } satisfies IpcMessage, + window.location.origin, + ); + } + + throw new Error("Destination not supported."); + } + + receive(): Promise { + return this.queue.dequeue(); + } +} diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index d5ec5bd19e8..1c38fa3fd3d 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -1,43 +1,23 @@ -import { Observable } from "rxjs"; +import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; +import { IpcService, PingMessagePayload } from "@bitwarden/common/platform/ipc"; +import { Manager } from "@bitwarden/sdk-internal"; -import { - IpcLink, - IpcMessage, - IpcService, - isIpcMessage, - PingMessagePayload, - PongMessagePayload, -} from "@bitwarden/common/platform/ipc"; +import { WebCommunicationProvider } from "./web-communication-provider"; export class WebIpcService extends IpcService { - private static LinkToExtensionBackground = new IpcLink( - async (data) => { - window.postMessage( - { type: "bitwarden-ipc-message", payload: data } satisfies IpcMessage, - window.location.origin, - ); - }, - new Observable((subscriber) => { - const listener = (event: MessageEvent) => { - const message = event.data; - if (!isIpcMessage(message)) { - return; - } + private communicationProvider: WebCommunicationProvider; - subscriber.next(message.payload); - }; - window.addEventListener("message", listener); + constructor(sdkService: SdkService) { + super(); + } - return () => window.removeEventListener("message", listener); - }), - ["BrowserBackground"], - ); + async init() { + this.communicationProvider = new WebCommunicationProvider(); + this.manager = new Manager(this.communicationProvider); - override async init() { await super.init(); - this.manager.register_link(WebIpcService.LinkToExtensionBackground); - + // TODO: remove void this.ping(); } @@ -45,15 +25,14 @@ export class WebIpcService extends IpcService { try { // eslint-disable-next-line no-console console.log("[IPC] Pinging"); - await this.manager.send("BrowserBackground", PingMessagePayload); + await this.manager.send({ + destination: "BrowserBackground", + // TODO: Fix hacky hack + data: PingMessagePayload as any as number[], + source: undefined, + }); // eslint-disable-next-line no-console console.log("[IPC] Sent ping"); - const message = await this.manager.receive("BrowserBackground"); - - if (message[0] === PongMessagePayload[0]) { - // eslint-disable-next-line no-console - console.log("[IPC] Received pong"); - } } catch (error) { // eslint-disable-next-line no-console console.error("[IPC] Ping failed", error); diff --git a/libs/common/src/platform/ipc/index.ts b/libs/common/src/platform/ipc/index.ts index 5126e9c3141..20c91fadd90 100644 --- a/libs/common/src/platform/ipc/index.ts +++ b/libs/common/src/platform/ipc/index.ts @@ -1,4 +1,3 @@ -export * from "./ipc-link"; export * from "./ipc-message"; export * from "./ipc.service"; export * from "./ping.message"; diff --git a/libs/common/src/platform/ipc/ipc-link.ts b/libs/common/src/platform/ipc/ipc-link.ts deleted file mode 100644 index 61352a58d1c..00000000000 --- a/libs/common/src/platform/ipc/ipc-link.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { firstValueFrom, Observable } from "rxjs"; - -import { Destination, Link } from "@bitwarden/sdk-internal"; - -/** - * A caching wrapper around JS transports - */ -export class IpcLink implements Link { - constructor( - private _send: (data: Uint8Array) => Promise, - private _receive: Observable, - private destinations: Destination[], - ) {} - - send(data: Uint8Array): Promise { - return this._send(data); - } - - receive(): Promise { - return firstValueFrom(this._receive); - } - - availableDestinations(): Destination[] { - return this.destinations; - } -} diff --git a/libs/common/src/platform/ipc/ipc-message.ts b/libs/common/src/platform/ipc/ipc-message.ts index 7fff419edcd..16d2c4a8cfb 100644 --- a/libs/common/src/platform/ipc/ipc-message.ts +++ b/libs/common/src/platform/ipc/ipc-message.ts @@ -1,6 +1,8 @@ +import { Message } from "@bitwarden/sdk-internal"; + export interface IpcMessage { type: "bitwarden-ipc-message"; - payload: Uint8Array; + message: Message; } export function isIpcMessage(message: any): message is IpcMessage { diff --git a/libs/common/src/platform/ipc/ipc.service.ts b/libs/common/src/platform/ipc/ipc.service.ts index e09c5a5a4bc..2714dccdbdb 100644 --- a/libs/common/src/platform/ipc/ipc.service.ts +++ b/libs/common/src/platform/ipc/ipc.service.ts @@ -1,17 +1,33 @@ -import { firstValueFrom, map } from "rxjs"; +import { Observable, shareReplay } from "rxjs"; -import { Manager } from "@bitwarden/sdk-internal"; - -import { SdkService } from "../abstractions/sdk/sdk.service"; +import { Manager, Message } from "@bitwarden/sdk-internal"; export abstract class IpcService { protected manager: Manager; - constructor(private sdkService: SdkService) {} + messages$: Observable; + + async init(): Promise { + this.messages$ = new Observable((subscriber) => { + let isSubscribed = true; + while (isSubscribed) { + this.manager + .receive() + .then((message) => { + subscriber.next(message); + }) + .catch((error) => { + subscriber.error(error); + }); + } + + return () => { + isSubscribed = false; + }; + }).pipe(shareReplay({ bufferSize: 1, refCount: true })); + } - async init() { - this.manager = await firstValueFrom( - this.sdkService.client$.pipe(map((client) => client.ipc().create_manager())), - ); + async send(message: Message) { + await this.manager.send(message); } } diff --git a/libs/common/src/platform/ipc/message-queue.ts b/libs/common/src/platform/ipc/message-queue.ts new file mode 100644 index 00000000000..2954d26bb23 --- /dev/null +++ b/libs/common/src/platform/ipc/message-queue.ts @@ -0,0 +1,20 @@ +import { firstValueFrom, Subject } from "rxjs"; + +export class MessageQueue { + private queue: T[] = []; + private messageAvailable$ = new Subject(); + + async enqueue(message: T): Promise { + this.queue.push(message); + this.messageAvailable$.next(); + } + + async dequeue(): Promise { + if (this.queue.length > 0) { + return this.queue.shift(); + } + + await firstValueFrom(this.messageAvailable$); + return this.queue.shift(); + } +} From 0fb246e56f442b2af334c7c2959f90a36e27f714 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Fri, 17 Jan 2025 10:04:02 +0100 Subject: [PATCH 13/22] wip: add some console logs --- .../src/platform/ipc/background-communication-provider.ts | 3 +++ .../browser/src/platform/ipc/content/ipc-content-script.ts | 1 + .../web/src/app/platform/ipc/web-communication-provider.ts | 3 ++- apps/web/src/app/platform/ipc/web-ipc.service.ts | 7 ++++++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/browser/src/platform/ipc/background-communication-provider.ts b/apps/browser/src/platform/ipc/background-communication-provider.ts index 755d0e95360..cbcc68bd62c 100644 --- a/apps/browser/src/platform/ipc/background-communication-provider.ts +++ b/apps/browser/src/platform/ipc/background-communication-provider.ts @@ -10,12 +10,15 @@ export class BackgroundCommunicationProvider implements CommunicationProvider { constructor() { // Web listener BrowserApi.messageListener("platform.ipc", (message, sender) => { + console.log("BrowserApi.messageListener received", message); if (!isIpcMessage(message)) { return; } void this.queue.enqueue({ ...message.message, source: { Web: sender.documentId } }); }); + + console.log("BackgroundCommunicationProvider initialized"); } async send(message: Message): Promise { diff --git a/apps/browser/src/platform/ipc/content/ipc-content-script.ts b/apps/browser/src/platform/ipc/content/ipc-content-script.ts index dbb963cd87f..379be158708 100644 --- a/apps/browser/src/platform/ipc/content/ipc-content-script.ts +++ b/apps/browser/src/platform/ipc/content/ipc-content-script.ts @@ -17,6 +17,7 @@ export function sendExtensionMessage(message: unknown) { } window.addEventListener("message", (event) => { + console.log("Received message", event.data); if (isIpcMessage(event.data)) { sendExtensionMessage(event.data); } diff --git a/apps/web/src/app/platform/ipc/web-communication-provider.ts b/apps/web/src/app/platform/ipc/web-communication-provider.ts index 14aacc6ab2e..626d988a179 100644 --- a/apps/web/src/app/platform/ipc/web-communication-provider.ts +++ b/apps/web/src/app/platform/ipc/web-communication-provider.ts @@ -23,9 +23,10 @@ export class WebCommunicationProvider implements CommunicationProvider { { type: "bitwarden-ipc-message", message } satisfies IpcMessage, window.location.origin, ); + return; } - throw new Error("Destination not supported."); + throw new Error(`Destination not supported: ${message.destination}`); } receive(): Promise { diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index 1c38fa3fd3d..eef704b8423 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -1,6 +1,6 @@ import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; import { IpcService, PingMessagePayload } from "@bitwarden/common/platform/ipc"; -import { Manager } from "@bitwarden/sdk-internal"; +import { Manager, SendError } from "@bitwarden/sdk-internal"; import { WebCommunicationProvider } from "./web-communication-provider"; @@ -34,6 +34,11 @@ export class WebIpcService extends IpcService { // eslint-disable-next-line no-console console.log("[IPC] Sent ping"); } catch (error) { + if (error instanceof SendError) { + // eslint-disable-next-line no-console + return console.error("[IPC] Ping failed", error.debug()); + } + // eslint-disable-next-line no-console console.error("[IPC] Ping failed", error); } From af27f815b4c008fe918f0a39fd44372f52558a65 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Mon, 20 Jan 2025 11:58:52 +0100 Subject: [PATCH 14/22] wip: almost working ping/pong --- .../ipc/background-communication-provider.ts | 20 ++++++--- .../platform/ipc/ipc-background.service.ts | 44 ++++++++++++++----- apps/web/src/app/core/core.module.ts | 1 + apps/web/src/app/core/init.service.ts | 1 + .../src/app/platform/ipc/web-ipc.service.ts | 14 ++++-- libs/common/src/platform/ipc/ipc.service.ts | 19 ++++---- 6 files changed, 70 insertions(+), 29 deletions(-) diff --git a/apps/browser/src/platform/ipc/background-communication-provider.ts b/apps/browser/src/platform/ipc/background-communication-provider.ts index cbcc68bd62c..6f6103e17e2 100644 --- a/apps/browser/src/platform/ipc/background-communication-provider.ts +++ b/apps/browser/src/platform/ipc/background-communication-provider.ts @@ -10,10 +10,10 @@ export class BackgroundCommunicationProvider implements CommunicationProvider { constructor() { // Web listener BrowserApi.messageListener("platform.ipc", (message, sender) => { - console.log("BrowserApi.messageListener received", message); if (!isIpcMessage(message)) { return; } + console.log("BrowserApi.messageListener(platform.ipc) received", message); void this.queue.enqueue({ ...message.message, source: { Web: sender.documentId } }); }); @@ -23,16 +23,24 @@ export class BackgroundCommunicationProvider implements CommunicationProvider { async send(message: Message): Promise { if (typeof message.destination === "object") { - await BrowserApi.sendMessage("platform.ipc", { - type: "bitwarden-ipc-message", + console.log( + "BackgroundCommunicationProvider.send() sending message to Web", + message.destination.Web, + ); + await BrowserApi.tabSendMessage( + // TODO: We should change Web(String) to Web(Number) in the SDK + { id: Number(message.destination.Web) } as chrome.tabs.Tab, message, - } satisfies IpcMessage); + ); + return; } throw new Error("Destination not supported."); } - receive(): Promise { - return this.queue.dequeue(); + async receive(): Promise { + const message = await this.queue.dequeue(); + console.log("BackgroundCommunicationProvider.receive() returning message", message); + return message; } } diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index f4ff4885665..f6e80648060 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -1,3 +1,5 @@ +import { firstValueFrom } from "rxjs"; + import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; import { IpcService, PingMessagePayload, PongMessagePayload } from "@bitwarden/common/platform/ipc"; import { Destination, Manager } from "@bitwarden/sdk-internal"; @@ -7,27 +9,40 @@ import { BackgroundCommunicationProvider } from "./background-communication-prov export class IpcBackgroundService extends IpcService { private communicationProvider: BackgroundCommunicationProvider; - constructor(sdkService: SdkService) { + constructor(private sdkService: SdkService) { super(); } - async init() { - this.communicationProvider = new BackgroundCommunicationProvider(); - this.manager = new Manager(this.communicationProvider); + override async init() { + try { + // Hack to initialize WASM + // TODO: remove when https://github.com/bitwarden/clients/pull/12764 is merged + await firstValueFrom(this.sdkService.client$); + this.communicationProvider = new BackgroundCommunicationProvider(); + this.manager = new Manager(this.communicationProvider); - await super.init(); + await super.init(); - this.messages$.subscribe((message) => { - if (message.data[0] === PingMessagePayload[0] && message.data[1] === PingMessagePayload[1]) { - void this.pong(message.source); - } - }); + this.messages$.subscribe((message) => { + if ( + message.data[0] === PingMessagePayload[0] && + message.data[1] === PingMessagePayload[1] + ) { + // eslint-disable-next-line no-console + console.log("[IPC] Received ping"); + void this.pong(message.source); + } + }); + } catch (e) { + // eslint-disable-next-line no-console + console.error("[IPC] Initialization failed", e); + } } async pong(destination: Destination) { try { // eslint-disable-next-line no-console - console.log("[IPC] Pinging"); + console.log("[IPC] Ponging"); await this.manager.send({ destination, // TODO: Fix hacky hack @@ -35,8 +50,13 @@ export class IpcBackgroundService extends IpcService { source: undefined, }); // eslint-disable-next-line no-console - console.log("[IPC] Sent ping"); + console.log("[IPC] Sent pong"); } catch (error) { + if (typeof error.debug === "function") { + // eslint-disable-next-line no-console + return console.error("[IPC] Pong failed", error.debug()); + } + // eslint-disable-next-line no-console console.error("[IPC] Ping failed", error); } diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 2af718914fd..dcebc12fd58 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -66,6 +66,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory"; +import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; import { IpcService } from "@bitwarden/common/platform/ipc"; diff --git a/apps/web/src/app/core/init.service.ts b/apps/web/src/app/core/init.service.ts index df2d6806112..28b3f9c3bf2 100644 --- a/apps/web/src/app/core/init.service.ts +++ b/apps/web/src/app/core/init.service.ts @@ -36,6 +36,7 @@ export class InitService { private userAutoUnlockKeyService: UserAutoUnlockKeyService, private accountService: AccountService, private versionService: VersionService, + private ipcService: IpcService, @Inject(DOCUMENT) private document: Document, ) {} diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index eef704b8423..2781f4be8b0 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -1,17 +1,23 @@ +import { firstValueFrom } from "rxjs"; + import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; import { IpcService, PingMessagePayload } from "@bitwarden/common/platform/ipc"; -import { Manager, SendError } from "@bitwarden/sdk-internal"; +import { Manager } from "@bitwarden/sdk-internal"; import { WebCommunicationProvider } from "./web-communication-provider"; export class WebIpcService extends IpcService { private communicationProvider: WebCommunicationProvider; - constructor(sdkService: SdkService) { + constructor(private sdkService: SdkService) { super(); } async init() { + // Hack to initialize WASM + // TODO: remove when https://github.com/bitwarden/clients/pull/12764 is merged + await firstValueFrom(this.sdkService.client$); + this.communicationProvider = new WebCommunicationProvider(); this.manager = new Manager(this.communicationProvider); @@ -34,7 +40,9 @@ export class WebIpcService extends IpcService { // eslint-disable-next-line no-console console.log("[IPC] Sent ping"); } catch (error) { - if (error instanceof SendError) { + // Doesn't work for some reason? + // if (error instanceof SendError) { + if (typeof error.debug === "function") { // eslint-disable-next-line no-console return console.error("[IPC] Ping failed", error.debug()); } diff --git a/libs/common/src/platform/ipc/ipc.service.ts b/libs/common/src/platform/ipc/ipc.service.ts index 2714dccdbdb..7409f855ffd 100644 --- a/libs/common/src/platform/ipc/ipc.service.ts +++ b/libs/common/src/platform/ipc/ipc.service.ts @@ -10,16 +10,19 @@ export abstract class IpcService { async init(): Promise { this.messages$ = new Observable((subscriber) => { let isSubscribed = true; - while (isSubscribed) { - this.manager - .receive() - .then((message) => { + + const receiveLoop = async () => { + while (isSubscribed) { + try { + const message = await this.manager.receive(); subscriber.next(message); - }) - .catch((error) => { + } catch (error) { subscriber.error(error); - }); - } + break; + } + } + }; + void receiveLoop(); return () => { isSubscribed = false; From 3eec430f8ca1ca2ff020df779060f2f0c2b50c3e Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Tue, 21 Jan 2025 10:02:39 +0100 Subject: [PATCH 15/22] feat: working ping/pong --- .../ipc/background-communication-provider.ts | 19 ++++----------- .../ipc/content/ipc-content-script.ts | 24 ++++++++++++++++++- .../platform/ipc/ipc-background.service.ts | 1 + .../src/app/platform/ipc/web-ipc.service.ts | 16 +++++++++++-- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/apps/browser/src/platform/ipc/background-communication-provider.ts b/apps/browser/src/platform/ipc/background-communication-provider.ts index 6f6103e17e2..29762524940 100644 --- a/apps/browser/src/platform/ipc/background-communication-provider.ts +++ b/apps/browser/src/platform/ipc/background-communication-provider.ts @@ -13,24 +13,17 @@ export class BackgroundCommunicationProvider implements CommunicationProvider { if (!isIpcMessage(message)) { return; } - console.log("BrowserApi.messageListener(platform.ipc) received", message); - void this.queue.enqueue({ ...message.message, source: { Web: sender.documentId } }); + void this.queue.enqueue({ ...message.message, source: { Web: sender.tab.id } }); }); - - console.log("BackgroundCommunicationProvider initialized"); } async send(message: Message): Promise { if (typeof message.destination === "object") { - console.log( - "BackgroundCommunicationProvider.send() sending message to Web", - message.destination.Web, - ); await BrowserApi.tabSendMessage( - // TODO: We should change Web(String) to Web(Number) in the SDK - { id: Number(message.destination.Web) } as chrome.tabs.Tab, - message, + { id: message.destination.Web } as chrome.tabs.Tab, + { type: "bitwarden-ipc-message", message } satisfies IpcMessage, + { frameId: 0 }, ); return; } @@ -39,8 +32,6 @@ export class BackgroundCommunicationProvider implements CommunicationProvider { } async receive(): Promise { - const message = await this.queue.dequeue(); - console.log("BackgroundCommunicationProvider.receive() returning message", message); - return message; + return this.queue.dequeue(); } } diff --git a/apps/browser/src/platform/ipc/content/ipc-content-script.ts b/apps/browser/src/platform/ipc/content/ipc-content-script.ts index 379be158708..8d406f13e2e 100644 --- a/apps/browser/src/platform/ipc/content/ipc-content-script.ts +++ b/apps/browser/src/platform/ipc/content/ipc-content-script.ts @@ -3,6 +3,7 @@ import { isIpcMessage } from "@bitwarden/common/platform/ipc/ipc-message"; +// Web -> Background export function sendExtensionMessage(message: unknown) { if ( typeof browser !== "undefined" && @@ -17,8 +18,29 @@ export function sendExtensionMessage(message: unknown) { } window.addEventListener("message", (event) => { - console.log("Received message", event.data); if (isIpcMessage(event.data)) { sendExtensionMessage(event.data); } }); + +// Background -> Web +function setupMessageListener() { + function listener(message: unknown) { + if (isIpcMessage(message)) { + void window.postMessage(message); + } + } + + if ( + typeof browser !== "undefined" && + typeof browser.runtime !== "undefined" && + typeof browser.runtime.onMessage !== "undefined" + ) { + browser.runtime.onMessage.addListener(listener); + return; + } + + chrome.runtime.onMessage.addListener(listener); +} + +setupMessageListener(); diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index f6e80648060..f1b6eab5328 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -23,6 +23,7 @@ export class IpcBackgroundService extends IpcService { await super.init(); + // TODO: Remove pong - this is simply a proof of concept this.messages$.subscribe((message) => { if ( message.data[0] === PingMessagePayload[0] && diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index 2781f4be8b0..ced695d2865 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -1,7 +1,7 @@ -import { firstValueFrom } from "rxjs"; +import { filter, firstValueFrom } from "rxjs"; import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; -import { IpcService, PingMessagePayload } from "@bitwarden/common/platform/ipc"; +import { IpcService, PingMessagePayload, PongMessagePayload } from "@bitwarden/common/platform/ipc"; import { Manager } from "@bitwarden/sdk-internal"; import { WebCommunicationProvider } from "./web-communication-provider"; @@ -39,6 +39,18 @@ export class WebIpcService extends IpcService { }); // eslint-disable-next-line no-console console.log("[IPC] Sent ping"); + + const pong = await firstValueFrom( + this.messages$.pipe( + filter( + (message) => + message.data[0] === PongMessagePayload[0] && + message.data[1] === PongMessagePayload[1], + ), + ), + ); + // eslint-disable-next-line no-console + console.log("[IPC] Received pong", pong); } catch (error) { // Doesn't work for some reason? // if (error instanceof SendError) { From 281332bbd9ecae12822c78ba83340f32b645e28a Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 12 Feb 2025 15:15:19 +0100 Subject: [PATCH 16/22] chore: clean-up ping/pong and some console logs --- .../ipc/background-communication-provider.ts | 1 - .../platform/ipc/ipc-background.service.ts | 54 ++---------------- .../ipc/web-communication-provider.ts | 1 - .../src/app/platform/ipc/web-ipc.service.ts | 55 ++----------------- 4 files changed, 10 insertions(+), 101 deletions(-) diff --git a/apps/browser/src/platform/ipc/background-communication-provider.ts b/apps/browser/src/platform/ipc/background-communication-provider.ts index 29762524940..9afa98378e5 100644 --- a/apps/browser/src/platform/ipc/background-communication-provider.ts +++ b/apps/browser/src/platform/ipc/background-communication-provider.ts @@ -8,7 +8,6 @@ export class BackgroundCommunicationProvider implements CommunicationProvider { private queue = new MessageQueue(); constructor() { - // Web listener BrowserApi.messageListener("platform.ipc", (message, sender) => { if (!isIpcMessage(message)) { return; diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index f1b6eab5328..de78f1a03b4 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -1,65 +1,23 @@ -import { firstValueFrom } from "rxjs"; +import { inject } from "@angular/core"; -import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; -import { IpcService, PingMessagePayload, PongMessagePayload } from "@bitwarden/common/platform/ipc"; -import { Destination, Manager } from "@bitwarden/sdk-internal"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { IpcService } from "@bitwarden/common/platform/ipc"; +import { Manager } from "@bitwarden/sdk-internal"; import { BackgroundCommunicationProvider } from "./background-communication-provider"; export class IpcBackgroundService extends IpcService { + private logService = inject(LogService); private communicationProvider: BackgroundCommunicationProvider; - constructor(private sdkService: SdkService) { - super(); - } - override async init() { try { - // Hack to initialize WASM - // TODO: remove when https://github.com/bitwarden/clients/pull/12764 is merged - await firstValueFrom(this.sdkService.client$); this.communicationProvider = new BackgroundCommunicationProvider(); this.manager = new Manager(this.communicationProvider); await super.init(); - - // TODO: Remove pong - this is simply a proof of concept - this.messages$.subscribe((message) => { - if ( - message.data[0] === PingMessagePayload[0] && - message.data[1] === PingMessagePayload[1] - ) { - // eslint-disable-next-line no-console - console.log("[IPC] Received ping"); - void this.pong(message.source); - } - }); } catch (e) { - // eslint-disable-next-line no-console - console.error("[IPC] Initialization failed", e); - } - } - - async pong(destination: Destination) { - try { - // eslint-disable-next-line no-console - console.log("[IPC] Ponging"); - await this.manager.send({ - destination, - // TODO: Fix hacky hack - data: PongMessagePayload as any as number[], - source: undefined, - }); - // eslint-disable-next-line no-console - console.log("[IPC] Sent pong"); - } catch (error) { - if (typeof error.debug === "function") { - // eslint-disable-next-line no-console - return console.error("[IPC] Pong failed", error.debug()); - } - - // eslint-disable-next-line no-console - console.error("[IPC] Ping failed", error); + this.logService.error("[IPC] Initialization failed", e); } } } diff --git a/apps/web/src/app/platform/ipc/web-communication-provider.ts b/apps/web/src/app/platform/ipc/web-communication-provider.ts index 626d988a179..e8690362c8b 100644 --- a/apps/web/src/app/platform/ipc/web-communication-provider.ts +++ b/apps/web/src/app/platform/ipc/web-communication-provider.ts @@ -6,7 +6,6 @@ export class WebCommunicationProvider implements CommunicationProvider { private queue = new MessageQueue(); constructor() { - // Background listener window.addEventListener("message", async (event: MessageEvent) => { const message = event.data; if (!isIpcMessage(message)) { diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index ced695d2865..a9f2483382d 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -1,66 +1,19 @@ -import { filter, firstValueFrom } from "rxjs"; +import { inject } from "@angular/core"; -import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; -import { IpcService, PingMessagePayload, PongMessagePayload } from "@bitwarden/common/platform/ipc"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { IpcService } from "@bitwarden/common/platform/ipc"; import { Manager } from "@bitwarden/sdk-internal"; import { WebCommunicationProvider } from "./web-communication-provider"; export class WebIpcService extends IpcService { + private logService = inject(LogService); private communicationProvider: WebCommunicationProvider; - constructor(private sdkService: SdkService) { - super(); - } - async init() { - // Hack to initialize WASM - // TODO: remove when https://github.com/bitwarden/clients/pull/12764 is merged - await firstValueFrom(this.sdkService.client$); - this.communicationProvider = new WebCommunicationProvider(); this.manager = new Manager(this.communicationProvider); await super.init(); - - // TODO: remove - void this.ping(); - } - - async ping() { - try { - // eslint-disable-next-line no-console - console.log("[IPC] Pinging"); - await this.manager.send({ - destination: "BrowserBackground", - // TODO: Fix hacky hack - data: PingMessagePayload as any as number[], - source: undefined, - }); - // eslint-disable-next-line no-console - console.log("[IPC] Sent ping"); - - const pong = await firstValueFrom( - this.messages$.pipe( - filter( - (message) => - message.data[0] === PongMessagePayload[0] && - message.data[1] === PongMessagePayload[1], - ), - ), - ); - // eslint-disable-next-line no-console - console.log("[IPC] Received pong", pong); - } catch (error) { - // Doesn't work for some reason? - // if (error instanceof SendError) { - if (typeof error.debug === "function") { - // eslint-disable-next-line no-console - return console.error("[IPC] Ping failed", error.debug()); - } - - // eslint-disable-next-line no-console - console.error("[IPC] Ping failed", error); - } } } From 2cf8b8f3a5f0bb7f065c5901376c2478ddd860a9 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 12 Feb 2025 15:29:06 +0100 Subject: [PATCH 17/22] chore: remove unused file --- .../platform/ipc/content/bitwarden-ipc-web-api.ts | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts diff --git a/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts b/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts deleted file mode 100644 index 29a27c7053c..00000000000 --- a/apps/browser/src/platform/ipc/content/bitwarden-ipc-web-api.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface BitwardenIpcWebApi { - /** - * Sends a message to the content script. - * @param payload The message to send. - */ - postMessage(payload: Uint8Array): void; - - /** - * The callback to be called when a message is received. - */ - onMessage?: (payload: Uint8Array) => void; -} From babc8aa8c919e044d206dee9184f6c0111370acf Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 12 Feb 2025 15:33:39 +0100 Subject: [PATCH 18/22] fix: override lint rule --- apps/browser/src/platform/ipc/content/ipc-content-script.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/browser/src/platform/ipc/content/ipc-content-script.ts b/apps/browser/src/platform/ipc/content/ipc-content-script.ts index 8d406f13e2e..49c3ded8818 100644 --- a/apps/browser/src/platform/ipc/content/ipc-content-script.ts +++ b/apps/browser/src/platform/ipc/content/ipc-content-script.ts @@ -40,6 +40,7 @@ function setupMessageListener() { return; } + // eslint-disable-next-line no-restricted-syntax -- This doesn't run in the popup but in the content script chrome.runtime.onMessage.addListener(listener); } From f28be5c6a76ac4cbb6516fbfe8986bc24bf96eea Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 12 Feb 2025 15:42:42 +0100 Subject: [PATCH 19/22] chore: remove unused ping message --- libs/common/src/platform/ipc/index.ts | 1 - libs/common/src/platform/ipc/ping.message.ts | 2 -- 2 files changed, 3 deletions(-) delete mode 100644 libs/common/src/platform/ipc/ping.message.ts diff --git a/libs/common/src/platform/ipc/index.ts b/libs/common/src/platform/ipc/index.ts index 20c91fadd90..f1acccdddbf 100644 --- a/libs/common/src/platform/ipc/index.ts +++ b/libs/common/src/platform/ipc/index.ts @@ -1,3 +1,2 @@ export * from "./ipc-message"; export * from "./ipc.service"; -export * from "./ping.message"; diff --git a/libs/common/src/platform/ipc/ping.message.ts b/libs/common/src/platform/ipc/ping.message.ts deleted file mode 100644 index 7ae81922572..00000000000 --- a/libs/common/src/platform/ipc/ping.message.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const PingMessagePayload = new Uint8Array([90, 1]); -export const PongMessagePayload = new Uint8Array([90, 2]); From 3199f0692a888de3a718d4cce60f22c6e47b9757 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Thu, 13 Feb 2025 11:39:30 +0100 Subject: [PATCH 20/22] feat: add tests for message queue --- .../src/platform/ipc/message-queue.spec.ts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 libs/common/src/platform/ipc/message-queue.spec.ts diff --git a/libs/common/src/platform/ipc/message-queue.spec.ts b/libs/common/src/platform/ipc/message-queue.spec.ts new file mode 100644 index 00000000000..9a9ebec1227 --- /dev/null +++ b/libs/common/src/platform/ipc/message-queue.spec.ts @@ -0,0 +1,48 @@ +import { MessageQueue } from "./message-queue"; + +type Message = symbol; + +describe("MessageQueue", () => { + let messageQueue!: MessageQueue; + + beforeEach(() => { + messageQueue = new MessageQueue(); + }); + + it("waits for a new message when queue is empty", async () => { + const message = createMessage(); + + // Start a promise to dequeue a message + let dequeuedValue: Message | undefined; + void messageQueue.dequeue().then((value) => { + dequeuedValue = value; + }); + + // No message is enqueued yet + expect(dequeuedValue).toBeUndefined(); + + // Enqueue a message + await messageQueue.enqueue(message); + + // Expect the message to be dequeued + await new Promise(process.nextTick); + expect(dequeuedValue).toBe(message); + }); + + it("returns existing message when queue is not empty", async () => { + const message = createMessage(); + + // Enqueue a message + await messageQueue.enqueue(message); + + // Dequeue the message + const dequeuedValue = await messageQueue.dequeue(); + + // Expect the message to be dequeued + expect(dequeuedValue).toBe(message); + }); +}); + +function createMessage(name?: string): symbol { + return Symbol(name); +} From a2c2c6a23ed1b9df4f6708c6e8340e7020315984 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Mon, 17 Feb 2025 15:31:14 +0100 Subject: [PATCH 21/22] fix: adapt to name changes and modifications to SDK branch --- apps/browser/src/background/main.background.ts | 2 +- ...der.ts => background-communication-backend.ts} | 10 +++++----- .../src/platform/ipc/ipc-background.service.ts | 10 +++++----- apps/web/src/app/core/core.module.ts | 3 +-- .../platform/ipc/web-communication-provider.ts | 15 +++++++++------ apps/web/src/app/platform/ipc/web-ipc.service.ts | 8 ++------ libs/common/src/platform/ipc/ipc-message.ts | 4 ++-- libs/common/src/platform/ipc/ipc.service.ts | 14 +++++++------- 8 files changed, 32 insertions(+), 34 deletions(-) rename apps/browser/src/platform/ipc/{background-communication-provider.ts => background-communication-backend.ts} (71%) diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 046365a3191..0eedd7faabd 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -1283,7 +1283,7 @@ export default class MainBackground { this.inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService(); - this.ipcService = new IpcBackgroundService(this.sdkService); + this.ipcService = new IpcBackgroundService(); } async bootstrap() { diff --git a/apps/browser/src/platform/ipc/background-communication-provider.ts b/apps/browser/src/platform/ipc/background-communication-backend.ts similarity index 71% rename from apps/browser/src/platform/ipc/background-communication-provider.ts rename to apps/browser/src/platform/ipc/background-communication-backend.ts index 9afa98378e5..10b08d5ee20 100644 --- a/apps/browser/src/platform/ipc/background-communication-provider.ts +++ b/apps/browser/src/platform/ipc/background-communication-backend.ts @@ -1,11 +1,11 @@ import { IpcMessage, isIpcMessage } from "@bitwarden/common/platform/ipc"; import { MessageQueue } from "@bitwarden/common/platform/ipc/message-queue"; -import { CommunicationProvider, Message } from "@bitwarden/sdk-internal"; +import { CommunicationBackend, IncomingMessage, OutgoingMessage } from "@bitwarden/sdk-internal"; import { BrowserApi } from "../browser/browser-api"; -export class BackgroundCommunicationProvider implements CommunicationProvider { - private queue = new MessageQueue(); +export class BackgroundCommunicationBackend implements CommunicationBackend { + private queue = new MessageQueue(); constructor() { BrowserApi.messageListener("platform.ipc", (message, sender) => { @@ -17,7 +17,7 @@ export class BackgroundCommunicationProvider implements CommunicationProvider { }); } - async send(message: Message): Promise { + async send(message: OutgoingMessage): Promise { if (typeof message.destination === "object") { await BrowserApi.tabSendMessage( { id: message.destination.Web } as chrome.tabs.Tab, @@ -30,7 +30,7 @@ export class BackgroundCommunicationProvider implements CommunicationProvider { throw new Error("Destination not supported."); } - async receive(): Promise { + async receive(): Promise { return this.queue.dequeue(); } } diff --git a/apps/browser/src/platform/ipc/ipc-background.service.ts b/apps/browser/src/platform/ipc/ipc-background.service.ts index de78f1a03b4..55f325713a3 100644 --- a/apps/browser/src/platform/ipc/ipc-background.service.ts +++ b/apps/browser/src/platform/ipc/ipc-background.service.ts @@ -2,18 +2,18 @@ import { inject } from "@angular/core"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { IpcService } from "@bitwarden/common/platform/ipc"; -import { Manager } from "@bitwarden/sdk-internal"; +import { IpcClient } from "@bitwarden/sdk-internal"; -import { BackgroundCommunicationProvider } from "./background-communication-provider"; +import { BackgroundCommunicationBackend } from "./background-communication-backend"; export class IpcBackgroundService extends IpcService { private logService = inject(LogService); - private communicationProvider: BackgroundCommunicationProvider; + private communicationProvider: BackgroundCommunicationBackend; override async init() { try { - this.communicationProvider = new BackgroundCommunicationProvider(); - this.manager = new Manager(this.communicationProvider); + this.communicationProvider = new BackgroundCommunicationBackend(); + this.client = new IpcClient(this.communicationProvider); await super.init(); } catch (e) { diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index d4cc62ec059..1cab77ffaab 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -128,7 +128,6 @@ import { InitService } from "./init.service"; import { ENV_URLS } from "./injection-tokens"; import { ModalService } from "./modal.service"; import { RouterService } from "./router.service"; -import { WebFileDownloadService } from "./web-file-download.service"; import { WebPlatformUtilsService } from "./web-platform-utils.service"; /** @@ -337,7 +336,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: IpcService, useClass: WebIpcService, - deps: [SdkService], + deps: [], }), ]; diff --git a/apps/web/src/app/platform/ipc/web-communication-provider.ts b/apps/web/src/app/platform/ipc/web-communication-provider.ts index e8690362c8b..35dee28d9e8 100644 --- a/apps/web/src/app/platform/ipc/web-communication-provider.ts +++ b/apps/web/src/app/platform/ipc/web-communication-provider.ts @@ -1,9 +1,12 @@ +import { Injectable } from "@angular/core"; + import { IpcMessage, isIpcMessage } from "@bitwarden/common/platform/ipc"; import { MessageQueue } from "@bitwarden/common/platform/ipc/message-queue"; -import { CommunicationProvider, Message } from "@bitwarden/sdk-internal"; +import { CommunicationBackend, IncomingMessage, OutgoingMessage } from "@bitwarden/sdk-internal"; -export class WebCommunicationProvider implements CommunicationProvider { - private queue = new MessageQueue(); +@Injectable({ providedIn: "root" }) +export class WebCommunicationProvider implements CommunicationBackend { + private queue = new MessageQueue(); constructor() { window.addEventListener("message", async (event: MessageEvent) => { @@ -12,11 +15,11 @@ export class WebCommunicationProvider implements CommunicationProvider { return; } - await this.queue.enqueue(message.message); + await this.queue.enqueue({ ...message.message, source: "BrowserBackground" }); }); } - async send(message: Message): Promise { + async send(message: OutgoingMessage): Promise { if (message.destination === "BrowserBackground") { window.postMessage( { type: "bitwarden-ipc-message", message } satisfies IpcMessage, @@ -28,7 +31,7 @@ export class WebCommunicationProvider implements CommunicationProvider { throw new Error(`Destination not supported: ${message.destination}`); } - receive(): Promise { + receive(): Promise { return this.queue.dequeue(); } } diff --git a/apps/web/src/app/platform/ipc/web-ipc.service.ts b/apps/web/src/app/platform/ipc/web-ipc.service.ts index a9f2483382d..0418fb4bcf9 100644 --- a/apps/web/src/app/platform/ipc/web-ipc.service.ts +++ b/apps/web/src/app/platform/ipc/web-ipc.service.ts @@ -1,18 +1,14 @@ -import { inject } from "@angular/core"; - -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { IpcService } from "@bitwarden/common/platform/ipc"; -import { Manager } from "@bitwarden/sdk-internal"; +import { IpcClient } from "@bitwarden/sdk-internal"; import { WebCommunicationProvider } from "./web-communication-provider"; export class WebIpcService extends IpcService { - private logService = inject(LogService); private communicationProvider: WebCommunicationProvider; async init() { this.communicationProvider = new WebCommunicationProvider(); - this.manager = new Manager(this.communicationProvider); + this.client = new IpcClient(this.communicationProvider); await super.init(); } diff --git a/libs/common/src/platform/ipc/ipc-message.ts b/libs/common/src/platform/ipc/ipc-message.ts index 16d2c4a8cfb..8658b19e949 100644 --- a/libs/common/src/platform/ipc/ipc-message.ts +++ b/libs/common/src/platform/ipc/ipc-message.ts @@ -1,8 +1,8 @@ -import { Message } from "@bitwarden/sdk-internal"; +import { OutgoingMessage } from "@bitwarden/sdk-internal"; export interface IpcMessage { type: "bitwarden-ipc-message"; - message: Message; + message: OutgoingMessage; } export function isIpcMessage(message: any): message is IpcMessage { diff --git a/libs/common/src/platform/ipc/ipc.service.ts b/libs/common/src/platform/ipc/ipc.service.ts index 7409f855ffd..7a429d411c2 100644 --- a/libs/common/src/platform/ipc/ipc.service.ts +++ b/libs/common/src/platform/ipc/ipc.service.ts @@ -1,20 +1,20 @@ import { Observable, shareReplay } from "rxjs"; -import { Manager, Message } from "@bitwarden/sdk-internal"; +import { IpcClient, IncomingMessage, OutgoingMessage } from "@bitwarden/sdk-internal"; export abstract class IpcService { - protected manager: Manager; + protected client: IpcClient; - messages$: Observable; + messages$: Observable; async init(): Promise { - this.messages$ = new Observable((subscriber) => { + this.messages$ = new Observable((subscriber) => { let isSubscribed = true; const receiveLoop = async () => { while (isSubscribed) { try { - const message = await this.manager.receive(); + const message = await this.client.receive(); subscriber.next(message); } catch (error) { subscriber.error(error); @@ -30,7 +30,7 @@ export abstract class IpcService { }).pipe(shareReplay({ bufferSize: 1, refCount: true })); } - async send(message: Message) { - await this.manager.send(message); + async send(message: OutgoingMessage) { + await this.client.send(message); } } From e042762656fe63396d1604537ec8e7a2a8e53310 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Mon, 17 Feb 2025 15:35:03 +0100 Subject: [PATCH 22/22] fix: missing import --- apps/web/src/app/core/core.module.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 1cab77ffaab..be860f25db6 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -114,6 +114,7 @@ import { WebSsoComponentService } from "../auth/core/services/login/web-sso-comp import { AcceptOrganizationInviteService } from "../auth/organization-invite/accept-organization.service"; import { HtmlStorageService } from "../core/html-storage.service"; import { I18nService } from "../core/i18n.service"; +import { WebFileDownloadService } from "../core/web-file-download.service"; import { WebLockComponentService } from "../key-management/lock/services/web-lock-component.service"; import { WebProcessReloadService } from "../key-management/services/web-process-reload.service"; import { WebBiometricsService } from "../key-management/web-biometric.service";