- 归档 close-phase-0(RBAC 权限 + 审计/登录日志 + seed 收口) - 新增主 spec:backend/auth、backend/res、backend/audit、backend/login - 追踪 sysmgr-nest passwordHash 泄漏修复 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
3.7 KiB
Markdown
45 lines
3.7 KiB
Markdown
## 1. Redis 接入与权限模型(auth 域)
|
||
|
||
- [x] 1.1 引入 ioredis 依赖,封装 RedisService(get/set/del/按前缀 SCAN 删除),连接用 env(REDIS_HOST/PORT/DB/PASSWORD、REDIS_KEY_PREFIX,默认 127.0.0.1:6379、`sysmgr:`)
|
||
- [x] 1.2 auth.service 登录/刷新时聚合权限码集(user_role → role_resource → resource,取 `type ∈ {button, api}` 的 code)与 `super` 标志(是否绑定 `code=super_admin`),写入 Redis `{prefix}perm:{tenantCode}:{userId}`(TTL 随会话,刷新续期);登出删除
|
||
- [x] 1.3 jwt-auth.guard 校验通过后将 userId/tenantCode/username 装入 `request.user`(JWT 不放权限集)
|
||
- [x] 1.4 permissions.guard 从 Redis 读 `{super, permissions}`:`super=true` 直接放行;否则校验权限集是否包含全部所需权限码,缺一返回 403
|
||
- [x] 1.5 data_scope 过滤对 `super=true` 按「全部」处理(resolveDataScope 或各列表查询入口统一短路)
|
||
- [x] 1.6 授权变更失效:roles 模块改 role_resource / user_role 后删除该租户权限缓存(SCAN `{prefix}perm:{tenantCode}:*`)
|
||
|
||
## 2. 权限码挂接口
|
||
|
||
- [x] 2.1 定义各域权限码常量清单(`domain:action`):tenant/user/role/resource/org/dict/config/audit/login-log 的 list/create/update/delete 等
|
||
- [x] 2.2 tenants、users、roles、resources、orgs、dicts、configs 各 controller 的全部受控接口挂 `@RequirePermissions(...)`(写操作强制;list 按 domain:list 挂)
|
||
- [x] 2.3 audit-logs、login-logs 查询接口挂 `audit:list` / `login-log:list`
|
||
- [x] 2.4 登录/刷新/登出及 `/docs` 保持 `@Public`,无需权限码
|
||
|
||
## 3. 审计日志落库
|
||
|
||
- [x] 3.1 新增 `@AuditLog(module, action)` 装饰器(SetMetadata 记录 module/action)
|
||
- [x] 3.2 新增 AuditLogInterceptor:请求进入时快照 tenantCode/userId/username/ip/userAgent/method/path/脱敏 body 与起始时间;完成后异步 fire-and-forget 写入;异常时记告警不阻塞
|
||
- [x] 3.3 新增 AuditLogService:写 sys_audit_log(显式传 tenantCode,复用 BodyLogging 脱敏)
|
||
- [x] 3.4 注册 AuditLogInterceptor(全局);给各写接口 controller 挂 `@AuditLog(domain, action)`
|
||
- [x] 3.5 登录成功/登出写 audit_log(module=auth,action=login/logout)
|
||
|
||
## 4. 登录日志落库
|
||
|
||
- [x] 4.1 新增 LoginLogService:写 sys_login_log(username/ip/user_agent/status/message)
|
||
- [x] 4.2 auth.service.login 成功分支写 status=success;失败分支写 status=fail + message(密码错误/账号停用/锁定/租户不存在),并附 IP/UA
|
||
|
||
## 5. seed 脚本
|
||
|
||
- [x] 5.1 新增 prisma/seed.ts:裸 PrismaClient,按唯一键 upsert,可重复执行
|
||
- [x] 5.2 生成租户 `touyun`、根组织、角色 `super_admin`(data_scope=all)、用户 `touyun`(bcryptjs 哈希 `Touyun@123`)并绑定 super_admin
|
||
- [x] 5.3 生成全量资源树:菜单(工作台 + 各域导航)、api(每个受控接口一个,code=`domain:action`,含 method/api_path)、button(纯前端按钮)
|
||
- [x] 5.4 `role_resource` 将 super_admin 关联全部资源 code
|
||
- [x] 5.5 package.json 增加 seed 脚本(prisma db seed 配置)并跑通
|
||
|
||
## 6. 验证
|
||
|
||
- [x] 6.1 跑 seed 后以 `touyun` / `Touyun@123` 登录成功,Redis 中生成 `{prefix}perm:touyun:{userId}` 缓存(含 permissions/super)
|
||
- [x] 6.2 超管访问受控接口放行、列表查询全量;新建一个无权限的普通用户访问受控接口返回 403
|
||
- [x] 6.3 修改某角色授权(role_resource)后,该租户权限缓存被删除,受影响用户下一次请求按新权限生效
|
||
- [x] 6.4 写操作后 sys_audit_log 有记录(status/params 脱敏);登录成功/失败后 sys_login_log 有记录(失败含原因)
|
||
- [x] 6.5 回归:登录/刷新/登出、现有 CRUD、日志输出均正常;测试后停止服务
|