Skip to main content

Electron Context Isolation

What is Context Isolation?

Electron's context isolation feature ensures that your preload scripts and Electron's internal logic run in a separate context from the web content being loaded. This is crucial for security, as it helps prevent websites from accessing Electron's internal components and the high-level APIs that your preload scripts can access.

This means that the window object your preload script accesses is not the same one that the website can access.

For example, if you set window.hello = 'wave' in your preload script and context isolation is enabled, the website will receive undefined when trying to access window.hello.

Note

Context isolation has been enabled by default since Electron 12, and it is a recommended security setting for all applications. For more details and usage, refer to the Electron official documentation.

Electron Context Isolation Solution

With context isolation enabled, you cannot directly import @rongcloud/imlib-next in the renderer process. Instead, you should import it in the preload script (preload.js) and expose RongIMLib to the renderer process via the contextBridge module. The specific modifications are as follows:

Step 1: Main Process Initialization

In the main process, set contextIsolation to true in webPreferences.

// main.js
const { app, BrowserWindow } = require('electron')
const RCInit = require('@rongcloud/electron')

let rcService

app.on('ready', () => {
// Initialize after the app's ready event
rcService = RCInit({
/**
* [Required] Appkey, mandatory since version 5.6.0
* [option]
*/
appkey: '<appkey>',
/**
* [Optional] Storage location for the message database, not recommended to change
* [option]
*/
dbPath: app.getPath('userData'),
/**
* [Optional] Log level
* [option] 4 - DEBUG, 3 - INFO, 2(default) - WARN, 1 - ERROR
*/
logOutputLevel: 2,
/**
* [Optional] Whether to sync empty pinned conversations, default is `false`
* [option]
*/
enableSyncEmptyTopConversation: false
})

// Initialize the UI window
const browserWin = new BrowserWindow({
webPreferences: {
// Specify the preload.js file, which references @rongcloud/electron-renderer
preload: '<path/to/preload.js>',
// Enable Electron context isolation
contextIsolation: true,
nodeIntegration: true
}
})

app.on('before-quit', () => {
// Clean up state when the app exits
rcService.destroy()
})
})

Step 2: SDK Import

Import @rongcloud/electron-renderer and @rongcloud/imlib-next in preload.js.

// preload.js
const { contextBridge } = require('electron')

require('@rongcloud/electron-renderer');

const RongIMLib = require('@rongcloud/imlib-next')

contextBridge.exposeInMainWorld('RongIMLib', RongIMLib)

Step 3: Renderer Process Usage

In the renderer process, you can access RongIMLib via the window object to perform initialization and connection actions.

// Renderer process index.js

import { initRenderer } from '@rongcloud/electron-renderer/renderer';
initRenderer();

// App initialization, ensure this process is executed only once
const RongIMLib = window.RongIMLib

RongIMLib.init({ appkey: '<Your-App-Key>' });

// Add event listeners
const Events = RongIMLib.Events

RongIMLib.addEventListener(Events.CONNECTING, () => {
console.log('Connecting to server...')
})

RongIMLib.addEventListener(Events.CONNECTED, () => {
console.log('Connected to server')
})

RongIMLib.addEventListener(Events.MESSAGES, (evt) => {
console.log(evt.messages)
})

// Establish connection
RongIMLib.connect('<Your-Token>').then(res => {
if (res.code === RongIMLib.ErrorCode.SUCCESS) {
console.log('Connection successful, connected user ID:', res.data.userId);
} else {
console.warn('Connection failed, code:', res.code)
}
})