matrix-js-sdk 41.0.0 → 41.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/@types/event.d.ts +1 -1
  3. package/lib/@types/event.d.ts.map +1 -1
  4. package/lib/@types/event.js +1 -1
  5. package/lib/@types/event.js.map +1 -1
  6. package/lib/client.d.ts.map +1 -1
  7. package/lib/client.js +250 -246
  8. package/lib/client.js.map +1 -1
  9. package/lib/crypto-api/index.d.ts +13 -2
  10. package/lib/crypto-api/index.d.ts.map +1 -1
  11. package/lib/crypto-api/index.js +11 -0
  12. package/lib/crypto-api/index.js.map +1 -1
  13. package/lib/logger.d.ts +5 -5
  14. package/lib/logger.d.ts.map +1 -1
  15. package/lib/logger.js.map +1 -1
  16. package/lib/matrixrtc/CallMembership.d.ts +49 -145
  17. package/lib/matrixrtc/CallMembership.d.ts.map +1 -1
  18. package/lib/matrixrtc/CallMembership.js +157 -265
  19. package/lib/matrixrtc/CallMembership.js.map +1 -1
  20. package/lib/matrixrtc/EncryptionManager.d.ts +1 -85
  21. package/lib/matrixrtc/EncryptionManager.d.ts.map +1 -1
  22. package/lib/matrixrtc/EncryptionManager.js +0 -317
  23. package/lib/matrixrtc/EncryptionManager.js.map +1 -1
  24. package/lib/matrixrtc/MatrixRTCSession.d.ts +18 -22
  25. package/lib/matrixrtc/MatrixRTCSession.d.ts.map +1 -1
  26. package/lib/matrixrtc/MatrixRTCSession.js +48 -76
  27. package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
  28. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts +2 -1
  29. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts.map +1 -1
  30. package/lib/matrixrtc/MatrixRTCSessionManager.js +3 -2
  31. package/lib/matrixrtc/MatrixRTCSessionManager.js.map +1 -1
  32. package/lib/matrixrtc/MembershipManager.d.ts +10 -4
  33. package/lib/matrixrtc/MembershipManager.d.ts.map +1 -1
  34. package/lib/matrixrtc/MembershipManager.js +10 -4
  35. package/lib/matrixrtc/MembershipManager.js.map +1 -1
  36. package/lib/matrixrtc/RTCEncryptionManager.d.ts +6 -7
  37. package/lib/matrixrtc/RTCEncryptionManager.d.ts.map +1 -1
  38. package/lib/matrixrtc/RTCEncryptionManager.js +4 -7
  39. package/lib/matrixrtc/RTCEncryptionManager.js.map +1 -1
  40. package/lib/matrixrtc/index.d.ts +1 -0
  41. package/lib/matrixrtc/index.d.ts.map +1 -1
  42. package/lib/matrixrtc/index.js.map +1 -1
  43. package/lib/matrixrtc/membershipData/common.d.ts +8 -0
  44. package/lib/matrixrtc/membershipData/common.d.ts.map +1 -0
  45. package/lib/matrixrtc/membershipData/common.js +26 -0
  46. package/lib/matrixrtc/membershipData/common.js.map +1 -0
  47. package/lib/matrixrtc/membershipData/index.d.ts +4 -0
  48. package/lib/matrixrtc/membershipData/index.d.ts.map +1 -0
  49. package/lib/matrixrtc/membershipData/index.js +20 -0
  50. package/lib/matrixrtc/membershipData/index.js.map +1 -0
  51. package/lib/matrixrtc/membershipData/rtc.d.ts +33 -0
  52. package/lib/matrixrtc/membershipData/rtc.d.ts.map +1 -0
  53. package/lib/matrixrtc/membershipData/rtc.js +137 -0
  54. package/lib/matrixrtc/membershipData/rtc.js.map +1 -0
  55. package/lib/matrixrtc/membershipData/session.d.ts +77 -0
  56. package/lib/matrixrtc/membershipData/session.d.ts.map +1 -0
  57. package/lib/matrixrtc/membershipData/session.js +62 -0
  58. package/lib/matrixrtc/membershipData/session.js.map +1 -0
  59. package/lib/matrixrtc/types.d.ts +23 -0
  60. package/lib/matrixrtc/types.d.ts.map +1 -1
  61. package/lib/matrixrtc/types.js +9 -1
  62. package/lib/matrixrtc/types.js.map +1 -1
  63. package/lib/matrixrtc/utils.d.ts +11 -1
  64. package/lib/matrixrtc/utils.d.ts.map +1 -1
  65. package/lib/matrixrtc/utils.js +24 -1
  66. package/lib/matrixrtc/utils.js.map +1 -1
  67. package/lib/rust-crypto/rust-crypto.d.ts.map +1 -1
  68. package/lib/rust-crypto/rust-crypto.js +2 -2
  69. package/lib/rust-crypto/rust-crypto.js.map +1 -1
  70. package/package.json +5 -7
  71. package/src/@types/event.ts +2 -2
  72. package/src/client.ts +5 -3
  73. package/src/crypto-api/index.ts +17 -2
  74. package/src/logger.ts +5 -5
  75. package/src/matrixrtc/CallMembership.ts +159 -373
  76. package/src/matrixrtc/EncryptionManager.ts +1 -417
  77. package/src/matrixrtc/MatrixRTCSession.ts +82 -122
  78. package/src/matrixrtc/MatrixRTCSessionManager.ts +5 -3
  79. package/src/matrixrtc/MembershipManager.ts +14 -17
  80. package/src/matrixrtc/RTCEncryptionManager.ts +7 -10
  81. package/src/matrixrtc/index.ts +1 -0
  82. package/src/matrixrtc/membershipData/common.ts +27 -0
  83. package/src/matrixrtc/membershipData/index.ts +19 -0
  84. package/src/matrixrtc/membershipData/rtc.ts +156 -0
  85. package/src/matrixrtc/membershipData/session.ts +146 -0
  86. package/src/matrixrtc/types.ts +27 -1
  87. package/src/matrixrtc/utils.ts +24 -2
  88. package/src/rust-crypto/rust-crypto.ts +4 -1
  89. package/lib/matrixrtc/RoomKeyTransport.d.ts +0 -25
  90. package/lib/matrixrtc/RoomKeyTransport.d.ts.map +0 -1
  91. package/lib/matrixrtc/RoomKeyTransport.js +0 -152
  92. package/lib/matrixrtc/RoomKeyTransport.js.map +0 -1
  93. package/src/matrixrtc/RoomKeyTransport.ts +0 -189
@@ -1 +1 @@
1
- {"version":3,"file":"EncryptionManager.js","names":["logger","rootLogger","secureRandomBase64Url","decodeBase64","encodeUnpaddedBase64","safeGetRetryAfterMs","KeyTransportEvents","isMyMembership","getEncryptionKeyMapKey","membership","concat","userId","deviceId","memberId","EncryptionManager","updateEncryptionKeyThrottle","_this$joinConfig$upda","_this$joinConfig","joinConfig","makeKeyDelay","_this$joinConfig$make","_this$joinConfig2","useKeyDelay","_this$joinConfig$useK","_this$joinConfig3","constructor","getMemberships","transport","statistics","onEncryptionKeysChanged","parentLogger","_this","_defineProperty","Set","Map","_ref","_asyncToGenerator","indexToSend","keysEventUpdateTimeout","undefined","clearTimeout","lastEncryptionKeyUpdateRequest","Date","now","joined","myKeys","getKeysForParticipant","warn","latestGeneratedKeyIndex","keyIndexToSend","info","keyToSend","counters","roomEventEncryptionKeysSent","targets","filter","sender","map","membershipTs","createdTs","sendKey","debug","length","error","resendDelay","setTimeout","sendEncryptionKeysEvent","_x","apply","arguments","keyBase64Encoded","index","timestamp","setEncryptionKey","manageMediaKeys","makeNewKeyTimeout","newKeyIndex","makeNewSenderKey","getChild","rtcBackendIdentityFromMembershipParts","getEncryptionKeys","keysMap","userKeyEntry","encryptionKeys","keys","entry","key","keyIndex","rtcBackendIdentity","set","join","_this$joinConfig$mana","_this$joinConfig4","_this$joinConfig5","on","ReceivedKeys","onNewKeyReceived","start","requestSendCurrentKey","leave","off","stop","t","setNewKeyTimeouts","clear","onMembershipsUpdate","oldMemberships","oldMembershipIds","m","newMembershipIds","anyLeft","Array","from","some","x","has","anyJoined","oldFingerprints","lastMembershipFingerprints","storeLastMembershipFingerprints","onRotateKeyTimeout","newFingerprints","candidateUpdates","delayBeforeUse","encryptionKey","encryptionKeyIndex","getNewEncryptionKeyIndex","_this$encryptionKeys$","get","encryptionKeyString","keyBin","mapKey","participantKeys","existingKeyAtIndex","keysEqual","useKeyTimeout","delete","add","a","b","every","i"],"sources":["../../src/matrixrtc/EncryptionManager.ts"],"sourcesContent":["import { type Logger, logger as rootLogger } from \"../logger.ts\";\nimport { type EncryptionConfig } from \"./MatrixRTCSession.ts\";\nimport { secureRandomBase64Url } from \"../randomstring.ts\";\nimport { decodeBase64, encodeUnpaddedBase64 } from \"../base64.ts\";\nimport { safeGetRetryAfterMs } from \"../http-api/errors.ts\";\nimport { type CallMembership } from \"./CallMembership.ts\";\nimport { type KeyTransportEventListener, KeyTransportEvents, type IKeyTransport } from \"./IKeyTransport.ts\";\nimport { isMyMembership, type EncryptionKeyMapKey, type Statistics } from \"./types.ts\";\n\n/**\n * The string used for the keys in the the encryption key map.\n * `@bob:examle.org:DEVICEID(UUIDRANDOM_MEMBERID_RANDOMUUID)`\n */\nexport function getEncryptionKeyMapKey(membership: CallMembershipIdentityParts): EncryptionKeyMapKey {\n return `${membership.userId}:${membership.deviceId}(${membership.memberId})`;\n}\n\n/**\n * This interface is for testing and for making it possible to interchange the encryption manager.\n * @internal\n */\nexport interface IEncryptionManager {\n /**\n * Joins the encryption manager with the provided configuration.\n *\n * @param joinConfig - The configuration for joining encryption, or undefined\n * if no specific configuration is provided.\n */\n join(joinConfig: EncryptionConfig | undefined): void;\n\n /**\n * Leaves the encryption manager, cleaning up any associated resources.\n */\n leave(): void;\n\n /**\n * Called from the MatrixRTCSession when the memberships in this session updated.\n *\n * @param oldMemberships - The previous state of call memberships before the update.\n */\n onMembershipsUpdate(oldMemberships: CallMembership[]): void;\n\n /**\n * Retrieves the encryption keys currently managed by the encryption manager.\n *\n * @returns A map of participant IDs to their encryption keys.\n */\n getEncryptionKeys(): ReadonlyMap<\n EncryptionKeyMapKey,\n ReadonlyArray<{\n key: Uint8Array<ArrayBuffer>;\n keyIndex: number;\n membership: CallMembershipIdentityParts;\n rtcBackendIdentity: string;\n }>\n >;\n}\n\nexport type CallMembershipIdentityParts = Pick<CallMembership, \"userId\" | \"deviceId\" | \"memberId\">;\n\n/**\n * This class implements the IEncryptionManager interface,\n * and takes care of managing the encryption keys of all rtc members:\n * - generate new keys for the local user and send them to other participants\n * - track all keys of all other members and update livekit.\n *\n * @internal\n */\nexport class EncryptionManager implements IEncryptionManager {\n private manageMediaKeys = false;\n private keysEventUpdateTimeout?: ReturnType<typeof setTimeout>;\n private makeNewKeyTimeout?: ReturnType<typeof setTimeout>;\n private setNewKeyTimeouts = new Set<ReturnType<typeof setTimeout>>();\n\n private get updateEncryptionKeyThrottle(): number {\n return this.joinConfig?.updateEncryptionKeyThrottle ?? 3_000;\n }\n\n private get makeKeyDelay(): number {\n return this.joinConfig?.makeKeyDelay ?? 3_000;\n }\n\n private get useKeyDelay(): number {\n return this.joinConfig?.useKeyDelay ?? 5_000;\n }\n\n private encryptionKeys = new Map<\n string,\n Array<{ key: Uint8Array<ArrayBuffer>; timestamp: number; membership: CallMembershipIdentityParts }>\n >();\n private lastEncryptionKeyUpdateRequest?: number;\n\n // We use this to store the last membership fingerprints we saw, so we can proactively re-send encryption keys\n // if it looks like a membership has been updated.\n private lastMembershipFingerprints: Set<string> | undefined;\n\n private latestGeneratedKeyIndex = -1;\n private joinConfig: EncryptionConfig | undefined;\n private logger: Logger;\n\n public constructor(\n private membership: CallMembershipIdentityParts,\n private getMemberships: () => CallMembership[],\n private transport: IKeyTransport,\n private statistics: Statistics,\n private onEncryptionKeysChanged: (\n keyBin: Uint8Array<ArrayBuffer>,\n encryptionKeyIndex: number,\n membership: CallMembershipIdentityParts,\n rtcBackendIdentity: string,\n ) => void,\n parentLogger?: Logger,\n ) {\n this.logger = (parentLogger ?? rootLogger).getChild(`[EncryptionManager]`);\n }\n\n private rtcBackendIdentityFromMembershipParts(membership: CallMembershipIdentityParts): string {\n // Implement logic to construct rtcBackendIdentity from membership parts\n return `${membership.userId}:${membership.deviceId}`;\n }\n\n public getEncryptionKeys(): ReadonlyMap<\n EncryptionKeyMapKey,\n ReadonlyArray<{\n key: Uint8Array<ArrayBuffer>;\n keyIndex: number;\n membership: CallMembershipIdentityParts;\n rtcBackendIdentity: string;\n }>\n > {\n const keysMap = new Map<\n EncryptionKeyMapKey,\n ReadonlyArray<{\n key: Uint8Array<ArrayBuffer>;\n keyIndex: number;\n membership: CallMembershipIdentityParts;\n rtcBackendIdentity: string;\n }>\n >();\n for (const [userId, userKeyEntry] of this.encryptionKeys) {\n const keys = userKeyEntry.map((entry, index) => ({\n key: entry.key,\n membership: entry.membership,\n keyIndex: index,\n rtcBackendIdentity: this.rtcBackendIdentityFromMembershipParts(entry.membership),\n }));\n keysMap.set(userId as EncryptionKeyMapKey, keys);\n }\n return keysMap;\n }\n\n private joined = false;\n\n public join(joinConfig: EncryptionConfig): void {\n this.joinConfig = joinConfig;\n this.joined = true;\n this.manageMediaKeys = this.joinConfig?.manageMediaKeys ?? this.manageMediaKeys;\n\n this.transport.on(KeyTransportEvents.ReceivedKeys, this.onNewKeyReceived);\n\n this.transport.start();\n if (this.joinConfig?.manageMediaKeys) {\n this.makeNewSenderKey();\n this.requestSendCurrentKey();\n }\n }\n\n public leave(): void {\n // clear our encryption keys as we're done with them now (we'll\n // make new keys if we rejoin). We leave keys for other participants\n // as they may still be using the same ones.\n this.encryptionKeys.set(getEncryptionKeyMapKey(this.membership), []);\n this.transport.off(KeyTransportEvents.ReceivedKeys, this.onNewKeyReceived);\n this.transport.stop();\n\n if (this.makeNewKeyTimeout !== undefined) {\n clearTimeout(this.makeNewKeyTimeout);\n this.makeNewKeyTimeout = undefined;\n }\n for (const t of this.setNewKeyTimeouts) {\n clearTimeout(t);\n }\n this.setNewKeyTimeouts.clear();\n\n this.manageMediaKeys = false;\n this.joined = false;\n }\n\n public onMembershipsUpdate(oldMemberships: CallMembership[]): void {\n if (this.manageMediaKeys && this.joined) {\n const oldMembershipIds = new Set(\n oldMemberships\n .filter((m) => !isMyMembership(m, this.membership.userId, this.membership.deviceId))\n .map(getEncryptionKeyMapKey),\n );\n const newMembershipIds = new Set(\n this.getMemberships()\n .filter((m) => !isMyMembership(m, this.membership.userId, this.membership.deviceId))\n .map(getEncryptionKeyMapKey),\n );\n\n // We can use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/symmetricDifference\n // for this once available\n const anyLeft = Array.from(oldMembershipIds).some((x) => !newMembershipIds.has(x));\n const anyJoined = Array.from(newMembershipIds).some((x) => !oldMembershipIds.has(x));\n\n const oldFingerprints = this.lastMembershipFingerprints;\n // always store the fingerprints of these latest memberships\n this.storeLastMembershipFingerprints();\n\n if (anyLeft) {\n if (this.makeNewKeyTimeout) {\n // existing rotation in progress, so let it complete\n } else {\n this.logger.debug(`Member(s) have left: queueing sender key rotation`);\n this.makeNewKeyTimeout = setTimeout(this.onRotateKeyTimeout, this.makeKeyDelay);\n }\n } else if (anyJoined) {\n this.logger.debug(`New member(s) have joined: re-sending keys`);\n this.requestSendCurrentKey();\n } else if (oldFingerprints) {\n // does it look like any of the members have updated their memberships?\n const newFingerprints = this.lastMembershipFingerprints!;\n\n // We can use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/symmetricDifference\n // for this once available\n const candidateUpdates =\n Array.from(oldFingerprints).some((x) => !newFingerprints.has(x)) ||\n Array.from(newFingerprints).some((x) => !oldFingerprints.has(x));\n if (candidateUpdates) {\n this.logger.debug(`Member(s) have updated/reconnected: re-sending keys to everyone`);\n this.requestSendCurrentKey();\n }\n }\n }\n }\n\n /**\n * Generate a new sender key and add it at the next available index\n * @param delayBeforeUse - If true, wait for a short period before setting the key for the\n * media encryptor to use. If false, set the key immediately.\n * @returns The index of the new key\n */\n private makeNewSenderKey(delayBeforeUse = false): number {\n const encryptionKey = secureRandomBase64Url(16);\n const encryptionKeyIndex = this.getNewEncryptionKeyIndex();\n this.logger.info(\"Generated new key at index \" + encryptionKeyIndex);\n this.setEncryptionKey(this.membership, encryptionKeyIndex, encryptionKey, Date.now(), delayBeforeUse);\n return encryptionKeyIndex;\n }\n\n /**\n * Requests that we resend our current keys to the room. May send a keys event immediately\n * or queue for alter if one has already been sent recently.\n */\n private requestSendCurrentKey(): void {\n if (!this.manageMediaKeys) return;\n\n if (\n this.lastEncryptionKeyUpdateRequest &&\n this.lastEncryptionKeyUpdateRequest + this.updateEncryptionKeyThrottle > Date.now()\n ) {\n this.logger.info(\"Last encryption key event sent too recently: postponing\");\n if (this.keysEventUpdateTimeout === undefined) {\n this.keysEventUpdateTimeout = setTimeout(\n () => void this.sendEncryptionKeysEvent(),\n this.updateEncryptionKeyThrottle,\n );\n }\n return;\n }\n\n void this.sendEncryptionKeysEvent();\n }\n\n /**\n * Get the known encryption keys for a given participant device.\n *\n * @param membership - The membership identity parts of the participant\n * @returns The encryption keys for the given participant, or undefined if they are not known.\n */\n private getKeysForParticipant(membership: CallMembershipIdentityParts): Array<Uint8Array<ArrayBuffer>> | undefined {\n return this.encryptionKeys.get(getEncryptionKeyMapKey(membership))?.map((entry) => entry.key);\n }\n\n /**\n * Re-sends the encryption keys room event\n */\n private sendEncryptionKeysEvent = async (indexToSend?: number): Promise<void> => {\n if (this.keysEventUpdateTimeout !== undefined) {\n clearTimeout(this.keysEventUpdateTimeout);\n this.keysEventUpdateTimeout = undefined;\n }\n this.lastEncryptionKeyUpdateRequest = Date.now();\n\n if (!this.joined) return;\n\n const myKeys = this.getKeysForParticipant(this.membership);\n\n if (!myKeys) {\n this.logger.warn(\"Tried to send encryption keys event but no keys found!\");\n return;\n }\n\n if (typeof indexToSend !== \"number\" && this.latestGeneratedKeyIndex === -1) {\n this.logger.warn(\"Tried to send encryption keys event but no current key index found!\");\n return;\n }\n\n const keyIndexToSend = indexToSend ?? this.latestGeneratedKeyIndex;\n\n this.logger.info(\n `Try sending encryption keys event. keyIndexToSend=${keyIndexToSend} (method parameter: ${indexToSend})`,\n );\n const keyToSend = myKeys[keyIndexToSend];\n\n try {\n this.statistics.counters.roomEventEncryptionKeysSent += 1;\n const targets = this.getMemberships()\n .filter((membership) => {\n return membership.sender != undefined;\n })\n .map((membership) => {\n return {\n userId: membership.sender!,\n deviceId: membership.deviceId,\n membershipTs: membership.createdTs(),\n };\n });\n await this.transport.sendKey(encodeUnpaddedBase64(keyToSend), keyIndexToSend, targets);\n this.logger.debug(\n `sendEncryptionKeysEvent participantId=${this.membership.userId}:${this.membership.deviceId} numKeys=${myKeys.length} currentKeyIndex=${this.latestGeneratedKeyIndex} keyIndexToSend=${keyIndexToSend}`,\n );\n } catch (error) {\n if (this.keysEventUpdateTimeout === undefined) {\n const resendDelay = safeGetRetryAfterMs(error, 5000);\n this.logger.warn(`Failed to send m.call.encryption_key, retrying in ${resendDelay}`, error);\n this.keysEventUpdateTimeout = setTimeout(() => void this.sendEncryptionKeysEvent(), resendDelay);\n } else {\n this.logger.info(\"Not scheduling key resend as another re-send is already pending\");\n }\n }\n };\n\n public onNewKeyReceived: KeyTransportEventListener = (membership, keyBase64Encoded, index, timestamp) => {\n this.logger.debug(\n `Received key over key transport ${membership.userId}:${membership.deviceId} at index ${index}`,\n );\n this.setEncryptionKey(membership, index, keyBase64Encoded, timestamp);\n };\n\n private storeLastMembershipFingerprints(): void {\n this.lastMembershipFingerprints = new Set(\n this.getMemberships()\n .filter((m) => !isMyMembership(m, this.membership.userId, this.membership.deviceId))\n .map((m) => `${getEncryptionKeyMapKey(m)}:${m.createdTs()}`),\n );\n }\n\n private getNewEncryptionKeyIndex(): number {\n if (this.latestGeneratedKeyIndex === -1) {\n return 0;\n }\n\n // maximum key index is 255\n return (this.latestGeneratedKeyIndex + 1) % 256;\n }\n\n /**\n * Sets an encryption key at a specified index for a participant.\n * The encryption keys for the local participant are also stored here under the\n * user and device ID of the local participant.\n * If the key is older than the existing key at the index, it will be ignored.\n * @param userId - The user ID of the participant\n * @param deviceId - Device ID of the participant\n * @param encryptionKeyIndex - The index of the key to set\n * @param encryptionKeyString - The string representation of the key to set in base64\n * @param timestamp - The timestamp of the key. We assume that these are monotonic for each participant device.\n * @param delayBeforeUse - If true, delay before emitting a key changed event. Useful when setting\n * encryption keys for the local participant to allow time for the key to\n * be distributed.\n */\n private setEncryptionKey(\n membership: CallMembershipIdentityParts,\n encryptionKeyIndex: number,\n encryptionKeyString: string,\n timestamp: number,\n delayBeforeUse = false,\n ): void {\n this.logger.debug(\n `Setting encryption key for ${membership.userId}:${membership.deviceId} at index ${encryptionKeyIndex}`,\n );\n const keyBin = decodeBase64(encryptionKeyString);\n\n const mapKey = getEncryptionKeyMapKey(membership);\n if (!this.encryptionKeys.has(mapKey)) {\n this.encryptionKeys.set(mapKey, []);\n }\n const participantKeys = this.encryptionKeys.get(mapKey)!;\n\n const existingKeyAtIndex = participantKeys[encryptionKeyIndex];\n\n if (existingKeyAtIndex) {\n if (existingKeyAtIndex.timestamp > timestamp) {\n this.logger.info(\n `Ignoring new key at index ${encryptionKeyIndex} for ${mapKey} as it is older than existing known key`,\n );\n return;\n }\n\n if (keysEqual(existingKeyAtIndex.key, keyBin)) {\n existingKeyAtIndex.timestamp = timestamp;\n return;\n }\n }\n\n if (membership.userId === this.membership.userId && membership.deviceId === this.membership.deviceId) {\n // It is important to already update the latestGeneratedKeyIndex here\n // NOT IN THE `delayBeforeUse` `setTimeout`.\n // Even though this is where we call onEncryptionKeysChanged and set the key in EC (and livekit).\n // It needs to happen here because we will send the key before the timeout has passed and sending\n // the key will use latestGeneratedKeyIndex as the index. if we update it in the `setTimeout` callback\n // it will use the wrong index (index - 1)!\n this.latestGeneratedKeyIndex = encryptionKeyIndex;\n }\n participantKeys[encryptionKeyIndex] = {\n key: keyBin,\n timestamp,\n membership: membership,\n };\n\n if (delayBeforeUse) {\n const useKeyTimeout = setTimeout(() => {\n this.setNewKeyTimeouts.delete(useKeyTimeout);\n this.logger.info(`Delayed-emitting key changed event for ${mapKey} index ${encryptionKeyIndex}`);\n\n this.onEncryptionKeysChanged(\n keyBin,\n encryptionKeyIndex,\n membership,\n this.rtcBackendIdentityFromMembershipParts(membership),\n );\n }, this.useKeyDelay);\n this.setNewKeyTimeouts.add(useKeyTimeout);\n } else {\n this.onEncryptionKeysChanged(\n keyBin,\n encryptionKeyIndex,\n membership,\n this.rtcBackendIdentityFromMembershipParts(membership),\n );\n }\n }\n\n private onRotateKeyTimeout = (): void => {\n if (!this.manageMediaKeys) return;\n\n this.makeNewKeyTimeout = undefined;\n this.logger.info(\"Making new sender key for key rotation\");\n const newKeyIndex = this.makeNewSenderKey(true);\n // send immediately: if we're about to start sending with a new key, it's\n // important we get it out to others as soon as we can.\n void this.sendEncryptionKeysEvent(newKeyIndex);\n };\n}\n\nfunction keysEqual(a: Uint8Array | undefined, b: Uint8Array | undefined): boolean {\n if (a === b) return true;\n return !!a && !!b && a.length === b.length && a.every((x, i) => x === b[i]);\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"EncryptionManager.js","names":["getEncryptionKeyMapKey","membership","concat","userId","deviceId","memberId"],"sources":["../../src/matrixrtc/EncryptionManager.ts"],"sourcesContent":["import { type EncryptionConfig } from \"./MatrixRTCSession.ts\";\nimport { type CallMembership } from \"./CallMembership.ts\";\nimport { type EncryptionKeyMapKey } from \"./types.ts\";\n\n/**\n * The string used for the keys in the the encryption key map.\n * `@bob:examle.org:DEVICEID(UUIDRANDOM_MEMBERID_RANDOMUUID)`\n */\nexport function getEncryptionKeyMapKey(membership: CallMembershipIdentityParts): EncryptionKeyMapKey {\n return `${membership.userId}:${membership.deviceId}(${membership.memberId})`;\n}\n\n/**\n * This interface is for testing and for making it possible to interchange the encryption manager.\n * @internal\n */\nexport interface IEncryptionManager {\n /**\n * Joins the encryption manager with the provided configuration.\n *\n * @param joinConfig - The configuration for joining encryption, or undefined\n * if no specific configuration is provided.\n */\n join(joinConfig: EncryptionConfig | undefined): void;\n\n /**\n * Leaves the encryption manager, cleaning up any associated resources.\n */\n leave(): void;\n\n /**\n * Called from the MatrixRTCSession when the memberships in this session updated.\n *\n * @param oldMemberships - The previous state of call memberships before the update.\n */\n onMembershipsUpdate(oldMemberships: CallMembership[]): void;\n\n /**\n * Retrieves the encryption keys currently managed by the encryption manager.\n *\n * @returns A map of participant IDs to their encryption keys.\n */\n getEncryptionKeys(): ReadonlyMap<\n EncryptionKeyMapKey,\n ReadonlyArray<{\n key: Uint8Array<ArrayBuffer>;\n keyIndex: number;\n membership: CallMembershipIdentityParts;\n rtcBackendIdentity: string;\n }>\n >;\n}\n\nexport type CallMembershipIdentityParts = Pick<CallMembership, \"userId\" | \"deviceId\" | \"memberId\">;\n"],"mappings":"AAIA;AACA;AACA;AACA;AACA,OAAO,SAASA,sBAAsBA,CAACC,UAAuC,EAAuB;EACjG,UAAAC,MAAA,CAAUD,UAAU,CAACE,MAAM,OAAAD,MAAA,CAAID,UAAU,CAACG,QAAQ,OAAAF,MAAA,CAAID,UAAU,CAACI,QAAQ;AAC7E;;AAEA;AACA;AACA;AACA","ignoreList":[]}
@@ -3,7 +3,7 @@ import { type Room } from "../models/room.ts";
3
3
  import { type MatrixClient } from "../client.ts";
4
4
  import { CallMembership } from "./CallMembership.ts";
5
5
  import { type CallMembershipIdentityParts } from "./EncryptionManager.ts";
6
- import type { Statistics, RTCNotificationType, Status, IRTCNotificationContent, RTCCallIntent, Transport } from "./types.ts";
6
+ import type { Statistics, RTCNotificationType, Status, IRTCNotificationContent, RTCCallIntent, Transport, SlotDescription } from "./types.ts";
7
7
  import { MembershipManagerEvent, type MembershipManagerEventHandlerMap } from "./IMembershipManager.ts";
8
8
  /**
9
9
  * Events emitted by MatrixRTCSession
@@ -37,15 +37,6 @@ export interface SessionConfig {
37
37
  */
38
38
  callIntent?: RTCCallIntent;
39
39
  }
40
- /**
41
- * The session description is used to identify a session. Used in the state event.
42
- */
43
- export interface SlotDescription {
44
- id: string;
45
- application: string;
46
- }
47
- export declare function slotIdToDescription(slotId: string): SlotDescription;
48
- export declare function slotDescriptionToId(slotDescription: SlotDescription): string;
49
40
  export interface MembershipConfig {
50
41
  /**
51
42
  * The timeout (in milliseconds) after we joined the call, that our membership should expire
@@ -86,10 +77,6 @@ export interface MembershipConfig {
86
77
  * failed to send due to a network error. (send membership event, send delayed event, restart delayed event...)
87
78
  */
88
79
  networkErrorRetryMs?: number;
89
- /**
90
- * If true, use the new to-device transport for sending encryption keys.
91
- */
92
- useExperimentalToDeviceTransport?: boolean;
93
80
  /**
94
81
  * The time (in milliseconds) after which a we consider a delayed event restart http request to have failed.
95
82
  * Setting this to a lower value will result in more frequent retries but also a higher chance of failiour.
@@ -182,6 +169,15 @@ export declare class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSession
182
169
  */
183
170
  private expiryTimeout?;
184
171
  memberships: CallMembership[];
172
+ /**
173
+ * Resolves when the session has calculated the initial membership of the session.
174
+ */
175
+ readonly initialMembershipCalculated: Promise<void>;
176
+ /**
177
+ * Does membership need to be recalculated? This is set to false upon
178
+ * recalculation.
179
+ */
180
+ private membershipNeedsRecalculation;
185
181
  /**
186
182
  * The statistics for this session.
187
183
  */
@@ -210,7 +206,7 @@ export declare class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSession
210
206
  *
211
207
  * By default, this will return *both* sticky and member state events.
212
208
  */
213
- static sessionMembershipsForSlot(room: Pick<Room, "getLiveTimeline" | "roomId" | "hasMembershipState" | "_unstable_getStickyEvents">, slotId: string, options?: SessionMembershipsForSlotOpts): Promise<CallMembership[]>;
209
+ static sessionMembershipsForSlot(room: Pick<Room, "getLiveTimeline" | "roomId" | "hasMembershipState" | "_unstable_getStickyEvents">, slotDescription: SlotDescription, options?: SessionMembershipsForSlotOpts): Promise<CallMembership[]>;
214
210
  /**
215
211
  * Return the MatrixRTC session for the room.
216
212
  * This returned session can be used to find out if there are active sessions
@@ -237,8 +233,9 @@ export declare class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSession
237
233
  * @param slotDescription The slot description is a virtual address where participants are allowed to meet.
238
234
  * This session will only manage memberships that match this slot description.Sessions are distinct if any of
239
235
  * those properties are distinct: `roomSubset.roomId`, `slotDescription.application`, `slotDescription.id`.
236
+ * @param calculateMembershipsOpts - Options to configure how memberships are calculated for this session.
240
237
  */
241
- constructor(client: Pick<MatrixClient, "getUserId" | "getDeviceId" | "sendEvent" | "sendStateEvent" | "_unstable_sendDelayedStateEvent" | "_unstable_updateDelayedEvent" | "_unstable_cancelScheduledDelayedEvent" | "_unstable_restartScheduledDelayedEvent" | "_unstable_sendScheduledDelayedEvent" | "_unstable_sendStickyEvent" | "_unstable_sendStickyDelayedEvent" | "cancelPendingEvent" | "encryptAndSendToDevice" | "off" | "on" | "decryptEventIfNeeded">, roomSubset: Pick<Room, "getLiveTimeline" | "roomId" | "getVersion" | "hasMembershipState" | "on" | "off">, slotDescription: SlotDescription, calculateMembershipsOpts?: SessionMembershipsForSlotOpts | undefined);
238
+ constructor(client: Pick<MatrixClient, "getUserId" | "getDeviceId" | "sendEvent" | "sendStateEvent" | "_unstable_sendDelayedStateEvent" | "_unstable_updateDelayedEvent" | "_unstable_cancelScheduledDelayedEvent" | "_unstable_restartScheduledDelayedEvent" | "_unstable_sendScheduledDelayedEvent" | "_unstable_sendStickyEvent" | "_unstable_sendStickyDelayedEvent" | "cancelPendingEvent" | "encryptAndSendToDevice" | "off" | "on" | "decryptEventIfNeeded">, roomSubset: Pick<Room, "getLiveTimeline" | "roomId" | "getVersion" | "hasMembershipState" | "on" | "off" | "_unstable_getStickyEvents">, slotDescription: SlotDescription, calculateMembershipsOpts?: SessionMembershipsForSlotOpts | undefined);
242
239
  isJoined(): boolean;
243
240
  /**
244
241
  * Performs cleanup & removes timers for client shutdown
@@ -287,11 +284,6 @@ export declare class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSession
287
284
  * @deprecated use `member.getTransport(session.getOldestMembership())` instead for the specific member you want to get the focus for.
288
285
  */
289
286
  getFocusInUse(): Transport | undefined;
290
- /**
291
- * The used focusActive of the oldest membership (to find out the selection type multi-sfu or oldest membership active focus)
292
- * @deprecated does not work with m.rtc.member. Do not rely on it.
293
- */
294
- getActiveFocus(): Transport | undefined;
295
287
  getOldestMembership(): CallMembership | undefined;
296
288
  /**
297
289
  * Get the call intent for the current call, based on what members are advertising. If one or more
@@ -331,8 +323,12 @@ export declare class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSession
331
323
  * Call this when something changed that may impacts the current MatrixRTC members in this session.
332
324
  */
333
325
  _onRTCSessionMemberUpdate: () => Promise<void>;
334
- private recalculateSessionMembersDirty;
335
326
  private recalculateSessionMembersPromise;
327
+ /**
328
+ * Ensures that membership is recalculated when the state of the session may have changed.
329
+ * Also ensures that only one recalculation is made at a time.
330
+ * @returns A promise resolving when the state has been recalculated.
331
+ */
336
332
  private ensureRecalculateSessionMembers;
337
333
  /**
338
334
  * Call this when anything that could impact rtc memberships has changed: Room Members or RTC members.
@@ -1 +1 @@
1
- {"version":3,"file":"MatrixRTCSession.d.ts","sourceRoot":"","sources":["../../src/matrixrtc/MatrixRTCSession.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MatrixRTCSession.d.ts","sourceRoot":"","sources":["../../src/matrixrtc/MatrixRTCSession.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
5
  /*
6
- Copyright 2023 - 2024 The Matrix.org Foundation C.I.C.
6
+ Copyright 2023 - 2026 The Matrix.org Foundation C.I.C.
7
7
 
8
8
  Licensed under the Apache License, Version 2.0 (the "License");
9
9
  you may not use this file except in compliance with the License.
@@ -26,14 +26,13 @@ import { KnownMembership } from "../@types/membership.js";
26
26
  import { CallMembership } from "./CallMembership.js";
27
27
  import { RoomStateEvent } from "../models/room-state.js";
28
28
  import { MembershipManager, StickyEventMembershipManager } from "./MembershipManager.js";
29
- import { EncryptionManager } from "./EncryptionManager.js";
30
29
  import { logDurationSync } from "../utils.js";
31
30
  import { MembershipManagerEvent } from "./IMembershipManager.js";
32
31
  import { RTCEncryptionManager } from "./RTCEncryptionManager.js";
33
32
  import { ToDeviceKeyTransport } from "./ToDeviceKeyTransport.js";
34
33
  import { TypedReEmitter } from "../ReEmitter.js";
35
34
  import { RoomStickyEventsEvent } from "../models/room-sticky-events.js";
36
- import { RoomKeyTransport } from "./RoomKeyTransport.js";
35
+ import { computeSlotId } from "./utils.js";
37
36
 
38
37
  /**
39
38
  * Events emitted by MatrixRTCSession
@@ -54,21 +53,6 @@ export var MatrixRTCSessionEvent = /*#__PURE__*/function (MatrixRTCSessionEvent)
54
53
  return MatrixRTCSessionEvent;
55
54
  }({});
56
55
 
57
- /**
58
- * The session description is used to identify a session. Used in the state event.
59
- */
60
-
61
- export function slotIdToDescription(slotId) {
62
- var [application, id] = slotId.split("#");
63
- return {
64
- application,
65
- id
66
- };
67
- }
68
- export function slotDescriptionToId(slotDescription) {
69
- return "".concat(slotDescription.application, "#").concat(slotDescription.id);
70
- }
71
-
72
56
  // The names follow these principles:
73
57
  // - we use the technical term delay if the option is related to delayed events.
74
58
  // - we use delayedLeaveEvent if the option is related to the delayed leave event.
@@ -118,7 +102,7 @@ export class MatrixRTCSession extends TypedEventEmitter {
118
102
  * The slotId is the property that, per definition, groups memberships into one call.
119
103
  */
120
104
  get slotId() {
121
- return slotDescriptionToId(this.slotDescription);
105
+ return computeSlotId(this.slotDescription);
122
106
  }
123
107
 
124
108
  /**
@@ -127,13 +111,13 @@ export class MatrixRTCSession extends TypedEventEmitter {
127
111
  *
128
112
  * By default, this will return *both* sticky and member state events.
129
113
  */
130
- static sessionMembershipsForSlot(room, slotId) {
114
+ static sessionMembershipsForSlot(room, slotDescription) {
131
115
  var _arguments = arguments;
132
116
  return _asyncToGenerator(function* () {
133
117
  var options = _arguments.length > 2 && _arguments[2] !== undefined ? _arguments[2] : DEFAULT_SESSION_MEMBERSHIPS_FOR_SLOT_OPTS;
134
- var logger = rootLogger.getChild("[MatrixRTCSession ".concat(room.roomId, "]"));
118
+ var logger = rootLogger.getChild("[MatrixRTCSession ".concat(room.roomId, " ").concat(slotDescription.application, "#").concat(slotDescription.id, "]"));
135
119
  var callMemberEvents = collectMembersEvents(room, options, logger);
136
- var callMemberships = yield computeBackendIdentityAndVerifyMemberEvents(room, callMemberEvents, slotId, logger);
120
+ var callMemberships = yield computeBackendIdentityAndVerifyMemberEvents(room, callMemberEvents, slotDescription, logger);
137
121
  callMemberships.sort((a, b) => a.createdTs() - b.createdTs());
138
122
  if (callMemberships.length > 1) {
139
123
  logger.debug("Call memberships in room ".concat(room.roomId, ", in order: "), callMemberships.map(m => [m.createdTs(), m.userId]));
@@ -174,6 +158,7 @@ export class MatrixRTCSession extends TypedEventEmitter {
174
158
  * @param slotDescription The slot description is a virtual address where participants are allowed to meet.
175
159
  * This session will only manage memberships that match this slot description.Sessions are distinct if any of
176
160
  * those properties are distinct: `roomSubset.roomId`, `slotDescription.application`, `slotDescription.id`.
161
+ * @param calculateMembershipsOpts - Options to configure how memberships are calculated for this session.
177
162
  */
178
163
  constructor(client, roomSubset, slotDescription, calculateMembershipsOpts) {
179
164
  var _this;
@@ -195,6 +180,15 @@ export class MatrixRTCSession extends TypedEventEmitter {
195
180
  */
196
181
  _defineProperty(this, "expiryTimeout", void 0);
197
182
  _defineProperty(this, "memberships", []);
183
+ /**
184
+ * Resolves when the session has calculated the initial membership of the session.
185
+ */
186
+ _defineProperty(this, "initialMembershipCalculated", void 0);
187
+ /**
188
+ * Does membership need to be recalculated? This is set to false upon
189
+ * recalculation.
190
+ */
191
+ _defineProperty(this, "membershipNeedsRecalculation", false);
198
192
  /**
199
193
  * The statistics for this session.
200
194
  */
@@ -212,14 +206,14 @@ export class MatrixRTCSession extends TypedEventEmitter {
212
206
  * Call this when the Matrix room members have changed.
213
207
  */
214
208
  _defineProperty(this, "onRoomMemberUpdate", () => {
215
- this.ensureRecalculateSessionMembers();
209
+ void this.ensureRecalculateSessionMembers();
216
210
  });
217
211
  /**
218
212
  * Call this when a sticky event update has occured.
219
213
  */
220
214
  _defineProperty(this, "onStickyEventUpdate", (added, updated, removed) => {
221
215
  if ([...added, ...removed, ...updated.flatMap(v => [v.current, v.previous])].some(e => e.getType() === EventType.RTCMembership)) {
222
- this.ensureRecalculateSessionMembers();
216
+ void this.ensureRecalculateSessionMembers();
223
217
  }
224
218
  });
225
219
  /**
@@ -231,8 +225,7 @@ export class MatrixRTCSession extends TypedEventEmitter {
231
225
  yield _this.recalculateSessionMembers();
232
226
  }));
233
227
  // helper variables to make sure we do not have parallel running recalculations.
234
- _defineProperty(this, "recalculateSessionMembersDirty", false);
235
- _defineProperty(this, "recalculateSessionMembersPromise", undefined);
228
+ _defineProperty(this, "recalculateSessionMembersPromise", Promise.resolve());
236
229
  /**
237
230
  * Call this when anything that could impact rtc memberships has changed: Room Members or RTC members.
238
231
  *
@@ -242,8 +235,10 @@ export class MatrixRTCSession extends TypedEventEmitter {
242
235
  */
243
236
  _defineProperty(this, "recalculateSessionMembers", /*#__PURE__*/_asyncToGenerator(function* () {
244
237
  var _this$encryptionManag;
238
+ // Clear the flag.
239
+ _this.membershipNeedsRecalculation = false;
245
240
  var oldMemberships = _this.memberships;
246
- _this.memberships = yield MatrixRTCSession.sessionMembershipsForSlot(_this.room, slotDescriptionToId(_this.slotDescription), _this.calculateMembershipsOpts);
241
+ _this.memberships = yield MatrixRTCSession.sessionMembershipsForSlot(_this.room, _this.slotDescription, _this.calculateMembershipsOpts);
247
242
  var changed = oldMemberships.length != _this.memberships.length || oldMemberships.some((m, i) => !CallMembership.equal(m, _this.memberships[i]));
248
243
  if (changed) {
249
244
  var _this$membershipManag4, _this$membershipManag5;
@@ -275,13 +270,10 @@ export class MatrixRTCSession extends TypedEventEmitter {
275
270
  void ((_this$encryptionManag = _this.encryptionManager) === null || _this$encryptionManag === void 0 ? void 0 : _this$encryptionManag.onMembershipsUpdate(oldMemberships));
276
271
  _this.setExpiryTimer();
277
272
  }));
278
- this.logger = rootLogger.getChild("[MatrixRTCSession ".concat(roomSubset.roomId, "]"));
273
+ this.logger = rootLogger.getChild("[MatrixRTCSession ".concat(roomSubset.roomId, " ").concat(slotDescription.application, "#").concat(slotDescription.id, "]"));
279
274
  this.roomSubset.on(RoomStateEvent.Members, this.onRoomMemberUpdate);
280
275
  this.roomSubset.on(RoomStickyEventsEvent.Update, this.onStickyEventUpdate);
281
-
282
- // We can ignore this promise because `recalculateSessionMembers` will emit
283
- // `MatrixRTCSessionEvent.MembershipsChanged` once it has completed.
284
- this.ensureRecalculateSessionMembers();
276
+ this.initialMembershipCalculated = this.ensureRecalculateSessionMembers();
285
277
  this.setExpiryTimer();
286
278
  }
287
279
  /*
@@ -335,22 +327,11 @@ export class MatrixRTCSession extends TypedEventEmitter {
335
327
  this.membershipManager = joinConfig !== null && joinConfig !== void 0 && joinConfig.unstableSendStickyEvents ? new StickyEventMembershipManager(joinConfig, this.roomSubset, this.client, this.slotDescription, ownMembershipIdentity.memberId, this.logger) : new MembershipManager(joinConfig, this.roomSubset, this.client, this.slotDescription, this.logger);
336
328
  this.reEmitter.reEmit(this.membershipManager, [MembershipManagerEvent.ProbablyLeft, MembershipManagerEvent.StatusChanged, MembershipManagerEvent.DelayIdChanged]);
337
329
  // Create Encryption manager
338
- var transport;
339
- if (joinConfig !== null && joinConfig !== void 0 && joinConfig.useExperimentalToDeviceTransport) {
340
- this.logger.info("Using experimental to-device transport for encryption keys");
341
- this.logger.info("Using to-device with room fallback transport for encryption keys");
342
- var [room, _client, statistics] = [this.roomSubset, this.client, this.statistics];
343
- var _transport = new ToDeviceKeyTransport(ownMembershipIdentity, room.roomId, _client, statistics);
344
- this.encryptionManager = new RTCEncryptionManager(ownMembershipIdentity, () => this.memberships, _transport, this.statistics, (keyBin, encryptionKeyIndex, membership, rtcBackendIdentity) => {
345
- this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, keyBin, encryptionKeyIndex, membership, rtcBackendIdentity);
346
- }, this.logger);
347
- } else {
348
- // TODO REMOVE ME!
349
- transport = new RoomKeyTransport(this.roomSubset, this.client, this.statistics);
350
- this.encryptionManager = new EncryptionManager(ownMembershipIdentity, () => this.memberships, transport, this.statistics, (keyBin, encryptionKeyIndex, membership, rtcBackendIdentity) => {
351
- this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, keyBin, encryptionKeyIndex, membership, rtcBackendIdentity);
352
- });
353
- }
330
+ var [room, _client, statistics] = [this.roomSubset, this.client, this.statistics];
331
+ var transport = new ToDeviceKeyTransport(ownMembershipIdentity, room.roomId, _client, statistics);
332
+ this.encryptionManager = new RTCEncryptionManager(ownMembershipIdentity, () => this.memberships, transport, (keyBin, encryptionKeyIndex, membership, rtcBackendIdentity) => {
333
+ this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, keyBin, encryptionKeyIndex, membership, rtcBackendIdentity);
334
+ }, this.logger);
354
335
  }
355
336
  this.joinConfig = joinConfig;
356
337
  this.pendingNotificationToSend = (_this$joinConfig2 = this.joinConfig) === null || _this$joinConfig2 === void 0 ? void 0 : _this$joinConfig2.notificationType;
@@ -418,15 +399,6 @@ export class MatrixRTCSession extends TypedEventEmitter {
418
399
  var oldestMembership = this.getOldestMembership();
419
400
  return oldestMembership === null || oldestMembership === void 0 ? void 0 : oldestMembership.getTransport(oldestMembership);
420
401
  }
421
-
422
- /**
423
- * The used focusActive of the oldest membership (to find out the selection type multi-sfu or oldest membership active focus)
424
- * @deprecated does not work with m.rtc.member. Do not rely on it.
425
- */
426
- getActiveFocus() {
427
- var _this$getOldestMember;
428
- return (_this$getOldestMember = this.getOldestMembership()) === null || _this$getOldestMember === void 0 ? void 0 : _this$getOldestMember.getFocusActive();
429
- }
430
402
  getOldestMembership() {
431
403
  return this.memberships[0];
432
404
  }
@@ -492,7 +464,7 @@ export class MatrixRTCSession extends TypedEventEmitter {
492
464
  }
493
465
  }
494
466
  if (soonestExpiry != undefined) {
495
- this.expiryTimeout = setTimeout(this.ensureRecalculateSessionMembers.bind(this), soonestExpiry);
467
+ this.expiryTimeout = setTimeout(() => void this.ensureRecalculateSessionMembers(), soonestExpiry);
496
468
  }
497
469
  }
498
470
 
@@ -542,18 +514,20 @@ export class MatrixRTCSession extends TypedEventEmitter {
542
514
  return this.logger.error("Failed to send call notification", errorLegacy, errorNew);
543
515
  });
544
516
  }
517
+ /**
518
+ * Ensures that membership is recalculated when the state of the session may have changed.
519
+ * Also ensures that only one recalculation is made at a time.
520
+ * @returns A promise resolving when the state has been recalculated.
521
+ */
545
522
  ensureRecalculateSessionMembers() {
546
- if (this.recalculateSessionMembersPromise === undefined) {
547
- this.recalculateSessionMembersPromise = this.recalculateSessionMembers().then(() => {
548
- this.recalculateSessionMembersPromise = undefined;
549
- if (this.recalculateSessionMembersDirty) {
550
- this.ensureRecalculateSessionMembers();
551
- this.recalculateSessionMembersDirty = false;
552
- }
553
- });
554
- } else {
555
- this.recalculateSessionMembersDirty = true;
523
+ if (this.membershipNeedsRecalculation) {
524
+ // We have already requested recalcuation, don't attempt a new one.
525
+ return this.recalculateSessionMembersPromise;
556
526
  }
527
+ this.membershipNeedsRecalculation = true;
528
+ // Chain the recalculation.
529
+ this.recalculateSessionMembersPromise = this.recalculateSessionMembersPromise.finally().then(() => this.recalculateSessionMembers());
530
+ return this.recalculateSessionMembersPromise;
557
531
  }
558
532
  }
559
533
 
@@ -562,20 +536,18 @@ function computeBackendIdentityAndVerifyMemberEvents(_x, _x2, _x3, _x4) {
562
536
  return _computeBackendIdentityAndVerifyMemberEvents.apply(this, arguments);
563
537
  }
564
538
  function _computeBackendIdentityAndVerifyMemberEvents() {
565
- _computeBackendIdentityAndVerifyMemberEvents = _asyncToGenerator(function* (room, callMemberEvents, slotId, logger) {
539
+ _computeBackendIdentityAndVerifyMemberEvents = _asyncToGenerator(function* (room, callMemberEvents, slotDescription, logger) {
566
540
  var callMemberships = [];
567
541
  for (var memberEvent of callMemberEvents) {
568
542
  var content = memberEvent.getContent();
569
543
 
570
544
  // Quick filter to avoid unneeded processing of invalid events or left events.
571
- // A more thorough validation will be done later with CallMembership.membershipDataFromMatrixEvent.
572
545
  if (!quickFilterNonRelevantContents(content, logger)) {
573
546
  continue;
574
547
  }
575
548
  try {
576
- var membershipData = CallMembership.membershipDataFromMatrixEvent(memberEvent);
577
- var membership = new CallMembership(memberEvent, membershipData, yield CallMembership.computeRtcBackendIdentity(memberEvent, membershipData), logger);
578
- if (isValidMembership(membership, room, slotId, logger)) {
549
+ var membership = yield CallMembership.parseFromEvent(memberEvent);
550
+ if (isValidMembership(membership, room, slotDescription, logger)) {
579
551
  callMemberships.push(membership);
580
552
  }
581
553
  } catch (e) {
@@ -604,10 +576,10 @@ function quickFilterNonRelevantContents(content, logger) {
604
576
  return false;
605
577
  }
606
578
  }
607
- function isValidMembership(membership, room, slotId, logger) {
579
+ function isValidMembership(membership, room, slotDescription, logger) {
608
580
  var _membership$userId;
609
- if (membership.slotId !== slotId) {
610
- logger.info("Ignoring membership of user ".concat(membership.userId, " for a different slot: user: ").concat(JSON.stringify(membership.slotDescription), ", slotId: ").concat(slotId, ")"));
581
+ if (membership.slotDescription.id !== slotDescription.id) {
582
+ logger.info("Ignoring membership of user ".concat(membership.userId, " for a different slot. Theirs: ").concat(JSON.stringify(membership.slotDescription), ", Expected: ").concat(JSON.stringify(slotDescription)));
611
583
  return false;
612
584
  }
613
585
  if (membership.isExpired()) {