fix(rtc): accept encryption_keys to-device without member.id; warn on unparseable keys (#135) #137
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/commet-encryption-keys-member-id"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #135. Upstream note for Commet: #136.
What: Commet's encrypted calls send
io.element.call.encryption_keyswithmember: {claimed_device_id}and noid. OurEncKeyMemberrequiredid, so serde rejected the content and matrix-sdk skipped the typed handler silently — the Commet caller's media key was never installed, their frames stayedMissingKey, Discord heard nothing (while our ghosts' keys reached them, so they heard us).Changes (
crates/matrix-rtc):member.id→Option<String>(serde(default)),sent_tsserde(default). Neither feeds identity (sender:claimed_device_id). Our outgoing content is unchanged (id: Some("{device_id}_m.call"), covered by the existing wire-shape tests).AnyToDeviceEvent + RawEventhandler re-parses everyencryption_keysevent and WARNs with the content's field names (never values) if it doesn't fit our type — so the next client-shape gap is loud instead of silent.[Unreleased].Verified on forgejo-runner:
cargo clippy -p nvb-matrix-rtc --all-targets -D warningsclean;cargo test -p nvb-matrix-rtc140 passed.Not yet verified live: a Commet join against this build. Expected after deploy:
received io.element.call.encryption_keys to-device … member_id=-→installed peer media key→ the #73 heal line, and Discord hears the Commet caller. If the new WARN fires instead, Commet's shape diverges further; if nothing fires, Commet didn't target our device (see #135 residual).🤖 Generated with Claude Code
Commet's experimental encrypted calls send io.element.call.encryption_keys with member: {claimed_device_id} only. EncKeyMember required `id`, so serde rejected the content and matrix-sdk skipped the typed handler with no log at prod's RUST_LOG — the caller's media key was never installed, their frames stayed MissingKey, and Discord heard silence while the ghosts' keys reached them fine (one-way audio, Dark Voice 2026-09-27). - member.id -> Option<String> (serde default); sent_ts serde default too (js-sdk marks it optional). Neither feeds identity, which is sender:claimed_device_id. What we send is unchanged. - Interop tripwire: catch-all AnyToDeviceEvent + RawEvent handler re-parses every encryption_keys event and WARNs with the content's field names (never values) when it doesn't fit our type. - Tests: Commet shape parses, EC shape still parses, shape describer leaks no key bytes. Upstream note for Commet tracked in #136. Co-Authored-By: Claude Fable 5.1 <[email protected]>