1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-12 22:44:11 +00:00

feat: working browser background <-> desktop renderer IPC communication

This commit is contained in:
Andreas Coroiu
2025-10-17 16:56:46 +02:00
parent 1272093883
commit 019c2f727b
6 changed files with 126 additions and 55 deletions

View File

@@ -1,7 +1,12 @@
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
import { IpcMessage, isIpcMessage, IpcService } from "@bitwarden/common/platform/ipc";
import {
IpcMessage,
isIpcMessage,
IpcService,
isForwardedIpcMessage,
} from "@bitwarden/common/platform/ipc";
import {
IpcCommunicationBackend,
IncomingMessage,
@@ -96,7 +101,7 @@ export class IpcBackgroundService extends IpcService {
});
this.nativeMessagingPort?.onMessage.addListener((ipcMessage) => {
if (!isIpcMessage(ipcMessage)) {
if (!isIpcMessage(ipcMessage) && !isForwardedIpcMessage(ipcMessage)) {
return;
}
@@ -104,7 +109,7 @@ export class IpcBackgroundService extends IpcService {
new IncomingMessage(
new Uint8Array(ipcMessage.message.payload),
ipcMessage.message.destination,
"DesktopMain",
isForwardedIpcMessage(ipcMessage) ? ipcMessage.originalSource : "DesktopMain",
ipcMessage.message.topic,
),
);

View File

@@ -314,7 +314,12 @@ export class Main {
this.windowMain,
);
this.ipcService = new IpcMainService(this.logService, app, this.nativeMessagingMain);
this.ipcService = new IpcMainService(
this.logService,
app,
this.nativeMessagingMain,
this.windowMain,
);
app
.whenReady()

View File

@@ -3,6 +3,7 @@ import { ipcRenderer } from "electron";
import { DeviceType } from "@bitwarden/common/enums";
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
import { ThemeType, LogLevelType } from "@bitwarden/common/platform/enums";
import { ForwardedIpcMessage, IpcMessage } from "@bitwarden/common/platform/ipc";
import {
EncryptedMessageResponse,
@@ -98,6 +99,18 @@ const nativeMessaging = {
},
};
const ipcService = {
onMessage: (callback: (message: ForwardedIpcMessage) => void) => {
ipcRenderer.on("ipc.onMessage", (_event, message: ForwardedIpcMessage) => {
callback(message);
});
},
send: (message: IpcMessage) => {
ipcRenderer.send("ipc.send", message);
},
};
const ephemeralStore = {
setEphemeralValue: (key: string, value: string): Promise<void> =>
ipcRenderer.invoke("setEphemeralValue", { key, value }),
@@ -185,6 +198,7 @@ export default {
crypto,
ephemeralStore,
localhostCallbackService,
ipcService,
};
function deviceType(): DeviceType {

View File

@@ -1,10 +1,14 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { inject, Injectable } from "@angular/core";
import { inject } from "@angular/core";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
import { IpcMessage, IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc";
import {
ForwardedIpcMessage,
IpcMessage,
IpcService,
isForwardedIpcMessage,
} from "@bitwarden/common/platform/ipc";
import {
IncomingMessage,
IpcClient,
@@ -31,50 +35,33 @@ export class IpcRendererService extends IpcService {
);
}
throw new Error("Not implemented");
// if (message.destination === "BrowserBackground" || message.destination === "ElectronMain") {
// window.postMessage(
// {
// type: "bitwarden-ipc-message",
// message: {
// destination: message.destination,
// payload: [...message.payload],
// topic: message.topic,
// },
// } satisfies IpcMessage,
// window.location.origin,
// );
// return;
// }
if (
message.destination === "BrowserBackground" ||
message.destination === "DesktopMain"
) {
ipc.platform.ipcService.send({
type: "bitwarden-ipc-message",
message: {
destination: message.destination,
payload: [...message.payload],
topic: message.topic,
},
} satisfies IpcMessage);
return;
}
},
});
// window.addEventListener("message", async (event: MessageEvent) => {
// if (event.origin !== window.origin) {
// return;
// }
// const message = event.data;
// if (!isIpcMessage(message)) {
// return;
// }
// if (
// typeof message.message.destination !== "object" ||
// message.message.destination.Web == undefined
// ) {
// return;
// }
// this.communicationBackend?.receive(
// new IncomingMessage(
// new Uint8Array(message.message.payload),
// message.message.destination,
// "BrowserBackground",
// message.message.topic,
// ),
// );
// });
ipc.platform.ipcService.onMessage((message: ForwardedIpcMessage | IpcMessage) => {
this.communicationBackend?.receive(
new IncomingMessage(
new Uint8Array(message.message.payload),
message.message.destination,
isForwardedIpcMessage(message) ? message.originalSource : "DesktopMain",
message.message.topic,
),
);
});
await super.initWithClient(new IpcClient(this.communicationBackend));

View File

@@ -1,6 +1,13 @@
import { ipcMain } from "electron";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
import { IpcMessage, IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc";
import {
ForwardedIpcMessage,
IpcMessage,
IpcService,
isIpcMessage,
} from "@bitwarden/common/platform/ipc";
import {
IncomingMessage,
IpcClient,
@@ -10,6 +17,7 @@ import {
} from "@bitwarden/sdk-internal";
import { NativeMessagingMain } from "../../main/native-messaging.main";
import { WindowMain } from "../../main/window.main";
import { isDev } from "../../utils";
export class IpcMainService extends IpcService {
@@ -19,6 +27,7 @@ export class IpcMainService extends IpcService {
private logService: LogService,
private app: Electron.App,
private nativeMessaging: NativeMessagingMain,
private windowMain: WindowMain,
) {
super();
}
@@ -49,26 +58,39 @@ export class IpcMainService extends IpcService {
}
if (message.destination === "DesktopRenderer") {
// TODO: Implement sending to renderer process
this.windowMain.win?.webContents.send("ipc.onMessage", {
type: "bitwarden-ipc-message",
message: {
destination: message.destination,
payload: [...message.payload],
topic: message.topic,
},
} satisfies IpcMessage);
return;
}
},
});
// window.addEventListener("message", async (event: MessageEvent) => {
this.nativeMessaging.messages$.subscribe((nativeMessage) => {
const ipcMessage = JSON.parse(nativeMessage.message);
if (!isIpcMessage(ipcMessage)) {
return;
}
// TODO: Add support for forwarding to DesktopRenderer
// Forward to renderer process
if (ipcMessage.message.destination === "DesktopRenderer") {
this.windowMain.win?.webContents.send("ipc.onMessage", {
type: "forwarded-bitwarden-ipc-message",
message: ipcMessage.message,
originalSource: "BrowserBackground",
} satisfies ForwardedIpcMessage);
return;
}
if (ipcMessage.message.destination !== "DesktopMain") {
return;
}
this.logService.info("[IPC] Received native message", ipcMessage);
this.communicationBackend?.receive(
new IncomingMessage(
new Uint8Array(ipcMessage.message.payload),
@@ -80,6 +102,34 @@ export class IpcMainService extends IpcService {
);
});
// Handle messages from renderer process
ipcMain.on("ipc.send", async (_event, message: IpcMessage) => {
if (message.message.destination === "DesktopMain") {
this.communicationBackend?.receive(
new IncomingMessage(
new Uint8Array(message.message.payload),
message.message.destination,
"DesktopRenderer",
message.message.topic,
),
);
return;
}
// Forward to native messaging
if (message.message.destination === "BrowserBackground") {
this.nativeMessaging.send({
type: "forwarded-bitwarden-ipc-message",
message: {
destination: message.message.destination,
payload: [...message.message.payload],
topic: message.message.topic,
},
originalSource: "DesktopRenderer",
} satisfies ForwardedIpcMessage);
}
});
await super.initWithClient(new IpcClient(this.communicationBackend));
if (isDev()) {

View File

@@ -1,10 +1,16 @@
import type { OutgoingMessage } from "@bitwarden/sdk-internal";
import type { Endpoint, OutgoingMessage } from "@bitwarden/sdk-internal";
export interface IpcMessage {
type: "bitwarden-ipc-message";
message: SerializedOutgoingMessage;
}
export interface ForwardedIpcMessage {
type: "forwarded-bitwarden-ipc-message";
message: SerializedOutgoingMessage;
originalSource: Endpoint;
}
export interface SerializedOutgoingMessage extends Omit<OutgoingMessage, "free" | "payload"> {
payload: number[];
}
@@ -12,3 +18,7 @@ export interface SerializedOutgoingMessage extends Omit<OutgoingMessage, "free"
export function isIpcMessage(message: any): message is IpcMessage {
return message.type === "bitwarden-ipc-message";
}
export function isForwardedIpcMessage(message: any): message is ForwardedIpcMessage {
return message.type === "forwarded-bitwarden-ipc-message";
}