This commit is contained in:
+53
-8
@@ -33,14 +33,15 @@ test("记录一条配置操作并可按项目/键查询", async () => {
|
||||
});
|
||||
|
||||
const byProject = await duckdbAdapter.loadAuditLogs({ projectId: "proj-a" });
|
||||
assert.strictEqual(byProject.length, 1);
|
||||
assert.strictEqual(byProject.items.length, 1);
|
||||
assert.strictEqual(byProject.total, 1);
|
||||
const byKey = await duckdbAdapter.loadAuditLogs({ projectId: "proj-a", key: "db/host" });
|
||||
assert.strictEqual(byKey.length, 1);
|
||||
assert.strictEqual(byKey.items.length, 1);
|
||||
// 其它项目/键查不到
|
||||
assert.strictEqual((await duckdbAdapter.loadAuditLogs({ projectId: "proj-b" })).length, 0);
|
||||
assert.strictEqual((await duckdbAdapter.loadAuditLogs({ projectId: "proj-a", key: "other" })).length, 0);
|
||||
assert.strictEqual((await duckdbAdapter.loadAuditLogs({ projectId: "proj-b" })).items.length, 0);
|
||||
assert.strictEqual((await duckdbAdapter.loadAuditLogs({ projectId: "proj-a", key: "other" })).items.length, 0);
|
||||
|
||||
const rec = byKey[0];
|
||||
const rec = byKey.items[0];
|
||||
assert.strictEqual(rec.source, "web");
|
||||
assert.strictEqual(rec.actor, "admin");
|
||||
assert.strictEqual(rec.ip, "203.0.113.9");
|
||||
@@ -55,9 +56,53 @@ test("记录按时间倒序返回,MCP 来源也正确记录 Token 名", async
|
||||
await auditLog({ source: "mcp", actor: "ci-token", ip: "10.0.0.1", projectId: "proj-a", key: "k/1", action: "create", value: "x" });
|
||||
|
||||
const logs = await duckdbAdapter.loadAuditLogs({ projectId: "proj-a", key: "k/1" });
|
||||
assert.strictEqual(logs.length, 2);
|
||||
assert.ok(logs[0].createdAt >= logs[1].createdAt, "最新的应在前");
|
||||
assert.ok(logs.every((l) => l.source === "mcp" && l.actor === "ci-token"));
|
||||
const items = logs.items;
|
||||
assert.strictEqual(items.length, 2);
|
||||
assert.ok(items[0].createdAt >= items[1].createdAt, "最新的应在前");
|
||||
assert.ok(items.every((l) => l.source === "mcp" && l.actor === "ci-token"));
|
||||
});
|
||||
|
||||
test("分页与过滤:action / start-end 时间范围 / 键名模糊匹配 / 页码切片", async () => {
|
||||
const base = Date.now() - 5 * 60000;
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
await duckdbAdapter.appendAuditLog({
|
||||
id: "aud-pg-" + i,
|
||||
source: "mcp",
|
||||
actor: "ci-token",
|
||||
projectId: "proj-p",
|
||||
key: `svc/app-${i}`,
|
||||
action: i === 3 ? "delete" : "create",
|
||||
value: `v${i}`,
|
||||
createdAt: new Date(base + i * 1000).toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
// 分页:page=1 取 2 条,total 应为 3
|
||||
const page1 = await duckdbAdapter.loadAuditLogs({ projectId: "proj-p", page: 1, pageSize: 2 });
|
||||
assert.strictEqual(page1.items.length, 2);
|
||||
assert.strictEqual(page1.total, 3);
|
||||
assert.strictEqual(page1.page, 1);
|
||||
assert.strictEqual(page1.pageSize, 2);
|
||||
const page2 = await duckdbAdapter.loadAuditLogs({ projectId: "proj-p", page: 2, pageSize: 2 });
|
||||
assert.strictEqual(page2.items.length, 1);
|
||||
|
||||
// action 过滤
|
||||
const creates = await duckdbAdapter.loadAuditLogs({ projectId: "proj-p", action: "create" });
|
||||
assert.strictEqual(creates.items.length, 2);
|
||||
assert.strictEqual(creates.items.every((l) => l.action === "create"), true);
|
||||
const deletes = await duckdbAdapter.loadAuditLogs({ projectId: "proj-p", action: "delete" });
|
||||
assert.strictEqual(deletes.items.length, 1);
|
||||
|
||||
// key 模糊匹配
|
||||
const fuzzy = await duckdbAdapter.loadAuditLogs({ projectId: "proj-p", key: "app-" });
|
||||
assert.strictEqual(fuzzy.items.length, 3);
|
||||
|
||||
// 时间范围:取中间那条
|
||||
const midStart = new Date(base + 1500).toISOString();
|
||||
const midEnd = new Date(base + 2500).toISOString();
|
||||
const range = await duckdbAdapter.loadAuditLogs({ projectId: "proj-p", start: midStart, end: midEnd });
|
||||
assert.strictEqual(range.items.length, 1);
|
||||
assert.strictEqual(range.items[0].key, "svc/app-2");
|
||||
});
|
||||
|
||||
test("getClientIp 优先取 X-Forwarded-For,其次 remoteAddress", () => {
|
||||
|
||||
+2
-2
@@ -182,7 +182,7 @@ test("Token 项目范围限制 MCP 配置访问,越权操作被拒绝且不入
|
||||
assert.ok(!createdReal.isError);
|
||||
|
||||
const logsReal = await loadAuditLogs({ projectId: project.id, key: "sql/dsn" });
|
||||
const createLog = logsReal.find((l) => l.action === "create");
|
||||
const createLog = logsReal.items.find((l) => l.action === "create");
|
||||
assert.ok(createLog, "应在 audit_logs 中存在 create 记录");
|
||||
assert.strictEqual(createLog.source, "mcp");
|
||||
assert.strictEqual(createLog.actor, "scope-token");
|
||||
@@ -191,7 +191,7 @@ test("Token 项目范围限制 MCP 配置访问,越权操作被拒绝且不入
|
||||
|
||||
// 越权操作不产生记录(other-proj 无任何记录)
|
||||
const deniedLogs = await loadAuditLogs({ projectId: "other-proj" });
|
||||
assert.strictEqual(deniedLogs.length, 0);
|
||||
assert.strictEqual(deniedLogs.items.length, 0);
|
||||
|
||||
// 清理测试项目
|
||||
const delProject = await callTool("delete_project", { projectId: project.id });
|
||||
|
||||
Reference in New Issue
Block a user