diff --git a/docs/api/extensions.md b/docs/api/extensions.md index 67837b391..4a9395102 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 3cc8ff5b6..de2fcd8f8 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 39a9f65c1..860d00101 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 e1ff0268b..e69d8eb85 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 })