Problem (pre-existing, surfaced during PR #297 review)
In ui/src/components/members/member_info_modal/nickname_field.rs, save_changes seals the edited nickname like this:
let sealed_nickname = match current_secret_opt {
Some((secret, version)) => seal_bytes(new_value.as_bytes(), &secret, version),
_ => SealedBytes::public(new_value.into_bytes()),
};
current_secret_opt is None both for a public room (correct — public rooms have no secret) and for a private room whose secret has not yet been decrypted locally. In the latter case the edit publishes the nickname as SealedBytes::public — plaintext — into a private room's member_info delta.
Why it matters
A private room's nicknames are supposed to be encrypted. Editing your nickname before the room secret has arrived locally leaks the plaintext nickname onto the network.
Scope
Pre-existing — not introduced by PR #297. PR #297 added a build_rejoin_delta / build_member_info_heal guard that prevents a stale Public-sealed self_member_info from being re-published into a private room, so the cached-state path is already neutralized. This issue is specifically the edit → delta path.
Fix direction
NicknameField should read room_data.is_private(). When the room is private and no secret is available, the edit must not publish a plaintext member_info — defer the member_info part of the edit (the self-heal will seal it once the secret arrives) or surface that the nickname can't be changed yet.
[AI-assisted - Claude]
Problem (pre-existing, surfaced during PR #297 review)
In
ui/src/components/members/member_info_modal/nickname_field.rs,save_changesseals the edited nickname like this:current_secret_optisNoneboth for a public room (correct — public rooms have no secret) and for a private room whose secret has not yet been decrypted locally. In the latter case the edit publishes the nickname asSealedBytes::public— plaintext — into a private room'smember_infodelta.Why it matters
A private room's nicknames are supposed to be encrypted. Editing your nickname before the room secret has arrived locally leaks the plaintext nickname onto the network.
Scope
Pre-existing — not introduced by PR #297. PR #297 added a
build_rejoin_delta/build_member_info_healguard that prevents a stale Public-sealedself_member_infofrom being re-published into a private room, so the cached-state path is already neutralized. This issue is specifically the edit → delta path.Fix direction
NicknameFieldshould readroom_data.is_private(). When the room is private and no secret is available, the edit must not publish a plaintextmember_info— defer the member_info part of the edit (the self-heal will seal it once the secret arrives) or surface that the nickname can't be changed yet.[AI-assisted - Claude]