feat(users): 多用户体系阶段一 — 管理员用户管理与角色鉴权#204
Open
g1331 wants to merge 10 commits into
Open
Conversation
新增 AuthPrincipal 判别联合(admin_token / user / null)与 authenticate / requireAdmin / requireUser 三个门禁。ADMIN_TOKEN 用 timingSafeEqual 常量时间比较 且不查库;JWT 验签后查库以最新 role 与 is_active 为准,停用用户与降级 admin 的旧 token 被拒。门禁封装将查库异常转为干净的 500 而非冒泡到 route。 补齐单元测试覆盖三类身份、未认证、停用、删除、过期/畸形 token、admin 降级、raw 与 Bearer 形态的 ADMIN_TOKEN、ADMIN_TOKEN 未配置守卫、选列回归与查库异常 500。
实现任务组4 的登录与会话端点:
- POST /api/auth/login:按归一化用户名查用户、校验 is_active、bcrypt 比对密码,
成功签发仅含 userId 与 role 的 JWT 并返回 id/username/displayName/role。用户名
不存在、停用、密码错误均返回一致的 401,且对缺失用户跑等量 bcrypt 消除时序枚举。
- 登录失败限流:按用户名与来源 IP 两个维度滑动窗口计数 + 短时锁定,超阈值返回 429
并带 Retry-After。
- GET /api/auth/me:复用 requireUser,返回当前用户资料;ADMIN_TOKEN 超管返回
{ kind: "admin_token", role: "admin" } 不查库。
- auth.ts 新增 normalizeUsername(trim + 小写归一化)。
附带修复两处:
- api-auth.ts、login、me 改为从 @/lib/db barrel 导入 users,与仓库既有 route 写法
一致。此前任务组3 让 api-auth 顶层 import @/lib/db/schema,使所有 mock drizzle-orm
的 admin route 测试在加载真实 schema 时因缺 relations 而失败;改用 barrel 后这些
测试经 @/lib/db mock 即完全隔离 schema,三个失败用例自动恢复。
- login-rate-limiter 参照 session-affinity 补键数量上限(超限 evictOldest)与周期
unref 清理定时器,防止伪造用户名/IP 注入导致 Map 无界增长(对抗性审查确认项)。
将全部 68 个 /api/admin/* route(91 处)的内联 validateAdminAuth(authHeader) 统一替换为角色感知守卫 requireAdmin(request);member 用户现在返回 403 而非放行, ADMIN_TOKEN 与 admin 用户行为保持不变。 - 清退无调用方的 withAdminAuth HOC 与 ApiHandler 类型及其单元测试 - 37 个 admin route 测试的鉴权 mock 从 validateAdminAuth 迁移到 requireAdmin override (importActual 保留 errorResponse/getPaginationParams 真实实现) - 新增 stats/overview 三类身份回归测试(ADMIN_TOKEN/admin 放行、member 403、未认证 401) 任务组5(5.1-5.5)
- user-service:创建(用户名归一化+唯一校验+bcrypt)、分页列表(名下密钥数聚合)、 更新资料/角色/状态、改用户名、重置密码、删除(单事务内置空名下密钥归属) - 最后一个启用 admin 锁定保护:拒绝降级、停用、删除 - /api/admin/users 路由组、keys/[id]/owner 所有权分配回收、users/[id]/upstreams 可用上游配置 - 全部以 requireAdmin 守卫,响应不含 password_hash - 测试:service 用真实 libsql 内存库验证事务、聚合、唯一约束与置空归属; route 层覆盖守卫(401/403)与服务错误到 HTTP 状态码的映射
升级 auth-provider,从 token 快照同步派生 AuthPrincipal(kind 与 role),畸形 JWT 容错退化为未认证;用户档案经 /api/auth/me 异步补充并按所属 token 过滤残留,避免在 effect 内同步清空状态。登录页改造为账号登录与管理员令牌双模式:账号模式调用 /api/auth/login,令牌模式沿用受保护接口探针。补充两个 locale 的账号登录文案,并为两种登录模式与认证状态转换新增组件测试。
实现管理员用户管理页面:分页用户列表、新建用户表单、编辑与操作菜单、改用户名、重置密码、停用启用、删除、配置可用上游、分配密钥,复用 ui/ 原语并在最后一个启用管理员上禁用危险操作。侧边栏 systemNavigation 追加用户管理入口并按角色显隐,补全中英文案,新增 use-users hooks 与组件测试。
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #204 +/- ##
==========================================
- Coverage 74.44% 73.92% -0.53%
==========================================
Files 160 172 +12
Lines 11626 12221 +595
Branches 3982 4085 +103
==========================================
+ Hits 8655 9034 +379
- Misses 1731 1937 +206
- Partials 1240 1250 +10
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
多用户体系(OpenSpec 变更
multi-user-system)阶段一,覆盖任务组 1–8。引入用户名 + 密码登录、统一角色感知鉴权、管理员用户管理 API 与管理页面。用户由后台管理员创建(非邮箱注册),区分admin与member角色。阶段二(任务组 9–13,用户自助门户)将作为独立 PR 叠加。Related Issue
Part of #109
Type of Change
Changes
users、user_upstreams表与 API 密钥归属外键,事实表补冗余归属列;PostgreSQL 与 SQLite schema 同步并各自生成迁移。adminroute 迁移至该工具。/api/auth/me)端点。member经/api/auth/me补全展示信息。ui/原语,最后一个启用管理员在前端禁用停用与删除入口。systemNavigation追加用户管理入口并按角色显隐,补全中英文全部相关文案。Test Plan
新增针对鉴权工具、登录端点与限流、用户管理 API(含授权与失败分支)、前端登录页与认证状态、用户管理页面 / 表格 / 创建表单 / 最后管理员禁用 / 按角色过滤导航的单元与组件测试。
Checklist
Additional Notes
OpenSpec 变更
multi-user-system的归档安排在阶段二(任务组 9–13)完成后统一处理。本 PR 仅交付阶段一,已通过本地全部质量门禁,等待 CI 与评审。UI 变更涉及登录页双模式与用户管理页面,受限于当前环境未附截图。