fix: reject mismatched canvas agent project ids

This commit is contained in:
134 2026-06-23 21:06:55 +08:00
parent ac0456eb97
commit 7c2e31cbe5
2 changed files with 40 additions and 0 deletions

View File

@ -64,6 +64,17 @@ export async function handleCanvasAgentOperationRouteRequest(params: {
try {
const rawBody = params.readBody ? await params.readBody() : params.rawBody;
const body = parseCanvasAgentOperationRequestBody(rawBody);
const planProjectId = String(body.operationPlan.projectId || "").trim();
if (planProjectId && planProjectId !== params.projectId) {
return {
status: 400,
body: {
success: false,
error: "operation projectId 与请求项目不一致",
code: "CANVAS_AGENT_PROJECT_MISMATCH",
},
};
}
const result = await params.applyOperation({
userId,
projectId: params.projectId,

View File

@ -428,6 +428,35 @@ test.describe("canvas agent operation route handler", () => {
]);
});
test("rejects operation plans for a different project before applying", async () => {
let operationApplied = false;
const response = await handleCanvasAgentOperationRouteRequest({
userId: "user-1",
projectId,
rawBody: buildRouteRequestBody({
projectId: "33333333-3333-4333-8333-333333333333",
operation: "insert_beside",
anchorNodeId: "image-1",
mediaItems: [buildMediaItem(1)],
}),
features: enabledRouteFeatures,
applyOperation: async () => {
operationApplied = true;
return buildRouteSuccessResult();
},
});
expect(response).toMatchObject({
status: 400,
body: {
success: false,
code: "CANVAS_AGENT_PROJECT_MISMATCH",
},
});
expect(operationApplied).toBe(false);
});
test("maps invalid bodies and mutation errors to API responses", async () => {
let operationApplied = false;
const invalidResponse = await handleCanvasAgentOperationRouteRequest({