mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-11 03:00:45 +08:00
重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。
同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。 Made-with: Cursor
This commit is contained in:
parent
4a23b715a2
commit
dbbe3add6a
14438 changed files with 2693620 additions and 2546 deletions
62
openclaw/scripts/check-webhook-auth-body-order.mjs
Normal file
62
openclaw/scripts/check-webhook-auth-body-order.mjs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import path from "node:path";
|
||||
import ts from "typescript";
|
||||
import { bundledPluginCallsite, bundledPluginFile } from "./lib/bundled-plugin-paths.mjs";
|
||||
import { runCallsiteGuard } from "./lib/callsite-guard.mjs";
|
||||
import { runAsScript, toLine, unwrapExpression } from "./lib/ts-guard-utils.mjs";
|
||||
|
||||
const sourceRoots = ["extensions"];
|
||||
const enforcedFiles = new Set([
|
||||
bundledPluginFile("bluebubbles", "src/monitor.ts"),
|
||||
bundledPluginFile("feishu", "src/monitor.transport.ts"),
|
||||
bundledPluginFile("googlechat", "src/monitor.ts"),
|
||||
bundledPluginFile("zalo", "src/monitor.webhook.ts"),
|
||||
]);
|
||||
const blockedCallees = new Set(["readJsonBodyWithLimit", "readRequestBodyWithLimit"]);
|
||||
const allowedCallsites = new Set([
|
||||
// Feishu signs the exact wire body, so this handler must read raw bytes before parsing JSON.
|
||||
bundledPluginCallsite("feishu", "src/monitor.transport.ts", 199),
|
||||
]);
|
||||
|
||||
function getCalleeName(expression) {
|
||||
const callee = unwrapExpression(expression);
|
||||
if (ts.isIdentifier(callee)) {
|
||||
return callee.text;
|
||||
}
|
||||
if (ts.isPropertyAccessExpression(callee)) {
|
||||
return callee.name.text;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function findBlockedWebhookBodyReadLines(content, fileName = "source.ts") {
|
||||
const sourceFile = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true);
|
||||
const lines = [];
|
||||
const visit = (node) => {
|
||||
if (ts.isCallExpression(node)) {
|
||||
const calleeName = getCalleeName(node.expression);
|
||||
if (calleeName && blockedCallees.has(calleeName)) {
|
||||
lines.push(toLine(sourceFile, node.expression));
|
||||
}
|
||||
}
|
||||
ts.forEachChild(node, visit);
|
||||
};
|
||||
visit(sourceFile);
|
||||
return lines;
|
||||
}
|
||||
|
||||
export async function main() {
|
||||
await runCallsiteGuard({
|
||||
importMetaUrl: import.meta.url,
|
||||
sourceRoots,
|
||||
findCallLines: findBlockedWebhookBodyReadLines,
|
||||
skipRelativePath: (relPath) => !enforcedFiles.has(relPath.replaceAll(path.sep, "/")),
|
||||
allowCallsite: (callsite) => allowedCallsites.has(callsite),
|
||||
header: "Found forbidden low-level body reads in auth-sensitive webhook handlers:",
|
||||
footer:
|
||||
"Use plugin-sdk webhook guards (`readJsonWebhookBodyOrReject` / `readWebhookBodyOrReject`) with explicit pre-auth/post-auth profiles.",
|
||||
});
|
||||
}
|
||||
|
||||
runAsScript(import.meta.url, main);
|
||||
Loading…
Add table
Add a link
Reference in a new issue