feat: add process.contextIsolation property (#28030)

This commit is contained in:
Milan Burda 2021-03-17 19:23:29 +01:00 committed by GitHub
parent 485fa5bea9
commit fc7f2042ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 40 additions and 12 deletions

View file

@ -30,6 +30,7 @@ In sandboxed renderers the `process` object contains only a subset of the APIs:
* `arch` * `arch`
* `platform` * `platform`
* `sandboxed` * `sandboxed`
* `contextIsolation`
* `type` * `type`
* `version` * `version`
* `versions` * `versions`
@ -94,6 +95,11 @@ A `String` representing the path to the resources directory.
A `Boolean`. When the renderer process is sandboxed, this property is `true`, A `Boolean`. When the renderer process is sandboxed, this property is `true`,
otherwise it is `undefined`. otherwise it is `undefined`.
### `process.contextIsolation` _Readonly_
A `Boolean` that indicates whether the current renderer context has `contextIsolation` enabled.
It is `undefined` in the main process.
### `process.throwDeprecation` ### `process.throwDeprecation`
A `Boolean` that controls whether or not deprecation warnings will be thrown as A `Boolean` that controls whether or not deprecation warnings will be thrown as

View file

@ -146,9 +146,8 @@ void ElectronRendererClient::DidCreateScriptContext(
// Add Electron extended APIs. // Add Electron extended APIs.
electron_bindings_->BindTo(env->isolate(), env->process_object()); electron_bindings_->BindTo(env->isolate(), env->process_object());
AddRenderBindings(env->isolate(), env->process_object());
gin_helper::Dictionary process_dict(env->isolate(), env->process_object()); gin_helper::Dictionary process_dict(env->isolate(), env->process_object());
process_dict.SetReadOnly("isMainFrame", render_frame->IsMainFrame()); BindProcess(env->isolate(), &process_dict, render_frame);
// Load everything. // Load everything.
node_bindings_->LoadEnvironment(env); node_bindings_->LoadEnvironment(env);

View file

@ -131,7 +131,7 @@ ElectronSandboxedRendererClient::~ElectronSandboxedRendererClient() = default;
void ElectronSandboxedRendererClient::InitializeBindings( void ElectronSandboxedRendererClient::InitializeBindings(
v8::Local<v8::Object> binding, v8::Local<v8::Object> binding,
v8::Local<v8::Context> context, v8::Local<v8::Context> context,
bool is_main_frame) { content::RenderFrame* render_frame) {
auto* isolate = context->GetIsolate(); auto* isolate = context->GetIsolate();
gin_helper::Dictionary b(isolate, binding); gin_helper::Dictionary b(isolate, binding);
b.SetMethod("get", GetBinding); b.SetMethod("get", GetBinding);
@ -141,13 +141,13 @@ void ElectronSandboxedRendererClient::InitializeBindings(
b.Set("process", process); b.Set("process", process);
ElectronBindings::BindProcess(isolate, &process, metrics_.get()); ElectronBindings::BindProcess(isolate, &process, metrics_.get());
BindProcess(isolate, &process, render_frame);
process.SetMethod("uptime", Uptime); process.SetMethod("uptime", Uptime);
process.Set("argv", base::CommandLine::ForCurrentProcess()->argv()); process.Set("argv", base::CommandLine::ForCurrentProcess()->argv());
process.SetReadOnly("pid", base::GetCurrentProcId()); process.SetReadOnly("pid", base::GetCurrentProcId());
process.SetReadOnly("sandboxed", true); process.SetReadOnly("sandboxed", true);
process.SetReadOnly("type", "renderer"); process.SetReadOnly("type", "renderer");
process.SetReadOnly("isMainFrame", is_main_frame);
} }
void ElectronSandboxedRendererClient::RenderFrameCreated( void ElectronSandboxedRendererClient::RenderFrameCreated(
@ -218,8 +218,7 @@ void ElectronSandboxedRendererClient::DidCreateScriptContext(
// argument. // argument.
auto* isolate = context->GetIsolate(); auto* isolate = context->GetIsolate();
auto binding = v8::Object::New(isolate); auto binding = v8::Object::New(isolate);
InitializeBindings(binding, context, render_frame->IsMainFrame()); InitializeBindings(binding, context, render_frame);
AddRenderBindings(isolate, binding);
std::vector<v8::Local<v8::String>> sandbox_preload_bundle_params = { std::vector<v8::Local<v8::String>> sandbox_preload_bundle_params = {
node::FIXED_ONE_BYTE_STRING(isolate, "binding")}; node::FIXED_ONE_BYTE_STRING(isolate, "binding")};

View file

@ -21,7 +21,7 @@ class ElectronSandboxedRendererClient : public RendererClientBase {
void InitializeBindings(v8::Local<v8::Object> binding, void InitializeBindings(v8::Local<v8::Object> binding,
v8::Local<v8::Context> context, v8::Local<v8::Context> context,
bool is_main_frame); content::RenderFrame* render_frame);
// electron::RendererClientBase: // electron::RendererClientBase:
void DidCreateScriptContext(v8::Handle<v8::Context> context, void DidCreateScriptContext(v8::Handle<v8::Context> context,
content::RenderFrame* render_frame) override; content::RenderFrame* render_frame) override;

View file

@ -137,9 +137,13 @@ void RendererClientBase::DidCreateScriptContext(
global.SetHidden("contextId", context_id); global.SetHidden("contextId", context_id);
} }
void RendererClientBase::AddRenderBindings( void RendererClientBase::BindProcess(v8::Isolate* isolate,
v8::Isolate* isolate, gin_helper::Dictionary* process,
v8::Local<v8::Object> binding_object) {} content::RenderFrame* render_frame) {
process->SetReadOnly("isMainFrame", render_frame->IsMainFrame());
process->SetReadOnly("contextIsolation",
render_frame->GetBlinkPreferences().context_isolation);
}
void RendererClientBase::RenderThreadStarted() { void RendererClientBase::RenderThreadStarted() {
auto* command_line = base::CommandLine::ForCurrentProcess(); auto* command_line = base::CommandLine::ForCurrentProcess();

View file

@ -13,6 +13,7 @@
#include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/content_renderer_client.h"
#include "electron/buildflags/buildflags.h" #include "electron/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h" #include "printing/buildflags/buildflags.h"
#include "shell/common/gin_helper/dictionary.h"
#include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame.h"
// In SHARED_INTERMEDIATE_DIR. // In SHARED_INTERMEDIATE_DIR.
#include "widevine_cdm_version.h" // NOLINT(build/include_directory) #include "widevine_cdm_version.h" // NOLINT(build/include_directory)
@ -92,8 +93,9 @@ class RendererClientBase : public content::ContentRendererClient
#endif #endif
protected: protected:
void AddRenderBindings(v8::Isolate* isolate, void BindProcess(v8::Isolate* isolate,
v8::Local<v8::Object> binding_object); gin_helper::Dictionary* process,
content::RenderFrame* render_frame);
// content::ContentRendererClient: // content::ContentRendererClient:
void RenderThreadStarted() override; void RenderThreadStarted() override;

View file

@ -2487,6 +2487,7 @@ describe('BrowserWindow module', () => {
expect(test.env).to.deep.equal(process.env); expect(test.env).to.deep.equal(process.env);
expect(test.execPath).to.equal(process.helperExecPath); expect(test.execPath).to.equal(process.helperExecPath);
expect(test.sandboxed).to.be.true('sandboxed'); expect(test.sandboxed).to.be.true('sandboxed');
expect(test.contextIsolation).to.be.false('contextIsolation');
expect(test.type).to.equal('renderer'); expect(test.type).to.equal('renderer');
expect(test.version).to.equal(process.version); expect(test.version).to.equal(process.version);
expect(test.versions).to.deep.equal(process.versions); expect(test.versions).to.deep.equal(process.versions);
@ -4305,6 +4306,19 @@ describe('BrowserWindow module', () => {
const [, data] = await p; const [, data] = await p;
expect(data.pageContext.openedLocation).to.equal('about:blank'); expect(data.pageContext.openedLocation).to.equal('about:blank');
}); });
it('reports process.contextIsolation', async () => {
const iw = new BrowserWindow({
show: false,
webPreferences: {
contextIsolation: true,
preload: path.join(fixtures, 'api', 'isolated-process.js')
}
});
const p = emittedOnce(ipcMain, 'context-isolation');
iw.loadURL('about:blank');
const [, contextIsolation] = await p;
expect(contextIsolation).to.be.true('contextIsolation');
});
}); });
describe('reloading with allowRendererProcessReuse enabled', () => { describe('reloading with allowRendererProcessReuse enabled', () => {

View file

@ -40,6 +40,7 @@
arch: process.arch, arch: process.arch,
platform: process.platform, platform: process.platform,
sandboxed: process.sandboxed, sandboxed: process.sandboxed,
contextIsolation: process.contextIsolation,
type: process.type, type: process.type,
version: process.version, version: process.version,
versions: process.versions, versions: process.versions,

3
spec/fixtures/api/isolated-process.js vendored Normal file
View file

@ -0,0 +1,3 @@
const { ipcRenderer } = require('electron');
ipcRenderer.send('context-isolation', process.contextIsolation);