const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('cryptoAPI', { generateKeys: () => ipcRenderer.invoke('generate-keys'), randomBytes: (size) => ipcRenderer.invoke('random-bytes', size), sha256: (data) => ipcRenderer.invoke('sha256', data), signMessage: (privateKey, message) => ipcRenderer.invoke('sign-message', privateKey, message), verifySignature: (publicKey, message, signature) => ipcRenderer.invoke('verify-signature', publicKey, message, signature), deriveAuthKeys: (password, salt) => ipcRenderer.invoke('derive-auth-keys', password, salt), encryptData: (data, key) => ipcRenderer.invoke('encrypt-data', data, key), decryptData: (encryptedData, key, iv, tag, options) => ipcRenderer.invoke('decrypt-data', encryptedData, key, iv, tag, options), decryptBatch: (items) => ipcRenderer.invoke('decrypt-batch', items), verifyBatch: (items) => ipcRenderer.invoke('verify-batch', items), // RSA Helpers publicEncrypt: (publicKey, data) => ipcRenderer.invoke('public-encrypt', publicKey, data), privateDecrypt: (privateKey, encryptedHex) => ipcRenderer.invoke('private-decrypt', privateKey, encryptedHex), fetchMetadata: (url) => ipcRenderer.invoke('fetch-metadata', url), openExternal: (url) => ipcRenderer.invoke('open-external', url), getScreenSources: () => ipcRenderer.invoke('get-screen-sources'), }); contextBridge.exposeInMainWorld('windowControls', { minimize: () => ipcRenderer.send('window-minimize'), maximize: () => ipcRenderer.send('window-maximize'), close: () => ipcRenderer.send('window-close'), flashFrame: () => ipcRenderer.send('flash-frame'), }); contextBridge.exposeInMainWorld('appSettings', { get: (key) => ipcRenderer.invoke('get-setting', key), set: (key, value) => ipcRenderer.invoke('set-setting', key, value), }); contextBridge.exposeInMainWorld('updateAPI', { checkFlatpakUpdate: () => ipcRenderer.invoke('check-flatpak-update'), }); contextBridge.exposeInMainWorld('sessionPersistence', { save: (data) => ipcRenderer.invoke('save-session', data), load: () => ipcRenderer.invoke('load-session'), clear: () => ipcRenderer.invoke('clear-session'), }); contextBridge.exposeInMainWorld('searchStorage', { load: (userId) => ipcRenderer.invoke('search-db-load', userId), save: (userId, data) => ipcRenderer.invoke('search-db-save', userId, data), clear: (userId) => ipcRenderer.invoke('search-db-clear', userId), }); contextBridge.exposeInMainWorld('idleAPI', { onIdleStateChanged: (callback) => ipcRenderer.on('idle-state-changed', (_event, data) => callback(data)), removeIdleStateListener: () => ipcRenderer.removeAllListeners('idle-state-changed'), getSystemIdleTime: () => ipcRenderer.invoke('get-system-idle-time'), }); // Voice recording — per-participant audio capture that writes // append-only WebM files to the user's chosen folder. See // apps/electron/main.cjs for the main-process implementation. contextBridge.exposeInMainWorld('recordingAPI', { getDefaultFolder: () => ipcRenderer.invoke('recording-get-default-folder'), pickFolder: () => ipcRenderer.invoke('recording-pick-folder'), validateFolder: (dir) => ipcRenderer.invoke('recording-validate-folder', dir), openFolder: (dir) => ipcRenderer.invoke('recording-open-folder', dir), openSessionFolder: (payload) => ipcRenderer.invoke('recording-open-session-folder', payload), startSession: (payload) => ipcRenderer.invoke('recording-start-session', payload), openTrack: (payload) => ipcRenderer.invoke('recording-open-track', payload), append: (payload) => ipcRenderer.invoke('recording-append', payload), closeTrack: (payload) => ipcRenderer.invoke('recording-close-track', payload), finalize: (payload) => ipcRenderer.invoke('recording-finalize', payload), listRecoverable: (payload) => ipcRenderer.invoke('recording-list-recoverable', payload), recoverSession: (payload) => ipcRenderer.invoke('recording-recover-session', payload), });