mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
- applyWindowsAppUserModelId() so Windows attributes toast notifications to the app (kept in sync with build.appId via a test); no-op on macOS/Linux - main window: setWindowOpenHandler denies uncontrolled popups, routes http(s) links to the system browser; intentionally no will-navigate guard so dev HMR reloads keep working - preview view: denies popups + blocks non-http(s) navigation (file:/custom schemes) while allowing in-page http(s) browsing Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
export type WindowOpenHandlerResult = { action: 'deny' } | { action: 'allow' }
|
|
|
|
export type NavigationGuardWebContents = {
|
|
setWindowOpenHandler(handler: (details: { url: string }) => WindowOpenHandlerResult): void
|
|
on(
|
|
event: 'will-navigate',
|
|
handler: (event: { preventDefault: () => void }, url: string) => void,
|
|
): unknown
|
|
}
|
|
|
|
export type NavigationGuardOptions = {
|
|
openExternal: (url: string) => void
|
|
}
|
|
|
|
export function isHttpUrl(url: string): boolean {
|
|
try {
|
|
const { protocol } = new URL(url)
|
|
return protocol === 'http:' || protocol === 'https:'
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Main app window guard. The renderer is a single-page app loaded from a fixed
|
|
* entry; it should never spawn an uncontrolled child window. Any window.open /
|
|
* target=_blank with an http(s) URL is routed to the system browser and the
|
|
* Electron popup is denied. We intentionally do NOT install a `will-navigate`
|
|
* guard here so that dev HMR reloads and in-app navigations keep working.
|
|
*/
|
|
export function installMainWindowNavigationGuards(
|
|
webContents: NavigationGuardWebContents,
|
|
{ openExternal }: NavigationGuardOptions,
|
|
): void {
|
|
webContents.setWindowOpenHandler(({ url }) => {
|
|
if (isHttpUrl(url)) openExternal(url)
|
|
return { action: 'deny' }
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Preview (WebContentsView) guard. The preview renders untrusted remote pages,
|
|
* so it must keep working as a browser: in-page http(s) navigation is allowed.
|
|
* Popups are denied (http(s) ones handed to the system browser), and navigation
|
|
* to any non-http(s) scheme (file:, custom schemes) is blocked outright.
|
|
*/
|
|
export function installPreviewNavigationGuards(
|
|
webContents: NavigationGuardWebContents,
|
|
{ openExternal }: NavigationGuardOptions,
|
|
): void {
|
|
webContents.setWindowOpenHandler(({ url }) => {
|
|
if (isHttpUrl(url)) openExternal(url)
|
|
return { action: 'deny' }
|
|
})
|
|
webContents.on('will-navigate', (event, url) => {
|
|
if (!isHttpUrl(url)) event.preventDefault()
|
|
})
|
|
}
|