зеркало из https://github.com/electron/electron.git
feat: add remote.require() / remote.getGlobal() filtering (#15014)
This commit is contained in:
Родитель
dffe4fdd4f
Коммит
db37ab1039
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Local<v8::Object> CreateWithSender(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> sender) {
|
||||
return mate::internal::CreateJSEvent(isolate, sender, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createWithSender", &CreateWithSender);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
|
|
@ -36,6 +36,7 @@
|
|||
V(atom_browser_debugger) \
|
||||
V(atom_browser_dialog) \
|
||||
V(atom_browser_download_item) \
|
||||
V(atom_browser_event) \
|
||||
V(atom_browser_global_shortcut) \
|
||||
V(atom_browser_in_app_purchase) \
|
||||
V(atom_browser_menu) \
|
||||
|
|
|
@ -399,6 +399,30 @@ non-minimized.
|
|||
This event is guaranteed to be emitted after the `ready` event of `app`
|
||||
gets emitted.
|
||||
|
||||
### Event: 'remote-require'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `moduleName` String
|
||||
|
||||
Emitted when `remote.require()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-global'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `globalName` String
|
||||
|
||||
Emitted when `remote.getGlobal()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
## Methods
|
||||
|
||||
The `app` object has the following methods:
|
||||
|
|
|
@ -663,6 +663,28 @@ Returns:
|
|||
Emitted when the associated window logs a console message. Will not be emitted
|
||||
for windows with *offscreen rendering* enabled.
|
||||
|
||||
#### Event: 'remote-require'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `moduleName` String
|
||||
|
||||
Emitted when `remote.require()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-global'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `globalName` String
|
||||
|
||||
Emitted when `remote.getGlobal()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Instance Methods
|
||||
|
||||
#### `contents.loadURL(url[, options])`
|
||||
|
|
|
@ -133,6 +133,7 @@ filenames = {
|
|||
"atom/browser/api/atom_api_dialog.cc",
|
||||
"atom/browser/api/atom_api_download_item.cc",
|
||||
"atom/browser/api/atom_api_download_item.h",
|
||||
"atom/browser/api/atom_api_event.cc",
|
||||
"atom/browser/api/atom_api_global_shortcut.cc",
|
||||
"atom/browser/api/atom_api_global_shortcut.h",
|
||||
"atom/browser/api/atom_api_in_app_purchase.cc",
|
||||
|
|
|
@ -338,6 +338,14 @@ WebContents.prototype._init = function () {
|
|||
})
|
||||
})
|
||||
|
||||
this.on('remote-require', (event, ...args) => {
|
||||
app.emit('remote-require', event, this, ...args)
|
||||
})
|
||||
|
||||
this.on('remote-get-global', (event, ...args) => {
|
||||
app.emit('remote-get-global', event, this, ...args)
|
||||
})
|
||||
|
||||
deprecate.event(this, 'did-get-response-details', '-did-get-response-details')
|
||||
deprecate.event(this, 'did-get-redirect-request', '-did-get-redirect-request')
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ const fs = require('fs')
|
|||
const os = require('os')
|
||||
const path = require('path')
|
||||
const v8Util = process.atomBinding('v8_util')
|
||||
const eventBinding = process.atomBinding('event')
|
||||
|
||||
const { isPromise } = electron
|
||||
|
||||
|
@ -280,16 +281,38 @@ const handleRemoteCommand = function (channel, handler) {
|
|||
})
|
||||
}
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, module) {
|
||||
return valueToMeta(event.sender, contextId, process.mainModule.require(module))
|
||||
handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, moduleName) {
|
||||
const customEvent = eventBinding.createWithSender(event.sender)
|
||||
event.sender.emit('remote-require', customEvent, moduleName)
|
||||
|
||||
if (customEvent.defaultPrevented) {
|
||||
if (typeof customEvent.returnValue === 'undefined') {
|
||||
throw new Error(`Invalid module: ${moduleName}`)
|
||||
}
|
||||
} else {
|
||||
customEvent.returnValue = process.mainModule.require(moduleName)
|
||||
}
|
||||
|
||||
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, module) {
|
||||
return valueToMeta(event.sender, contextId, electron[module])
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, name) {
|
||||
return valueToMeta(event.sender, contextId, global[name])
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, globalName) {
|
||||
const customEvent = eventBinding.createWithSender(event.sender)
|
||||
event.sender.emit('remote-get-global', customEvent, globalName)
|
||||
|
||||
if (customEvent.defaultPrevented) {
|
||||
if (typeof customEvent.returnValue === 'undefined') {
|
||||
throw new Error(`Invalid global: ${globalName}`)
|
||||
}
|
||||
} else {
|
||||
customEvent.returnValue = global[globalName]
|
||||
}
|
||||
|
||||
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
|
||||
|
|
|
@ -358,6 +358,28 @@ describe('app module', () => {
|
|||
})
|
||||
w = new BrowserWindow({ show: false })
|
||||
})
|
||||
|
||||
it('should emit remote-require event when remote.require() is invoked', (done) => {
|
||||
app.once('remote-require', (event, webContents, moduleName) => {
|
||||
expect(webContents).to.equal(w.webContents)
|
||||
expect(moduleName).to.equal('test')
|
||||
done()
|
||||
})
|
||||
w = new BrowserWindow({ show: false })
|
||||
w.loadURL('about:blank')
|
||||
w.webContents.executeJavaScript(`require('electron').remote.require('test')`)
|
||||
})
|
||||
|
||||
it('should emit remote-get-global event when remote.getGlobal() is invoked', (done) => {
|
||||
app.once('remote-get-global', (event, webContents, globalName) => {
|
||||
expect(webContents).to.equal(w.webContents)
|
||||
expect(globalName).to.equal('test')
|
||||
done()
|
||||
})
|
||||
w = new BrowserWindow({ show: false })
|
||||
w.loadURL('about:blank')
|
||||
w.webContents.executeJavaScript(`require('electron').remote.getGlobal('test')`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('app.setBadgeCount', () => {
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
'use strict'
|
||||
|
||||
const assert = require('assert')
|
||||
const chai = require('chai')
|
||||
const dirtyChai = require('dirty-chai')
|
||||
const path = require('path')
|
||||
const { closeWindow } = require('./window-helpers')
|
||||
const { resolveGetters } = require('./assert-helpers')
|
||||
|
||||
const { remote } = require('electron')
|
||||
const { remote, ipcRenderer } = require('electron')
|
||||
const { expect } = chai
|
||||
|
||||
chai.use(dirtyChai)
|
||||
|
||||
const comparePaths = (path1, path2) => {
|
||||
if (process.platform === 'win32') {
|
||||
|
@ -22,7 +27,29 @@ describe('remote module', () => {
|
|||
|
||||
afterEach(() => closeWindow(w).then(() => { w = null }))
|
||||
|
||||
describe('remote.getGlobal', () => {
|
||||
it('can return custom values', () => {
|
||||
ipcRenderer.send('handle-next-remote-get-global', { test: 'Hello World!' })
|
||||
expect(remote.getGlobal('test')).to.be.equal('Hello World!')
|
||||
})
|
||||
|
||||
it('throws when no returnValue set', () => {
|
||||
ipcRenderer.send('handle-next-remote-get-global')
|
||||
expect(() => remote.getGlobal('process')).to.throw('Invalid global: process')
|
||||
})
|
||||
})
|
||||
|
||||
describe('remote.require', () => {
|
||||
it('can return custom values', () => {
|
||||
ipcRenderer.send('handle-next-remote-require', { test: 'Hello World!' })
|
||||
expect(remote.require('test')).to.be.equal('Hello World!')
|
||||
})
|
||||
|
||||
it('throws when no returnValue set', () => {
|
||||
ipcRenderer.send('handle-next-remote-require')
|
||||
expect(() => remote.require('electron')).to.throw('Invalid module: electron')
|
||||
})
|
||||
|
||||
it('should returns same object for the same module', () => {
|
||||
const dialog1 = remote.require('electron')
|
||||
const dialog2 = remote.require('electron')
|
||||
|
|
|
@ -242,6 +242,24 @@ app.on('ready', function () {
|
|||
})
|
||||
})
|
||||
|
||||
ipcMain.on('handle-next-remote-require', function (event, modulesMap = {}) {
|
||||
event.sender.once('remote-require', (event, moduleName) => {
|
||||
event.preventDefault()
|
||||
if (modulesMap.hasOwnProperty(moduleName)) {
|
||||
event.returnValue = modulesMap[moduleName]
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('handle-next-remote-get-global', function (event, globalsMap = {}) {
|
||||
event.sender.once('remote-get-global', (event, globalName) => {
|
||||
event.preventDefault()
|
||||
if (globalsMap.hasOwnProperty(globalName)) {
|
||||
event.returnValue = globalsMap[globalName]
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('set-client-certificate-option', function (event, skip) {
|
||||
app.once('select-client-certificate', function (event, webContents, url, list, callback) {
|
||||
event.preventDefault()
|
||||
|
|
Загрузка…
Ссылка в новой задаче