-
Notifications
You must be signed in to change notification settings - Fork 0
Implement config saving logic in gateway server #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Design Choices | ||
|
|
||
| ## Configuration Persistence | ||
| - **Choice**: Persist `ScholarConfig` to `scholar.json` in the project root. | ||
| - **Rationale**: The CLI `init` command description explicitly mentions initializing `scholar.json`. Saving it in the project root ensures it's easily discoverable and follows standard Node.js practices for local configuration. | ||
| - **Implementation**: Used `node:fs/promises`'s `writeFile` in the `GatewayServer`'s `init_config` request handler. This ensures that the response and event broadcast only happen after a successful write, maintaining consistency. | ||
|
|
||
| ## Error Handling in WebSocket Requests | ||
| - **Choice**: Use `.then().catch()` for asynchronous file operations within the request handler. | ||
| - **Rationale**: This prevents the server from hanging if an error occurs during file I/O and allows sending a meaningful error response to the client. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| import { WebSocketServer, WebSocket } from 'ws'; | ||
| import { writeFile } from 'node:fs/promises'; | ||
| import { createResponse, createEvent } from '../../core/protocol.js'; | ||
| import type { ProtocolMessage, RequestMessage } from '../../core/protocol.js'; | ||
|
|
||
|
|
@@ -49,11 +50,16 @@ export class GatewayServer { | |
| break; | ||
| case 'init_config': | ||
| console.log('Received config init payload:', request.payload); | ||
| // Implementation for saving the config logic would go here | ||
| ws.send(JSON.stringify(createResponse(request.id, true, { status: 'saved' }))); | ||
|
|
||
| // Broadcast an event to all connected clients that config changed | ||
| this.broadcastEvent('config_updated', { version: request.payload?.version || '1.0' }); | ||
| this.saveConfig(request.payload) | ||
| .then(() => { | ||
| ws.send(JSON.stringify(createResponse(request.id, true, { status: 'saved' }))); | ||
| // Broadcast an event to all connected clients that config changed | ||
| this.broadcastEvent('config_updated', { version: request.payload?.version || '1.0' }); | ||
|
Comment on lines
51
to
+57
|
||
| }) | ||
| .catch((err) => { | ||
| console.error('Failed to save config:', err); | ||
| ws.send(JSON.stringify(createResponse(request.id, false, undefined, `Failed to save config: ${err.message}`))); | ||
| }); | ||
|
Comment on lines
51
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1. Unauthenticated config overwrite init_config persists client-provided payloads to scholar.json without any authentication/authorization, so any connected client can overwrite local configuration (including secret fields like API keys/tokens). This enables unauthorized configuration tampering via the Gateway WebSocket. Agent Prompt
Comment on lines
+53
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2. Send on closed socket The init_config handler calls ws.send() after an async file write without checking ws.readyState, so a client disconnect during the write can make ws.send() throw. The error-path ws.send() in .catch() is also unguarded, which can lead to an unhandled rejection and potentially crash the server. Agent Prompt
Comment on lines
+53
to
+62
|
||
| break; | ||
| default: | ||
| ws.send(JSON.stringify(createResponse(request.id, false, undefined, 'Unknown command'))); | ||
|
|
@@ -73,6 +79,12 @@ export class GatewayServer { | |
| public stop() { | ||
| this.wss.close(); | ||
| } | ||
|
|
||
| private async saveConfig(config: any) { | ||
| const configPath = './scholar.json'; | ||
| await writeFile(configPath, JSON.stringify(config, null, 4), 'utf-8'); | ||
| console.log(`Config saved to ${configPath}`); | ||
|
Comment on lines
+83
to
+86
|
||
| } | ||
| } | ||
|
|
||
| // Support running the daemon directly | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rationale says using
.then().catch()"prevents the server from hanging" during file I/O. The server/event loop won't inherently hang withasync/awaiteither; the key benefit here is ensuring errors are handled and a response is sent back. Consider rewording this to focus on handled rejections / returning an error response rather than implying.then().catch()prevents hangs.