From 58eca1aa7db7d8b0947dd1b90930230f6ccd996a Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 13 Jan 2021 15:39:18 +0000 Subject: [PATCH] Use isolated IPC API This adjusts to match changes on the desktop side where we now use Electron's context isolation feature to expose only the IPC channels and methods we actually expect to use. --- src/@types/global.d.ts | 23 ++++++++++++++-- src/vector/init.tsx | 4 +-- src/vector/platform/ElectronPlatform.tsx | 35 ++++++++++++------------ 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 469ef59c69..f498103d60 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -1,5 +1,5 @@ /* -Copyright 2020 New Vector Ltd +Copyright 2020, 2021 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,13 +17,32 @@ limitations under the License. import "matrix-react-sdk/src/@types/global"; // load matrix-react-sdk's type extensions first import type {Renderer} from "react-dom"; +type ElectronChannel = + "app_onAction" | + "before-quit" | + "check_updates" | + "install_update" | + "ipcCall" | + "ipcReply" | + "loudNotification" | + "preferences" | + "seshat" | + "seshatReply" | + "setBadgeCount" | + "update-downloaded" | + "userDownloadCompleted" | + "userDownloadOpen"; + declare global { interface Window { mxSendRageshake: (text: string, withLogs?: boolean) => void; matrixChat: ReturnType; // electron-only - ipcRenderer: any; + electron: { + on(channel: ElectronChannel, listener: (event: Event, ...args: any[]) => void): void; + send(channel: ElectronChannel, ...args: any[]): void; + } // opera-only opera: any; diff --git a/src/vector/init.tsx b/src/vector/init.tsx index f625644d04..de022622db 100644 --- a/src/vector/init.tsx +++ b/src/vector/init.tsx @@ -1,8 +1,8 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd -Copyright 2018, 2019, 2020 New Vector Ltd Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> +Copyright 2018 - 2021 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ import { initRageshake } from "./rageshakesetup"; export const rageshakePromise = initRageshake(); export function preparePlatform() { - if (window.ipcRenderer) { + if (window.electron) { console.log("Using Electron platform"); PlatformPeg.set(new ElectronPlatform()); } else if (window.matchMedia('(display-mode: standalone)').matches) { diff --git a/src/vector/platform/ElectronPlatform.tsx b/src/vector/platform/ElectronPlatform.tsx index 10a9600608..722892649b 100644 --- a/src/vector/platform/ElectronPlatform.tsx +++ b/src/vector/platform/ElectronPlatform.tsx @@ -1,9 +1,8 @@ /* Copyright 2016 Aviral Dasgupta Copyright 2016 OpenMarket Ltd -Copyright 2018 New Vector Ltd Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> -Copyright 2020 The Matrix.org Foundation C.I.C. +Copyright 2018 - 2021 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -49,7 +48,7 @@ import {CheckUpdatesPayload} from "matrix-react-sdk/src/dispatcher/payloads/Chec import ToastStore from "matrix-react-sdk/src/stores/ToastStore"; import GenericExpiringToast from "matrix-react-sdk/src/components/views/toasts/GenericExpiringToast"; -const ipcRenderer = window.ipcRenderer; +const electron = window.electron; const isMac = navigator.platform.toUpperCase().includes('MAC'); function platformFriendlyName(): string { @@ -74,7 +73,7 @@ function platformFriendlyName(): string { function _onAction(payload: ActionPayload) { // Whitelist payload actions, no point sending most across if (['call_state'].includes(payload.action)) { - ipcRenderer.send('app_onAction', payload); + electron.send('app_onAction', payload); } } @@ -104,7 +103,7 @@ class SeshatIndexManager extends BaseEventIndexManager { constructor() { super(); - ipcRenderer.on('seshatReply', this._onIpcReply); + electron.on('seshatReply', this._onIpcReply); } async _ipcCall(name: string, ...args: any[]): Promise { @@ -112,7 +111,7 @@ class SeshatIndexManager extends BaseEventIndexManager { const ipcCallId = ++this.nextIpcCallId; return new Promise((resolve, reject) => { this.pendingIpcCalls[ipcCallId] = {resolve, reject}; - window.ipcRenderer.send('seshat', {id: ipcCallId, name, args}); + window.electron.send('seshat', {id: ipcCallId, name, args}); }); } @@ -230,7 +229,7 @@ export default class ElectronPlatform extends VectorBasePlatform { false if there is not or the error if one is encountered */ - ipcRenderer.on('check_updates', (event, status) => { + electron.on('check_updates', (event, status) => { dis.dispatch({ action: Action.CheckUpdates, ...getUpdateCheckStatus(status), @@ -238,21 +237,21 @@ export default class ElectronPlatform extends VectorBasePlatform { }); // try to flush the rageshake logs to indexeddb before quit. - ipcRenderer.on('before-quit', function() { + electron.on('before-quit', function() { console.log('element-desktop closing'); rageshake.flush(); }); - ipcRenderer.on('ipcReply', this._onIpcReply); - ipcRenderer.on('update-downloaded', this.onUpdateDownloaded); + electron.on('ipcReply', this._onIpcReply); + electron.on('update-downloaded', this.onUpdateDownloaded); - ipcRenderer.on('preferences', () => { + electron.on('preferences', () => { dis.fire(Action.ViewUserSettings); }); - ipcRenderer.on('userDownloadCompleted', (ev, {path, name}) => { + electron.on('userDownloadCompleted', (ev, {path, name}) => { const onAccept = () => { - ipcRenderer.send('userDownloadOpen', {path}); + electron.send('userDownloadOpen', {path}); }; ToastStore.sharedInstance().addOrReplaceToast({ @@ -328,7 +327,7 @@ export default class ElectronPlatform extends VectorBasePlatform { if (this.notificationCount === count) return; super.setNotificationCount(count); - ipcRenderer.send('setBadgeCount', count); + electron.send('setBadgeCount', count); } supportsNotifications(): boolean { @@ -371,7 +370,7 @@ export default class ElectronPlatform extends VectorBasePlatform { } loudNotification(ev: Event, room: Object) { - ipcRenderer.send('loudNotification'); + electron.send('loudNotification'); } async getAppVersion(): Promise { @@ -423,14 +422,14 @@ export default class ElectronPlatform extends VectorBasePlatform { startUpdateCheck() { super.startUpdateCheck(); - ipcRenderer.send('check_updates'); + electron.send('check_updates'); } installUpdate() { // IPC to the main process to install the update, since quitAndInstall // doesn't fire the before-quit event so the main process needs to know // it should exit. - ipcRenderer.send('install_update'); + electron.send('install_update'); } getDefaultDeviceDisplayName(): string { @@ -460,7 +459,7 @@ export default class ElectronPlatform extends VectorBasePlatform { const ipcCallId = ++this.nextIpcCallId; return new Promise((resolve, reject) => { this.pendingIpcCalls[ipcCallId] = {resolve, reject}; - window.ipcRenderer.send('ipcCall', {id: ipcCallId, name, args}); + window.electron.send('ipcCall', {id: ipcCallId, name, args}); // Maybe add a timeout to these? Probably not necessary. }); }