Files
pi-agent-integrated/pi-web/lib/bash-output.test.mjs

64 lines
2.3 KiB
JavaScript

import assert from "node:assert/strict";
import { mkdtemp, rm, symlink, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import test from "node:test";
async function loadSubject() {
return import("./bash-output.ts");
}
test("accepts only pi bash logs directly inside the configured temp directory", async () => {
const { resolveBashOutputPath } = await loadSubject();
const tempRoot = join(tmpdir(), "pi-web-output-tests");
const expected = resolve(tempRoot, "pi-bash-ab12.log");
assert.equal(resolveBashOutputPath(join(tempRoot, "pi-bash-ab12.log"), tempRoot), expected);
assert.equal(resolveBashOutputPath(join(tempRoot, "..", "pi-bash-ab12.log"), tempRoot), null);
assert.equal(resolveBashOutputPath(join(tempRoot, "pi-bash-ab12.log.bak"), tempRoot), null);
assert.equal(resolveBashOutputPath(join(`${tempRoot}-other`, "pi-bash-ab12.log"), tempRoot), null);
});
test("reads small output and rejects oversized inline output before buffering it", async () => {
const { readUtf8FileWithinLimit } = await loadSubject();
const dir = await mkdtemp(join(tmpdir(), "pi-web-bash-output-"));
const filePath = join(dir, "pi-bash-ab12.log");
try {
await writeFile(filePath, "shell output", "utf8");
assert.deepEqual(await readUtf8FileWithinLimit(filePath, 32), {
tooLarge: false,
content: "shell output",
size: 12,
});
assert.deepEqual(await readUtf8FileWithinLimit(filePath, 4), {
tooLarge: true,
size: 12,
});
} finally {
await rm(dir, { recursive: true, force: true });
}
});
test("rejects symbolic links when opening bash output", async (t) => {
const { readUtf8FileWithinLimit } = await loadSubject();
const dir = await mkdtemp(join(tmpdir(), "pi-web-bash-output-link-"));
const targetPath = join(dir, "target.log");
const linkPath = join(dir, "pi-bash-link.log");
try {
await writeFile(targetPath, "not authorized through a link", "utf8");
try {
await symlink(targetPath, linkPath);
} catch (error) {
if (error?.code === "EPERM") {
t.skip("Creating symbolic links requires additional privileges on this platform");
return;
}
throw error;
}
await assert.rejects(() => readUtf8FileWithinLimit(linkPath));
} finally {
await rm(dir, { recursive: true, force: true });
}
});