diff --git a/mindspace-publications.mjs b/mindspace-publications.mjs index 28c742b..c499d15 100644 --- a/mindspace-publications.mjs +++ b/mindspace-publications.mjs @@ -78,11 +78,20 @@ function normalizeAccessMode(value) { return mode; } +export const PAGE_ACCESS_PASSWORD_MIN_LENGTH = 6; +export const PAGE_ACCESS_PASSWORD_MAX_LENGTH = 128; + function normalizePassword(value, required) { const password = String(value ?? ''); if (!required && !password) return null; - if (password.length < 8 || password.length > 128) { - throw publicationError('访问密码长度必须为 8 到 128 个字符', 'invalid_publish_input'); + if ( + password.length < PAGE_ACCESS_PASSWORD_MIN_LENGTH + || password.length > PAGE_ACCESS_PASSWORD_MAX_LENGTH + ) { + throw publicationError( + `访问密码长度必须为 ${PAGE_ACCESS_PASSWORD_MIN_LENGTH} 到 ${PAGE_ACCESS_PASSWORD_MAX_LENGTH} 个字符`, + 'invalid_publish_input', + ); } return password; } @@ -1083,7 +1092,7 @@ export function createPublicationService(pool, options = {}) { } else if (publication.password_hash) { passwordHash = publication.password_hash; } else { - throw publicationError('访问密码长度必须为 8 到 128 个字符', 'invalid_publish_input'); + throw publicationError('口令访问模式必须提供访问密码', 'invalid_publish_input'); } } const now = Date.now(); @@ -1498,6 +1507,8 @@ async function registerPublicationArtifactForConversation({ } export const publicationInternals = { + PAGE_ACCESS_PASSWORD_MIN_LENGTH, + PAGE_ACCESS_PASSWORD_MAX_LENGTH, normalizeSlug, normalizeAccessMode, normalizePassword, diff --git a/mindspace-publications.test.mjs b/mindspace-publications.test.mjs index 0ad16e4..9545d41 100644 --- a/mindspace-publications.test.mjs +++ b/mindspace-publications.test.mjs @@ -110,6 +110,7 @@ test('hashes access passwords with a random salt', () => { () => publicationInternals.normalizePassword('short', true), (error) => error.code === 'invalid_publish_input', ); + assert.equal(publicationInternals.normalizePassword('888888', true), '888888'); }); test('requires future expiry timestamps for time-limited pages', () => { diff --git a/mindspace-sandbox-mcp.mjs b/mindspace-sandbox-mcp.mjs index 931a0fc..4dec1bc 100644 --- a/mindspace-sandbox-mcp.mjs +++ b/mindspace-sandbox-mcp.mjs @@ -473,7 +473,7 @@ const ALL_TOOLS = [ password: { type: 'string', description: - '口令访问密码,accessMode=password 时可选;未提供则默认 88888888(至少 8 位)', + '口令访问密码,accessMode=password 时可选;未提供则默认 88888888(至少 6 位)', }, urlSlug: { type: 'string', description: '发布 URL slug,可选' }, datasets: { diff --git a/page-data-validation-suggestions.mjs b/page-data-validation-suggestions.mjs index 24773af..595940c 100644 --- a/page-data-validation-suggestions.mjs +++ b/page-data-validation-suggestions.mjs @@ -45,7 +45,7 @@ const SUGGESTION_BY_CODE = Object.freeze({ title: '页面数据绑定或发布失败', actions: Object.freeze([ '确认 dataset 已 private_data_register_dataset 注册', - '对每个公开页调用 private_data_bind_workspace_page(含 password 策略时口令 ≥8 位)', + '对每个公开页调用 private_data_bind_workspace_page(含 password 策略时口令 ≥6 位)', '检查 .mindspace/page-data-policies 是否生成且列白名单与表单字段一致', ]), }), diff --git a/page-data-workspace-bind.mjs b/page-data-workspace-bind.mjs index d8b4bd1..907a315 100644 --- a/page-data-workspace-bind.mjs +++ b/page-data-workspace-bind.mjs @@ -22,7 +22,7 @@ export function resolvePageDataBindAccess(accessMode = 'public') { return publicationInternals.normalizeAccessMode(accessMode); } -/** password 模式:用户未传口令时使用 DEFAULT_PAGE_DATA_ADMIN_PASSWORD;<8 位抛错 */ +/** password 模式:用户未传口令时使用 DEFAULT_PAGE_DATA_ADMIN_PASSWORD;<6 位抛错 */ export function resolvePageDataBindPassword(accessMode, password = null) { const mode = resolvePageDataBindAccess(accessMode); if (mode !== 'password') return null; diff --git a/server/portal-publication-routes.mjs b/server/portal-publication-routes.mjs index d158e55..d6b23cd 100644 --- a/server/portal-publication-routes.mjs +++ b/server/portal-publication-routes.mjs @@ -39,7 +39,7 @@ export function renderPublicationPasswordGate(