fix(security): audit fixes — path traversal, race conditions, memory leaks, transaction safety
- lib.rs: claude_read_skill path traversal prevention (canonicalize + starts_with) - agent-dispatcher.ts: re-entrancy guard on exit handler, clear maps in stop - machines.svelte.ts: track UnlistenFn array + destroyMachineListeners() - agent-runner.ts: controller.signal.aborted, async handleMessage + .catch() - remote.rs: try_lock → async lock, abort tasks on remove - session.rs: unchecked_transaction for save_agent_messages - agent-bridge.ts: safe msg.event check (implicit in dispatcher changes)
This commit is contained in:
parent
73ca780b54
commit
4bdb74721d
6 changed files with 102 additions and 57 deletions
|
|
@ -71,41 +71,47 @@ export async function disconnectMachine(id: string): Promise<void> {
|
|||
if (machine) machine.status = 'disconnected';
|
||||
}
|
||||
|
||||
// Stored unlisten functions for cleanup
|
||||
let unlistenFns: (() => void)[] = [];
|
||||
|
||||
// Initialize event listeners for machine status updates
|
||||
export async function initMachineListeners(): Promise<void> {
|
||||
await onRemoteMachineReady((msg) => {
|
||||
// Clean up any existing listeners first
|
||||
destroyMachineListeners();
|
||||
|
||||
unlistenFns.push(await onRemoteMachineReady((msg) => {
|
||||
const machine = machines.find(m => m.id === msg.machineId);
|
||||
if (machine) {
|
||||
machine.status = 'connected';
|
||||
notify('success', `Connected to ${machine.label}`);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
await onRemoteMachineDisconnected((msg) => {
|
||||
unlistenFns.push(await onRemoteMachineDisconnected((msg) => {
|
||||
const machine = machines.find(m => m.id === msg.machineId);
|
||||
if (machine) {
|
||||
machine.status = 'disconnected';
|
||||
notify('warning', `Disconnected from ${machine.label}`);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
await onRemoteError((msg) => {
|
||||
unlistenFns.push(await onRemoteError((msg) => {
|
||||
const machine = machines.find(m => m.id === msg.machineId);
|
||||
if (machine) {
|
||||
machine.status = 'error';
|
||||
notify('error', `Error from ${machine.label}: ${msg.error}`);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
await onRemoteMachineReconnecting((msg) => {
|
||||
unlistenFns.push(await onRemoteMachineReconnecting((msg) => {
|
||||
const machine = machines.find(m => m.id === msg.machineId);
|
||||
if (machine) {
|
||||
machine.status = 'reconnecting';
|
||||
notify('info', `Reconnecting to ${machine.label} in ${msg.backoffSecs}s…`);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
await onRemoteMachineReconnectReady((msg) => {
|
||||
unlistenFns.push(await onRemoteMachineReconnectReady((msg) => {
|
||||
const machine = machines.find(m => m.id === msg.machineId);
|
||||
if (machine) {
|
||||
notify('info', `${machine.label} reachable — reconnecting…`);
|
||||
|
|
@ -113,5 +119,13 @@ export async function initMachineListeners(): Promise<void> {
|
|||
notify('error', `Auto-reconnect failed for ${machine.label}: ${e}`);
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
/** Remove all event listeners to prevent leaks */
|
||||
export function destroyMachineListeners(): void {
|
||||
for (const unlisten of unlistenFns) {
|
||||
unlisten();
|
||||
}
|
||||
unlistenFns = [];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue