refactor: use IPC helpers in window-setup (#17948)

This commit is contained in:
Milan Burda 2019-07-09 01:43:49 +02:00 committed by Alexey Kuzmin
parent c3ae476deb
commit 419ce494e9
7 changed files with 72 additions and 93 deletions

View file

@ -3,6 +3,7 @@
const { BrowserWindow, webContents } = require('electron')
const { isSameOrigin } = process.electronBinding('v8_util')
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
const parseFeaturesString = require('@electron/internal/common/parse-features-string')
const hasProp = {}.hasOwnProperty
@ -153,6 +154,9 @@ const getGuestWindow = function (guestContents) {
guestWindow = BrowserWindow.fromWebContents(hostContents)
}
}
if (!guestWindow) {
throw new Error('getGuestWindow failed')
}
return guestWindow
}
@ -267,53 +271,42 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', functio
}
})
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', function (event, guestId) {
const guestContents = webContents.fromId(guestId)
if (guestContents == null) return
const handleMessage = function (channel, handler) {
ipcMainUtils.handle(channel, (event, guestId, ...args) => {
const guestContents = webContents.fromId(guestId)
if (!guestContents) {
throw new Error(`Invalid guestId: ${guestId}`)
}
if (!canAccessWindow(event.sender, guestContents)) {
console.error(`Blocked ${event.sender.getURL()} from closing its opener.`)
return
}
const guestWindow = getGuestWindow(guestContents)
if (guestWindow != null) guestWindow.destroy()
})
return handler(event, guestContents, ...args)
})
}
const windowMethods = new Set([
'destroy',
'focus',
'blur'
])
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function (event, guestId, method, ...args) {
const guestContents = webContents.fromId(guestId)
if (guestContents == null) {
event.returnValue = null
return
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestContents, method, ...args) => {
if (!canAccessWindow(event.sender, guestContents)) {
console.error(`Blocked ${event.sender.getURL()} from accessing guestId: ${guestContents.id}`)
throw new Error(`Access denied to guestId: ${guestContents.id}`)
}
if (!canAccessWindow(event.sender, guestContents) || !windowMethods.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling ${method} on its opener.`)
event.returnValue = null
return
if (!windowMethods.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
throw new Error(`Invalid method: ${method}`)
}
const guestWindow = getGuestWindow(guestContents)
if (guestWindow != null) {
event.returnValue = guestWindow[method](...args)
} else {
event.returnValue = null
}
return getGuestWindow(guestContents)[method](...args)
})
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function (event, guestId, message, targetOrigin, sourceOrigin) {
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestContents, message, targetOrigin, sourceOrigin) => {
if (targetOrigin == null) {
targetOrigin = '*'
}
const guestContents = webContents.fromId(guestId)
if (guestContents == null) return
// The W3C does not seem to have word on how postMessage should work when the
// origins do not match, so we do not do |canAccessWindow| check here since
// postMessage across origins is useful and not harmful.
@ -324,37 +317,22 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function
})
const webContentsMethods = new Set([
'print',
'executeJavaScript'
])
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', function (event, guestId, method, ...args) {
const guestContents = webContents.fromId(guestId)
if (guestContents == null) return
if (canAccessWindow(event.sender, guestContents) && webContentsMethods.has(method)) {
guestContents[method](...args)
} else {
console.error(`Blocked ${event.sender.getURL()} from calling ${method} on its opener.`)
}
})
const webContentsSyncMethods = new Set([
'getURL',
'loadURL'
'loadURL',
'executeJavaScript',
'print'
])
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', function (event, guestId, method, ...args) {
const guestContents = webContents.fromId(guestId)
if (guestContents == null) {
event.returnValue = null
return
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
if (!canAccessWindow(event.sender, guestContents)) {
console.error(`Blocked ${event.sender.getURL()} from accessing guestId: ${guestContents.id}`)
throw new Error(`Access denied to guestId: ${guestContents.id}`)
}
if (canAccessWindow(event.sender, guestContents) && webContentsSyncMethods.has(method)) {
event.returnValue = guestContents[method](...args)
} else {
console.error(`Blocked ${event.sender.getURL()} from calling ${method} on its opener.`)
event.returnValue = null
if (!webContentsMethods.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
throw new Error(`Invalid method: ${method}`)
}
return guestContents[method](...args)
})