fix(voice): set caller E2EE key on participant_connected + for all remote LK identities

Two race conditions when bot joins first (remote=0):
1. Key arrives before participant joins LK → on_participant_connected now applies stored keys
2. Key arrives after session start → on_encryption_key now sets key for all remote_participants by LK identity

Fixes identity mismatch between Matrix device_id (from key event) and LK participant identity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-02-22 11:30:23 +02:00
parent 5d31886192
commit 2a799f5760

View File

@@ -138,6 +138,13 @@ class VoiceSession:
kp.set_key(caller_id, key, index) kp.set_key(caller_id, key, index)
logger.info("Live-updated caller raw key[%d] for %s (%d bytes)", logger.info("Live-updated caller raw key[%d] for %s (%d bytes)",
index, caller_id, len(key)) index, caller_id, len(key))
# Also set for all current remote participants by LK identity —
# handles mismatch between Matrix device_id and LK session identity.
for p in self.lk_room.remote_participants.values():
if p.identity != caller_id:
kp.set_key(p.identity, key, index)
logger.info("Live-updated caller raw key[%d] for LK identity %s",
index, p.identity)
except Exception as e: except Exception as e:
logger.warning("Failed to live-update caller key: %s", e) logger.warning("Failed to live-update caller key: %s", e)
@@ -250,6 +257,17 @@ class VoiceSession:
@self.lk_room.on("participant_connected") @self.lk_room.on("participant_connected")
def on_p(p): def on_p(p):
logger.info("Participant connected: %s", p.identity) logger.info("Participant connected: %s", p.identity)
# Apply any already-received caller keys to the new participant's LK identity.
# This handles the case where key arrives before the participant joins LiveKit.
if self._caller_all_keys:
try:
kp_local = self.lk_room.e2ee_manager.key_provider
for idx, base_k in sorted(self._caller_all_keys.items()):
kp_local.set_key(p.identity, base_k, idx)
logger.info("on_p: applied %d caller key(s) to %s",
len(self._caller_all_keys), p.identity)
except Exception as exc:
logger.warning("on_p: failed to set caller key for %s: %s", p.identity, exc)
@self.lk_room.on("track_published") @self.lk_room.on("track_published")
def on_tp(pub, p): def on_tp(pub, p):