diff --git a/docs/02-architecture-and-code-map.md b/docs/02-architecture-and-code-map.md index 7741aca..87b804d 100644 --- a/docs/02-architecture-and-code-map.md +++ b/docs/02-architecture-and-code-map.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Architecture-and-Code-Map wiki_url: https://git.ilapage.cn/OPC/chorus/wiki/Architecture-and-Code-Map.- -wiki_revision: 656753d7ce1285da7857e5276fb7748c2b429d64 -synchronized_at: 2026-08-24T09:08:44Z +wiki_revision: e65276530a4fb1e317ea9236aabf3677f137d199 +synchronized_at: 2026-08-24T09:45:01Z # 架构与代码地图 @@ -422,3 +422,9 @@ Provider 限流检查发生在真实上游调用前。放行后才执行 `BeginP - Portal `POST /api/session/login` 只接收 `account` 与 `password`,认证服务规范化账号后只查询 `users.username`;`email` 请求字段和把邮箱值作为账号提交都不能登录。 - `users.email` 继续作为受控用户资料保留;管理员 `sys_user` 与终端用户 `users` 继续分表,密码、Cookie、JWT 和 API Key 均不复用。 - `cmd/chorus-seed` 要求 `CHORUS_SEED_USER_USERNAME`、邮箱、密码和 mock Provider 地址;账号冲突失败关闭,命令不输出凭据。 + +## #51 终端用户密码编码边界(2026-08-24) + +- `internal/platform/password.Encode` 接受 6 至 1024 个字符并输出 `bcrypt:v1:`;5 个字符及以下失败关闭。 +- `Verify` 的版本检查和 bcrypt 验证保持不变,因此已有密码无需迁移;管理员认证使用独立 go-admin 链路,不受此边界影响。 +- 回退最小长度不会使已有 6 至 11 位哈希失去验证能力;强制升级密码需另行设计重置流程。 diff --git a/docs/03-business-rules-and-glossary.md b/docs/03-business-rules-and-glossary.md index 9507c2c..a945338 100644 --- a/docs/03-business-rules-and-glossary.md +++ b/docs/03-business-rules-and-glossary.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Business-Rules-and-Glossary wiki_url: https://git.ilapage.cn/OPC/chorus/wiki/Business-Rules-and-Glossary.- -wiki_revision: 575443f808c909383071207adb0be843b88f8b0d -synchronized_at: 2026-08-24T09:08:49Z +wiki_revision: c0bfdb1121f034cd4acb512a547d7d131747a7d5 +synchronized_at: 2026-08-24T09:45:06Z # 业务规则与术语 @@ -166,3 +166,10 @@ synchronized_at: 2026-08-24T09:08:49Z - 同一用户的幂等键跨浏览器和 OpenAPI 共用。只有完整请求语义一致才是 200 重放;图片会比较 capability、Prompt、role rule、输入顺序/角色/备注、文件元数据和文件内容。任何差异返回 409,且不会覆盖原任务或写第二份输入。 - 新提交立即返回 202 pending,程序需要用历史或详情接口查询状态;OpenAPI 不提供同步等待、流式、取消、批量、webhook、Swagger UI 或 SDK。 + + +## #51 终端用户密码长度(2026-08-24) + +- 当前受控用户且不开放注册的阶段,终端用户密码最小长度为 6 个字符、最大长度为 1024 个字符;密码继续使用 `bcrypt:v1:` 版本化编码。 +- 该调整不适用于 go-admin 管理员密码策略。Portal 登录限流、统一认证错误、Session 与 CSRF 边界不变。 +- 6 位密码抗猜测能力较弱;未来开放注册或外部用户前必须重新评估并提高密码策略。 diff --git a/docs/04-local-development-and-verification.md b/docs/04-local-development-and-verification.md index f04034c..bc3c340 100644 --- a/docs/04-local-development-and-verification.md +++ b/docs/04-local-development-and-verification.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Local-Development-and-Verification wiki_url: https://git.ilapage.cn/OPC/chorus/wiki/Local-Development-and-Verification.- -wiki_revision: 4d052c431913a259bbf1383b4e40c729486f3d99 -synchronized_at: 2026-08-24T09:08:54Z +wiki_revision: 16d71776a494099a31556d68a76ac32b8405199e +synchronized_at: 2026-08-24T09:45:12Z # 本地开发与验证 @@ -475,3 +475,7 @@ go test ./... ### 用户端账号登录(#50) 执行 `000008_portal_username_login` 后,历史用户账号为 `user_`。Portal 登录 JSON 契约固定为 `{"account":"<账号>","password":"<密码>"}`;旧 `email` 字段返回 400,把邮箱作为 `account` 返回统一的 401。需要易记账号时,在受保护环境中设置 `CHORUS_SEED_USER_USERNAME` 后重新执行 seed。生产和常驻启动脚本仍不会自动执行 migration 或 seed。 + +### 终端用户密码长度(#51) + +当前受控用户的 seed/E2E 密码长度必须为 6 至 1024 个字符。5 个字符及以下会在哈希前被拒绝;6 个字符使用与长密码相同的版本化 bcrypt 编码。该策略不影响管理端账号,未来开放注册或外部用户前必须重新评估。 diff --git a/internal/platform/password/password.go b/internal/platform/password/password.go index ce5bf63..b5b8b4f 100644 --- a/internal/platform/password/password.go +++ b/internal/platform/password/password.go @@ -8,11 +8,12 @@ import ( ) const prefix = "bcrypt:v1:" +const minLength = 6 var ErrInvalidEncoding = errors.New("password hash encoding is invalid") func Encode(value string) (string, error) { - if len(value) < 12 || len(value) > 1024 { + if len(value) < minLength || len(value) > 1024 { return "", ErrInvalidEncoding } hash, err := bcrypt.GenerateFromPassword([]byte(value), bcrypt.DefaultCost) diff --git a/internal/platform/password/password_test.go b/internal/platform/password/password_test.go index 24edc8d..9b21001 100644 --- a/internal/platform/password/password_test.go +++ b/internal/platform/password/password_test.go @@ -15,8 +15,15 @@ func TestVersionedPasswordEncoding(t *testing.T) { } } func TestPasswordLength(t *testing.T) { - if _, err := Encode("short"); err == nil { - t.Fatal("short password accepted") + if _, err := Encode("12345"); err == nil { + t.Fatal("five-character password accepted") + } + encoded, err := Encode("123456") + if err != nil { + t.Fatalf("six-character password rejected: %v", err) + } + if !Verify(encoded, "123456") { + t.Fatal("six-character password could not be verified") } if Verify("bcrypt:v2:anything", "value") { t.Fatal("unknown version accepted")