liuyun a8e8ef8606
Some checks are pending
CI / backend (push) Waiting to run
CI / frontend (push) Waiting to run
feat(session): 在线会话强踢 + 账号锁定/解锁(子模块 + openspec change)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 21:36:24 +08:00

47 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 1. 数据模型与迁移
- [x] 1.1 Prisma:`User` 新增 `lockedAt`/`lockReason`(可空,snake_case 映射 `locked_at`/`lock_reason`)
- [x] 1.2 Prisma:`RefreshToken` 新增 `sid`(uuid v7,可空,加索引)
- [x] 1.3 生成并部署 migration(`prisma migrate` / `migrate diff` + `deploy`)
## 2. 认证核心(sid + 锁定判定)
- [x] 2.1 `issue()` 增加 `sid` 参数并写入 access token 载荷;登录时生成新 sid,刷新时沿用旧 sid 并携带 `loginAt/ip/userAgent`、延长 `expireAt`
- [x] 2.2 `loginTenant` 与 `refresh` 拒绝 `lockedAt != null` 的账号
- [x] 2.3 `checkUserActive` 的 user-state 缓存对象扩展为 `{status, tokenVersion, lockedAt}`,`!lockedAt` 才放行
- [x] 2.4 `JwtAuthGuard` 在 checkUserActive 后追加 sid 黑名单判定(Redis `sessionRevoked:{sid}`,命中即 401)
## 3. 在线会话模块
- [x] 3.1 新增 `sessions` 模块(service + controller + DTO)
- [x] 3.2 `GET /sessions`:分页查询活跃会话(join user 取 username/nickname),按用户名/IP 筛选,按数据权限过滤可见用户
- [x] 3.3 `POST /sessions/:sid/kick`:吊销该 sid 的 refresh token + 写 Redis 黑名单(TTL=ACCESS_TTL)
## 4. 用户锁定/解锁与踢全部
- [x] 4.1 `users` service 新增 `lock`/`unlock`/`kickSessions`
- [x] 4.2 `lock`:置 `lockedAt/lockReason` + 调 `invalidateSessions`;`unlock`:清锁定 + 清登录失败计数(loginFail key)
- [x] 4.3 `users` controller 新增 `POST /users/:id/lock`、`POST /users/:id/unlock`、`POST /users/:id/kick-sessions`
## 5. 资源注册与存量补齐
- [x] 5.1 `Permissions` 枚举新增 `session:list`、`session:kick`、`user:kickSessions`、`user:lock`、`user:unlock`
- [x] 5.2 `tenant-template` 新增 session 菜单(parent=monitor,/monitor/session)与上述接口资源
- [x] 5.3 提取 `syncTenantResources`(仅资源+字典+授权,不触碰用户/密码),提供存量租户补齐脚本并执行
## 6. 前端 API
- [x] 6.1 新增 `api/session.ts`:`listSessions`、`kickSession`
- [x] 6.2 `api/user.ts` 扩展 `kickSessions`、`lockUser`、`unlockUser`
## 7. 前端页面
- [x] 7.1 新增 `pages/monitor/session/index.vue`:会话列表 + 单个强退 + 按用户踢全部(确认框)
- [x] 7.2 `pages/system/user/index.vue`:新增「锁定/解锁」操作,锁定状态以标签展示
## 8. 验证
- [x] 8.1 后端 build + 单测通过
- [x] 8.2 前端 type-check 通过
- [x] 8.3 冒烟测试:登录 → 锁定用户(旧 token 失效)→ 会话列表 → 单会话强退 → 解锁后恢复登录