Harden auth/vault path sanitization and clean WeKnora docs

This commit is contained in:
Agent Board
2026-07-28 17:04:27 +08:00
parent 2deaf59f7b
commit 26ff1a9c9a
190 changed files with 13454 additions and 4987 deletions
+67 -44
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env node
"use strict";
const { loginViaAuthForm, withAdminBrowserSession } = require('./lib/browser-auth-login');
const assert = require("node:assert");
const fs = require("node:fs");
const os = require("node:os");
@@ -28,13 +29,30 @@ function mkdirp(dir) {
}
async function quickLogin(page) {
await page.goto(`${BASE}/auth`, { waitUntil: "commit", timeout: TIMEOUT });
const quickLoginButton = page.getByRole("button", { name: "测试账号快速登录" });
await quickLoginButton.waitFor({ state: "visible", timeout: TIMEOUT });
await Promise.all([
page.waitForURL((url) => !url.toString().includes("/auth"), { timeout: TIMEOUT }).catch(() => null),
quickLoginButton.click(),
]);
// 7-76 P0: 标准表单登录(无测试快速登录按钮)
const base =
(typeof BASE_URL !== "undefined" && BASE_URL) ||
(typeof baseUrl !== "undefined" && baseUrl) ||
process.env.MNOTE_UI_BASE_URL ||
"http://127.0.0.1:3000";
const timeout =
(typeof UI_TIMEOUT_MS !== "undefined" && UI_TIMEOUT_MS) ||
(typeof TIMEOUT !== "undefined" && TIMEOUT) ||
30_000;
if (!String(page.url() || "").includes("/auth")) {
await page.goto(String(base).replace(/\/+$/, "") + "/auth", {
waitUntil: "commit",
timeout,
});
}
await loginViaAuthForm(page, {
baseUrl: base,
timeoutMs: timeout,
gotoAuth: false,
});
await page
.waitForURL((url) => !String(url).includes("/auth"), { timeout })
.catch(() => {});
}
async function requestJson(page, url, options = {}) {
@@ -78,45 +96,50 @@ function policyForLightRag() {
};
}
async function ensureDirectoryGrant(page) {
const response = await page.request.fetch(`${BASE}/api/admin/access-policy/grants`, {
method: "POST",
headers: {
accept: "application/json",
"content-type": "application/json",
},
data: {
userId: ACTOR_ID,
rootUri: ROOT_URI,
rootPath: ROOT_PATH,
permission: "write",
recursive: true,
capabilities: ["ai"],
},
timeout: TIMEOUT,
});
const text = await response.text();
let body = {};
try {
body = text ? JSON.parse(text) : {};
} catch {
body = { raw: text };
}
if (response.ok()) return body;
if (body && body.code === "local_access_policy_grant_duplicate") return body;
throw new Error(`POST /api/admin/access-policy/grants failed: ${response.status()} ${text.slice(0, 800)}`);
async function ensureDirectoryGrant(browser) {
// 方案 Aadmin 能力仅 mnote-admine2e 为 AI 主体,不可调 /api/admin/*
return withAdminBrowserSession(browser, async (adminPage) => {
const response = await adminPage.request.fetch(`${BASE}/api/admin/access-policy/grants`, {
method: "POST",
headers: {
accept: "application/json",
"content-type": "application/json",
},
data: {
userId: ACTOR_ID,
rootUri: ROOT_URI,
rootPath: ROOT_PATH,
permission: "write",
recursive: true,
capabilities: ["ai"],
},
timeout: TIMEOUT,
});
const text = await response.text();
let body = {};
try {
body = text ? JSON.parse(text) : {};
} catch {
body = { raw: text };
}
if (response.ok()) return body;
if (body && body.code === "local_access_policy_grant_duplicate") return body;
throw new Error(`POST /api/admin/access-policy/grants failed: ${response.status()} ${text.slice(0, 800)}`);
}, { baseUrl: BASE, timeoutMs: TIMEOUT });
}
async function seedRuntimePolicy(page) {
async function seedRuntimePolicy(browser) {
mkdirp(ROOT_PATH);
await ensureDirectoryGrant(page);
await requestJson(page, "/api/ai-admin/settings", {
method: "PUT",
data: {
...policyForLightRag(),
quota: { daily: 200 },
},
});
await ensureDirectoryGrant(browser);
await withAdminBrowserSession(browser, async (adminPage) => {
await requestJson(adminPage, "/api/ai-admin/settings", {
method: "PUT",
data: {
...policyForLightRag(),
quota: { daily: 200 },
},
});
}, { baseUrl: BASE, timeoutMs: TIMEOUT });
}
async function ensureLightRagReady(page) {
@@ -271,7 +294,7 @@ async function main() {
try {
await quickLogin(page);
await seedRuntimePolicy(page);
await seedRuntimePolicy(browser);
result.lightRagStatus = await ensureLightRagReady(page);
result.seededEffective = await requestJson(page, `/api/ai-settings/effective?workspaceId=${encodeURIComponent(WORKSPACE_ID)}`);
result.checks.lightRagToolsEnabled = [