tju-yxq opened a new issue, #5315:
URL: https://github.com/apache/rocketmq-dashboard/issues/5315
## Problem
The session drawer offers exactly one action: **revoke all** of a user's
active sessions. When an administrator reviewing the drawer spots one
suspicious session — an unknown origin, an unexpected client — the only
available response is to terminate *every* session of that account, including
the user's legitimate ones, and force a full re-login everywhere. For an
account with sessions on office browser, laptop and phone, killing one
suspicious token means disrupting three.
Session review without surgical action is half a control: the console can
show which sessions exist (and with client attribution can now show where they
came from), but the remediation step is all-or-nothing.
## Current behavior and reproduction
1. As an administrator, open **User Management** and a user's session drawer
with several active sessions.
2. Identify the one session you want gone.
3. Look for a per-row action: the session table has no action column. The
only buttons are the drawer-level 注销全部 (revoke all) and the refresh.
4. Choose between leaving the suspicious session alive or revoking every
session of the account.
`server/src/main/java/org/apache/rocketmq/studio/auth/StudioUserController.java`
(around line 92) exposes exactly one revocation path, scoped to a whole
account:
```java
@PostMapping("/{userId}/sessions/revoke")
public Result<StudioUserSessionRevokeVO> revokeSessions(@PathVariable Long
userId) {
int revokedSessionCount = authService.revokeSessionsForUser(userId);
...
}
```
And the drawer's session table in `web/src/pages/studio/UserManagement.tsx`
(`sessionDetailColumns`, around line 375) renders only informational columns —
no per-row action.
## Proposed behavior
- `DELETE /api/studio-users/sessions/{sessionId}` revokes exactly one
session: a single UPDATE over the row (`id` + `revoked_at IS NULL`) setting
`revoked_at`, mirroring the active-session predicate the bulk paths use.
- Revoking an already-revoked or expired session is a **no-op** rather than
an error, so a stale drawer never turns a repeated confirmation into a failure
toast.
- An unknown id answers 404 "Session not found", consistent with the
module's other lookups.
- The drawer's session table gains an action column: a per-row destructive
confirmation that revokes that session, reloads the drawer with the survivors,
and refreshes the user table's active-session counts.
- The per-row action shares the per-user in-flight guard with revoke-all, so
the two can never overlap on the same account.
- Existing revoke-all behavior is unchanged.
## Acceptance criteria
- [ ] Revoking a session by id updates only that row and marks `revoked_at`.
- [ ] Revoking an already-revoked session performs no update and returns
success.
- [ ] Revoking an expired session performs no update and returns success.
- [ ] An unknown session id returns 404 "Session not found".
- [ ] The drawer renders a revoke action per session row behind a
destructive confirmation naming the session id.
- [ ] Confirming revokes exactly that session and reloads the drawer without
the revoked row, keeping the others.
- [ ] Revoke-all and every other endpoint behave exactly as before.
## Importance
Must-have. This is the surgical half of session incident response; the
current workaround — revoke all and let the user re-login everywhere — punishes
the account for one bad token and makes the lightest-weight response the most
disruptive one.
## Duplicate check
Searched open and closed issues and PRs for `revoke single session` and
`revoke one session`. Nothing proposes per-session revocation; the merged #4060
introduced the per-user overview and revoke-all action this builds beside.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]