fix: address PR review comments

- Fix server restart logic to use event-based termination
- Use app.getPath('userData') for cross-platform data directory
- Implement VALID_CHANNELS validation in preload script
- Fix incorrect copy command in user guide
- Fix broken markdown table formatting

Refs: #150
This commit is contained in:
benzntech
2026-02-28 11:54:41 +05:30
parent 5e72cd34f0
commit a3d15cf971
3 changed files with 62 additions and 14 deletions
+2 -2
View File
@@ -327,7 +327,7 @@ npm install -g omniroute
mkdir -p ~/.omniroute
# Create .env file (see .env.example)
cp ~/.omniroute/.env
cp .env.example ~/.omniroute/.env
# Start server
omniroute
@@ -421,7 +421,7 @@ For host-integrated mode with CLI binaries, see the Docker section in the main d
| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
| `OMNIROUTE_MEMORY_MB` | `256` | Node.js heap limit in MB |
| `PROMPT_CACHE_MAX_SIZE` | `50` | Max prompt cache entries |
| `SEMANTIC_CACHE_MAX_SIZE`| `100` | Max semantic cache entries |
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max semantic cache entries |
For the full environment variable reference, see the [README](../README.md).
+5 -3
View File
@@ -251,14 +251,16 @@ function setupIpcHandlers() {
// Get data directory
ipcMain.handle('get-data-dir', () => {
const home = require('os').homedir();
return path.join(home, '.omniroute');
return app.getPath('userData');
});
// Restart server
ipcMain.handle('restart-server', async () => {
const serverToStop = nextServer;
stopNextServer();
await new Promise(resolve => setTimeout(resolve, 1000));
if (serverToStop) {
await new Promise(resolve => serverToStop.once('exit', resolve));
}
startNextServer();
return { success: true };
});
+55 -9
View File
@@ -29,6 +29,16 @@ const VALID_CHANNELS = {
],
};
/**
* Validate IPC channel name for security
* @param {string} channel - The channel to validate
* @param {'invoke' | 'send' | 'receive'} type - The channel type
* @returns {boolean}
*/
function isValidChannel(channel, type) {
return VALID_CHANNELS[type]?.includes(channel) ?? false;
}
/**
* Expose a limited API to the renderer process
*/
@@ -37,47 +47,81 @@ contextBridge.exposeInMainWorld('electronAPI', {
* Get application information
* @returns {Promise<{name: string, version: string, platform: string, isDev: boolean, port: number}>}
*/
getAppInfo: () => ipcRenderer.invoke('get-app-info'),
getAppInfo: () => {
if (!isValidChannel('get-app-info', 'invoke')) {
return Promise.reject(new Error('Invalid channel'));
}
return ipcRenderer.invoke('get-app-info');
},
/**
* Open an external URL in the default browser
* @param {string} url - The URL to open
*/
openExternal: (url) => ipcRenderer.invoke('open-external', url),
openExternal: (url) => {
if (!isValidChannel('open-external', 'invoke')) {
return Promise.reject(new Error('Invalid channel'));
}
return ipcRenderer.invoke('open-external', url);
},
/**
* Get the data directory path
* @returns {Promise<string>}
*/
getDataDir: () => ipcRenderer.invoke('get-data-dir'),
getDataDir: () => {
if (!isValidChannel('get-data-dir', 'invoke')) {
return Promise.reject(new Error('Invalid channel'));
}
return ipcRenderer.invoke('get-data-dir');
},
/**
* Restart the server
* @returns {Promise<{success: boolean}>}
*/
restartServer: () => ipcRenderer.invoke('restart-server'),
restartServer: () => {
if (!isValidChannel('restart-server', 'invoke')) {
return Promise.reject(new Error('Invalid channel'));
}
return ipcRenderer.invoke('restart-server');
},
/**
* Minimize the window
*/
minimizeWindow: () => ipcRenderer.send('window-minimize'),
minimizeWindow: () => {
if (isValidChannel('window-minimize', 'send')) {
ipcRenderer.send('window-minimize');
}
},
/**
* Maximize/unmaximize the window
*/
maximizeWindow: () => ipcRenderer.send('window-maximize'),
maximizeWindow: () => {
if (isValidChannel('window-maximize', 'send')) {
ipcRenderer.send('window-maximize');
}
},
/**
* Close the window
*/
closeWindow: () => ipcRenderer.send('window-close'),
closeWindow: () => {
if (isValidChannel('window-close', 'send')) {
ipcRenderer.send('window-close');
}
},
/**
* Listen for server status updates
* @param {function} callback - Callback function
*/
onServerStatus: (callback) => {
ipcRenderer.on('server-status', (event, data) => callback(data));
if (isValidChannel('server-status', 'receive')) {
ipcRenderer.on('server-status', (event, data) => callback(data));
}
},
/**
@@ -92,7 +136,9 @@ contextBridge.exposeInMainWorld('electronAPI', {
* @param {function} callback - Callback function
*/
onPortChanged: (callback) => {
ipcRenderer.on('port-changed', (event, port) => callback(port));
if (isValidChannel('port-changed', 'receive')) {
ipcRenderer.on('port-changed', (event, port) => callback(port));
}
},
/**