[GH-ISSUE #88] 🗺️ Roadmap: Message Indicator #159

Closed
opened 2026-03-13 17:32:34 +03:00 by kerem · 1 comment
Owner

Originally created by @Aetherinox on GitHub (Jun 10, 2025).
Original GitHub issue: https://github.com/Aetherinox/ntfy-desktop/issues/88

Originally assigned to: @Aetherinox on GitHub.

Summary

Add application badge indicator stating how many unread messages are currently pending review in the desktop app.


Tasks

  • Create a preload.js script and attach it to BrowserWindow
    • create api end-points to expose to the main process:
      • send
      • receive
    • BrowserWindow should contain the following webPreferences:
      • nodeIntegration: false
      • contextIsolation: true
      • enableRemoteModule: false
      • preload: path.join(__dirname, "preload.js")
    • Inject window.api.receive into webContents.on( 'did-finish-load', ()
  • Create ipcMain in main process index.js
  • Use Storage class to store current number of unread messages
  • Clear unread message badge count once user opens message window

Resources


References:




Notes

Since we are injecting code between the main process and the ipc; we must ensure security when sending data. Main browser window must contain the following settings

webPreferences: {
    nodeIntegration: false,
    contextIsolation: true // to protect against prototype pollution
    enableRemoteModule: false // turn off remote
    preload: path.join(__dirname, "preload.js")  // use preload script
}

The renderer should not have direct access to node (ie. require()). We should only be giving access to require(), and anytime the renderer process needs to use require, marshal a request to the main process.

On the renderer side; we set up ipcRenderer bindings. On the main side; set up ipcMain bindings.

In the ipcMain bindings; set up listener methods that use modules that we require(). This allows the main process access to require(), but moderates what it has access to.

Use the contextBridge to pass the ipcRenderer bindings to our app code for use. When the app needs to use the required() modules in main, it sends a message via IPC (inter-process-communication) and the main process runs some code, and we then send a message back with our result.


Warning

Using nodeIntegration

Try to keep nodeIntegration: false to act as a safeguard for accidental/malicious users using apps, and prevent any possible malware that might ever get installed on a machine from interacting with the electron app and using the nodeIntegration: true attack vector.

This problem manifests when you (any one of the below):

  • Have nodeIntegration: true enabled
  • Use the remote module

All of these problems give uninterrupted access to node from your renderer process.

Originally created by @Aetherinox on GitHub (Jun 10, 2025). Original GitHub issue: https://github.com/Aetherinox/ntfy-desktop/issues/88 Originally assigned to: @Aetherinox on GitHub. ## Summary Add application badge indicator stating how many unread messages are currently pending review in the desktop app. <br /> ### Tasks - [x] Create a `preload.js` script and attach it to `BrowserWindow` - [x] create api end-points to expose to the main process: - [x] `send` - [x] `receive` - [x] `BrowserWindow` should contain the following `webPreferences`: - [x] `nodeIntegration: false` - [x] `contextIsolation: true` - [x] `enableRemoteModule: false` - [x] `preload: path.join(__dirname, "preload.js")` - [x] Inject `window.api.receive` into `webContents.on( 'did-finish-load', ()` - [x] Create `ipcMain` in main process `index.js` - [x] Use `Storage` class to store current number of unread messages - [x] Clear unread message badge count once user opens message window <br /> ### Resources - https://www.electronjs.org/docs/latest/tutorial/tutorial-preload - https://www.electronjs.org/docs/latest/api/web-contents <br /> ### References: - #27 <br /> --- <br /> ## Notes Since we are injecting code between the main process and the ipc; we must ensure security when sending data. Main browser window must contain the following settings ```javascript webPreferences: { nodeIntegration: false, contextIsolation: true // to protect against prototype pollution enableRemoteModule: false // turn off remote preload: path.join(__dirname, "preload.js") // use preload script } ``` <br /> The renderer should not have direct access to node (ie. require()). We should only be giving access to `require()`, and anytime the renderer process needs to use require, marshal a request to the main process. On the **renderer** side; we set up [ipcRenderer](https://www.electronjs.org/docs/api/ipc-renderer) bindings. On the **main** side; set up [ipcMain](https://www.electronjs.org/docs/api/ipc-main) bindings. In the **ipcMain** bindings; set up **listener** methods that use modules that we `require()`. This allows the main process access to `require()`, but moderates what it has access to. Use the [contextBridge](https://www.electronjs.org/docs/api/context-bridge) to pass the **ipcRenderer** bindings to our app code for use. When the app needs to use the `required()` modules in main, it sends a message via IPC (inter-process-communication) and the main process runs some code, and we then send a message back with our result. <br /> > [!WARNING] > Using `nodeIntegration` > > Try to keep `nodeIntegration: false` to act as a safeguard for accidental/malicious users using apps, and prevent any possible malware that might ever get installed on a machine from interacting with the electron app and using the `nodeIntegration: true` attack vector. > > This problem manifests when you (any one of the below): > > - Have `nodeIntegration: true` enabled > - Use the [remote](https://www.electronjs.org/docs/api/remote) module > > All of these problems give uninterrupted access to node from your renderer process.
Author
Owner

@Aetherinox commented on GitHub (Jun 25, 2025):

Update

  • ipc communication between renderer and main process added
  • badge count clears when user brings ntfy window to front and clicks on a button on the left-side to ensure user activity
  • added new renderer and preload scripts to handle communication between all processes
<!-- gh-comment-id:3005423834 --> @Aetherinox commented on GitHub (Jun 25, 2025): ## Update - ipc communication between renderer and main process added - badge count clears when user brings ntfy window to front and clicks on a button on the left-side to ensure user activity - added new `renderer` and `preload` scripts to handle communication between all processes
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ntfy-desktop#159
No description provided.