fix: handle Element X to-device encryption key delivery
Element X (26.03.3+) sends io.element.call.encryption_keys as to-device messages, not room timeline events. Added UnknownToDeviceEvent callback to catch these and deliver keys to active voice sessions. Also added m.room.encrypted decryption attempt in timeline scan as fallback for older Element versions that send encrypted timeline events. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
18
voice.py
18
voice.py
@@ -598,7 +598,7 @@ class VoiceSession:
|
||||
except Exception as e:
|
||||
logger.debug("call.member state key fetch failed: %s", e)
|
||||
|
||||
# Legacy: timeline scan
|
||||
# Legacy: timeline scan (decrypts m.room.encrypted events to find encryption_keys)
|
||||
url = f"{homeserver}/_matrix/client/v3/rooms/{self.room_id}/messages"
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10.0) as http:
|
||||
@@ -614,6 +614,22 @@ class VoiceSession:
|
||||
now_ms = int(time.time() * 1000)
|
||||
for evt in events:
|
||||
evt_type = evt.get("type", "")
|
||||
# Decrypt m.room.encrypted events to find encryption_keys inside
|
||||
if evt_type == "m.room.encrypted" and self.nio_client.olm:
|
||||
try:
|
||||
from nio import Event as NioEvent
|
||||
parsed = NioEvent.parse_encrypted_event(evt)
|
||||
if parsed:
|
||||
decrypted = self.nio_client.decrypt_event(parsed)
|
||||
if hasattr(decrypted, "source") and decrypted.source:
|
||||
dec_type = decrypted.source.get("type", "")
|
||||
if dec_type == "io.element.call.encryption_keys":
|
||||
evt = decrypted.source
|
||||
evt_type = dec_type
|
||||
logger.info("Decrypted m.room.encrypted -> %s from %s",
|
||||
dec_type, evt.get("sender", ""))
|
||||
except Exception as dec_err:
|
||||
logger.debug("Failed to decrypt timeline event: %s", dec_err)
|
||||
if evt_type == "io.element.call.encryption_keys":
|
||||
sender = evt.get("sender", "")
|
||||
if sender == user_id:
|
||||
|
||||
Reference in New Issue
Block a user