fix(desktop): use different method to send messages across main and render without node integration in preload (#1769)

This commit is contained in:
Mo
2022-10-07 14:30:07 -05:00
committed by GitHub
parent a1352d9f65
commit 20226c3269
4 changed files with 47 additions and 69 deletions

View File

@@ -5,6 +5,7 @@ import { autoUpdater } from 'electron-updater'
import { action, autorun, computed, makeObservable, observable } from 'mobx'
import { MessageType } from '../../../test/TestIpcMessage'
import { AppState } from '../../AppState'
import { MessageToWebApp } from '../Shared/IpcMessages'
import { BackupsManagerInterface } from './Backups/BackupsManagerInterface'
import { StoreKeys } from './Store/StoreKeys'
import { updates as str } from './Strings'
@@ -113,12 +114,12 @@ export function setupUpdates(window: BrowserWindow, appState: AppState, backupsM
setInterval(checkUpdateSafety, oneHour)
autoUpdater.on('update-downloaded', (info: { version?: string }) => {
window.webContents.send('update-available', null)
window.webContents.send(MessageToWebApp.UpdateAvailable, null)
updateState.autoUpdateHasBeenDownloaded(info.version || null)
})
autoUpdater.on('error', logError)
autoUpdater.on('update-available', (info: { version?: string }) => {
autoUpdater.on(MessageToWebApp.UpdateAvailable, (info: { version?: string }) => {
updateState.checkedForUpdate(info.version || null)
if (updateState.enableAutoUpdate) {
const canUpdate = checkUpdateSafety()

View File

@@ -166,6 +166,7 @@ async function createWindow(store: Store): Promise<Electron.BrowserWindow> {
spellcheck: true,
nodeIntegration: isTesting(),
contextIsolation: true,
sandbox: true,
preload: Paths.preloadJs,
},
})

View File

@@ -1,42 +1,28 @@
import { IpcRendererEvent } from 'electron/renderer'
import { MessageToWebApp } from '../Shared/IpcMessages'
const { ipcRenderer } = require('electron')
const path = require('path')
const rendererPath = path.join('file://', __dirname, '/renderer.js')
const RemoteBridge = require('@electron/remote').getGlobal('RemoteBridge')
const { contextBridge } = require('electron')
type MainEventCallback = (event: IpcRendererEvent, value: any) => void
process.once('loaded', function () {
contextBridge.exposeInMainWorld('electronRemoteBridge', RemoteBridge.exposableValue)
listenForIpcEventsFromMainProcess()
contextBridge.exposeInMainWorld('electronMainEvents', {
handleUpdateAvailable: (callback: MainEventCallback) => ipcRenderer.on(MessageToWebApp.UpdateAvailable, callback),
handlePerformAutomatedBackup: (callback: MainEventCallback) =>
ipcRenderer.on(MessageToWebApp.PerformAutomatedBackup, callback),
handleFinishedSavingBackup: (callback: MainEventCallback) =>
ipcRenderer.on(MessageToWebApp.FinishedSavingBackup, callback),
handleWindowBlurred: (callback: MainEventCallback) => ipcRenderer.on(MessageToWebApp.WindowBlurred, callback),
handleWindowFocused: (callback: MainEventCallback) => ipcRenderer.on(MessageToWebApp.WindowFocused, callback),
handleInstallComponentComplete: (callback: MainEventCallback) =>
ipcRenderer.on(MessageToWebApp.InstallComponentComplete, callback),
})
})
function listenForIpcEventsFromMainProcess() {
const sendMessageToRenderProcess = (message: string, payload = {}) => {
window.postMessage(JSON.stringify({ message, data: payload }), rendererPath)
}
ipcRenderer.on(MessageToWebApp.UpdateAvailable, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.UpdateAvailable, data)
})
ipcRenderer.on(MessageToWebApp.PerformAutomatedBackup, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.PerformAutomatedBackup, data)
})
ipcRenderer.on(MessageToWebApp.FinishedSavingBackup, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.FinishedSavingBackup, data)
})
ipcRenderer.on(MessageToWebApp.WindowBlurred, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.WindowBlurred, data)
})
ipcRenderer.on(MessageToWebApp.WindowFocused, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.WindowFocused, data)
})
ipcRenderer.on(MessageToWebApp.InstallComponentComplete, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.InstallComponentComplete, data)
})
}

View File

@@ -1,6 +1,6 @@
import { DesktopClientRequiresWebMethods } from '@web/Application/Device/DesktopSnjsExports'
import { StartApplication } from '@web/Application/Device/StartApplication'
import { MessageToWebApp } from '../Shared/IpcMessages'
import { IpcRendererEvent } from 'electron/renderer'
import { CrossProcessBridge } from './CrossProcessBridge'
import { DesktopDevice } from './DesktopDevice'
@@ -23,6 +23,7 @@ declare global {
purchaseUrl: string
startApplication: StartApplication
zip: any
electronMainEvents: any
}
}
@@ -41,8 +42,6 @@ const loadAndStartApplication = async () => {
window.device = await createDesktopDevice(remoteBridge)
window.startApplication(DEFAULT_SYNC_SERVER, window.device, window.enableUnfinishedFeatures, WEBSOCKET_URL)
listenForMessagesSentFromMainToPreloadToUs(window.device)
}
window.onload = () => {
@@ -134,35 +133,26 @@ async function configureWindow(remoteBridge: CrossProcessBridge) {
}
}
function listenForMessagesSentFromMainToPreloadToUs(device: DesktopDevice) {
window.addEventListener('message', async (event) => {
// We don't have access to the full file path.
if (event.origin !== 'file://') {
return
}
let payload
try {
payload = JSON.parse(event.data)
} catch (e) {
// message doesn't belong to us
return
}
const receiver = window.webClient
const message = payload.message
const data = payload.data
window.electronMainEvents.handleUpdateAvailable(() => {
window.webClient.updateAvailable()
})
if (message === MessageToWebApp.WindowBlurred) {
receiver.windowLostFocus()
} else if (message === MessageToWebApp.WindowFocused) {
receiver.windowGainedFocus()
} else if (message === MessageToWebApp.InstallComponentComplete) {
receiver.onComponentInstallationComplete(data.component, undefined)
} else if (message === MessageToWebApp.UpdateAvailable) {
receiver.updateAvailable()
} else if (message === MessageToWebApp.PerformAutomatedBackup) {
void device.downloadBackup()
} else if (message === MessageToWebApp.FinishedSavingBackup) {
receiver.didFinishBackup(data.success)
}
})
}
window.electronMainEvents.handlePerformAutomatedBackup(() => {
void window.device.downloadBackup()
})
window.electronMainEvents.handleFinishedSavingBackup((_: IpcRendererEvent, data: any) => {
window.webClient.didFinishBackup(data.success)
})
window.electronMainEvents.handleWindowBlurred(() => {
window.webClient.windowLostFocus()
})
window.electronMainEvents.handleWindowFocused(() => {
window.webClient.windowGainedFocus()
})
window.electronMainEvents.handleInstallComponentComplete((_: IpcRendererEvent, data: any) => {
window.webClient.onComponentInstallationComplete(data.component, undefined)
})