fix: harden server reliability and OAuth security

This commit is contained in:
kst
2026-08-21 17:19:13 +09:00
parent b2aab2c520
commit 080030c764
16 changed files with 946 additions and 100 deletions
+56
View File
@@ -76,4 +76,60 @@ describe("ProcessManager", () => {
expect(result.timedOut).toBe(true);
expect(result.error).toContain("timeout");
});
it("handles a rejected initial stdin write without crashing the server", async () => {
manager = createManager();
const sessionId = manager.start({
executable: "/bin/bash",
args: ["-c", "true"],
commandForDisplay: "true",
cwd: process.cwd(),
stdin: "x".repeat(1024 * 1024),
});
await manager.waitForExit(sessionId, 2000);
await new Promise<void>((resolve) => setImmediate(resolve));
const result = await manager.read(sessionId);
expect(result.running).toBe(false);
expect(result.error).toMatch(/stdin write failed|EPIPE/i);
});
it("rejects a follow-up stdin write without emitting an unhandled error", async () => {
manager = createManager();
const sessionId = manager.start({
executable: "/bin/bash",
args: ["-c", "exec 0<&-; printf ready; sleep 2"],
commandForDisplay: "closed stdin",
cwd: process.cwd(),
});
expect((await manager.read(sessionId, { waitMs: 1000 })).stdout).toContain("ready");
await expect(manager.write(sessionId, "x".repeat(1024 * 1024))).rejects.toThrow();
await new Promise<void>((resolve) => setImmediate(resolve));
expect((await manager.read(sessionId)).error).toMatch(/stdin write failed|EPIPE/i);
});
it("preserves UTF-8 characters across paged process output", async () => {
manager = createManager();
const expected = `${"a".repeat(16 * 1024 - 1)}😀B`;
const encoded = Buffer.from(expected).toString("base64");
const sessionId = manager.start({
executable: process.execPath,
args: ["-e", `process.stdout.write(Buffer.from(${JSON.stringify(encoded)}, "base64"))`],
commandForDisplay: "unicode output",
cwd: process.cwd(),
});
await manager.waitForExit(sessionId, 2000);
const first = await manager.read(sessionId, { maxOutputBytes: 16 * 1024 });
const second = await manager.read(sessionId, {
afterSeq: first.nextSeq,
maxOutputBytes: 16 * 1024,
});
expect(first.hasMore).toBe(true);
expect(first.output + second.output).toBe(expected);
expect(first.output + second.output).not.toContain("");
});
});