From 23c052e98b8f0fe3949738cf6731216b615f9948 Mon Sep 17 00:00:00 2001 From: nwaschk Date: Sun, 22 Jun 2025 15:53:05 +0200 Subject: [PATCH] =?UTF-8?q?Weiterf=C3=BChrung=20der=20IPC=20Verbindung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/electron/main.ts | 7 ++--- src/electron/preload.cts | 24 +++++++++++++++++ src/electron/utils.ts | 56 +++++++++++++++++++++++++++++++++++++++- types.d.ts | 5 ++++ 4 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/electron/main.ts b/src/electron/main.ts index d725c2e..ad98376 100644 --- a/src/electron/main.ts +++ b/src/electron/main.ts @@ -1,11 +1,8 @@ import {app, BrowserWindow} from 'electron'; -import path from 'path'; -import {getPreloadPath, inDevelopment} from './utils.js'; +import {getPreloadPath, getUIPath, inDevelopment} from './utils.js'; import {ipcMain} from 'electron/main'; import {ProdressConnection} from './pdr2com/connection.js'; -const APPLICATION_PATH = path.join(app.getAppPath(), '/dist-svelte/index.html'); - app.on('ready', async () => { const mainWindow = new BrowserWindow({ webPreferences: { @@ -15,7 +12,7 @@ app.on('ready', async () => { if (inDevelopment()) { mainWindow.loadURL('http://localhost:5123/'); } else { - mainWindow.loadFile(APPLICATION_PATH); + mainWindow.loadFile(getUIPath()); } ipcMain.handle('ping', () => { diff --git a/src/electron/preload.cts b/src/electron/preload.cts index 3b6f766..946596c 100644 --- a/src/electron/preload.cts +++ b/src/electron/preload.cts @@ -3,3 +3,27 @@ const electron: typeof Electron = require('electron'); electron.contextBridge.exposeInMainWorld('electron', { ping: () => electron.ipcRenderer.invoke('ping'), } satisfies Window['electron']); + +/** + * adapter for the ipcRenderer invoke function + * - invokes an event to from the frontend to the backend + *@param event + * @returns the response from the backend + */ +function ipcInvoke(event: Event): Promise { + return electron.ipcRenderer.invoke(event); +} + +/** + * adapter for the ipcRenderer on function + * - subscribes to an event from the backend + * @param event + */ +function ipcOn( + event: Event, + subscribeFunction: SubscribeFunction, +): UnsubscribeFunction { + const callback = (_: Electron.IpcRendererEvent, payload: EventPayloadMapping[Event]) => subscribeFunction(payload); + electron.ipcRenderer.on(event, callback); + return () => electron.ipcRenderer.off(event, callback); +} diff --git a/src/electron/utils.ts b/src/electron/utils.ts index 3ddacdb..8d680f3 100644 --- a/src/electron/utils.ts +++ b/src/electron/utils.ts @@ -1,5 +1,6 @@ import path from 'path'; -import {app} from 'electron'; +import {app, ipcMain, WebContents, WebFrameMain} from 'electron'; +import {pathToFileURL} from 'url'; /** * @returns true, when the application is starded in develpoment mode @@ -34,3 +35,56 @@ export function getPreloadPath(): string { const preloadScript = '/dist-electron/preload.cjs'; return path.join(app.getAppPath(), inDevelopment() ? '.' : '..', preloadScript); } + +/** + * resolves teh path of the build ui + * @returns the path of the ui + */ +export function getUIPath(): string { + return path.join(app.getAppPath(), '/dist-svelte/index.html'); +} + +/** + * @todo + * adapter for the ipc handle function + * @param event + * @param handler + */ +export function ipcMainHandle( + event: Event, + handler: () => EventPayloadMapping[Event], +): void { + ipcMain.handle(event, (eventInstance) => { + validateEventFrame(eventInstance.senderFrame); + return handler(); + }); +} + +/** + * @todo + * adapter for the webContents send function + * @param event + * @param webContents + * @param payload + */ +export function ipcWebContentsSend( + event: Event, + webContents: WebContents, + payload: EventPayloadMapping[Event], +): void { + webContents.send(event, payload); +} + +/** + * barebones event validation + * @param frame + * @throws when an event gets listend to which is not invoked by the mainframe + */ +export function validateEventFrame(frame: WebFrameMain | null) { + if (inDevelopment() && frame && new URL(frame.url).host === 'localhost:5123') { + return; + } + if (!frame || frame.url !== pathToFileURL(getUIPath()).toString()) { + throw new Error('Malicious Event'); + } +} diff --git a/types.d.ts b/types.d.ts index 1020cff..80fa0fb 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,3 +1,5 @@ +type EventPayloadMapping = {}; + /** * Extends the Main "Window" Interface */ @@ -6,3 +8,6 @@ interface Window { ping: () => Promise; }; } + +type UnsubscribeFunction = () => void; +type SubscribeFunction = (payload: EventPayloadMapping[Event]) => void;