tju-yxq opened a new issue, #5389:
URL: https://github.com/apache/rocketmq-dashboard/issues/5389

   ## Problem
   
   When an administrator resets a user's password, or creates an account with 
an initial one, that credential can be used indefinitely. Nothing ever requires 
the owner to replace a password that somebody else chose and knows:
   
   - The administrator retains working knowledge of every account they have 
ever reset — an audit finding in most access-control regimes, and a standing 
escalation path if the admin account itself is later compromised.
   - Initial passwords handed to new joiners survive unchanged for the lifetime 
of the account, shared over whatever channel delivered them (chat, email, a 
ticket).
   - The console already records `password_changed_at`, so it can *show* that 
an account never rotated its password — but nothing acts on it.
   
   The standard control is to flag credentials issued by someone other than 
their owner and force the owner to replace them at the next login.
   
   ## Current behavior and reproduction
   
   1. As an administrator, reset a user's password (User Management → reset), 
or create a new account with an initial password.
   2. The recipient logs in with the handed-out password — and can keep using 
it forever. No prompt, no flag, no marker anywhere.
   3. A year later the administrator still knows a working password for that 
account.
   
   
`server/src/main/java/org/apache/rocketmq/studio/persistence/entity/RmqStudioUser.java`
 has no rotation flag; `AuthService.changePassword` (around line 360) writes 
the new hash identically for both the self-service and the admin-reset paths — 
the two flows are indistinguishable afterwards; and `AuthService.createUser` 
(around line 298) inserts the account with no marker on the initial password.
   
   ## Proposed behavior
   
   - `rmq_studio_user` gains `password_must_change` (TINYINT(1), default 0), 
added to existing databases by the established startup-migration pattern. 
Pre-existing accounts default to **no rotation pending**: their passwords were 
set by their owners under the previous behavior, and an upgrade must not lock 
anyone out.
   - `createUser` flags the initial password; the admin-reset path of 
`changePassword` (`requireCurrentPassword == false`) sets the flag; the 
self-service path clears it. A password chosen by its owner needs no rotation.
   - `LoginVO.UserInfo` carries `mustChangePassword` so the login flow can 
react.
   - The login page replaces its form with a change-password step when the flag 
is set: the owner sets a new password, and since the change revokes the current 
session (existing `changePassword` behavior), the flow signs in again with the 
new password and proceeds. The owner cannot reach the console with the 
handed-out credential beyond that first rotation.
   - The user management table shows a "rotation due" tag on flagged accounts 
so administrators can see which ones await rotation.
   - The properties-based (in-memory) mode is unchanged: its users rotate 
passwords by editing configuration and restarting.
   
   ## Acceptance criteria
   
   - [ ] A created account's initial password is flagged for rotation.
   - [ ] An administrator's password reset sets the flag; the owner's own 
password change clears it.
   - [ ] A flagged account's login response reports `mustChangePassword: true`; 
an unflagged one reports false.
   - [ ] The login page blocks entry for a flagged account until the owner sets 
a new password, then signs in with it and proceeds.
   - [ ] The user table shows the rotation-due tag only for flagged accounts.
   - [ ] The migration adds the column to existing databases without touching 
existing rows (which default to no rotation pending), is idempotent, and skips 
a missing table.
   - [ ] Existing `changePassword` semantics (validation, session revocation, 
transaction) are unchanged.
   
   ## Importance
   
   Must-have. This is the standard first-use control for issued credentials; 
its absence means every password an administrator has ever set remains an 
administrator-known working credential. Workaround today: none within the 
console — an operator can only notice the stale `password_changed_at` in the 
drawer and chase the user by hand.
   
   ## Duplicate check
   
   Searched open and closed issues and PRs for `password change next login`, 
`initial password`, and `forced password`. The only adjacent item is #4252 
(create-dialog form residue — unrelated); nothing proposes forced rotation of 
issued credentials.
   


-- 
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]

Reply via email to