fix(electrobun): address all 22 Codex review #2 findings
CRITICAL:
- DocsTab XSS: DOMPurify sanitization on all {@html} output
- File RPC path traversal: guardPath() validates against project CWDs
HIGH:
- SSH injection: spawn /usr/bin/ssh via PTY args, no shell string
- Search XSS: strip HTML, highlight matches client-side with <mark>
- Terminal listener leak: cleanup functions stored + called in onDestroy
- FileBrowser race: request token, discard stale responses
- SearchOverlay race: same request token pattern
- App startup ordering: groups.list chains into active_group restore
- PtyClient timeout: 5-second auth timeout on connect()
- Rule 55: 6 {#if} patterns converted to style:display toggle
MEDIUM:
- Agent persistence: only persist NEW messages (lastPersistedIndex)
- Search errors: typed error response, "Invalid query" UI
- Health store wired: agent events call recordActivity/setProjectStatus
- index.ts SRP: split into 8 domain handler modules (298 lines)
- App.svelte: extracted workspace-store.svelte.ts
- rpc.ts: typed AppRpcHandle, removed `any`
LOW:
- CommandPalette listener wired in App.svelte
- Dead code removed (removeGroup, onDragStart, plugin loaded)
This commit is contained in:
parent
8e756d3523
commit
1cd4558740
28 changed files with 1342 additions and 1164 deletions
|
|
@ -30,6 +30,8 @@
|
|||
let fileLoading = $state(false);
|
||||
let isDirty = $state(false);
|
||||
let editorContent = $state('');
|
||||
// Fix #6: Request token to discard stale file load responses
|
||||
let fileRequestToken = 0;
|
||||
|
||||
// Extension-based type detection
|
||||
const CODE_EXTS = new Set([
|
||||
|
|
@ -115,7 +117,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
/** Select and load a file. */
|
||||
/** Select and load a file. Fix #6: uses request token to discard stale responses. */
|
||||
async function selectFile(filePath: string) {
|
||||
if (selectedFile === filePath) return;
|
||||
selectedFile = filePath;
|
||||
|
|
@ -123,6 +125,7 @@
|
|||
fileContent = null;
|
||||
fileError = null;
|
||||
fileLoading = true;
|
||||
const token = ++fileRequestToken;
|
||||
|
||||
const type = detectFileType(filePath);
|
||||
|
||||
|
|
@ -136,6 +139,7 @@
|
|||
if (type === 'image') {
|
||||
try {
|
||||
const result = await appRpc.request["files.read"]({ path: filePath });
|
||||
if (token !== fileRequestToken) return;
|
||||
if (result.error) {
|
||||
fileError = result.error;
|
||||
return;
|
||||
|
|
@ -144,15 +148,17 @@
|
|||
fileEncoding = result.encoding;
|
||||
fileSize = result.size;
|
||||
} catch (err) {
|
||||
if (token !== fileRequestToken) return;
|
||||
fileError = err instanceof Error ? err.message : String(err);
|
||||
} finally {
|
||||
fileLoading = false;
|
||||
if (token === fileRequestToken) fileLoading = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await appRpc.request["files.read"]({ path: filePath });
|
||||
if (token !== fileRequestToken) return;
|
||||
if (result.error) {
|
||||
fileError = result.error;
|
||||
return;
|
||||
|
|
@ -162,9 +168,10 @@
|
|||
fileSize = result.size;
|
||||
editorContent = fileContent;
|
||||
} catch (err) {
|
||||
if (token !== fileRequestToken) return;
|
||||
fileError = err instanceof Error ? err.message : String(err);
|
||||
} finally {
|
||||
fileLoading = false;
|
||||
if (token === fileRequestToken) fileLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue