unbridled-41 opened a new issue, #5921:
URL: https://github.com/apache/rocketmq-dashboard/issues/5921
### Studio Version
branch: `rocketmq-studio` @ `7e7aa344` (the revision verified; the branch is
based on it)
deployed as: not required to reproduce (any multi-user Studio)
### Runtime Environment
Reproduced with the frontend tests (`cd web && npx vitest run
src/pages/ai/hooks/useComposerDraft.test.ts`); any browser.
### Connected RocketMQ Cluster
Not involved.
### Describe the Bug
The AI composer keeps unsent text in `sessionStorage` under one global key:
```ts
export const COMPOSER_DRAFT_STORAGE_KEY =
'rocketmq-studio-ai-composer-draft';
```
`sessionStorage` is per tab and survives a client-side logout in that tab:
logout only clears `localStorage` (`authStorage.clearAuthSession` removes the
token and the user keys from `localStorage`), and nothing removes the draft key
except an explicit send or clear. The next operator who signs in on the same
tab therefore opens /ai with the previous operator's unsent prompt already in
the composer, and can send it as their own - cluster addresses, topic and group
names, whatever the first operator was mid-question about.
The sibling client-side preferences already key their storage by the account
for exactly this reason, and the hook's own design note explains the per-tab
lifetime without ever addressing whose draft it is.
### Steps to Reproduce
1. Sign in as operator A, open /ai, type a question but do not send it.
2. Log out (client-side) and sign in as operator B in the same tab, then
open /ai.
3. The composer contains A's text.
Red before the fix: `expected 'check the backlog on rmq-prod' to be ''`.
### What Did You Expect to See?
The draft belongs to the account that typed it, and a different account
starts with an empty composer.
### What Did You See Instead?
The previous account's unsent text, ready to be sent.
### Evidence
- `web/src/pages/ai/hooks/useComposerDraft.ts` (the key and the read/write
helpers), `web/src/stores/authStorage.ts:57-62` (logout clears localStorage
only), `web/src/stores/authStore.ts` (the account to scope by).
- `cd web && npx vitest run src/pages/ai/hooks/useComposerDraft.test.ts` -
the new case fails before the fix.
### Impact
Cross-account disclosure of whatever the previous operator had typed but not
sent, on a shared workstation tab, and the leaked text can be submitted under
the new account.
### Acceptance Criteria
- The draft is stored per account (user id when present, username
otherwise), the anonymous case keeps working, and a regression test pins that a
second account starts empty.
**Corresponding PR:** #ISSUEPR#
--
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]