Remove electron remote (#332)

* Replace remote calls with ipcRenderer.invoke.
This commit is contained in:
Oscar Hinton 2021-04-07 19:42:06 +02:00 committed by GitHub
parent 728e40fbfa
commit 78d40d9f18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 118 additions and 26 deletions

View File

@ -20,7 +20,7 @@ export abstract class PlatformUtilsService {
lockTimeout: () => number;
launchUri: (uri: string, options?: any) => void;
saveFile: (win: Window, blobData: any, blobOptions: any, fileName: string) => void;
getApplicationVersion: () => string;
getApplicationVersion: () => Promise<string>;
supportsWebAuthn: (win: Window) => boolean;
supportsDuo: () => boolean;
showToast: (type: 'error' | 'success' | 'warning' | 'info', title: string, text: string | string[],
@ -34,7 +34,7 @@ export abstract class PlatformUtilsService {
readFromClipboard: (options?: any) => Promise<string>;
supportsBiometric: () => Promise<boolean>;
authenticateBiometric: () => Promise<boolean>;
getDefaultSystemTheme: () => 'light' | 'dark';
getDefaultSystemTheme: () => Promise<'light' | 'dark'>;
onDefaultSystemThemeChange: (callback: ((theme: 'light' | 'dark') => unknown)) => unknown;
supportsSecureStorage: () => boolean;
}

View File

@ -16,7 +16,7 @@ export class UpdateCommand {
}
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/' +
this.repoName + '/releases/latest');

View File

@ -96,8 +96,8 @@ export class CliPlatformUtilsService implements PlatformUtilsService {
throw new Error('Not implemented.');
}
getApplicationVersion(): string {
return this.packageJson.version;
getApplicationVersion(): Promise<string> {
return Promise.resolve(this.packageJson.version);
}
supportsWebAuthn(win: Window) {
@ -147,7 +147,7 @@ export class CliPlatformUtilsService implements PlatformUtilsService {
}
getDefaultSystemTheme() {
return 'light' as 'light' | 'dark';
return Promise.resolve('light' as 'light' | 'dark');
}
onDefaultSystemThemeChange() {

View File

@ -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 { RendererMenuItem } from '../utils';
import { WindowMain } from '../window.main';
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 = {}) {
const message = Object.assign({}, { command: subscriber }, arg);

View File

@ -1,10 +1,8 @@
import {
clipboard,
ipcRenderer,
remote,
shell,
} from 'electron';
import * as fs from 'fs';
import {
isDev,
@ -114,20 +112,14 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
}
saveFile(win: Window, blobData: any, blobOptions: any, fileName: string): void {
remote.dialog.showSaveDialog(remote.getCurrentWindow(), {
defaultPath: fileName,
showsTagField: false,
}).then(ret => {
if (ret.filePath != null) {
fs.writeFile(ret.filePath, Buffer.from(blobData), { mode: 0o600 }, err => {
// error check?
});
}
ipcRenderer.invoke('saveFile', {
fileName: fileName,
buffer: Buffer.from(blobData),
});
}
getApplicationVersion(): string {
return remote.app.getVersion();
getApplicationVersion(): Promise<string> {
return ipcRenderer.invoke('appVersion');
}
// 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);
}
const result = await remote.dialog.showMessageBox(remote.getCurrentWindow(), {
const result = await ipcRenderer.invoke('showMessageBox', {
type: type,
title: title,
message: title,
@ -221,13 +213,11 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
}
getDefaultSystemTheme() {
return remote.nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
return ipcRenderer.invoke('systemTheme');
}
onDefaultSystemThemeChange(callback: ((theme: 'light' | 'dark') => unknown)) {
remote.nativeTheme.on('updated', () => {
callback(this.getDefaultSystemTheme());
});
ipcRenderer.on('systemThemeUpdated', (event, theme: 'light' | 'dark') => callback(theme));
}
supportsSecureStorage(): boolean {

View 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,
});
}
}

View File

@ -1,3 +1,4 @@
import { ipcMain, ipcRenderer } from 'electron';
import * as fs from 'fs';
import { StorageService } from '../../abstractions/storage.service';
@ -19,6 +20,17 @@ export class ElectronStorageService implements StorageService {
name: 'data',
};
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> {

View File

@ -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() {
// ref: https://github.com/sindresorhus/electron-is-dev
if ('ELECTRON_IS_DEV' in process.env) {

View File

@ -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.platformUtilsService.isMacAppStore();
this.gaTrackingId = this.platformUtilsService.analyticsId();