mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 01:33:33 +00:00
[BEEEP] [PM-565] Implement clipboard logic in rust (#4516)
Implement the Desktop clipboard logic natively using rust. This uses the arboard crate for clipboard functionality. This change consists of 3 portions: * Rust component. * Updating renderer to call main using electron ipc. * Update main to listen to renderer ipc and forward calls to the native clipboard module.
This commit is contained in:
@@ -15,6 +15,7 @@ import { UpdaterMain } from "./main/updater.main";
|
||||
import { WindowMain } from "./main/window.main";
|
||||
import { Account } from "./models/account";
|
||||
import { BiometricsService, BiometricsServiceAbstraction } from "./platform/main/biometric/index";
|
||||
import { ClipboardMain } from "./platform/main/clipboard.main";
|
||||
import { DesktopCredentialStorageListener } from "./platform/main/desktop-credential-storage-listener";
|
||||
import { ElectronLogService } from "./platform/services/electron-log.service";
|
||||
import { ElectronStateService } from "./platform/services/electron-state.service";
|
||||
@@ -39,6 +40,7 @@ export class Main {
|
||||
trayMain: TrayMain;
|
||||
biometricsService: BiometricsServiceAbstraction;
|
||||
nativeMessagingMain: NativeMessagingMain;
|
||||
clipboardMain: ClipboardMain;
|
||||
|
||||
constructor() {
|
||||
// Set paths for portable builds
|
||||
@@ -138,6 +140,9 @@ export class Main {
|
||||
app.getPath("userData"),
|
||||
app.getPath("exe")
|
||||
);
|
||||
|
||||
this.clipboardMain = new ClipboardMain();
|
||||
this.clipboardMain.init();
|
||||
}
|
||||
|
||||
bootstrap() {
|
||||
|
||||
17
apps/desktop/src/platform/main/clipboard.main.ts
Normal file
17
apps/desktop/src/platform/main/clipboard.main.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ipcMain } from "electron";
|
||||
|
||||
import { clipboards } from "@bitwarden/desktop-native";
|
||||
|
||||
import { ClipboardWriteMessage } from "../types/clipboard";
|
||||
|
||||
export class ClipboardMain {
|
||||
init() {
|
||||
ipcMain.handle("clipboard.read", async (_event: any, _message: any) => {
|
||||
return await clipboards.read();
|
||||
});
|
||||
|
||||
ipcMain.handle("clipboard.write", async (_event: any, message: ClipboardWriteMessage) => {
|
||||
return await clipboards.write(message.text, message.password ?? false);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
import { clipboard, ipcRenderer, shell } from "electron";
|
||||
import { ipcRenderer, shell } from "electron";
|
||||
|
||||
import { ClientType, DeviceType } from "@bitwarden/common/enums";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import {
|
||||
ClipboardOptions,
|
||||
PlatformUtilsService,
|
||||
} from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
import { BiometricMessage, BiometricStorageAction } from "../../types/biometric-message";
|
||||
import { isDev, isMacAppStore } from "../../utils";
|
||||
import { ClipboardWriteMessage } from "../types/clipboard";
|
||||
|
||||
export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
||||
private deviceCache: DeviceType = null;
|
||||
@@ -117,24 +121,26 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
||||
return false;
|
||||
}
|
||||
|
||||
copyToClipboard(text: string, options?: any): void {
|
||||
const type = options ? options.type : null;
|
||||
const clearing = options ? !!options.clearing : false;
|
||||
const clearMs: number = options && options.clearMs ? options.clearMs : null;
|
||||
clipboard.writeText(text, type);
|
||||
copyToClipboard(text: string, options?: ClipboardOptions): void {
|
||||
const clearing = options?.clearing === true;
|
||||
const clearMs = options?.clearMs ?? null;
|
||||
|
||||
ipcRenderer.invoke("clipboard.write", {
|
||||
text: text,
|
||||
password: (options?.allowHistory ?? false) === false, // default to false
|
||||
} satisfies ClipboardWriteMessage);
|
||||
|
||||
if (!clearing) {
|
||||
this.messagingService.send("copiedToClipboard", {
|
||||
clipboardValue: text,
|
||||
clearMs: clearMs,
|
||||
type: type,
|
||||
clearing: clearing,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
readFromClipboard(options?: any): Promise<string> {
|
||||
const type = options ? options.type : null;
|
||||
return Promise.resolve(clipboard.readText(type));
|
||||
readFromClipboard(): Promise<string> {
|
||||
return ipcRenderer.invoke("clipboard.read");
|
||||
}
|
||||
|
||||
async supportsBiometric(): Promise<boolean> {
|
||||
|
||||
4
apps/desktop/src/platform/types/clipboard.ts
Normal file
4
apps/desktop/src/platform/types/clipboard.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export type ClipboardWriteMessage = {
|
||||
text: string;
|
||||
password?: boolean;
|
||||
};
|
||||
Reference in New Issue
Block a user