forked from EduCraft/curriculum-project-hub
fix: confine Agent and MCP data access
This commit is contained in:
@@ -1,36 +1,50 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { mkdir, rm, writeFile } from "node:fs/promises";
|
||||
import { mkdir, realpath, rm, symlink, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { resolveDeliverableFile } from "../../src/feishu/fileDelivery.js";
|
||||
|
||||
const itOnLinux = process.platform === "linux" ? it : it.skip;
|
||||
|
||||
describe("file delivery path resolution", () => {
|
||||
it("resolves a repo-root file from a project workspace only when explicitly named", async () => {
|
||||
itOnLinux("never resolves a Git-root file outside the current project workspace", async () => {
|
||||
const root = await makeRepo();
|
||||
try {
|
||||
const workspace = join(root, "examples", "TH-141");
|
||||
await writeFile(join(root, "README.md"), "# root readme\n");
|
||||
|
||||
await expect(resolveDeliverableFile("README.md", workspace)).resolves.toEqual({
|
||||
path: join(root, "README.md"),
|
||||
name: "README.md",
|
||||
});
|
||||
await expect(resolveDeliverableFile("README.md", join(root, "examples"), workspace)).resolves.toBeNull();
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("resolves a bare build filename against workspace/build", async () => {
|
||||
itOnLinux("resolves a bare build filename against workspace/build", async () => {
|
||||
const root = await makeRepo();
|
||||
try {
|
||||
const workspace = join(root, "examples", "TH-141");
|
||||
const pdf = join(workspace, "build", "student.pdf");
|
||||
await writeFile(pdf, "pdf bytes");
|
||||
|
||||
await expect(resolveDeliverableFile("student.pdf", workspace)).resolves.toEqual({
|
||||
path: pdf,
|
||||
name: "student.pdf",
|
||||
});
|
||||
const resolved = await resolveDeliverableFile("student.pdf", join(root, "examples"), workspace);
|
||||
expect(resolved).toMatchObject({ path: await realpath(pdf), name: "student.pdf" });
|
||||
expect(resolved?.data.toString("utf8")).toBe("pdf bytes");
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
itOnLinux("rejects a deliverable symlink even when its target exists", async () => {
|
||||
const root = await makeRepo();
|
||||
try {
|
||||
const workspace = join(root, "examples", "TH-141");
|
||||
const outside = join(root, "outside.pdf");
|
||||
await writeFile(outside, "outside secret");
|
||||
await symlink(outside, join(workspace, "build", "student.pdf"));
|
||||
|
||||
await expect(
|
||||
resolveDeliverableFile("student.pdf", join(root, "examples"), workspace),
|
||||
).rejects.toThrow(/symlink|no-follow|directory/i);
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
@@ -42,7 +56,9 @@ describe("file delivery path resolution", () => {
|
||||
const workspace = join(root, "examples", "TH-141");
|
||||
await writeFile(join(workspace, "build", "student.pdf"), "pdf bytes");
|
||||
|
||||
await expect(resolveDeliverableFile("cph build 生成 PDF 给我", workspace)).resolves.toBeNull();
|
||||
await expect(
|
||||
resolveDeliverableFile("cph build 生成 PDF 给我", join(root, "examples"), workspace),
|
||||
).resolves.toBeNull();
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user