Files
vibn-agent-runner/fix_mcp_fs_normalize.js

83 lines
3.0 KiB
JavaScript

const fs = require('fs');
const file = 'vibn-frontend/app/api/mcp/route.ts';
let code = fs.readFileSync(file, 'utf8');
const oldNormalize = `function normalizeFsPath(p: string): string | NextResponse {
if (!p || typeof p !== "string") {
return NextResponse.json(
{ error: 'Param "path" is required' },
{ status: 400 },
);
}
let abs: string;
if (p.startsWith("/")) {
abs = p;
} else {
abs = \`\${FS_ROOT}/\${p}\`.replace(/\\/+/g, "/");
}
// Disallow .. traversal that escapes /workspace.
const norm = abs.replace(/\\/[^/]+\\/\\.\\.(?=\\/|$)/g, "").replace(/\\/+/g, "/");
if (!norm.startsWith(FS_ROOT) && norm !== FS_ROOT) {
return NextResponse.json(
{
error: \`Path "\${p}" is outside \${FS_ROOT}; use shell.exec for system paths.\`,
},
{ status: 400 },
);
}
return norm;
}`;
const newNormalize = `function normalizeFsPath(
p: string,
projectSlug?: string,
): string | NextResponse {
if (!p || typeof p !== "string") {
return NextResponse.json(
{ error: 'Param "path" is required' },
{ status: 400 },
);
}
const projectRoot = projectSlug ? \`\${FS_ROOT}/\${projectSlug}\` : FS_ROOT;
let abs: string;
if (p.startsWith("/")) {
abs = p;
} else {
abs = \`\${projectRoot}/\${p}\`.replace(/\\/+/g, "/");
}
const norm = abs.replace(/\\/[^/]+\\/\\.\\.(?=\\/|$)/g, "").replace(/\\/+/g, "/");
// When projectSlug is set, REJECT paths outside the project root.
if (projectSlug) {
if (!norm.startsWith(projectRoot) && norm !== projectRoot) {
return NextResponse.json(
{
ok: false,
error: \`PATH_OUTSIDE_PROJECT: path "\${p}" resolves to "\${norm}" which is outside the active project at "\${projectRoot}". Did you mean "\${projectRoot}/\${p.replace(/^\\/+/, "")}"?\`,
},
{ status: 400 },
);
}
} else {
// Workspace-level fallback (legacy behaviour)
if (!norm.startsWith(FS_ROOT) && norm !== FS_ROOT) {
return NextResponse.json(
{ error: \`Path "\${p}" is outside \${FS_ROOT}; use shell.exec for system paths.\` },
{ status: 400 },
);
}
}
return norm;
}`;
code = code.replace(oldNormalize, newNormalize);
code = code.replace(/const path = normalizeFsPath\(String\(params\.path \?\? ""\)\);/g, 'const path = normalizeFsPath(String(params.path ?? ""), project.slug);');
code = code.replace(/const path = normalizeFsPath\(String\(params\.path \?\? "\/workspace"\)\);/g, 'const path = normalizeFsPath(String(params.path ?? "/workspace"), project.slug);');
code = code.replace(/const cwd = normalizeFsPath\(String\(params\.cwd \?\? "\/workspace"\)\);/g, 'const cwd = normalizeFsPath(String(params.cwd ?? "/workspace"), project.slug);');
code = code.replace(/const targetPath = normalizeFsPath\(String\(params\.targetPath \?\? ""\)\);/g, 'const targetPath = normalizeFsPath(String(params.targetPath ?? ""), project.slug);');
fs.writeFileSync(file, code);
console.log("Patched normalizeFsPath with projectSlug scoping");