Harden render server and import boundaries
This commit is contained in:
1 parent
5cc373cf6b
commit
fae55e3f13
11 files changed
+2400
-54
No files matched your search
+26
-3
@@ -1,9 +1,11 @@
|
||||
import { app, BrowserWindow, Menu, shell } from 'electron'
|
||||
import type { BrowserWindow as BrowserWindowInstance, Event, MenuItemConstructorOptions } from 'electron'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const isDev = !app.isPackaged
|
||||
const devServerUrl = process.env.VITE_DEV_SERVER_URL ?? 'http://localhost:5200'
|
||||
const devServerOrigin = new URL(devServerUrl).origin
|
||||
const appIconPath = isDev
|
||||
? path.join(process.cwd(), 'build', 'icon.png')
|
||||
: path.join(process.resourcesPath, 'build', 'icon.png')
|
||||
@@ -15,6 +17,28 @@ function sendAppCommand(command: string): void {
|
||||
mainWindow.webContents.send('ruwio:menu-command', command)
|
||||
}
|
||||
|
||||
function parseUrl(raw: string): URL | null {
|
||||
try {
|
||||
return new URL(raw)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function isAllowedAppNavigation(raw: string): boolean {
|
||||
const url = parseUrl(raw)
|
||||
if (!url) return false
|
||||
if (isDev) return url.origin === devServerOrigin
|
||||
if (url.protocol !== 'file:') return false
|
||||
const appEntry = path.join(app.getAppPath(), 'dist', 'index.html')
|
||||
return path.normalize(fileURLToPath(url)) === path.normalize(appEntry)
|
||||
}
|
||||
|
||||
function isAllowedExternalUrl(raw: string): boolean {
|
||||
const url = parseUrl(raw)
|
||||
return url?.protocol === 'https:'
|
||||
}
|
||||
|
||||
function createMainWindow(): void {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
@@ -38,15 +62,14 @@ function createMainWindow(): void {
|
||||
})
|
||||
|
||||
mainWindow.webContents.setWindowOpenHandler(({ url }: { url: string }) => {
|
||||
if (url.startsWith('https://') || url.startsWith('http://')) {
|
||||
if (isAllowedExternalUrl(url)) {
|
||||
void shell.openExternal(url)
|
||||
}
|
||||
return { action: 'deny' }
|
||||
})
|
||||
|
||||
mainWindow.webContents.on('will-navigate', (event: Event, url: string) => {
|
||||
const allowedUrl = isDev ? devServerUrl : `file://${path.join(app.getAppPath(), 'dist', 'index.html')}`
|
||||
if (!url.startsWith(allowedUrl)) {
|
||||
if (!isAllowedAppNavigation(url)) {
|
||||
event.preventDefault()
|
||||
}
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user