matrix-js-sdk 41.8.0 → 41.9.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.
- package/CHANGELOG.md +11 -0
- package/README.md +1 -1
- package/lib/@types/AESEncryptedSecretStoragePayload.js +3 -1
- package/lib/@types/IIdentityServerProvider.js +3 -1
- package/lib/@types/PushRules.js +7 -7
- package/lib/@types/PushRules.js.map +1 -1
- package/lib/@types/auth.js +4 -4
- package/lib/@types/auth.js.map +1 -1
- package/lib/@types/beacon.js +2 -2
- package/lib/@types/beacon.js.map +1 -1
- package/lib/@types/common.js +3 -1
- package/lib/@types/crypto.js +3 -1
- package/lib/@types/event.js +20 -20
- package/lib/@types/event.js.map +1 -1
- package/lib/@types/events.js +3 -1
- package/lib/@types/extensible_events.js +6 -6
- package/lib/@types/extensible_events.js.map +1 -1
- package/lib/@types/global.d.js.map +1 -1
- package/lib/@types/json.js +3 -1
- package/lib/@types/local_notifications.js +3 -1
- package/lib/@types/location.js +4 -4
- package/lib/@types/location.js.map +1 -1
- package/lib/@types/matrix-sdk-crypto-wasm.d.js +3 -1
- package/lib/@types/media.js +3 -1
- package/lib/@types/membership.js +1 -1
- package/lib/@types/membership.js.map +1 -1
- package/lib/@types/partials.js +6 -6
- package/lib/@types/partials.js.map +1 -1
- package/lib/@types/polls.js +5 -5
- package/lib/@types/polls.js.map +1 -1
- package/lib/@types/read_receipts.js +2 -2
- package/lib/@types/read_receipts.js.map +1 -1
- package/lib/@types/registration.js +3 -1
- package/lib/@types/requests.js +1 -1
- package/lib/@types/requests.js.map +1 -1
- package/lib/@types/retention.js +1 -1
- package/lib/@types/retention.js.map +1 -1
- package/lib/@types/search.js +1 -1
- package/lib/@types/search.js.map +1 -1
- package/lib/@types/signed.js +3 -1
- package/lib/@types/spaces.js +3 -1
- package/lib/@types/state_events.js +3 -1
- package/lib/@types/synapse.js +3 -1
- package/lib/@types/sync.js +1 -1
- package/lib/@types/sync.js.map +1 -1
- package/lib/@types/threepids.js +1 -1
- package/lib/@types/threepids.js.map +1 -1
- package/lib/@types/topic.js +1 -1
- package/lib/@types/topic.js.map +1 -1
- package/lib/@types/uia.js +3 -1
- package/lib/NamespacedValue.js +8 -8
- package/lib/NamespacedValue.js.map +1 -1
- package/lib/ReEmitter.js +9 -16
- package/lib/ReEmitter.js.map +1 -1
- package/lib/ToDeviceMessageQueue.js +49 -57
- package/lib/ToDeviceMessageQueue.js.map +1 -1
- package/lib/autodiscovery.js +232 -247
- package/lib/autodiscovery.js.map +1 -1
- package/lib/base64.js +1 -1
- package/lib/base64.js.map +1 -1
- package/lib/browser-index.d.ts +2 -2
- package/lib/browser-index.d.ts.map +1 -1
- package/lib/browser-index.js +5 -5
- package/lib/browser-index.js.map +1 -1
- package/lib/capabilityPoller.js +19 -22
- package/lib/capabilityPoller.js.map +1 -1
- package/lib/client.d.ts +2 -8
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +2043 -2487
- package/lib/client.js.map +1 -1
- package/lib/common-crypto/CryptoBackend.js +2 -2
- package/lib/common-crypto/CryptoBackend.js.map +1 -1
- package/lib/common-crypto/key-passphrase.js.map +1 -1
- package/lib/content-helpers.js +43 -48
- package/lib/content-helpers.js.map +1 -1
- package/lib/content-repo.js +14 -24
- package/lib/content-repo.js.map +1 -1
- package/lib/crypto/store/base.js +6 -6
- package/lib/crypto/store/base.js.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store-backend.js +190 -238
- package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store.js +25 -30
- package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -1
- package/lib/crypto/store/localStorage-crypto-store.js +113 -145
- package/lib/crypto/store/localStorage-crypto-store.js.map +1 -1
- package/lib/crypto/store/memory-crypto-store.js +74 -105
- package/lib/crypto/store/memory-crypto-store.js.map +1 -1
- package/lib/crypto-api/CryptoEvent.js +1 -1
- package/lib/crypto-api/CryptoEvent.js.map +1 -1
- package/lib/crypto-api/CryptoEventHandlerMap.js +3 -1
- package/lib/crypto-api/index.d.ts +15 -6
- package/lib/crypto-api/index.d.ts.map +1 -1
- package/lib/crypto-api/index.js +22 -22
- package/lib/crypto-api/index.js.map +1 -1
- package/lib/crypto-api/key-passphrase.js +15 -23
- package/lib/crypto-api/key-passphrase.js.map +1 -1
- package/lib/crypto-api/keybackup.js +3 -1
- package/lib/crypto-api/recovery-key.js +11 -12
- package/lib/crypto-api/recovery-key.js.map +1 -1
- package/lib/crypto-api/verification.js +3 -3
- package/lib/crypto-api/verification.js.map +1 -1
- package/lib/digest.js +7 -14
- package/lib/digest.js.map +1 -1
- package/lib/embedded.d.ts.map +1 -1
- package/lib/embedded.js +380 -505
- package/lib/embedded.js.map +1 -1
- package/lib/errors.js +2 -2
- package/lib/errors.js.map +1 -1
- package/lib/event-mapper.js +10 -12
- package/lib/event-mapper.js.map +1 -1
- package/lib/extensible_events_v1/ExtensibleEvent.js.map +1 -1
- package/lib/extensible_events_v1/InvalidEventError.js.map +1 -1
- package/lib/extensible_events_v1/MessageEvent.js +11 -13
- package/lib/extensible_events_v1/MessageEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollEndEvent.js +3 -4
- package/lib/extensible_events_v1/PollEndEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollResponseEvent.js +5 -6
- package/lib/extensible_events_v1/PollResponseEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollStartEvent.js +8 -10
- package/lib/extensible_events_v1/PollStartEvent.js.map +1 -1
- package/lib/extensible_events_v1/utilities.js.map +1 -1
- package/lib/feature.js +18 -31
- package/lib/feature.js.map +1 -1
- package/lib/filter-component.d.ts.map +1 -1
- package/lib/filter-component.js +20 -26
- package/lib/filter-component.js.map +1 -1
- package/lib/filter.js +14 -17
- package/lib/filter.js.map +1 -1
- package/lib/http-api/errors.js +28 -43
- package/lib/http-api/errors.js.map +1 -1
- package/lib/http-api/fetch.js +141 -159
- package/lib/http-api/fetch.js.map +1 -1
- package/lib/http-api/index.js +17 -20
- package/lib/http-api/index.js.map +1 -1
- package/lib/http-api/interface.js +1 -1
- package/lib/http-api/interface.js.map +1 -1
- package/lib/http-api/method.js +1 -1
- package/lib/http-api/method.js.map +1 -1
- package/lib/http-api/prefix.js +3 -3
- package/lib/http-api/prefix.js.map +1 -1
- package/lib/http-api/refresh.js +74 -94
- package/lib/http-api/refresh.js.map +1 -1
- package/lib/http-api/utils.d.ts +1 -1
- package/lib/http-api/utils.d.ts.map +1 -1
- package/lib/http-api/utils.js +34 -42
- package/lib/http-api/utils.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/indexeddb-helpers.js +3 -3
- package/lib/indexeddb-helpers.js.map +1 -1
- package/lib/indexeddb-worker.js.map +1 -1
- package/lib/interactive-auth.d.ts +5 -5
- package/lib/interactive-auth.d.ts.map +1 -1
- package/lib/interactive-auth.js +172 -204
- package/lib/interactive-auth.js.map +1 -1
- package/lib/logger.js +21 -57
- package/lib/logger.js.map +1 -1
- package/lib/matrix.js +7 -11
- package/lib/matrix.js.map +1 -1
- package/lib/matrixrtc/CallMembership.js +80 -74
- package/lib/matrixrtc/CallMembership.js.map +1 -1
- package/lib/matrixrtc/EncryptionManager.js +1 -1
- package/lib/matrixrtc/EncryptionManager.js.map +1 -1
- package/lib/matrixrtc/IKeyTransport.js +1 -1
- package/lib/matrixrtc/IKeyTransport.js.map +1 -1
- package/lib/matrixrtc/IMembershipManager.js +1 -1
- package/lib/matrixrtc/IMembershipManager.js.map +1 -1
- package/lib/matrixrtc/LivekitTransport.d.ts +1 -1
- package/lib/matrixrtc/LivekitTransport.js +4 -4
- package/lib/matrixrtc/LivekitTransport.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSession.js +137 -187
- package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSessionManager.js +36 -41
- package/lib/matrixrtc/MatrixRTCSessionManager.js.map +1 -1
- package/lib/matrixrtc/MembershipManager.js +332 -378
- package/lib/matrixrtc/MembershipManager.js.map +1 -1
- package/lib/matrixrtc/MembershipManagerActionScheduler.js +54 -63
- package/lib/matrixrtc/MembershipManagerActionScheduler.js.map +1 -1
- package/lib/matrixrtc/RTCEncryptionManager.js +119 -143
- package/lib/matrixrtc/RTCEncryptionManager.js.map +1 -1
- package/lib/matrixrtc/ToDeviceKeyTransport.js +53 -58
- package/lib/matrixrtc/ToDeviceKeyTransport.js.map +1 -1
- package/lib/matrixrtc/index.js.map +1 -1
- package/lib/matrixrtc/membershipData/common.js +1 -1
- package/lib/matrixrtc/membershipData/common.js.map +1 -1
- package/lib/matrixrtc/membershipData/index.js.map +1 -1
- package/lib/matrixrtc/membershipData/rtc.js +15 -23
- package/lib/matrixrtc/membershipData/rtc.js.map +1 -1
- package/lib/matrixrtc/membershipData/session.js +4 -5
- package/lib/matrixrtc/membershipData/session.js.map +1 -1
- package/lib/matrixrtc/types.js +4 -6
- package/lib/matrixrtc/types.js.map +1 -1
- package/lib/matrixrtc/utils.js +4 -11
- package/lib/matrixrtc/utils.js.map +1 -1
- package/lib/models/MSC3089Branch.js +91 -116
- package/lib/models/MSC3089Branch.js.map +1 -1
- package/lib/models/MSC3089TreeSpace.js +209 -245
- package/lib/models/MSC3089TreeSpace.js.map +1 -1
- package/lib/models/ToDeviceMessage.js +3 -1
- package/lib/models/beacon.js +14 -13
- package/lib/models/beacon.js.map +1 -1
- package/lib/models/compare-event-ordering.js +13 -13
- package/lib/models/compare-event-ordering.js.map +1 -1
- package/lib/models/device.js +3 -3
- package/lib/models/device.js.map +1 -1
- package/lib/models/event-context.js +5 -8
- package/lib/models/event-context.js.map +1 -1
- package/lib/models/event-status.js +1 -1
- package/lib/models/event-status.js.map +1 -1
- package/lib/models/event-timeline-set.js +88 -94
- package/lib/models/event-timeline-set.js.map +1 -1
- package/lib/models/event-timeline.js +28 -30
- package/lib/models/event-timeline.js.map +1 -1
- package/lib/models/event.js +182 -226
- package/lib/models/event.js.map +1 -1
- package/lib/models/invites-ignorer-types.js +4 -4
- package/lib/models/invites-ignorer-types.js.map +1 -1
- package/lib/models/invites-ignorer.js +159 -179
- package/lib/models/invites-ignorer.js.map +1 -1
- package/lib/models/poll.js +71 -81
- package/lib/models/poll.js.map +1 -1
- package/lib/models/profile-keys.js +2 -2
- package/lib/models/profile-keys.js.map +1 -1
- package/lib/models/read-receipt.js +40 -56
- package/lib/models/read-receipt.js.map +1 -1
- package/lib/models/related-relations.js.map +1 -1
- package/lib/models/relations-container.js +22 -23
- package/lib/models/relations-container.js.map +1 -1
- package/lib/models/relations.js +133 -159
- package/lib/models/relations.js.map +1 -1
- package/lib/models/room-member.js +24 -29
- package/lib/models/room-member.js.map +1 -1
- package/lib/models/room-receipts.js +29 -43
- package/lib/models/room-receipts.js.map +1 -1
- package/lib/models/room-retention.js +74 -83
- package/lib/models/room-retention.js.map +1 -1
- package/lib/models/room-state.js +143 -172
- package/lib/models/room-state.js.map +1 -1
- package/lib/models/room-sticky-events.d.ts +1 -0
- package/lib/models/room-sticky-events.d.ts.map +1 -1
- package/lib/models/room-sticky-events.js +45 -65
- package/lib/models/room-sticky-events.js.map +1 -1
- package/lib/models/room-summary.js.map +1 -1
- package/lib/models/room.d.ts.map +1 -1
- package/lib/models/room.js +765 -909
- package/lib/models/room.js.map +1 -1
- package/lib/models/search-result.js +5 -5
- package/lib/models/search-result.js.map +1 -1
- package/lib/models/thread.js +225 -285
- package/lib/models/thread.js.map +1 -1
- package/lib/models/typed-event-emitter.js +7 -18
- package/lib/models/typed-event-emitter.js.map +1 -1
- package/lib/models/user.js +8 -8
- package/lib/models/user.js.map +1 -1
- package/lib/oidc/authorize.js +208 -241
- package/lib/oidc/authorize.js.map +1 -1
- package/lib/oidc/discovery.js +23 -36
- package/lib/oidc/discovery.js.map +1 -1
- package/lib/oidc/error.js +1 -1
- package/lib/oidc/error.js.map +1 -1
- package/lib/oidc/index.js +1 -0
- package/lib/oidc/index.js.map +1 -1
- package/lib/oidc/register.js +60 -66
- package/lib/oidc/register.js.map +1 -1
- package/lib/oidc/tokenRefresher.js +77 -91
- package/lib/oidc/tokenRefresher.js.map +1 -1
- package/lib/oidc/validate.js +18 -18
- package/lib/oidc/validate.js.map +1 -1
- package/lib/pushprocessor.js +71 -82
- package/lib/pushprocessor.js.map +1 -1
- package/lib/randomstring.js +9 -9
- package/lib/randomstring.js.map +1 -1
- package/lib/realtime-callbacks.js +25 -28
- package/lib/realtime-callbacks.js.map +1 -1
- package/lib/receipt-accumulator.d.ts +2 -0
- package/lib/receipt-accumulator.d.ts.map +1 -1
- package/lib/receipt-accumulator.js +14 -22
- package/lib/receipt-accumulator.js.map +1 -1
- package/lib/rendezvous/MSC4108SignInWithQR.js +271 -302
- package/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -1
- package/lib/rendezvous/RendezvousChannel.js +3 -1
- package/lib/rendezvous/RendezvousCode.js +3 -1
- package/lib/rendezvous/RendezvousError.js.map +1 -1
- package/lib/rendezvous/RendezvousFailureReason.js +2 -2
- package/lib/rendezvous/RendezvousFailureReason.js.map +1 -1
- package/lib/rendezvous/RendezvousIntent.js +1 -1
- package/lib/rendezvous/RendezvousIntent.js.map +1 -1
- package/lib/rendezvous/RendezvousTransport.js +3 -1
- package/lib/rendezvous/channels/MSC4108SecureChannel.js +123 -147
- package/lib/rendezvous/channels/MSC4108SecureChannel.js.map +1 -1
- package/lib/rendezvous/index.js +44 -69
- package/lib/rendezvous/index.js.map +1 -1
- package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts +1 -1
- package/lib/rendezvous/transports/MSC4108RendezvousSession.js +134 -152
- package/lib/rendezvous/transports/MSC4108RendezvousSession.js.map +1 -1
- package/lib/retentionPolicy.js +6 -9
- package/lib/retentionPolicy.js.map +1 -1
- package/lib/room-hierarchy.js +52 -60
- package/lib/room-hierarchy.js.map +1 -1
- package/lib/rust-crypto/CrossSigningIdentity.js +94 -104
- package/lib/rust-crypto/CrossSigningIdentity.js.map +1 -1
- package/lib/rust-crypto/DehydratedDeviceManager.js +157 -190
- package/lib/rust-crypto/DehydratedDeviceManager.js.map +1 -1
- package/lib/rust-crypto/KeyClaimManager.js +18 -22
- package/lib/rust-crypto/KeyClaimManager.js.map +1 -1
- package/lib/rust-crypto/OutgoingRequestProcessor.js +109 -139
- package/lib/rust-crypto/OutgoingRequestProcessor.js.map +1 -1
- package/lib/rust-crypto/OutgoingRequestsManager.js +66 -80
- package/lib/rust-crypto/OutgoingRequestsManager.js.map +1 -1
- package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts +1 -1
- package/lib/rust-crypto/PerSessionKeyBackupDownloader.js +196 -224
- package/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +1 -1
- package/lib/rust-crypto/RoomEncryptor.js +127 -143
- package/lib/rust-crypto/RoomEncryptor.js.map +1 -1
- package/lib/rust-crypto/backup.js +453 -549
- package/lib/rust-crypto/backup.js.map +1 -1
- package/lib/rust-crypto/constants.js +1 -1
- package/lib/rust-crypto/constants.js.map +1 -1
- package/lib/rust-crypto/device-converter.js +15 -28
- package/lib/rust-crypto/device-converter.js.map +1 -1
- package/lib/rust-crypto/index.js +103 -116
- package/lib/rust-crypto/index.js.map +1 -1
- package/lib/rust-crypto/libolm_migration.js +303 -365
- package/lib/rust-crypto/libolm_migration.js.map +1 -1
- package/lib/rust-crypto/rust-crypto.d.ts +5 -1
- package/lib/rust-crypto/rust-crypto.d.ts.map +1 -1
- package/lib/rust-crypto/rust-crypto.js +1067 -1332
- package/lib/rust-crypto/rust-crypto.js.map +1 -1
- package/lib/rust-crypto/secret-storage.js +12 -25
- package/lib/rust-crypto/secret-storage.js.map +1 -1
- package/lib/rust-crypto/verification.js +137 -189
- package/lib/rust-crypto/verification.js.map +1 -1
- package/lib/scheduler.js +44 -19
- package/lib/scheduler.js.map +1 -1
- package/lib/secret-storage.js +179 -213
- package/lib/secret-storage.js.map +1 -1
- package/lib/serverCapabilities.js +6 -9
- package/lib/serverCapabilities.js.map +1 -1
- package/lib/service-types.js +1 -1
- package/lib/service-types.js.map +1 -1
- package/lib/sliding-sync-sdk.d.ts.map +1 -1
- package/lib/sliding-sync-sdk.js +368 -424
- package/lib/sliding-sync-sdk.js.map +1 -1
- package/lib/sliding-sync.js +135 -171
- package/lib/sliding-sync.js.map +1 -1
- package/lib/store/index.js +3 -1
- package/lib/store/indexeddb-backend.js +3 -1
- package/lib/store/indexeddb-local-backend.js +194 -253
- package/lib/store/indexeddb-local-backend.js.map +1 -1
- package/lib/store/indexeddb-remote-backend.js +33 -63
- package/lib/store/indexeddb-remote-backend.js.map +1 -1
- package/lib/store/indexeddb-store-worker.js +22 -23
- package/lib/store/indexeddb-store-worker.js.map +1 -1
- package/lib/store/indexeddb.js +44 -71
- package/lib/store/indexeddb.js.map +1 -1
- package/lib/store/local-storage-events-emitter.js +2 -2
- package/lib/store/local-storage-events-emitter.js.map +1 -1
- package/lib/store/memory.js +34 -57
- package/lib/store/memory.js.map +1 -1
- package/lib/store/stub.js +22 -35
- package/lib/store/stub.js.map +1 -1
- package/lib/sync-accumulator.js +54 -66
- package/lib/sync-accumulator.js.map +1 -1
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +905 -998
- package/lib/sync.js.map +1 -1
- package/lib/testing.js +63 -105
- package/lib/testing.js.map +1 -1
- package/lib/thread-utils.js +1 -4
- package/lib/thread-utils.js.map +1 -1
- package/lib/timeline-window.js +89 -102
- package/lib/timeline-window.js.map +1 -1
- package/lib/types.js +1 -1
- package/lib/types.js.map +1 -1
- package/lib/utils/decryptAESSecretStorageItem.js +14 -25
- package/lib/utils/decryptAESSecretStorageItem.js.map +1 -1
- package/lib/utils/encryptAESSecretStorageItem.js +27 -38
- package/lib/utils/encryptAESSecretStorageItem.js.map +1 -1
- package/lib/utils/internal/deriveKeys.js +25 -32
- package/lib/utils/internal/deriveKeys.js.map +1 -1
- package/lib/utils/roomVersion.js +1 -1
- package/lib/utils/roomVersion.js.map +1 -1
- package/lib/utils.js +83 -135
- package/lib/utils.js.map +1 -1
- package/lib/version-support.js +3 -3
- package/lib/version-support.js.map +1 -1
- package/lib/webrtc/audioContext.js +5 -6
- package/lib/webrtc/audioContext.js.map +1 -1
- package/lib/webrtc/call.js +1081 -1250
- package/lib/webrtc/call.js.map +1 -1
- package/lib/webrtc/callEventHandler.js +202 -214
- package/lib/webrtc/callEventHandler.js.map +1 -1
- package/lib/webrtc/callEventTypes.js +2 -2
- package/lib/webrtc/callEventTypes.js.map +1 -1
- package/lib/webrtc/callFeed.js +18 -20
- package/lib/webrtc/callFeed.js.map +1 -1
- package/lib/webrtc/groupCall.js +513 -602
- package/lib/webrtc/groupCall.js.map +1 -1
- package/lib/webrtc/groupCallEventHandler.js +59 -62
- package/lib/webrtc/groupCallEventHandler.js.map +1 -1
- package/lib/webrtc/mediaHandler.js +198 -232
- package/lib/webrtc/mediaHandler.js.map +1 -1
- package/lib/webrtc/stats/callFeedStatsReporter.js +16 -20
- package/lib/webrtc/stats/callFeedStatsReporter.js.map +1 -1
- package/lib/webrtc/stats/callStatsReportGatherer.js +67 -75
- package/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -1
- package/lib/webrtc/stats/callStatsReportSummary.js +3 -1
- package/lib/webrtc/stats/connectionStats.js.map +1 -1
- package/lib/webrtc/stats/connectionStatsBuilder.js +2 -2
- package/lib/webrtc/stats/connectionStatsBuilder.js.map +1 -1
- package/lib/webrtc/stats/connectionStatsReportBuilder.js +20 -24
- package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +1 -1
- package/lib/webrtc/stats/groupCallStats.js +6 -8
- package/lib/webrtc/stats/groupCallStats.js.map +1 -1
- package/lib/webrtc/stats/media/mediaSsrcHandler.js +7 -8
- package/lib/webrtc/stats/media/mediaSsrcHandler.js.map +1 -1
- package/lib/webrtc/stats/media/mediaTrackHandler.js +7 -9
- package/lib/webrtc/stats/media/mediaTrackHandler.js.map +1 -1
- package/lib/webrtc/stats/media/mediaTrackStats.js +3 -3
- package/lib/webrtc/stats/media/mediaTrackStats.js.map +1 -1
- package/lib/webrtc/stats/media/mediaTrackStatsHandler.js +7 -7
- package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +1 -1
- package/lib/webrtc/stats/statsReport.js +1 -1
- package/lib/webrtc/stats/statsReport.js.map +1 -1
- package/lib/webrtc/stats/statsReportEmitter.js.map +1 -1
- package/lib/webrtc/stats/summaryStatsReportGatherer.js +14 -14
- package/lib/webrtc/stats/summaryStatsReportGatherer.js.map +1 -1
- package/lib/webrtc/stats/trackStatsBuilder.js +32 -34
- package/lib/webrtc/stats/trackStatsBuilder.js.map +1 -1
- package/lib/webrtc/stats/transportStats.js +3 -1
- package/lib/webrtc/stats/transportStatsBuilder.js +9 -9
- package/lib/webrtc/stats/transportStatsBuilder.js.map +1 -1
- package/lib/webrtc/stats/valueFormatter.js +1 -1
- package/lib/webrtc/stats/valueFormatter.js.map +1 -1
- package/package.json +18 -33
- package/src/@types/global.d.ts +2 -2
- package/src/ToDeviceMessageQueue.ts +2 -2
- package/src/browser-index.ts +4 -4
- package/src/client.ts +15 -20
- package/src/crypto-api/index.ts +17 -6
- package/src/embedded.ts +4 -6
- package/src/filter-component.ts +1 -0
- package/src/http-api/utils.ts +1 -1
- package/src/interactive-auth.ts +11 -5
- package/src/matrixrtc/LivekitTransport.ts +1 -1
- package/src/matrixrtc/MatrixRTCSession.ts +1 -1
- package/src/models/MSC3089Branch.ts +1 -1
- package/src/models/room-sticky-events.ts +1 -0
- package/src/models/room.ts +9 -11
- package/src/receipt-accumulator.ts +2 -0
- package/src/rendezvous/index.ts +1 -1
- package/src/rendezvous/transports/MSC4108RendezvousSession.ts +2 -2
- package/src/rust-crypto/PerSessionKeyBackupDownloader.ts +1 -1
- package/src/rust-crypto/index.ts +6 -6
- package/src/rust-crypto/rust-crypto.ts +31 -7
- package/src/rust-crypto/verification.ts +1 -1
- package/src/sliding-sync-sdk.ts +5 -7
- package/src/store/indexeddb-local-backend.ts +3 -3
- package/src/sync.ts +6 -8
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
2
|
/*
|
|
4
3
|
Copyright 2025 The Matrix.org Foundation C.I.C.
|
|
@@ -35,14 +34,10 @@ export class NotSupportedError extends Error {
|
|
|
35
34
|
*/
|
|
36
35
|
export class ToDeviceKeyTransport extends TypedEventEmitter {
|
|
37
36
|
setParentLogger(parentLogger) {
|
|
38
|
-
this.logger = parentLogger.getChild(
|
|
37
|
+
this.logger = parentLogger.getChild(`[ToDeviceKeyTransport]`);
|
|
39
38
|
}
|
|
40
39
|
constructor(membership, roomId, client, statistics, parentLogger) {
|
|
41
40
|
super();
|
|
42
|
-
this.membership = membership;
|
|
43
|
-
this.roomId = roomId;
|
|
44
|
-
this.client = client;
|
|
45
|
-
this.statistics = statistics;
|
|
46
41
|
_defineProperty(this, "logger", rootLogger);
|
|
47
42
|
_defineProperty(this, "onToDeviceEvent", event => {
|
|
48
43
|
if (event.getType() !== EventType.CallEncryptionKeysPrefix) {
|
|
@@ -58,12 +53,16 @@ export class ToDeviceKeyTransport extends TypedEventEmitter {
|
|
|
58
53
|
// return;
|
|
59
54
|
// }
|
|
60
55
|
|
|
61
|
-
|
|
56
|
+
const content = this.getValidEventContent(event);
|
|
62
57
|
if (!content) return;
|
|
63
58
|
if (!event.getSender()) return;
|
|
64
59
|
this.receiveCallKeyEvent(event.getSender(), content);
|
|
65
60
|
});
|
|
66
|
-
this.
|
|
61
|
+
this.membership = membership;
|
|
62
|
+
this.roomId = roomId;
|
|
63
|
+
this.client = client;
|
|
64
|
+
this.statistics = statistics;
|
|
65
|
+
this.setParentLogger(parentLogger ?? rootLogger);
|
|
67
66
|
}
|
|
68
67
|
start() {
|
|
69
68
|
this.client.on(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);
|
|
@@ -71,74 +70,70 @@ export class ToDeviceKeyTransport extends TypedEventEmitter {
|
|
|
71
70
|
stop() {
|
|
72
71
|
this.client.off(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);
|
|
73
72
|
}
|
|
74
|
-
sendKey(keyBase64Encoded, index, members) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
73
|
+
async sendKey(keyBase64Encoded, index, members) {
|
|
74
|
+
const content = {
|
|
75
|
+
keys: {
|
|
76
|
+
index: index,
|
|
77
|
+
key: keyBase64Encoded
|
|
78
|
+
},
|
|
79
|
+
room_id: this.roomId,
|
|
80
|
+
member: {
|
|
81
|
+
claimed_device_id: this.membership.deviceId,
|
|
82
|
+
id: this.membership.memberId
|
|
83
|
+
},
|
|
84
|
+
session: {
|
|
85
|
+
call_id: "",
|
|
86
|
+
application: "m.call",
|
|
87
|
+
scope: "m.room"
|
|
88
|
+
},
|
|
89
|
+
sent_ts: Date.now()
|
|
90
|
+
};
|
|
91
|
+
const targets = members.map(member => {
|
|
92
|
+
return {
|
|
93
|
+
userId: member.userId,
|
|
94
|
+
deviceId: member.deviceId
|
|
93
95
|
};
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
113
|
-
_this.statistics.counters.roomEventEncryptionKeysSent += 1;
|
|
114
|
-
} else {
|
|
115
|
-
_this.logger.warn("No targets found for sending key");
|
|
116
|
-
}
|
|
117
|
-
})();
|
|
96
|
+
})
|
|
97
|
+
// filter out me
|
|
98
|
+
.filter(member => !(member.userId == this.membership.userId && member.deviceId == this.membership.deviceId));
|
|
99
|
+
if (targets.length > 0) {
|
|
100
|
+
await this.client.encryptAndSendToDevice(EventType.CallEncryptionKeysPrefix, targets, content).catch(error => {
|
|
101
|
+
const msg = error.message;
|
|
102
|
+
// This is not ideal. We would want to have a custom error type for unsupported actions.
|
|
103
|
+
// This is not part of the widget API spec. Since as of now there are only two implementations:
|
|
104
|
+
// Rust SDK + JS-SDK, and the JS-SDK does support to-device sending, we can assume that
|
|
105
|
+
// this is a widget driver issue error message.
|
|
106
|
+
if (msg.includes("unknown variant") && msg.includes("send_to_device") || msg.includes("not supported")) {
|
|
107
|
+
throw new NotSupportedError("The widget driver does not support to-device encryption");
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
this.statistics.counters.roomEventEncryptionKeysSent += 1;
|
|
111
|
+
} else {
|
|
112
|
+
this.logger.warn("No targets found for sending key");
|
|
113
|
+
}
|
|
118
114
|
}
|
|
119
115
|
receiveCallKeyEvent(fromUser, content) {
|
|
120
|
-
var _content$member$id;
|
|
121
116
|
// The event has already been validated at this point.
|
|
122
117
|
|
|
123
118
|
this.statistics.counters.roomEventEncryptionKeysReceived += 1;
|
|
124
119
|
|
|
125
120
|
// What is this, and why is it needed?
|
|
126
121
|
// Also to device events do not have an origin server ts
|
|
127
|
-
|
|
128
|
-
|
|
122
|
+
const now = Date.now();
|
|
123
|
+
const age = now - (typeof content.sent_ts === "number" ? content.sent_ts : now);
|
|
129
124
|
this.statistics.totals.roomEventEncryptionKeysReceivedTotalAge += age;
|
|
130
|
-
|
|
125
|
+
const hardcodedMemberIdAlternative = `${fromUser}:${content.member.claimed_device_id}`;
|
|
131
126
|
this.emit(KeyTransportEvents.ReceivedKeys,
|
|
132
127
|
// TODO userId this is claimed information, deviceId is claimed information
|
|
133
128
|
{
|
|
134
129
|
userId: fromUser,
|
|
135
130
|
deviceId: content.member.claimed_device_id,
|
|
136
|
-
memberId:
|
|
131
|
+
memberId: content.member.id ?? hardcodedMemberIdAlternative
|
|
137
132
|
}, content.keys.key, content.keys.index, now);
|
|
138
133
|
}
|
|
139
134
|
getValidEventContent(event) {
|
|
140
|
-
|
|
141
|
-
|
|
135
|
+
const content = event.getContent();
|
|
136
|
+
const roomId = content.room_id;
|
|
142
137
|
if (!roomId) {
|
|
143
138
|
// Invalid event
|
|
144
139
|
this.logger.warn("Malformed Event: invalid call encryption keys event, no roomId");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToDeviceKeyTransport.js","names":["TypedEventEmitter","KeyTransportEvents","logger","rootLogger","ClientEvent","EventType","NotSupportedError","Error","constructor","message","name","ToDeviceKeyTransport","setParentLogger","parentLogger","getChild","membership","roomId","client","statistics","_defineProperty","event","getType","CallEncryptionKeysPrefix","content","getValidEventContent","getSender","receiveCallKeyEvent","start","on","ToDeviceEvent","onToDeviceEvent","stop","off","sendKey","keyBase64Encoded","index","members","_this","_asyncToGenerator","keys","key","room_id","member","claimed_device_id","deviceId","id","memberId","session","call_id","application","scope","sent_ts","Date","now","targets","map","userId","filter","length","encryptAndSendToDevice","catch","error","msg","includes","counters","roomEventEncryptionKeysSent","warn","fromUser","_content$member$id","roomEventEncryptionKeysReceived","age","totals","roomEventEncryptionKeysReceivedTotalAge","hardcodedMemberIdAlternative","concat","emit","ReceivedKeys","getContent"],"sources":["../../src/matrixrtc/ToDeviceKeyTransport.ts"],"sourcesContent":["/*\nCopyright 2025 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { type WidgetApiResponseError } from \"matrix-widget-api\";\n\nimport { TypedEventEmitter } from \"../models/typed-event-emitter.ts\";\nimport { type IKeyTransport, KeyTransportEvents, type KeyTransportEventsHandlerMap } from \"./IKeyTransport.ts\";\nimport { type Logger, logger as rootLogger } from \"../logger.ts\";\nimport { type EncryptionKeysToDeviceEventContent, type ParticipantDeviceInfo, type Statistics } from \"./types.ts\";\nimport { ClientEvent, type MatrixClient } from \"../client.ts\";\nimport type { MatrixEvent } from \"../models/event.ts\";\nimport { EventType } from \"../@types/event.ts\";\nimport { type CallMembershipIdentityParts } from \"./EncryptionManager.ts\";\n\nexport class NotSupportedError extends Error {\n public constructor(message?: string) {\n super(message);\n }\n public get name(): string {\n return \"NotSupportedError\";\n }\n}\n/**\n * ToDeviceKeyTransport is used to send MatrixRTC keys to other devices using the\n * to-device CS-API.\n */\nexport class ToDeviceKeyTransport\n extends TypedEventEmitter<KeyTransportEvents, KeyTransportEventsHandlerMap>\n implements IKeyTransport\n{\n private logger: Logger = rootLogger;\n\n public setParentLogger(parentLogger: Logger): void {\n this.logger = parentLogger.getChild(`[ToDeviceKeyTransport]`);\n }\n\n public constructor(\n private membership: CallMembershipIdentityParts,\n private roomId: string,\n private client: Pick<MatrixClient, \"encryptAndSendToDevice\" | \"on\" | \"off\">,\n private statistics: Statistics,\n parentLogger?: Logger,\n ) {\n super();\n this.setParentLogger(parentLogger ?? rootLogger);\n }\n\n public start(): void {\n this.client.on(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);\n }\n\n public stop(): void {\n this.client.off(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);\n }\n\n public async sendKey(keyBase64Encoded: string, index: number, members: ParticipantDeviceInfo[]): Promise<void> {\n const content: EncryptionKeysToDeviceEventContent = {\n keys: {\n index: index,\n key: keyBase64Encoded,\n },\n room_id: this.roomId,\n member: {\n claimed_device_id: this.membership.deviceId,\n id: this.membership.memberId,\n },\n session: {\n call_id: \"\",\n application: \"m.call\",\n scope: \"m.room\",\n },\n sent_ts: Date.now(),\n };\n\n const targets = members\n .map((member) => {\n return {\n userId: member.userId!,\n deviceId: member.deviceId!,\n };\n })\n // filter out me\n .filter(\n (member) => !(member.userId == this.membership.userId && member.deviceId == this.membership.deviceId),\n );\n\n if (targets.length > 0) {\n await this.client\n .encryptAndSendToDevice(EventType.CallEncryptionKeysPrefix, targets, content)\n .catch((error: WidgetApiResponseError) => {\n const msg: string = error.message;\n // This is not ideal. We would want to have a custom error type for unsupported actions.\n // This is not part of the widget API spec. Since as of now there are only two implementations:\n // Rust SDK + JS-SDK, and the JS-SDK does support to-device sending, we can assume that\n // this is a widget driver issue error message.\n if (\n (msg.includes(\"unknown variant\") && msg.includes(\"send_to_device\")) ||\n msg.includes(\"not supported\")\n ) {\n throw new NotSupportedError(\"The widget driver does not support to-device encryption\");\n }\n });\n this.statistics.counters.roomEventEncryptionKeysSent += 1;\n } else {\n this.logger.warn(\"No targets found for sending key\");\n }\n }\n\n private receiveCallKeyEvent(fromUser: string, content: EncryptionKeysToDeviceEventContent): void {\n // The event has already been validated at this point.\n\n this.statistics.counters.roomEventEncryptionKeysReceived += 1;\n\n // What is this, and why is it needed?\n // Also to device events do not have an origin server ts\n const now = Date.now();\n const age = now - (typeof content.sent_ts === \"number\" ? content.sent_ts : now);\n this.statistics.totals.roomEventEncryptionKeysReceivedTotalAge += age;\n\n const hardcodedMemberIdAlternative = `${fromUser}:${content.member.claimed_device_id}`;\n\n this.emit(\n KeyTransportEvents.ReceivedKeys,\n // TODO userId this is claimed information, deviceId is claimed information\n {\n userId: fromUser,\n deviceId: content.member.claimed_device_id!,\n memberId: content.member.id ?? hardcodedMemberIdAlternative,\n },\n content.keys.key,\n content.keys.index,\n now,\n );\n }\n\n private onToDeviceEvent = (event: MatrixEvent): void => {\n if (event.getType() !== EventType.CallEncryptionKeysPrefix) {\n // Ignore this is not a call encryption event\n return;\n }\n\n // TODO: Not possible to check if the event is encrypted or not\n // see https://github.com/matrix-org/matrix-rust-sdk/issues/4883\n // if (evnt.getWireType() != EventType.RoomMessageEncrypted) {\n // // WARN: The call keys were sent in clear. Ignore them\n // logger.warn(`Call encryption keys sent in clear from: ${event.getSender()}`);\n // return;\n // }\n\n const content = this.getValidEventContent(event);\n if (!content) return;\n\n if (!event.getSender()) return;\n\n this.receiveCallKeyEvent(event.getSender()!, content);\n };\n\n private getValidEventContent(event: MatrixEvent): EncryptionKeysToDeviceEventContent | undefined {\n const content = event.getContent();\n const roomId = content.room_id;\n if (!roomId) {\n // Invalid event\n this.logger.warn(\"Malformed Event: invalid call encryption keys event, no roomId\");\n return;\n }\n if (roomId !== this.roomId) {\n this.logger.warn(\"Malformed Event: Mismatch roomId\");\n return;\n }\n\n if (!content.keys || !content.keys.key || typeof content.keys.index !== \"number\") {\n this.logger.warn(\"Malformed Event: Missing keys field\");\n return;\n }\n\n if (!content.member || !content.member.claimed_device_id) {\n this.logger.warn(\"Malformed Event: Missing claimed_device_id\");\n return;\n }\n\n // TODO check for session related fields once the to-device encryption uses the new format.\n return content as EncryptionKeysToDeviceEventContent;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"ToDeviceKeyTransport.js","names":[],"sources":["../../src/matrixrtc/ToDeviceKeyTransport.ts"],"sourcesContent":["/*\nCopyright 2025 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { type WidgetApiResponseError } from \"matrix-widget-api\";\n\nimport { TypedEventEmitter } from \"../models/typed-event-emitter.ts\";\nimport { type IKeyTransport, KeyTransportEvents, type KeyTransportEventsHandlerMap } from \"./IKeyTransport.ts\";\nimport { type Logger, logger as rootLogger } from \"../logger.ts\";\nimport { type EncryptionKeysToDeviceEventContent, type ParticipantDeviceInfo, type Statistics } from \"./types.ts\";\nimport { ClientEvent, type MatrixClient } from \"../client.ts\";\nimport type { MatrixEvent } from \"../models/event.ts\";\nimport { EventType } from \"../@types/event.ts\";\nimport { type CallMembershipIdentityParts } from \"./EncryptionManager.ts\";\n\nexport class NotSupportedError extends Error {\n public constructor(message?: string) {\n super(message);\n }\n public get name(): string {\n return \"NotSupportedError\";\n }\n}\n/**\n * ToDeviceKeyTransport is used to send MatrixRTC keys to other devices using the\n * to-device CS-API.\n */\nexport class ToDeviceKeyTransport\n extends TypedEventEmitter<KeyTransportEvents, KeyTransportEventsHandlerMap>\n implements IKeyTransport\n{\n private logger: Logger = rootLogger;\n\n public setParentLogger(parentLogger: Logger): void {\n this.logger = parentLogger.getChild(`[ToDeviceKeyTransport]`);\n }\n\n public constructor(\n private membership: CallMembershipIdentityParts,\n private roomId: string,\n private client: Pick<MatrixClient, \"encryptAndSendToDevice\" | \"on\" | \"off\">,\n private statistics: Statistics,\n parentLogger?: Logger,\n ) {\n super();\n this.setParentLogger(parentLogger ?? rootLogger);\n }\n\n public start(): void {\n this.client.on(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);\n }\n\n public stop(): void {\n this.client.off(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);\n }\n\n public async sendKey(keyBase64Encoded: string, index: number, members: ParticipantDeviceInfo[]): Promise<void> {\n const content: EncryptionKeysToDeviceEventContent = {\n keys: {\n index: index,\n key: keyBase64Encoded,\n },\n room_id: this.roomId,\n member: {\n claimed_device_id: this.membership.deviceId,\n id: this.membership.memberId,\n },\n session: {\n call_id: \"\",\n application: \"m.call\",\n scope: \"m.room\",\n },\n sent_ts: Date.now(),\n };\n\n const targets = members\n .map((member) => {\n return {\n userId: member.userId!,\n deviceId: member.deviceId!,\n };\n })\n // filter out me\n .filter(\n (member) => !(member.userId == this.membership.userId && member.deviceId == this.membership.deviceId),\n );\n\n if (targets.length > 0) {\n await this.client\n .encryptAndSendToDevice(EventType.CallEncryptionKeysPrefix, targets, content)\n .catch((error: WidgetApiResponseError) => {\n const msg: string = error.message;\n // This is not ideal. We would want to have a custom error type for unsupported actions.\n // This is not part of the widget API spec. Since as of now there are only two implementations:\n // Rust SDK + JS-SDK, and the JS-SDK does support to-device sending, we can assume that\n // this is a widget driver issue error message.\n if (\n (msg.includes(\"unknown variant\") && msg.includes(\"send_to_device\")) ||\n msg.includes(\"not supported\")\n ) {\n throw new NotSupportedError(\"The widget driver does not support to-device encryption\");\n }\n });\n this.statistics.counters.roomEventEncryptionKeysSent += 1;\n } else {\n this.logger.warn(\"No targets found for sending key\");\n }\n }\n\n private receiveCallKeyEvent(fromUser: string, content: EncryptionKeysToDeviceEventContent): void {\n // The event has already been validated at this point.\n\n this.statistics.counters.roomEventEncryptionKeysReceived += 1;\n\n // What is this, and why is it needed?\n // Also to device events do not have an origin server ts\n const now = Date.now();\n const age = now - (typeof content.sent_ts === \"number\" ? content.sent_ts : now);\n this.statistics.totals.roomEventEncryptionKeysReceivedTotalAge += age;\n\n const hardcodedMemberIdAlternative = `${fromUser}:${content.member.claimed_device_id}`;\n\n this.emit(\n KeyTransportEvents.ReceivedKeys,\n // TODO userId this is claimed information, deviceId is claimed information\n {\n userId: fromUser,\n deviceId: content.member.claimed_device_id!,\n memberId: content.member.id ?? hardcodedMemberIdAlternative,\n },\n content.keys.key,\n content.keys.index,\n now,\n );\n }\n\n private onToDeviceEvent = (event: MatrixEvent): void => {\n if (event.getType() !== EventType.CallEncryptionKeysPrefix) {\n // Ignore this is not a call encryption event\n return;\n }\n\n // TODO: Not possible to check if the event is encrypted or not\n // see https://github.com/matrix-org/matrix-rust-sdk/issues/4883\n // if (evnt.getWireType() != EventType.RoomMessageEncrypted) {\n // // WARN: The call keys were sent in clear. Ignore them\n // logger.warn(`Call encryption keys sent in clear from: ${event.getSender()}`);\n // return;\n // }\n\n const content = this.getValidEventContent(event);\n if (!content) return;\n\n if (!event.getSender()) return;\n\n this.receiveCallKeyEvent(event.getSender()!, content);\n };\n\n private getValidEventContent(event: MatrixEvent): EncryptionKeysToDeviceEventContent | undefined {\n const content = event.getContent();\n const roomId = content.room_id;\n if (!roomId) {\n // Invalid event\n this.logger.warn(\"Malformed Event: invalid call encryption keys event, no roomId\");\n return;\n }\n if (roomId !== this.roomId) {\n this.logger.warn(\"Malformed Event: Mismatch roomId\");\n return;\n }\n\n if (!content.keys || !content.keys.key || typeof content.keys.index !== \"number\") {\n this.logger.warn(\"Malformed Event: Missing keys field\");\n return;\n }\n\n if (!content.member || !content.member.claimed_device_id) {\n this.logger.warn(\"Malformed Event: Missing claimed_device_id\");\n return;\n }\n\n // TODO check for session related fields once the to-device encryption uses the new format.\n return content as EncryptionKeysToDeviceEventContent;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/matrixrtc/index.ts"],"sourcesContent":["/*\nCopyright 2024 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport * from \"./CallMembership.ts\";\nexport * from \"./LivekitTransport.ts\";\nexport * from \"./MatrixRTCSession.ts\";\nexport * from \"./MatrixRTCSessionManager.ts\";\nexport type * from \"./types.ts\";\nexport { type SessionMembershipData, type RtcMembershipData } from \"./membershipData/index.ts\";\nexport { Status, parseCallNotificationContent, isMyMembership } from \"./types.ts\";\nexport { MembershipManagerEvent } from \"./IMembershipManager.ts\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAc,qBAAqB;AACnC,cAAc,uBAAuB;AACrC,cAAc,uBAAuB;AACrC,cAAc,8BAA8B;AAG5C,SAAS,MAAM,EAAE,4BAA4B,EAAE,cAAc,QAAQ,YAAY;AACjF,SAAS,sBAAsB,QAAQ,yBAAyB","ignoreList":[]}
|
|
@@ -19,7 +19,7 @@ limitations under the License.
|
|
|
19
19
|
*/
|
|
20
20
|
export class MatrixRTCMembershipParseError extends AggregateError {
|
|
21
21
|
constructor(type, errors) {
|
|
22
|
-
super(errors,
|
|
22
|
+
super(errors, `Does not match ${type}:\n${errors.join("\n")}`);
|
|
23
23
|
this.type = type;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../../../src/matrixrtc/membershipData/common.ts"],"sourcesContent":["/*\nCopyright 2026 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Thrown when an event is not valid for use with MatrixRTC.\n */\nexport class MatrixRTCMembershipParseError extends AggregateError {\n public constructor(\n public readonly type: string,\n errors: string[],\n ) {\n super(errors, `Does not match ${type}:\\n${errors.join(\"\\n\")}`);\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,MAAM,6BAA6B,SAAS,cAAc,CAAC;EACvD,WAAW,CACE,IAAY,EAC5B,MAAgB,EAClB;IACE,KAAK,CAAC,MAAM,EAAE,kBAAkB,IAAI,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAAC,KAH/C,IAAY,GAAZ,IAAY;EAIhC;AACJ","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/matrixrtc/membershipData/index.ts"],"sourcesContent":["/*\nCopyright 2026 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport { type SessionMembershipData, checkSessionsMembershipData } from \"./session.ts\";\nexport { type RtcMembershipData, computeRtcIdentityRaw, checkRtcMembershipData } from \"./rtc.ts\";\nexport { MatrixRTCMembershipParseError } from \"./common.ts\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAAqC,2BAA2B,QAAQ,cAAc;AACtF,SAAiC,qBAAqB,EAAE,sBAAsB,QAAQ,UAAU;AAChG,SAAS,6BAA6B,QAAQ,aAAa","ignoreList":[]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
1
|
/*
|
|
3
2
|
Copyright 2026 The Matrix.org Foundation C.I.C.
|
|
4
3
|
|
|
@@ -32,22 +31,21 @@ import { slotIdToDescription } from "../utils.js";
|
|
|
32
31
|
* @returns true if `data` is valid RtcMembershipData
|
|
33
32
|
* @throws {MatrixRTCMembershipParseError} if the content is not valid
|
|
34
33
|
*/
|
|
35
|
-
export
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
var expectedSlotPrefix = "".concat(data === null || data === void 0 || (_data$application = data.application) === null || _data$application === void 0 ? void 0 : _data$application.type, "#");
|
|
34
|
+
export const checkRtcMembershipData = (data, sender) => {
|
|
35
|
+
const errors = [];
|
|
36
|
+
const prefix = " - ";
|
|
37
|
+
const expectedSlotPrefix = `${data?.application?.type}#`;
|
|
40
38
|
|
|
41
39
|
// required fields
|
|
42
40
|
if (typeof data.slot_id !== "string") {
|
|
43
41
|
errors.push(prefix + "slot_id must be string");
|
|
44
42
|
} else if (!data.slot_id.startsWith(expectedSlotPrefix)) {
|
|
45
|
-
errors.push(prefix +
|
|
43
|
+
errors.push(prefix + `slot_id must start with ${expectedSlotPrefix}`);
|
|
46
44
|
} else {
|
|
47
45
|
try {
|
|
48
46
|
slotIdToDescription(data.slot_id);
|
|
49
47
|
} catch (ex) {
|
|
50
|
-
errors.push(prefix +
|
|
48
|
+
errors.push(prefix + `slot_id was badly formed${ex instanceof Error ? `: ${ex.message}` : ""}`);
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
if (typeof data.member !== "object" || data.member === null) {
|
|
@@ -82,7 +80,7 @@ export var checkRtcMembershipData = (data, sender) => {
|
|
|
82
80
|
errors.push(prefix + "rtc_transports must be an array");
|
|
83
81
|
} else {
|
|
84
82
|
// validate that each transport has at least a string 'type'
|
|
85
|
-
for (
|
|
83
|
+
for (const t of data.rtc_transports) {
|
|
86
84
|
if (typeof t !== "object" || t === null || typeof t.type !== "string") {
|
|
87
85
|
errors.push(prefix + "rtc_transports entries must be objects with a string type");
|
|
88
86
|
break;
|
|
@@ -96,7 +94,7 @@ export var checkRtcMembershipData = (data, sender) => {
|
|
|
96
94
|
}
|
|
97
95
|
|
|
98
96
|
// optional fields
|
|
99
|
-
if ((
|
|
97
|
+
if ((data.sticky_key ?? data.msc4354_sticky_key) === undefined) {
|
|
100
98
|
errors.push(prefix + "sticky_key or msc4354_sticky_key must be a defined");
|
|
101
99
|
}
|
|
102
100
|
if (data.sticky_key !== undefined && typeof data.sticky_key !== "string") {
|
|
@@ -109,7 +107,7 @@ export var checkRtcMembershipData = (data, sender) => {
|
|
|
109
107
|
errors.push(prefix + "sticky_key and msc4354_sticky_key must be equal if both are defined");
|
|
110
108
|
}
|
|
111
109
|
if (data["m.relates_to"] !== undefined) {
|
|
112
|
-
|
|
110
|
+
const rel = data["m.relates_to"];
|
|
113
111
|
if (typeof rel !== "object" || rel === null) {
|
|
114
112
|
errors.push(prefix + "m.relates_to must be an object if provided");
|
|
115
113
|
} else {
|
|
@@ -122,17 +120,11 @@ export var checkRtcMembershipData = (data, sender) => {
|
|
|
122
120
|
}
|
|
123
121
|
return true;
|
|
124
122
|
};
|
|
125
|
-
export function computeRtcIdentityRaw(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
var jsonStr = JSON.stringify([userId, deviceId, memberId]);
|
|
132
|
-
var hashBuffer = yield sha256(jsonStr);
|
|
133
|
-
var hashedString = encodeUnpaddedBase64(hashBuffer);
|
|
134
|
-
return hashedString;
|
|
135
|
-
});
|
|
136
|
-
return _computeRtcIdentityRaw.apply(this, arguments);
|
|
123
|
+
export async function computeRtcIdentityRaw(userId, deviceId, memberId) {
|
|
124
|
+
// canonical JSON serialization (Matrix canonical JSON for arrays)
|
|
125
|
+
const jsonStr = JSON.stringify([userId, deviceId, memberId]);
|
|
126
|
+
const hashBuffer = await sha256(jsonStr);
|
|
127
|
+
const hashedString = encodeUnpaddedBase64(hashBuffer);
|
|
128
|
+
return hashedString;
|
|
137
129
|
}
|
|
138
130
|
//# sourceMappingURL=rtc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rtc.js","names":["MXID_PATTERN","MatrixRTCMembershipParseError","sha256","encodeUnpaddedBase64","slotIdToDescription","checkRtcMembershipData","data","sender","_data$application","_data$sticky_key","errors","prefix","expectedSlotPrefix","concat","application","type","slot_id","push","startsWith","ex","Error","message","member","user_id","test","device_id","id","includes","rtc_transports","undefined","Array","isArray","t","versions","every","v","sticky_key","msc4354_sticky_key","rel","event_id","rel_type","length","computeRtcIdentityRaw","_x","_x2","_x3","_computeRtcIdentityRaw","apply","arguments","_asyncToGenerator","userId","deviceId","memberId","jsonStr","JSON","stringify","hashBuffer","hashedString"],"sources":["../../../src/matrixrtc/membershipData/rtc.ts"],"sourcesContent":["/*\nCopyright 2026 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { MXID_PATTERN } from \"../../models/room-member.ts\";\nimport type { IContent } from \"../../models/event.ts\";\nimport type { RelationType } from \"../../types.ts\";\nimport { type RtcSlotEventContent, type Transport } from \"../types.ts\";\nimport { MatrixRTCMembershipParseError } from \"./common.ts\";\nimport { sha256 } from \"../../digest.ts\";\nimport { encodeUnpaddedBase64 } from \"../../base64.ts\";\nimport { slotIdToDescription } from \"../utils.ts\";\n\n/**\n * Represents the current form of MSC4143, which uses sticky events to store membership.\n */\nexport interface RtcMembershipData {\n \"slot_id\": string;\n \"member\": {\n user_id: string;\n device_id: string;\n id: string;\n };\n \"m.relates_to\"?: {\n event_id: string;\n rel_type: RelationType.Reference;\n };\n \"application\": RtcSlotEventContent[\"application\"];\n \"rtc_transports\": Transport[];\n \"versions\": string[];\n \"msc4354_sticky_key\"?: string;\n \"sticky_key\"?: string;\n}\n\n/**\n * Validates that `data` matches the format expected by MSC4143.\n * @param data The event content.\n * @param sender The sender of the event.\n * @returns true if `data` is valid RtcMembershipData\n * @throws {MatrixRTCMembershipParseError} if the content is not valid\n */\nexport const checkRtcMembershipData = (data: IContent, sender: string): data is RtcMembershipData => {\n const errors: string[] = [];\n const prefix = \" - \";\n const expectedSlotPrefix = `${data?.application?.type}#`;\n\n // required fields\n if (typeof data.slot_id !== \"string\") {\n errors.push(prefix + \"slot_id must be string\");\n } else if (!data.slot_id.startsWith(expectedSlotPrefix)) {\n errors.push(prefix + `slot_id must start with ${expectedSlotPrefix}`);\n } else {\n try {\n slotIdToDescription(data.slot_id);\n } catch (ex) {\n errors.push(prefix + `slot_id was badly formed${ex instanceof Error ? `: ${ex.message}` : \"\"}`);\n }\n }\n\n if (typeof data.member !== \"object\" || data.member === null) {\n errors.push(prefix + \"member must be an object\");\n } else {\n if (typeof data.member.user_id !== \"string\") {\n errors.push(prefix + \"member.user_id must be string\");\n } else if (!MXID_PATTERN.test(data.member.user_id)) {\n errors.push(prefix + \"member.user_id must be a valid mxid\");\n }\n // This is not what the spec enforces but there currently are no rules what power levels are required to\n // send a m.rtc.member event for a other user. So we add this check for simplicity and to avoid possible attacks until there\n // is a proper definition when this is allowed.\n else if (data.member.user_id !== sender) {\n errors.push(prefix + \"member.user_id must match the sender\");\n }\n if (typeof data.member.device_id !== \"string\") {\n errors.push(prefix + \"member.device_id must be string\");\n }\n if (typeof data.member.id !== \"string\") errors.push(prefix + \"member.id must be string\");\n }\n if (typeof data.application !== \"object\" || data.application === null) {\n errors.push(prefix + \"application must be an object\");\n } else {\n if (typeof data.application.type !== \"string\") {\n errors.push(prefix + \"application.type must be a string\");\n } else {\n if (data.application.type.includes(\"#\")) errors.push(prefix + 'application.type must not include \"#\"');\n }\n }\n if (data.rtc_transports === undefined || !Array.isArray(data.rtc_transports)) {\n errors.push(prefix + \"rtc_transports must be an array\");\n } else {\n // validate that each transport has at least a string 'type'\n for (const t of data.rtc_transports) {\n if (typeof t !== \"object\" || t === null || typeof (t as any).type !== \"string\") {\n errors.push(prefix + \"rtc_transports entries must be objects with a string type\");\n break;\n }\n }\n }\n if (data.versions === undefined || !Array.isArray(data.versions)) {\n errors.push(prefix + \"versions must be an array\");\n } else if (!data.versions.every((v) => typeof v === \"string\")) {\n errors.push(prefix + \"versions must be an array of strings\");\n }\n\n // optional fields\n if ((data.sticky_key ?? data.msc4354_sticky_key) === undefined) {\n errors.push(prefix + \"sticky_key or msc4354_sticky_key must be a defined\");\n }\n if (data.sticky_key !== undefined && typeof data.sticky_key !== \"string\") {\n errors.push(prefix + \"sticky_key must be a string\");\n }\n if (data.msc4354_sticky_key !== undefined && typeof data.msc4354_sticky_key !== \"string\") {\n errors.push(prefix + \"msc4354_sticky_key must be a string\");\n }\n if (\n data.sticky_key !== undefined &&\n data.msc4354_sticky_key !== undefined &&\n data.sticky_key !== data.msc4354_sticky_key\n ) {\n errors.push(prefix + \"sticky_key and msc4354_sticky_key must be equal if both are defined\");\n }\n if (data[\"m.relates_to\"] !== undefined) {\n const rel = data[\"m.relates_to\"] as RtcMembershipData[\"m.relates_to\"];\n if (typeof rel !== \"object\" || rel === null) {\n errors.push(prefix + \"m.relates_to must be an object if provided\");\n } else {\n if (typeof rel.event_id !== \"string\") errors.push(prefix + \"m.relates_to.event_id must be a string\");\n if (rel.rel_type !== \"m.reference\") errors.push(prefix + \"m.relates_to.rel_type must be m.reference\");\n }\n }\n\n if (errors.length) {\n throw new MatrixRTCMembershipParseError(\"RtcMembership\", errors);\n }\n\n return true;\n};\n\nexport async function computeRtcIdentityRaw(userId: string, deviceId: string, memberId: string): Promise<string> {\n // canonical JSON serialization (Matrix canonical JSON for arrays)\n const jsonStr = JSON.stringify([userId, deviceId, memberId]);\n const hashBuffer = await sha256(jsonStr);\n const hashedString = encodeUnpaddedBase64(hashBuffer);\n return hashedString;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"rtc.js","names":[],"sources":["../../../src/matrixrtc/membershipData/rtc.ts"],"sourcesContent":["/*\nCopyright 2026 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { MXID_PATTERN } from \"../../models/room-member.ts\";\nimport type { IContent } from \"../../models/event.ts\";\nimport type { RelationType } from \"../../types.ts\";\nimport { type RtcSlotEventContent, type Transport } from \"../types.ts\";\nimport { MatrixRTCMembershipParseError } from \"./common.ts\";\nimport { sha256 } from \"../../digest.ts\";\nimport { encodeUnpaddedBase64 } from \"../../base64.ts\";\nimport { slotIdToDescription } from \"../utils.ts\";\n\n/**\n * Represents the current form of MSC4143, which uses sticky events to store membership.\n */\nexport interface RtcMembershipData {\n \"slot_id\": string;\n \"member\": {\n user_id: string;\n device_id: string;\n id: string;\n };\n \"m.relates_to\"?: {\n event_id: string;\n rel_type: RelationType.Reference;\n };\n \"application\": RtcSlotEventContent[\"application\"];\n \"rtc_transports\": Transport[];\n \"versions\": string[];\n \"msc4354_sticky_key\"?: string;\n \"sticky_key\"?: string;\n}\n\n/**\n * Validates that `data` matches the format expected by MSC4143.\n * @param data The event content.\n * @param sender The sender of the event.\n * @returns true if `data` is valid RtcMembershipData\n * @throws {MatrixRTCMembershipParseError} if the content is not valid\n */\nexport const checkRtcMembershipData = (data: IContent, sender: string): data is RtcMembershipData => {\n const errors: string[] = [];\n const prefix = \" - \";\n const expectedSlotPrefix = `${data?.application?.type}#`;\n\n // required fields\n if (typeof data.slot_id !== \"string\") {\n errors.push(prefix + \"slot_id must be string\");\n } else if (!data.slot_id.startsWith(expectedSlotPrefix)) {\n errors.push(prefix + `slot_id must start with ${expectedSlotPrefix}`);\n } else {\n try {\n slotIdToDescription(data.slot_id);\n } catch (ex) {\n errors.push(prefix + `slot_id was badly formed${ex instanceof Error ? `: ${ex.message}` : \"\"}`);\n }\n }\n\n if (typeof data.member !== \"object\" || data.member === null) {\n errors.push(prefix + \"member must be an object\");\n } else {\n if (typeof data.member.user_id !== \"string\") {\n errors.push(prefix + \"member.user_id must be string\");\n } else if (!MXID_PATTERN.test(data.member.user_id)) {\n errors.push(prefix + \"member.user_id must be a valid mxid\");\n }\n // This is not what the spec enforces but there currently are no rules what power levels are required to\n // send a m.rtc.member event for a other user. So we add this check for simplicity and to avoid possible attacks until there\n // is a proper definition when this is allowed.\n else if (data.member.user_id !== sender) {\n errors.push(prefix + \"member.user_id must match the sender\");\n }\n if (typeof data.member.device_id !== \"string\") {\n errors.push(prefix + \"member.device_id must be string\");\n }\n if (typeof data.member.id !== \"string\") errors.push(prefix + \"member.id must be string\");\n }\n if (typeof data.application !== \"object\" || data.application === null) {\n errors.push(prefix + \"application must be an object\");\n } else {\n if (typeof data.application.type !== \"string\") {\n errors.push(prefix + \"application.type must be a string\");\n } else {\n if (data.application.type.includes(\"#\")) errors.push(prefix + 'application.type must not include \"#\"');\n }\n }\n if (data.rtc_transports === undefined || !Array.isArray(data.rtc_transports)) {\n errors.push(prefix + \"rtc_transports must be an array\");\n } else {\n // validate that each transport has at least a string 'type'\n for (const t of data.rtc_transports) {\n if (typeof t !== \"object\" || t === null || typeof (t as any).type !== \"string\") {\n errors.push(prefix + \"rtc_transports entries must be objects with a string type\");\n break;\n }\n }\n }\n if (data.versions === undefined || !Array.isArray(data.versions)) {\n errors.push(prefix + \"versions must be an array\");\n } else if (!data.versions.every((v) => typeof v === \"string\")) {\n errors.push(prefix + \"versions must be an array of strings\");\n }\n\n // optional fields\n if ((data.sticky_key ?? data.msc4354_sticky_key) === undefined) {\n errors.push(prefix + \"sticky_key or msc4354_sticky_key must be a defined\");\n }\n if (data.sticky_key !== undefined && typeof data.sticky_key !== \"string\") {\n errors.push(prefix + \"sticky_key must be a string\");\n }\n if (data.msc4354_sticky_key !== undefined && typeof data.msc4354_sticky_key !== \"string\") {\n errors.push(prefix + \"msc4354_sticky_key must be a string\");\n }\n if (\n data.sticky_key !== undefined &&\n data.msc4354_sticky_key !== undefined &&\n data.sticky_key !== data.msc4354_sticky_key\n ) {\n errors.push(prefix + \"sticky_key and msc4354_sticky_key must be equal if both are defined\");\n }\n if (data[\"m.relates_to\"] !== undefined) {\n const rel = data[\"m.relates_to\"] as RtcMembershipData[\"m.relates_to\"];\n if (typeof rel !== \"object\" || rel === null) {\n errors.push(prefix + \"m.relates_to must be an object if provided\");\n } else {\n if (typeof rel.event_id !== \"string\") errors.push(prefix + \"m.relates_to.event_id must be a string\");\n if (rel.rel_type !== \"m.reference\") errors.push(prefix + \"m.relates_to.rel_type must be m.reference\");\n }\n }\n\n if (errors.length) {\n throw new MatrixRTCMembershipParseError(\"RtcMembership\", errors);\n }\n\n return true;\n};\n\nexport async function computeRtcIdentityRaw(userId: string, deviceId: string, memberId: string): Promise<string> {\n // canonical JSON serialization (Matrix canonical JSON for arrays)\n const jsonStr = JSON.stringify([userId, deviceId, memberId]);\n const hashBuffer = await sha256(jsonStr);\n const hashedString = encodeUnpaddedBase64(hashBuffer);\n return hashedString;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -28,17 +28,16 @@ import { MatrixRTCMembershipParseError } from "./common.js";
|
|
|
28
28
|
* @returns true if `data` is valid SessionMembershipData
|
|
29
29
|
* @throws {MatrixRTCMembershipParseError} if the content is not valid
|
|
30
30
|
*/
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
var errors = [];
|
|
31
|
+
export const checkSessionsMembershipData = data => {
|
|
32
|
+
const prefix = " - ";
|
|
33
|
+
const errors = [];
|
|
35
34
|
if (typeof data.device_id !== "string") errors.push(prefix + "device_id must be string");
|
|
36
35
|
if (typeof data.call_id !== "string") errors.push(prefix + "call_id must be string");
|
|
37
36
|
if (typeof data.application !== "string") errors.push(prefix + "application must be a string");
|
|
38
37
|
if (data.focus_active === undefined) {
|
|
39
38
|
errors.push(prefix + "focus_active has an invalid type");
|
|
40
39
|
}
|
|
41
|
-
if (typeof
|
|
40
|
+
if (typeof data.focus_active?.type !== "string") {
|
|
42
41
|
errors.push(prefix + "focus_active.type must be a string");
|
|
43
42
|
}
|
|
44
43
|
if (data.foci_preferred !== undefined && !(Array.isArray(data.foci_preferred) && data.foci_preferred.every(f => typeof f === "object" && f !== null && typeof f.type === "string"))) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","names":[
|
|
1
|
+
{"version":3,"file":"session.js","names":[],"sources":["../../../src/matrixrtc/membershipData/session.ts"],"sourcesContent":["/*\nCopyright 2026 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { type IContent } from \"../../matrix.ts\";\nimport { type RTCCallIntent, type Transport } from \"../types.ts\";\nimport { MatrixRTCMembershipParseError } from \"./common.ts\";\n\n/**\n * (MatrixRTC) session membership data.\n * This represents the *OLD* form of MSC4143, which uses state events to store membership.\n * Represents the `session` in the memberships section of an m.call.member event as it is on the wire.\n **/\nexport type SessionMembershipData = {\n /**\n * The RTC application defines the type of the RTC session.\n */\n \"application\": string;\n\n /**\n * The id of this session.\n * A session can never span over multiple rooms so this id is to distinguish between\n * multiple session in one room. A room wide session that is not associated with a user,\n * and therefore immune to creation race conflicts, uses the `call_id: \"\"`.\n */\n \"call_id\": string;\n\n /**\n * The Matrix device ID of this session. A single user can have multiple sessions on different devices.\n */\n \"device_id\": string;\n\n /**\n * The focus selection system this user/membership is using.\n * NOTE: This is still included for legacy reasons, but not consumed by the SDK.\n */\n \"focus_active\": {\n type: \"livekit\" | string;\n focus_selection: \"oldest_membership\" | \"multi_sfu\" | string;\n };\n\n /**\n * A list of possible foci this user knows about. One of them might be used based on the focus_active\n * selection system.\n */\n \"foci_preferred\": Transport[];\n\n /**\n * Optional field that contains the creation of the session. If it is undefined the creation\n * is the `origin_server_ts` of the event itself. For updates to the event this property tracks\n * the `origin_server_ts` of the initial join event.\n * - If it is undefined it can be interpreted as a \"Join\".\n * - If it is defined it can be interpreted as an \"Update\"\n */\n \"created_ts\"?: number;\n\n // Application specific data\n\n /**\n * If the `application` = `\"m.call\"` this defines if it is a room or user owned call.\n * There can always be one room scoped call but multiple user owned calls (breakout sessions)\n */\n \"scope\"?: \"m.room\" | \"m.user\";\n\n /**\n * Optionally we allow to define a delta to the `created_ts` that defines when the event is expired/invalid.\n * This should be set to multiple hours. The only reason it exist is to deal with failed delayed events.\n * (for example caused by a homeserver crashes)\n **/\n \"expires\"?: number;\n\n /**\n * The intent of the call from the perspective of this user. This may be an audio call, video call or\n * something else.\n */\n \"m.call.intent\"?: RTCCallIntent;\n\n /**\n * The id used on the media backend.\n * (With livekit this is the participant identity on the LK SFU)\n * This can be a UUID but right now it is `${this.matrixEventData.sender}:${data.device_id}`.\n *\n * It is compleatly valid to not set this field. Other clients will treat `undefined` as `${this.matrixEventData.sender}:${data.device_id}`\n */\n \"membershipID\"?: string;\n};\n\n/**\n * Validates that `data` matches the format expected by the legacy form of MSC4143.\n * @param data The event content.\n * @returns true if `data` is valid SessionMembershipData\n * @throws {MatrixRTCMembershipParseError} if the content is not valid\n */\nexport const checkSessionsMembershipData = (data: IContent): data is SessionMembershipData => {\n const prefix = \" - \";\n const errors: string[] = [];\n if (typeof data.device_id !== \"string\") errors.push(prefix + \"device_id must be string\");\n if (typeof data.call_id !== \"string\") errors.push(prefix + \"call_id must be string\");\n if (typeof data.application !== \"string\") errors.push(prefix + \"application must be a string\");\n if (data.focus_active === undefined) {\n errors.push(prefix + \"focus_active has an invalid type\");\n }\n if (typeof data.focus_active?.type !== \"string\") {\n errors.push(prefix + \"focus_active.type must be a string\");\n }\n if (\n data.foci_preferred !== undefined &&\n !(\n Array.isArray(data.foci_preferred) &&\n data.foci_preferred.every(\n (f: Transport) => typeof f === \"object\" && f !== null && typeof f.type === \"string\",\n )\n )\n ) {\n errors.push(prefix + \"foci_preferred must be an array of transport objects\");\n }\n // optional parameters\n if (data.created_ts !== undefined && typeof data.created_ts !== \"number\") {\n errors.push(prefix + \"created_ts must be number\");\n }\n\n // application specific data (we first need to check if they exist)\n if (data.scope !== undefined && typeof data.scope !== \"string\") errors.push(prefix + \"scope must be string\");\n\n if (data[\"m.call.intent\"] !== undefined && typeof data[\"m.call.intent\"] !== \"string\") {\n errors.push(prefix + \"m.call.intent must be a string\");\n }\n\n if (errors.length) {\n throw new MatrixRTCMembershipParseError(\"SessionMembership\", errors);\n }\n\n return true;\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,SAAS,6BAA6B,QAAQ,aAAa;;AAE3D;AACA;AACA;AACA;AACA;;AA2EA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM,2BAA2B,GAAI,IAAc,IAAoC;EAC1F,MAAM,MAAM,GAAG,KAAK;EACpB,MAAM,MAAgB,GAAG,EAAE;EAC3B,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,0BAA0B,CAAC;EACxF,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,wBAAwB,CAAC;EACpF,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,8BAA8B,CAAC;EAC9F,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE;IACjC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,kCAAkC,CAAC;EAC5D;EACA,IAAI,OAAO,IAAI,CAAC,YAAY,EAAE,IAAI,KAAK,QAAQ,EAAE;IAC7C,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,oCAAoC,CAAC;EAC9D;EACA,IACI,IAAI,CAAC,cAAc,KAAK,SAAS,IACjC,EACI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,IAClC,IAAI,CAAC,cAAc,CAAC,KAAK,CACpB,CAAY,IAAK,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAC/E,CAAC,CACJ,EACH;IACE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,sDAAsD,CAAC;EAChF;EACA;EACA,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE;IACtE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,2BAA2B,CAAC;EACrD;;EAEA;EACA,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,sBAAsB,CAAC;EAE5G,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,QAAQ,EAAE;IAClF,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,gCAAgC,CAAC;EAC1D;EAEA,IAAI,MAAM,CAAC,MAAM,EAAE;IACf,MAAM,IAAI,6BAA6B,CAAC,mBAAmB,EAAE,MAAM,CAAC;EACxE;EAEA,OAAO,IAAI;AACf,CAAC","ignoreList":[]}
|
package/lib/matrixrtc/types.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
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; }
|
|
3
|
-
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; }
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
|
|
4
2
|
/*
|
|
5
3
|
Copyright 2023-2026 The Matrix.org Foundation C.I.C.
|
|
6
4
|
|
|
@@ -72,7 +70,7 @@ export function parseCallNotificationContent(content) {
|
|
|
72
70
|
if (content["m.call.intent"] && typeof content["m.call.intent"] !== "string") {
|
|
73
71
|
throw new Error("Invalid m.call.intent");
|
|
74
72
|
}
|
|
75
|
-
|
|
73
|
+
const cappedLifetime = content["lifetime"] >= 90000 ? 90000 : content["lifetime"];
|
|
76
74
|
return _objectSpread(_objectSpread({}, content), {}, {
|
|
77
75
|
lifetime: cappedLifetime
|
|
78
76
|
});
|
|
@@ -88,7 +86,7 @@ export function parseCallNotificationContent(content) {
|
|
|
88
86
|
* Sent as a standard m.reference relation to an `org.matrix.msc4075.rtc.notification` event.
|
|
89
87
|
*/
|
|
90
88
|
|
|
91
|
-
export
|
|
89
|
+
export let Status = /*#__PURE__*/function (Status) {
|
|
92
90
|
Status["Disconnected"] = "Disconnected";
|
|
93
91
|
Status["Connecting"] = "Connecting";
|
|
94
92
|
Status["Connected"] = "Connected";
|
|
@@ -101,7 +99,7 @@ export var Status = /*#__PURE__*/function (Status) {
|
|
|
101
99
|
* A type collecting call encryption statistics for a session.
|
|
102
100
|
*/
|
|
103
101
|
|
|
104
|
-
export
|
|
102
|
+
export const isMyMembership = (m, userId, deviceId) => m.sender === userId && m.deviceId === deviceId;
|
|
105
103
|
|
|
106
104
|
/**
|
|
107
105
|
* A RTC transport is a JSON object that describes how to connect to a RTC member.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/matrixrtc/types.ts"],"sourcesContent":["/*\nCopyright 2023-2026 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport type { IContent, IMentions } from \"../matrix.ts\";\nimport type { RelationEvent } from \"../types.ts\";\nimport type { CallMembership } from \"./CallMembership.ts\";\nimport { type CallMembershipIdentityParts } from \"./EncryptionManager.ts\";\n\nexport type EncryptionKeyMapKey = string;\n\nexport interface EncryptionKeyEntry {\n index: number;\n key: string;\n}\n\n/**\n * The mxID, deviceId and membership timestamp of a RTC session participant.\n */\nexport type ParticipantDeviceInfo = {\n userId: string;\n deviceId: string;\n membershipTs: number;\n};\n\n/**\n * A type representing the information needed to decrypt video streams.\n */\nexport type InboundEncryptionSession = {\n key: Uint8Array<ArrayBuffer>;\n membership: CallMembershipIdentityParts;\n keyIndex: number;\n creationTS: number;\n};\n\n/**\n * The information about the key used to encrypt video streams.\n */\nexport type OutboundEncryptionSession = {\n key: Uint8Array<ArrayBuffer>;\n creationTS: number;\n // The devices that this key is shared with.\n sharedWith: Array<ParticipantDeviceInfo>;\n // This is an index acting as the id of the key\n keyId: number;\n};\n\nexport interface EncryptionKeysEventContent {\n keys: EncryptionKeyEntry[];\n device_id: string;\n call_id: string;\n sent_ts?: number;\n}\n\n/**\n * THe content of a to-device event that contains encryption keys.\n */\nexport interface EncryptionKeysToDeviceEventContent {\n keys: { index: number; key: string };\n member: {\n id: string;\n // TODO Remove that it is claimed, need to get the sealed sender from decryption info\n // Or add some validation on it based on the encryption info\n claimed_device_id: string;\n };\n room_id: string;\n session: {\n application: string;\n call_id: string;\n scope: string;\n };\n // Why is this needed?\n sent_ts?: number;\n}\n/**\n * @deprecated Use `RTCNotificationType` instead.\n */\nexport type CallNotifyType = \"ring\" | \"notify\";\n/**\n * @deprecated Use `IRTCNotificationContent` instead.\n */\nexport interface ICallNotifyContent {\n \"application\": string;\n \"m.mentions\": IMentions;\n \"notify_type\": CallNotifyType;\n \"call_id\": string;\n}\n\nexport type RTCNotificationType = \"ring\" | \"notification\";\n\n/**\n * Represents the intention of the call from the perspective of the sending user.\n * May be any string, although `\"audio\"` and `\"video\"` are commonly accepted values.\n */\nexport type RTCCallIntent = \"audio\" | \"video\" | string;\n\n/**\n * This will check if the content has all the expected fields to be a valid IRTCNotificationContent.\n * It will also cap the lifetime to 90000ms (1.5 min) if a higher value is provided.\n * @param content\n * @throws if the content is invalid\n * @returns a parsed IRTCNotificationContent\n */\nexport function parseCallNotificationContent(content: IContent): IRTCNotificationContent {\n if (content[\"m.mentions\"] && typeof content[\"m.mentions\"] !== \"object\") {\n throw new Error(\"malformed m.mentions\");\n }\n if (typeof content[\"notification_type\"] !== \"string\") {\n throw new Error(\"Missing or invalid notification_type\");\n }\n if (typeof content[\"sender_ts\"] !== \"number\") {\n throw new Error(\"Missing or invalid sender_ts\");\n }\n if (typeof content[\"lifetime\"] !== \"number\") {\n throw new Error(\"Missing or invalid lifetime\");\n }\n\n if (content[\"relation\"] && content[\"relation\"][\"rel_type\"] !== \"m.reference\") {\n throw new Error(\"Invalid relation\");\n }\n if (content[\"m.call.intent\"] && typeof content[\"m.call.intent\"] !== \"string\") {\n throw new Error(\"Invalid m.call.intent\");\n }\n\n const cappedLifetime = content[\"lifetime\"] >= 90000 ? 90000 : content[\"lifetime\"];\n return { ...content, lifetime: cappedLifetime } as IRTCNotificationContent;\n}\n\n/**\n * Interface for `org.matrix.msc4075.rtc.notification` events.\n * Don't cast event content to this directly. Use `parseCallNotificationContent` instead to validate the content first.\n */\nexport interface IRTCNotificationContent extends RelationEvent {\n \"m.mentions\"?: IMentions;\n \"notification_type\": RTCNotificationType;\n /**\n * The initial intent of the calling user.\n */\n \"m.call.intent\"?: RTCCallIntent;\n \"sender_ts\": number;\n \"lifetime\": number;\n}\n\n/**\n * MSC4310 decline event content for `org.matrix.msc4310.rtc.decline`.\n * Sent as a standard m.reference relation to an `org.matrix.msc4075.rtc.notification` event.\n */\nexport interface IRTCDeclineContent extends RelationEvent {}\n\nexport enum Status {\n Disconnected = \"Disconnected\",\n Connecting = \"Connecting\",\n Connected = \"Connected\",\n Disconnecting = \"Disconnecting\",\n Unknown = \"Unknown\",\n}\n\n/**\n * A type collecting call encryption statistics for a session.\n */\nexport type Statistics = {\n counters: {\n /**\n * The number of times we have sent a room event containing encryption keys.\n */\n roomEventEncryptionKeysSent: number;\n /**\n * The number of times we have received a room event containing encryption keys.\n */\n roomEventEncryptionKeysReceived: number;\n };\n totals: {\n /**\n * The total age (in milliseconds) of all room events containing encryption keys that we have received.\n * We track the total age so that we can later calculate the average age of all keys received.\n */\n roomEventEncryptionKeysReceivedTotalAge: number;\n };\n};\n\nexport const isMyMembership = (m: CallMembership, userId: string, deviceId: string): boolean =>\n m.sender === userId && m.deviceId === deviceId;\n\n/**\n * A RTC transport is a JSON object that describes how to connect to a RTC member.\n */\nexport interface Transport {\n type: string;\n [key: string]: unknown;\n}\n\n/**\n * Event content for a `m.rtc.slot` state event.\n */\nexport interface RtcSlotEventContent<T extends string = string> {\n application: {\n type: T;\n // other application specific keys\n [key: string]: unknown;\n };\n slot_id: string;\n}\n\n/**\n * The session description is used to identify a session. Used in the state event.\n */\nexport interface SlotDescription {\n /**\n * The application type. e.g. \"m.call\".\n */\n application: string;\n /**\n * The application-specific slot ID. e.g. \"ROOM\".\n */\n id: string;\n}\n"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;;AAOA;AACA;AACA;;AAQA;AACA;AACA;;AAiBA;AACA;AACA;;AAkBA;AACA;AACA;;AAEA;AACA;AACA;;AAUA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,4BAA4B,CAAC,OAAiB,EAA2B;EACrF,IAAI,OAAO,CAAC,YAAY,CAAC,IAAI,OAAO,OAAO,CAAC,YAAY,CAAC,KAAK,QAAQ,EAAE;IACpE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC;EAC3C;EACA,IAAI,OAAO,OAAO,CAAC,mBAAmB,CAAC,KAAK,QAAQ,EAAE;IAClD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC;EAC3D;EACA,IAAI,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE;IAC1C,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC;EACnD;EACA,IAAI,OAAO,OAAO,CAAC,UAAU,CAAC,KAAK,QAAQ,EAAE;IACzC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC;EAClD;EAEA,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,KAAK,aAAa,EAAE;IAC1E,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC;EACvC;EACA,IAAI,OAAO,CAAC,eAAe,CAAC,IAAI,OAAO,OAAO,CAAC,eAAe,CAAC,KAAK,QAAQ,EAAE;IAC1E,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC;EAC5C;EAEA,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;EACjF,uCAAY,OAAO;IAAE,QAAQ,EAAE;EAAc;AACjD;;AAEA;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;;AAGA,WAAY,MAAM,0BAAN,MAAM;EAAN,MAAM;EAAN,MAAM;EAAN,MAAM;EAAN,MAAM;EAAN,MAAM;EAAA,OAAN,MAAM;AAAA;;AAQlB;AACA;AACA;;AAqBA,OAAO,MAAM,cAAc,GAAG,CAAC,CAAiB,EAAE,MAAc,EAAE,QAAgB,KAC9E,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ;;AAElD;AACA;AACA;;AAMA;AACA;AACA;;AAUA;AACA;AACA","ignoreList":[]}
|