diff --git a/docs/api/extensions.md b/docs/api/extensions.md index 67837b391f..4a93951024 100644 --- a/docs/api/extensions.md +++ b/docs/api/extensions.md @@ -28,6 +28,9 @@ session.loadExtension('path/to/unpacked/extension').then(({ id }) => { Loaded extensions will not be automatically remembered across exits; if you do not call `loadExtension` when the app runs, the extension will not be loaded. +Note that loading extensions is only supported in persistent sessions. +Attempting to load an extension into an in-memory session will throw an error. + See the [`session`](session.md) documentation for more information about loading, unloading, and querying active extensions. diff --git a/docs/api/session.md b/docs/api/session.md index 3cc8ff5b63..de2fcd8f86 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -507,6 +507,8 @@ requests an API that Electron does not support) then they will be logged to the console. Note that Electron does not support the full range of Chrome extensions APIs. +See [Supported Extensions APIs](extensions.md#supported-extensions-apis) for +more details on what is supported. Note that in previous versions of Electron, extensions that were loaded would be remembered for future runs of the application. This is no longer the case: @@ -529,6 +531,9 @@ This API does not support loading packed (.crx) extensions. **Note:** This API cannot be called before the `ready` event of the `app` module is emitted. +**Note:** Loading extensions into in-memory (non-persistent) sessions is not +supported and will throw an error. + #### `ses.removeExtension(extensionId)` * `extensionId` String - ID of extension to remove diff --git a/shell/browser/api/electron_api_session.cc b/shell/browser/api/electron_api_session.cc index 39a9f65c12..860d001019 100644 --- a/shell/browser/api/electron_api_session.cc +++ b/shell/browser/api/electron_api_session.cc @@ -613,6 +613,11 @@ v8::Local Session::LoadExtension( const base::FilePath& extension_path) { gin_helper::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); + if (browser_context()->IsOffTheRecord()) { + promise.RejectWithErrorMessage( + "Extensions cannot be loaded in a temporary session"); + return handle; + } auto* extension_system = static_cast( extensions::ExtensionSystem::Get(browser_context())); diff --git a/spec-main/extensions-spec.ts b/spec-main/extensions-spec.ts index e1ff0268be..e69d8eb856 100644 --- a/spec-main/extensions-spec.ts +++ b/spec-main/extensions-spec.ts @@ -24,8 +24,13 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex after(() => { server.close() }) - afterEach(closeAllWindows) + afterEach(() => { + session.defaultSession.getAllExtensions().forEach((e: any) => { + session.defaultSession.removeExtension(e.id) + }) + }) + it('loads an extension', async () => { // NB. we have to use a persist: session (i.e. non-OTR) because the // extension registry is redirected to the main session. so installing an @@ -73,13 +78,18 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex it('confines an extension to the session it was loaded in', async () => { const customSession = session.fromPartition(`persist:${require('uuid').v4()}`) - customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg')) + await customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg')) const w = new BrowserWindow({ show: false }) // not in the session await w.loadURL(url) const bg = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor') expect(bg).to.equal('') }) + it('loading an extension in a temporary session throws an error', async () => { + const customSession = session.fromPartition(require('uuid').v4()) + await expect(customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'))).to.eventually.be.rejectedWith('Extensions cannot be loaded in a temporary session') + }) + describe('chrome.runtime', () => { let content: any before(async () => { @@ -239,12 +249,6 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex }) describe('deprecation shims', () => { - afterEach(() => { - session.defaultSession.getAllExtensions().forEach((e: any) => { - session.defaultSession.removeExtension(e.id) - }) - }) - it('loads an extension through BrowserWindow.addExtension', async () => { BrowserWindow.addExtension(path.join(fixtures, 'extensions', 'red-bg')) const w = new BrowserWindow({ show: false })