Skip to content

Commit ae449a4

Browse files
Bump the npm_and_yarn group across 1 directory with 2 updates (#683)
* Bump the npm_and_yarn group across 1 directory with 2 updates Bumps the npm_and_yarn group with 2 updates in the /gcs directory: [electron](https://github.com/electron/electron) and [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). Updates `electron` from 26.6.10 to 38.0.0 - [Release notes](https://github.com/electron/electron/releases) - [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md) - [Commits](electron/electron@v26.6.10...v38.0.0) Updates `vite` from 4.5.14 to 7.1.5 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v7.1.5/packages/vite) --- updated-dependencies: - dependency-name: electron dependency-version: 38.0.0 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: vite dependency-version: 7.1.5 dependency-type: direct:development dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> * Update to new latest electron version, refactor ipc renderer functions * Address copilot review comments --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kush Makkapati <kush.makkapati@icloud.com>
1 parent 3e91d65 commit ae449a4

21 files changed

Lines changed: 165 additions & 131 deletions

File tree

gcs/electron/main.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,54 +129,55 @@ function getUserConfiguration() {
129129
return userSettings
130130
}
131131

132-
ipcMain.handle("getSettings", () => {
132+
ipcMain.handle("settings:fetch-settings", () => {
133133
return getUserConfiguration()
134134
})
135-
ipcMain.handle("setSettings", (_, settings) => {
135+
ipcMain.handle("settings:save-settings", (_, settings) => {
136136
saveUserConfiguration(settings)
137137
})
138138

139-
ipcMain.handle("isMac", () => {
139+
ipcMain.handle("app:is-mac", () => {
140140
return process.platform == "darwin"
141141
})
142-
ipcMain.on("close", () => {
142+
ipcMain.on("window:close", () => {
143143
closeWithBackend()
144144
})
145-
ipcMain.on("minimise", () => {
145+
ipcMain.on("window:minimise", () => {
146146
getWindow()?.minimize()
147147
})
148-
ipcMain.on("maximise", () => {
148+
ipcMain.on("window:maximise", () => {
149149
getWindow()?.isMaximized()
150150
? getWindow()?.unmaximize()
151151
: getWindow()?.maximize()
152152
})
153153

154-
ipcMain.on("reload", () => {
154+
ipcMain.on("window:reload", () => {
155155
getWindow()?.reload()
156156
})
157-
ipcMain.on("force_reload", () => {
157+
ipcMain.on("window:force-reload", () => {
158158
getWindow()?.webContents.reloadIgnoringCache()
159159
})
160-
ipcMain.on("toggle_developer_tools", () => {
160+
ipcMain.on("window:toggle-developer-tools", () => {
161161
getWindow()?.webContents.toggleDevTools()
162162
})
163-
ipcMain.on("actual_size", () => {
163+
ipcMain.on("window:actual-size", () => {
164164
getWindow()?.webContents.setZoomFactor(1)
165165
})
166-
ipcMain.on("toggle_fullscreen", () => {
166+
ipcMain.on("window:toggle-fullscreen", () => {
167167
getWindow()?.isFullScreen()
168168
? getWindow()?.setFullScreen(false)
169169
: getWindow()?.setFullScreen(true)
170170
})
171-
ipcMain.on("zoom_in", () => {
171+
ipcMain.on("window:zoom-in", () => {
172172
const window = getWindow()?.webContents
173173
window?.setZoomFactor(window?.getZoomFactor() + 0.1)
174174
})
175-
ipcMain.on("zoom_out", () => {
175+
ipcMain.on("window:zoom-out", () => {
176176
const window = getWindow()?.webContents
177177
window?.setZoomFactor(window?.getZoomFactor() - 0.1)
178178
})
179-
ipcMain.on("openFileInExplorer", (_event, filePath) => {
179+
180+
ipcMain.on("window:open-file-in-explorer", (_event, filePath) => {
180181
shell.showItemInFolder(filePath)
181182
})
182183

gcs/electron/modules/aboutWindow.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ export function openAboutPopout() {
3737
return { action: "deny" }
3838
})
3939

40-
// Windows doesn't consider maximising to be fullscreening so we must prevent default
41-
aboutPopoutWin.on("maximize", (e: Event) => {
42-
e.preventDefault()
43-
})
4440
aboutPopoutWin.on("close", () => {
4541
aboutPopoutWin = null
4642
})
@@ -58,11 +54,11 @@ export function destroyAboutWindow() {
5854
}
5955

6056
export default function registerAboutIPC() {
61-
ipcMain.removeHandler("openAboutWindow")
62-
ipcMain.removeHandler("closeAboutWindow")
57+
ipcMain.removeHandler("app:open-about-window")
58+
ipcMain.removeHandler("app:close-about-window")
6359

64-
ipcMain.handle("openAboutWindow", () => {
60+
ipcMain.handle("app:open-about-window", () => {
6561
openAboutPopout()
6662
})
67-
ipcMain.handle("closeAboutWindow", () => closeAboutPopout())
63+
ipcMain.handle("app:close-about-window", () => closeAboutPopout())
6864
}

gcs/electron/modules/linkStatsWindow.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ export function openLinkStatsWindow() {
2929
linkStatsWin?.loadFile(path.join(process.env.DIST, "linkStats.html"))
3030
}
3131

32-
// Windows doesn't consider maximising to be fullscreening so we must prevent default
33-
linkStatsWin.on("maximize", (e: Event) => {
34-
e.preventDefault()
35-
})
3632
linkStatsWin.on("close", () => {
3733
linkStatsWin = null
3834
})
@@ -50,16 +46,16 @@ export function destroyLinkStatsWindow() {
5046
}
5147

5248
export default function registerLinkStatsIPC() {
53-
ipcMain.removeHandler("openLinkStatsWindow")
54-
ipcMain.removeHandler("closeLinkStatsWindow")
55-
ipcMain.removeHandler("update-link-stats")
49+
ipcMain.removeHandler("app:open-link-stats-window")
50+
ipcMain.removeHandler("app:close-link-stats-window")
51+
ipcMain.removeHandler("app:update-link-stats")
5652

57-
ipcMain.handle("openLinkStatsWindow", () => {
53+
ipcMain.handle("app:open-link-stats-window", () => {
5854
openLinkStatsWindow()
5955
})
60-
ipcMain.handle("closeLinkStatsWindow", () => closeLinkStatsWindow())
61-
ipcMain.handle("update-link-stats", (_, linkStats) => {
62-
linkStatsWin?.webContents.send("send-link-stats", linkStats)
56+
ipcMain.handle("app:close-link-stats-window", () => closeLinkStatsWindow())
57+
ipcMain.handle("app:update-link-stats", (_, linkStats) => {
58+
linkStatsWin?.webContents.send("app:send-link-stats", linkStats)
6359
const uptimeFormatted = new Date(Math.round(linkStats.uptime) * 1000)
6460
.toISOString()
6561
.substring(11, 19)

gcs/electron/modules/webcam.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@ export function openWebcamPopout(
7171
})
7272
})
7373

74-
// Windows doesn't consider maximising to be fullscreening so we must prevent default
75-
webcamPopoutWin.on("maximize", (e: Event) => {
76-
e.preventDefault()
77-
})
78-
7974
// Ensure initial size fits the aspect ratio ()
8075
webcamPopoutWin.setSize(
8176
webcamPopoutWin.getBounds().width,
@@ -92,7 +87,7 @@ export function openWebcamPopout(
9287
export function closeWebcamPopout(mainWindow: BrowserWindow | null) {
9388
console.log("Destroying webcam window")
9489
destroyWebcamWindow()
95-
mainWindow?.webContents.send("webcam-closed")
90+
mainWindow?.webContents.send("app:webcam-closed")
9691
}
9792

9893
export function destroyWebcamWindow() {
@@ -101,11 +96,11 @@ export function destroyWebcamWindow() {
10196
}
10297

10398
export default function registerWebcamIPC(mainWindow: BrowserWindow) {
104-
ipcMain.removeHandler("openWebcamWindow")
105-
ipcMain.removeHandler("closeWebcamWindow")
99+
ipcMain.removeHandler("app:open-webcam-window")
100+
ipcMain.removeHandler("app:close-webcam-window")
106101

107-
ipcMain.handle("openWebcamWindow", (_, videoStreamId, name, aspect) => {
102+
ipcMain.handle("app:open-webcam-window", (_, videoStreamId, name, aspect) => {
108103
openWebcamPopout(videoStreamId, name, aspect)
109104
})
110-
ipcMain.handle("closeWebcamWindow", () => closeWebcamPopout(mainWindow))
105+
ipcMain.handle("app:close-webcam-window", () => closeWebcamPopout(mainWindow))
111106
}

gcs/electron/preload.js

Lines changed: 71 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,82 @@
11
import { contextBridge, ipcRenderer } from "electron"
22

33
// --------- Expose some API to the Renderer process ---------
4+
// Whitelist of allowed IPC channels for security
5+
const ALLOWED_INVOKE_CHANNELS = [
6+
"fla:open-file",
7+
"fla:get-recent-logs",
8+
"fla:clear-recent-logs",
9+
"missions:get-save-mission-file-path",
10+
"app:get-node-env",
11+
"app:get-version",
12+
"app:is-mac",
13+
"settings:fetch-settings",
14+
"settings:save-settings",
15+
"app:open-webcam-window",
16+
"app:close-webcam-window",
17+
"app:open-about-window",
18+
"app:close-about-window",
19+
"app:open-link-stats-window",
20+
"app:close-link-stats-window",
21+
"app:update-link-stats",
22+
]
23+
24+
const ALLOWED_SEND_CHANNELS = [
25+
"window:close",
26+
"window:minimise",
27+
"window:maximise",
28+
"window:reload",
29+
"window:force-reload",
30+
"window:toggle-developer-tools",
31+
"window:actual-size",
32+
"window:toggle-fullscreen",
33+
"window:zoom-in",
34+
"window:zoom-out",
35+
"window:open-file-in-explorer",
36+
]
37+
38+
const ALLOWED_ON_CHANNELS = [
39+
"main-process-message",
40+
"app:webcam-closed",
41+
"app:send-link-stats",
42+
"fla:log-parse-progress",
43+
]
44+
445
contextBridge.exposeInMainWorld("ipcRenderer", {
5-
...withPrototype(ipcRenderer),
6-
loadFile: (data) => ipcRenderer.invoke("fla:open-file", data),
7-
getRecentLogs: () => ipcRenderer.invoke("fla:get-recent-logs"),
8-
clearRecentLogs: () => ipcRenderer.invoke("fla:clear-recent-logs"),
9-
getSaveMissionFilePath: (options) =>
10-
ipcRenderer.invoke("missions:get-save-mission-file-path", options),
11-
getNodeEnv: () => ipcRenderer.invoke("app:get-node-env"),
12-
getVersion: () => ipcRenderer.invoke("app:get-version"),
13-
getSettings: () => ipcRenderer.invoke("getSettings"),
14-
saveSettings: (settings) => ipcRenderer.invoke("setSettings", settings),
15-
openWebcamWindow: (id, name, aspect) =>
16-
ipcRenderer.invoke("openWebcamWindow", id, name, aspect),
17-
closeWebcamWindow: () => ipcRenderer.invoke("closeWebcamWindow"),
18-
onCameraWindowClose: (callback) =>
19-
ipcRenderer.on("webcam-closed", () => callback()),
20-
openAboutWindow: () => ipcRenderer.invoke("openAboutWindow"),
21-
closeAboutWindow: () => ipcRenderer.invoke("closeAboutWindow"),
22-
openLinkStatsWindow: () => ipcRenderer.invoke("openLinkStatsWindow"),
23-
closeLinkStatsWindow: () => ipcRenderer.invoke("closeLinkStatsWindow"),
24-
updateLinkStats: (linkStats) =>
25-
ipcRenderer.invoke("update-link-stats", linkStats),
26-
onGetLinkStats: (callback) =>
27-
ipcRenderer.on("send-link-stats", (_, stats) => callback(stats)),
28-
})
46+
// Secure invoke method - only allows whitelisted channels
47+
invoke: (channel, ...args) => {
48+
if (ALLOWED_INVOKE_CHANNELS.includes(channel)) {
49+
return ipcRenderer.invoke(channel, ...args)
50+
}
51+
throw new Error(`IPC invoke channel '${channel}' is not allowed`)
52+
},
2953

30-
// `exposeInMainWorld` can't detect attributes and methods of `prototype`, manually patching it.
31-
function withPrototype(obj) {
32-
const protos = Object.getPrototypeOf(obj)
54+
// Secure send method - only allows whitelisted channels
55+
send: (channel, ...args) => {
56+
if (ALLOWED_SEND_CHANNELS.includes(channel)) {
57+
return ipcRenderer.send(channel, ...args)
58+
}
59+
throw new Error(`IPC send channel '${channel}' is not allowed`)
60+
},
3361

34-
for (const [key, value] of Object.entries(protos)) {
35-
if (Object.prototype.hasOwnProperty.call(obj, key)) continue
62+
// Secure on method - only allows whitelisted channels
63+
on: (channel, callback) => {
64+
if (ALLOWED_ON_CHANNELS.includes(channel)) {
65+
return ipcRenderer.on(channel, callback)
66+
}
67+
throw new Error(`IPC on channel '${channel}' is not allowed`)
68+
},
3669

37-
if (typeof value === "function") {
38-
// Some native APIs, like `NodeJS.EventEmitter['on']`, don't work in the Renderer process. Wrapping them into a function.
39-
obj[key] = function (...args) {
40-
return value.call(obj, ...args)
41-
}
42-
} else {
43-
obj[key] = value
70+
// Secure removeAllListeners - only for whitelisted channels
71+
removeAllListeners: (channel) => {
72+
if (ALLOWED_ON_CHANNELS.includes(channel)) {
73+
return ipcRenderer.removeAllListeners(channel)
4474
}
45-
}
46-
return obj
47-
}
75+
throw new Error(
76+
`IPC removeAllListeners channel '${channel}' is not allowed`,
77+
)
78+
},
79+
})
4880

4981
// --------- Preload scripts loading ---------
5082
function domReady(condition = ["complete", "interactive"]) {

gcs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
"@vitejs/plugin-react": "^4.0.4",
8888
"@vitest/browser": "^2.0.5",
8989
"autoprefixer": "^10.4.16",
90-
"electron": "^26.1.0",
90+
"electron": "^38.0.0",
9191
"electron-builder": "^24.6.4",
9292
"eslint": "^8.48.0",
9393
"eslint-plugin-react-hooks": "^4.6.0",
@@ -96,7 +96,7 @@
9696
"postcss-preset-mantine": "^1.12.0",
9797
"postcss-simple-vars": "^7.0.1",
9898
"typescript": "^5.2.2",
99-
"vite": "^4.5.3",
99+
"vite": "^7.1.5",
100100
"vite-plugin-electron": "^0.14.0",
101101
"vite-plugin-electron-renderer": "^0.14.5"
102102
},

gcs/src/components/SingleRunWrapper.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ export default function SingleRunWrapper({ children }) {
4848
// this is done by getting the latest release from the GitHub API and comparing
4949
// it to the current version.
5050

51-
const nodeEnv = await window.ipcRenderer.getNodeEnv()
51+
const nodeEnv = await window.ipcRenderer.invoke("app:get-node-env")
5252
if (nodeEnv !== "production") return
5353

54-
const currentVersion = await window.ipcRenderer.getVersion()
54+
const currentVersion = await window.ipcRenderer.invoke("app:get-version")
5555

5656
// https://docs.github.com/en/rest/releases/releases#get-the-latest-release
5757
const latestGithubRelease = await octokit.request(

gcs/src/components/dashboard/tabsSectionTabs/cameraTabsSection.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
*/
55

66
// Native
7-
import { useCallback, useState, useEffect, useRef } from "react"
7+
import { useCallback, useEffect, useRef, useState } from "react"
88

99
// Mantine
10+
import { Select, Tabs } from "@mantine/core"
1011
import { useSessionStorage } from "@mantine/hooks"
11-
import { Tabs, Select } from "@mantine/core"
1212

1313
// Helper
14-
import Webcam from "react-webcam"
1514
import { IconExternalLink, IconVideoOff } from "@tabler/icons-react"
15+
import Webcam from "react-webcam"
1616

1717
export default function CameraTabsSection({ tabPadding }) {
1818
// Camera devices
@@ -21,7 +21,7 @@ export default function CameraTabsSection({ tabPadding }) {
2121
defaultValue: null,
2222
})
2323

24-
window.ipcRenderer.onCameraWindowClose(() => setPictureInPicture(false))
24+
window.ipcRenderer.on("app:webcam-closed", () => setPictureInPicture(false))
2525

2626
// Ref used to get video capture stream to send to new electron window
2727
const videoRef = useRef(null)
@@ -47,8 +47,9 @@ export default function CameraTabsSection({ tabPadding }) {
4747
streamTrack.getSettings().width / streamTrack.getSettings().height
4848

4949
pictureInPicture
50-
? window.ipcRenderer.closeWebcamWindow()
51-
: window.ipcRenderer.openWebcamWindow(
50+
? window.ipcRenderer.invoke("app:close-webcam-window")
51+
: window.ipcRenderer.invoke(
52+
"app:open-webcam-window",
5253
deviceId,
5354
streamTrack.label,
5455
streamAspect,

gcs/src/components/dashboard/webcam/webcam.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"use client"
22

3-
import Webcam from "react-webcam"
43
import { IconX } from "@tabler/icons-react"
54
import { useRef } from "react"
5+
import Webcam from "react-webcam"
66

77
export default function CameraWindow() {
88
const searchParams = new URLSearchParams(window.location.search)
@@ -22,7 +22,7 @@ export default function CameraWindow() {
2222
</div>
2323
<button
2424
className="group px-2 no-drag hover:bg-red-500 h-[100%]"
25-
onClick={() => window.ipcRenderer.closeWebcamWindow()}
25+
onClick={() => window.ipcRenderer.invoke("app:close-webcam-window")}
2626
>
2727
<IconX
2828
stroke={2}

gcs/src/components/error/errorBoundary.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default function ErrorBoundaryFallback({ error }) {
5555
size="lg"
5656
variant="light"
5757
color="blue"
58-
onClick={() => window.ipcRenderer.send("force_reload")}
58+
onClick={() => window.ipcRenderer.send("window:force-reload")}
5959
className="mt-2"
6060
>
6161
Go Back!

0 commit comments

Comments
 (0)