mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 23:03:32 +00:00
Remove electron remote (#332)
* Replace remote calls with ipcRenderer.invoke.
This commit is contained in:
@@ -20,7 +20,7 @@ export abstract class PlatformUtilsService {
|
|||||||
lockTimeout: () => number;
|
lockTimeout: () => number;
|
||||||
launchUri: (uri: string, options?: any) => void;
|
launchUri: (uri: string, options?: any) => void;
|
||||||
saveFile: (win: Window, blobData: any, blobOptions: any, fileName: string) => void;
|
saveFile: (win: Window, blobData: any, blobOptions: any, fileName: string) => void;
|
||||||
getApplicationVersion: () => string;
|
getApplicationVersion: () => Promise<string>;
|
||||||
supportsWebAuthn: (win: Window) => boolean;
|
supportsWebAuthn: (win: Window) => boolean;
|
||||||
supportsDuo: () => boolean;
|
supportsDuo: () => boolean;
|
||||||
showToast: (type: 'error' | 'success' | 'warning' | 'info', title: string, text: string | string[],
|
showToast: (type: 'error' | 'success' | 'warning' | 'info', title: string, text: string | string[],
|
||||||
@@ -34,7 +34,7 @@ export abstract class PlatformUtilsService {
|
|||||||
readFromClipboard: (options?: any) => Promise<string>;
|
readFromClipboard: (options?: any) => Promise<string>;
|
||||||
supportsBiometric: () => Promise<boolean>;
|
supportsBiometric: () => Promise<boolean>;
|
||||||
authenticateBiometric: () => Promise<boolean>;
|
authenticateBiometric: () => Promise<boolean>;
|
||||||
getDefaultSystemTheme: () => 'light' | 'dark';
|
getDefaultSystemTheme: () => Promise<'light' | 'dark'>;
|
||||||
onDefaultSystemThemeChange: (callback: ((theme: 'light' | 'dark') => unknown)) => unknown;
|
onDefaultSystemThemeChange: (callback: ((theme: 'light' | 'dark') => unknown)) => unknown;
|
||||||
supportsSecureStorage: () => boolean;
|
supportsSecureStorage: () => boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export class UpdateCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async run(): Promise<Response> {
|
async run(): Promise<Response> {
|
||||||
const currentVersion = this.platformUtilsService.getApplicationVersion();
|
const currentVersion = await this.platformUtilsService.getApplicationVersion();
|
||||||
|
|
||||||
const response = await fetch.default('https://api.github.com/repos/bitwarden/' +
|
const response = await fetch.default('https://api.github.com/repos/bitwarden/' +
|
||||||
this.repoName + '/releases/latest');
|
this.repoName + '/releases/latest');
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ export class CliPlatformUtilsService implements PlatformUtilsService {
|
|||||||
throw new Error('Not implemented.');
|
throw new Error('Not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplicationVersion(): string {
|
getApplicationVersion(): Promise<string> {
|
||||||
return this.packageJson.version;
|
return Promise.resolve(this.packageJson.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
supportsWebAuthn(win: Window) {
|
supportsWebAuthn(win: Window) {
|
||||||
@@ -147,7 +147,7 @@ export class CliPlatformUtilsService implements PlatformUtilsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDefaultSystemTheme() {
|
getDefaultSystemTheme() {
|
||||||
return 'light' as 'light' | 'dark';
|
return Promise.resolve('light' as 'light' | 'dark');
|
||||||
}
|
}
|
||||||
|
|
||||||
onDefaultSystemThemeChange() {
|
onDefaultSystemThemeChange() {
|
||||||
|
|||||||
@@ -1,9 +1,57 @@
|
|||||||
|
import { app, dialog, ipcMain, Menu, MenuItem, nativeTheme } from 'electron';
|
||||||
|
import { promises as fs } from 'fs';
|
||||||
import { MessagingService } from '../../abstractions/messaging.service';
|
import { MessagingService } from '../../abstractions/messaging.service';
|
||||||
|
import { RendererMenuItem } from '../utils';
|
||||||
|
|
||||||
import { WindowMain } from '../window.main';
|
import { WindowMain } from '../window.main';
|
||||||
|
|
||||||
export class ElectronMainMessagingService implements MessagingService {
|
export class ElectronMainMessagingService implements MessagingService {
|
||||||
constructor(private windowMain: WindowMain, private onMessage: (message: any) => void) { }
|
constructor(private windowMain: WindowMain, private onMessage: (message: any) => void) {
|
||||||
|
ipcMain.handle('appVersion', () => {
|
||||||
|
return app.getVersion();
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('systemTheme', () => {
|
||||||
|
return nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('showMessageBox', (event, options) => {
|
||||||
|
return dialog.showMessageBox(options);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('saveFile', (event, options) => {
|
||||||
|
dialog.showSaveDialog(windowMain.win, {
|
||||||
|
defaultPath: options.fileName,
|
||||||
|
showsTagField: false,
|
||||||
|
}).then(ret => {
|
||||||
|
if (ret.filePath != null) {
|
||||||
|
fs.writeFile(ret.filePath, options.buffer, { mode: 0o600 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('openContextMenu', (event, options: {menu: RendererMenuItem[]}) => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const menu = new Menu();
|
||||||
|
options.menu.forEach((m, index) => {
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: m.label,
|
||||||
|
type: m.type,
|
||||||
|
click: () => {
|
||||||
|
resolve(index);
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
menu.popup({ window: windowMain.win, callback: () => {
|
||||||
|
resolve(-1);
|
||||||
|
}});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
nativeTheme.on('updated', () => {
|
||||||
|
windowMain.win.webContents.send('systemThemeUpdated', nativeTheme.shouldUseDarkColors ? 'dark' : 'light');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
send(subscriber: string, arg: any = {}) {
|
send(subscriber: string, arg: any = {}) {
|
||||||
const message = Object.assign({}, { command: subscriber }, arg);
|
const message = Object.assign({}, { command: subscriber }, arg);
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
clipboard,
|
clipboard,
|
||||||
ipcRenderer,
|
ipcRenderer,
|
||||||
remote,
|
|
||||||
shell,
|
shell,
|
||||||
} from 'electron';
|
} from 'electron';
|
||||||
import * as fs from 'fs';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isDev,
|
isDev,
|
||||||
@@ -114,20 +112,14 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
saveFile(win: Window, blobData: any, blobOptions: any, fileName: string): void {
|
saveFile(win: Window, blobData: any, blobOptions: any, fileName: string): void {
|
||||||
remote.dialog.showSaveDialog(remote.getCurrentWindow(), {
|
ipcRenderer.invoke('saveFile', {
|
||||||
defaultPath: fileName,
|
fileName: fileName,
|
||||||
showsTagField: false,
|
buffer: Buffer.from(blobData),
|
||||||
}).then(ret => {
|
|
||||||
if (ret.filePath != null) {
|
|
||||||
fs.writeFile(ret.filePath, Buffer.from(blobData), { mode: 0o600 }, err => {
|
|
||||||
// error check?
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplicationVersion(): string {
|
getApplicationVersion(): Promise<string> {
|
||||||
return remote.app.getVersion();
|
return ipcRenderer.invoke('appVersion');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporarily restricted to only Windows until https://github.com/electron/electron/pull/28349
|
// Temporarily restricted to only Windows until https://github.com/electron/electron/pull/28349
|
||||||
@@ -157,7 +149,7 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
|||||||
buttons.push(cancelText);
|
buttons.push(cancelText);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await remote.dialog.showMessageBox(remote.getCurrentWindow(), {
|
const result = await ipcRenderer.invoke('showMessageBox', {
|
||||||
type: type,
|
type: type,
|
||||||
title: title,
|
title: title,
|
||||||
message: title,
|
message: title,
|
||||||
@@ -221,13 +213,11 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDefaultSystemTheme() {
|
getDefaultSystemTheme() {
|
||||||
return remote.nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
return ipcRenderer.invoke('systemTheme');
|
||||||
}
|
}
|
||||||
|
|
||||||
onDefaultSystemThemeChange(callback: ((theme: 'light' | 'dark') => unknown)) {
|
onDefaultSystemThemeChange(callback: ((theme: 'light' | 'dark') => unknown)) {
|
||||||
remote.nativeTheme.on('updated', () => {
|
ipcRenderer.on('systemThemeUpdated', (event, theme: 'light' | 'dark') => callback(theme));
|
||||||
callback(this.getDefaultSystemTheme());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
supportsSecureStorage(): boolean {
|
supportsSecureStorage(): boolean {
|
||||||
|
|||||||
27
src/electron/services/electronRendererStorage.service.ts
Normal file
27
src/electron/services/electronRendererStorage.service.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { ipcRenderer } from 'electron';
|
||||||
|
|
||||||
|
import { StorageService } from '../../abstractions/storage.service';
|
||||||
|
|
||||||
|
export class ElectronRendererStorageService implements StorageService {
|
||||||
|
get<T>(key: string): Promise<T> {
|
||||||
|
return ipcRenderer.invoke('storageService', {
|
||||||
|
action: 'get',
|
||||||
|
key: key,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
save(key: string, obj: any): Promise<any> {
|
||||||
|
return ipcRenderer.invoke('storageService', {
|
||||||
|
action: 'save',
|
||||||
|
key: key,
|
||||||
|
obj: obj,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(key: string): Promise<any> {
|
||||||
|
return ipcRenderer.invoke('storageService', {
|
||||||
|
action: 'remove',
|
||||||
|
key: key,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ipcMain, ipcRenderer } from 'electron';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import { StorageService } from '../../abstractions/storage.service';
|
import { StorageService } from '../../abstractions/storage.service';
|
||||||
@@ -19,6 +20,17 @@ export class ElectronStorageService implements StorageService {
|
|||||||
name: 'data',
|
name: 'data',
|
||||||
};
|
};
|
||||||
this.store = new Store(storeConfig);
|
this.store = new Store(storeConfig);
|
||||||
|
|
||||||
|
ipcMain.handle('storageService', (event, options) => {
|
||||||
|
switch (options.action) {
|
||||||
|
case 'get':
|
||||||
|
return this.get(options.key);
|
||||||
|
case 'save':
|
||||||
|
return this.save(options.key, options.obj);
|
||||||
|
case 'remove':
|
||||||
|
return this.remove(options.key);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get<T>(key: string): Promise<T> {
|
get<T>(key: string): Promise<T> {
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
import { ipcRenderer } from 'electron';
|
||||||
|
|
||||||
|
export type RendererMenuItem = {label?: string, type?: ('normal' | 'separator' | 'submenu' | 'checkbox' | 'radio'), click?: () => any};
|
||||||
|
|
||||||
|
export function invokeMenu(menu: RendererMenuItem[]) {
|
||||||
|
const menuWithoutClick = menu.map(m => {
|
||||||
|
return { label: m.label, type: m.type };
|
||||||
|
});
|
||||||
|
ipcRenderer.invoke('openContextMenu', { menu: menuWithoutClick }).then((i: number) => {
|
||||||
|
if (i !== -1) {
|
||||||
|
menu[i].click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function isDev() {
|
export function isDev() {
|
||||||
// ref: https://github.com/sindresorhus/electron-is-dev
|
// ref: https://github.com/sindresorhus/electron-is-dev
|
||||||
if ('ELECTRON_IS_DEV' in process.env) {
|
if ('ELECTRON_IS_DEV' in process.env) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export class Analytics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.appVersion = this.platformUtilsService.getApplicationVersion();
|
this.platformUtilsService.getApplicationVersion().then(v => this.appVersion = v);
|
||||||
this.defaultDisabled = this.platformUtilsService.getDevice() === DeviceType.FirefoxExtension ||
|
this.defaultDisabled = this.platformUtilsService.getDevice() === DeviceType.FirefoxExtension ||
|
||||||
this.platformUtilsService.isMacAppStore();
|
this.platformUtilsService.isMacAppStore();
|
||||||
this.gaTrackingId = this.platformUtilsService.analyticsId();
|
this.gaTrackingId = this.platformUtilsService.analyticsId();
|
||||||
|
|||||||
Reference in New Issue
Block a user