fix(electrobun): complete all 16 Codex #3 findings
CRITICAL:
- Message persistence race: snapshot batchEnd before async save
- Double-start guard: startingProjects Set prevents concurrent launches
- Symlink path traversal: fs.realpathSync() in path-guard.ts
- Relay false success: connect() returns { ok, machineId, error }
HIGH:
- Session restore skips if active session exists
- Remote remove: new RPC, cleans backend map
- Task board poll token: stale responses discarded after drag-drop
- Health concurrent tools: toolsInFlight counter (was boolean)
- bttask transactions: delete wraps comments+task, addComment validates
- PTY buffer cleared on reconnect
- PTY large paste: chunked String.fromCharCode (8KB chunks)
- Sidecar max line: 10MB limit prevents unbounded memory
- btmsg authorization: group validation, channel membership checks
MEDIUM:
- Session retention: max 5 per project, purgeSession/untrackProject
- Relay IPv6: URL parser replaces string split
- PTY schema: fixed misleading base64 comment
This commit is contained in:
parent
c145e37316
commit
0f75cb8e32
12 changed files with 190 additions and 42 deletions
|
|
@ -63,8 +63,12 @@ export class RelayClient {
|
|||
this.statusListeners.push(cb);
|
||||
}
|
||||
|
||||
/** Connect to an agor-relay instance. Returns a machine ID. */
|
||||
async connect(url: string, token: string, label?: string): Promise<string> {
|
||||
/**
|
||||
* Connect to an agor-relay instance.
|
||||
* Fix #4 (Codex audit): Returns { ok, machineId, error } instead of always
|
||||
* returning machineId even on failure.
|
||||
*/
|
||||
async connect(url: string, token: string, label?: string): Promise<{ ok: boolean; machineId?: string; error?: string }> {
|
||||
const machineId = randomUUID();
|
||||
const machine: MachineConnection = {
|
||||
machineId,
|
||||
|
|
@ -84,14 +88,14 @@ export class RelayClient {
|
|||
|
||||
try {
|
||||
await this.openWebSocket(machine);
|
||||
return { ok: true, machineId };
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
machine.status = "error";
|
||||
this.emitStatus(machineId, "error", msg);
|
||||
this.scheduleReconnect(machine);
|
||||
return { ok: false, machineId, error: msg };
|
||||
}
|
||||
|
||||
return machineId;
|
||||
}
|
||||
|
||||
/** Disconnect from a relay and stop reconnection attempts. */
|
||||
|
|
@ -299,16 +303,24 @@ export class RelayClient {
|
|||
machine.reconnectTimer = setTimeout(attempt, delay);
|
||||
}
|
||||
|
||||
/** TCP-only probe to check if the relay host is reachable. */
|
||||
private tcpProbe(url: string): Promise<boolean> {
|
||||
/**
|
||||
* TCP-only probe to check if the relay host is reachable.
|
||||
* Fix #15 (Codex audit): Uses URL() to correctly parse IPv6, ports, etc.
|
||||
*/
|
||||
private tcpProbe(wsUrl: string): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
const host = this.extractHost(url);
|
||||
if (!host) { resolve(false); return; }
|
||||
|
||||
const [hostname, portStr] = host.includes(":")
|
||||
? [host.split(":")[0], host.split(":")[1]]
|
||||
: [host, "9750"];
|
||||
const port = parseInt(portStr, 10);
|
||||
let hostname: string;
|
||||
let port: number;
|
||||
try {
|
||||
// Convert ws/wss to http/https so URL() can parse it
|
||||
const httpUrl = wsUrl.replace(/^ws(s)?:\/\//, "http$1://");
|
||||
const parsed = new URL(httpUrl);
|
||||
hostname = parsed.hostname; // strips IPv6 brackets automatically
|
||||
port = parsed.port ? parseInt(parsed.port, 10) : 9750;
|
||||
} catch {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const socket = new Socket();
|
||||
const timer = setTimeout(() => { socket.destroy(); resolve(false); }, 5_000);
|
||||
|
|
@ -327,10 +339,6 @@ export class RelayClient {
|
|||
});
|
||||
}
|
||||
|
||||
private extractHost(url: string): string | null {
|
||||
return url.replace("wss://", "").replace("ws://", "").split("/")[0] ?? null;
|
||||
}
|
||||
|
||||
private emitStatus(machineId: string, status: ConnectionStatus, error?: string): void {
|
||||
for (const cb of this.statusListeners) {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue