Compare commits

...

1 Commits

Author SHA1 Message Date
Hona 07c4e096ad fix(desktop): preserve window permissions 2026-08-27 17:01:59 +00:00
3 changed files with 44 additions and 8 deletions
@@ -0,0 +1,17 @@
import { describe, expect, test } from "bun:test"
import { isMainWindowWebContents, isRendererPermission } from "./permissions"
describe("renderer permissions", () => {
test("allows only required renderer permissions", () => {
expect(isRendererPermission("notifications")).toBe(true)
expect(isRendererPermission("clipboard-sanitized-write")).toBe(true)
expect(isRendererPermission("media")).toBe(false)
})
test("accepts every current main window", () => {
const windows = [11, 22]
expect(isMainWindowWebContents(11, windows)).toBe(true)
expect(isMainWindowWebContents(22, windows)).toBe(true)
expect(isMainWindowWebContents(33, windows)).toBe(false)
})
})
@@ -0,0 +1,9 @@
const rendererPermissions = new Set(["clipboard-sanitized-write", "notifications"])
export function isRendererPermission(permission: string) {
return rendererPermissions.has(permission)
}
export function isMainWindowWebContents(id: number, windowIds: number[]) {
return windowIds.includes(id)
}
+18 -8
View File
@@ -1,18 +1,28 @@
import type { BrowserWindow } from "electron"
import { BrowserWindow } from "electron"
import type { Session } from "electron"
import { isMainWindowWebContents, isRendererPermission } from "./permissions"
import { addRendererHeaders, isRendererUrl, upsertHeader } from "./protocol"
const rendererPermissions = new Set(["clipboard-sanitized-write", "notifications"])
const configuredSessions = new WeakSet<Session>()
export function allowRendererPermissions(win: BrowserWindow) {
const webContentsId = win.webContents.id
win.webContents.session.setPermissionRequestHandler((webContents, permission, callback, details) => {
const session = win.webContents.session
if (configuredSessions.has(session)) return
configuredSessions.add(session)
const windowIds = () =>
BrowserWindow.getAllWindows()
.filter((win) => !win.isDestroyed())
.map((win) => win.webContents.id)
session.setPermissionRequestHandler((webContents, permission, callback, details) => {
callback(
rendererPermissions.has(permission) && isRendererUrl(details.requestingUrl) && webContents.id === webContentsId,
isRendererPermission(permission) &&
isRendererUrl(details.requestingUrl) &&
isMainWindowWebContents(webContents.id, windowIds()),
)
})
win.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
if (!rendererPermissions.has(permission)) return false
if (webContents && webContents.id !== webContentsId) return false
session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
if (!isRendererPermission(permission)) return false
if (webContents && !isMainWindowWebContents(webContents.id, windowIds())) return false
return isRendererUrl(details.requestingUrl) || isRendererUrl(requestingOrigin)
})
}