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
+36 -24
View File
@@ -7,12 +7,19 @@ const DOCUMENT_UI_BASE_URL = (
BASE_URL
).replace(/\/+$/, "");
const MNOTE_WEB_BASE_URL = (process.env.MNOTE_WEB_SMOKE_BASE_URL || "").replace(/\/+$/, "");
const {
DEFAULT_EMAIL,
DEFAULT_PASSWORD,
loginViaAuthForm,
loginViaAuthApi,
} = require("./lib/browser-auth-login");
const REQUEST_TIMEOUT_MS = Number(process.env.MNOTE_SMOKE_TIMEOUT_MS || 20_000);
const UI_TIMEOUT_MS = Number(process.env.MNOTE_SMOKE_UI_TIMEOUT_MS || 30_000);
const TEST_LOGIN_BUTTON_NAME = "测试账号快速登录";
// 7-76 P0:不再依赖「测试账号快速登录」按钮;UI 走标准表单,API 走 /api/auth。
const TEST_USERNAME_PREFIX = "mnote-e2e-";
const TEST_EMAIL = "mnote.e2e@example.com";
const TEST_PASSWORD = "MnoteE2E123!";
const TEST_EMAIL = DEFAULT_EMAIL;
const TEST_PASSWORD = DEFAULT_PASSWORD;
function assert(condition, message) {
if (!condition) {
@@ -128,19 +135,12 @@ async function getViewerIdentity(requestContext) {
}
async function tryApiQuickLogin(requestContext) {
await requestJson(requestContext, "/api/auth", {
method: "POST",
data: {
action: "auth:signIn",
args: {
provider: "password",
params: {
email: TEST_EMAIL,
password: TEST_PASSWORD,
flow: "signIn",
},
},
},
// 名称保留兼容旧 smoke;实现为标准 password signIn(必要时 signUp)。
await loginViaAuthApi(requestContext, {
baseUrl: BASE_URL,
email: TEST_EMAIL,
password: TEST_PASSWORD,
timeoutMs: REQUEST_TIMEOUT_MS,
});
}
@@ -232,10 +232,10 @@ async function ensureAuthenticatedViaUi(page, requestContext) {
await page.goto(`${BASE_URL}/auth`, { waitUntil: "commit", timeout: UI_TIMEOUT_MS });
if (page.url().includes("/auth")) {
const quickLoginButton = page.getByRole("button", { name: TEST_LOGIN_BUTTON_NAME });
const accountField = page.locator("#account, input[name='account']").first();
const deadline = Date.now() + UI_TIMEOUT_MS;
while (page.url().includes("/auth") && Date.now() < deadline) {
if (await isVisible(quickLoginButton)) {
if (await isVisible(accountField)) {
break;
}
await page.waitForTimeout(200);
@@ -243,11 +243,11 @@ async function ensureAuthenticatedViaUi(page, requestContext) {
if (!page.url().includes("/auth")) {
return await waitForViewerIdentity(requestContext);
}
if (!(await isVisible(quickLoginButton))) {
if (!(await isVisible(accountField))) {
await page.reload({ waitUntil: "commit", timeout: UI_TIMEOUT_MS }).catch(() => undefined);
const retryDeadline = Date.now() + Math.min(8_000, UI_TIMEOUT_MS);
while (page.url().includes("/auth") && Date.now() < retryDeadline) {
if (await isVisible(quickLoginButton)) {
if (await isVisible(accountField)) {
break;
}
await page.waitForTimeout(200);
@@ -256,18 +256,30 @@ async function ensureAuthenticatedViaUi(page, requestContext) {
if (!page.url().includes("/auth")) {
return await waitForViewerIdentity(requestContext);
}
if (!(await isVisible(quickLoginButton))) {
throw new Error("认证页未出现测试账号快速登录按钮");
if (!(await isVisible(accountField))) {
throw new Error("认证页未出现标准登录表单(#account");
}
await quickLoginButton.click({ timeout: UI_TIMEOUT_MS });
await loginViaAuthForm(page, {
baseUrl: BASE_URL,
email: TEST_EMAIL,
password: TEST_PASSWORD,
timeoutMs: UI_TIMEOUT_MS,
gotoAuth: false,
});
try {
await waitForAuthenticatedRedirect(page, UI_TIMEOUT_MS);
} catch {
// 账号可能尚未 seed:UI 注册或 API 兜底创建后再进站。
const completedUsername = await completeUsernameSetupIfNeeded(page);
if (!completedUsername) {
const registered = await registerTestAccountIfNeeded(page);
if (!registered) {
throw new Error("测试账号登录后仍停留在 /auth,且未进入可恢复的用户名/注册流程");
try {
await tryApiQuickLogin(requestContext);
await page.goto(`${BASE_URL}/`, { waitUntil: "commit", timeout: UI_TIMEOUT_MS });
} catch {
throw new Error("标准登录后仍停留在 /auth,且注册/API 兜底失败");
}
}
}
}