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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CrossSigningIdentity.js","names":["CrossSigningIdentity","constructor","logger","olmMachine","outgoingRequestProcessor","secretStorage","bootstrapCrossSigning","opts","_this","_asyncToGenerator","setupNewCrossSigning","resetCrossSigning","authUploadDeviceSigningKeys","olmDeviceStatus","crossSigningStatus","masterKeyFromSecretStorage","get","selfSigningKeyFromSecretStorage","userSigningKeyFromSecretStorage","privateKeysInSecretStorage","Boolean","olmDeviceHasKeys","hasMaster","hasUserSigning","hasSelfSigning","debug","olmDeviceHasMaster","olmDeviceHasUserSigning","olmDeviceHasSelfSigning","hasKey","warn","exportCrossSigningKeysToStorage","status","importCrossSigningKeys","Error","device","getDevice","userId","deviceId","request","verify","makeOutgoingRequest","free","_this2","outgoingRequests","req","uploadKeysRequest","uploadSigningKeysRequest","uploadSignaturesRequest","_this3","exported","exportCrossSigningKeys","masterKey","store","error","self_signing_key","userSigningKey"],"sources":["../../src/rust-crypto/CrossSigningIdentity.ts"],"sourcesContent":["/*\nCopyright 2023 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 {\n type OlmMachine,\n type CrossSigningStatus,\n type CrossSigningBootstrapRequests,\n} from \"@matrix-org/matrix-sdk-crypto-wasm\";\n\nimport type * as RustSdkCryptoJs from \"@matrix-org/matrix-sdk-crypto-wasm\";\nimport { type BootstrapCrossSigningOpts } from \"../crypto-api/index.ts\";\nimport { type Logger } from \"../logger.ts\";\nimport { type OutgoingRequestProcessor } from \"./OutgoingRequestProcessor.ts\";\nimport { type UIAuthCallback } from \"../interactive-auth.ts\";\nimport { type ServerSideSecretStorage } from \"../secret-storage.ts\";\n\n/** Manages the cross-signing keys for our own user.\n *\n * @internal\n */\nexport class CrossSigningIdentity {\n public constructor(\n private readonly logger: Logger,\n private readonly olmMachine: OlmMachine,\n private readonly outgoingRequestProcessor: OutgoingRequestProcessor,\n private readonly secretStorage: ServerSideSecretStorage,\n ) {}\n\n /**\n * Initialise our cross-signing keys by creating new keys if they do not exist, and uploading to the server\n */\n public async bootstrapCrossSigning(opts: BootstrapCrossSigningOpts): Promise<void> {\n if (opts.setupNewCrossSigning) {\n await this.resetCrossSigning(opts.authUploadDeviceSigningKeys);\n return;\n }\n\n const olmDeviceStatus: CrossSigningStatus = await this.olmMachine.crossSigningStatus();\n\n // Try to fetch cross signing keys from the secret storage\n const masterKeyFromSecretStorage = await this.secretStorage.get(\"m.cross_signing.master\");\n const selfSigningKeyFromSecretStorage = await this.secretStorage.get(\"m.cross_signing.self_signing\");\n const userSigningKeyFromSecretStorage = await this.secretStorage.get(\"m.cross_signing.user_signing\");\n const privateKeysInSecretStorage = Boolean(\n masterKeyFromSecretStorage && selfSigningKeyFromSecretStorage && userSigningKeyFromSecretStorage,\n );\n\n const olmDeviceHasKeys =\n olmDeviceStatus.hasMaster && olmDeviceStatus.hasUserSigning && olmDeviceStatus.hasSelfSigning;\n\n // Log all relevant state for easier parsing of debug logs.\n this.logger.debug(\"bootstrapCrossSigning: starting\", {\n setupNewCrossSigning: opts.setupNewCrossSigning,\n olmDeviceHasMaster: olmDeviceStatus.hasMaster,\n olmDeviceHasUserSigning: olmDeviceStatus.hasUserSigning,\n olmDeviceHasSelfSigning: olmDeviceStatus.hasSelfSigning,\n privateKeysInSecretStorage,\n });\n\n if (olmDeviceHasKeys) {\n if (!(await this.secretStorage.hasKey())) {\n this.logger.warn(\n \"bootstrapCrossSigning: Olm device has private keys, but secret storage is not yet set up; doing nothing for now.\",\n );\n // the keys should get uploaded to 4S once that is set up.\n } else if (!privateKeysInSecretStorage) {\n // the device has the keys but they are not in 4S, so update it\n this.logger.debug(\"bootstrapCrossSigning: Olm device has private keys: exporting to secret storage\");\n await this.exportCrossSigningKeysToStorage();\n } else {\n this.logger.debug(\n \"bootstrapCrossSigning: Olm device has private keys and they are saved in secret storage; doing nothing\",\n );\n }\n } /* (!olmDeviceHasKeys) */ else {\n if (privateKeysInSecretStorage) {\n // they are in 4S, so import from there\n this.logger.debug(\n \"bootstrapCrossSigning: Cross-signing private keys not found locally, but they are available \" +\n \"in secret storage, reading storage and caching locally\",\n );\n const status = await this.olmMachine.importCrossSigningKeys(\n masterKeyFromSecretStorage,\n selfSigningKeyFromSecretStorage,\n userSigningKeyFromSecretStorage,\n );\n\n // Check that `importCrossSigningKeys` worked correctly (for example, it will fail silently if the\n // public keys are not available).\n if (!status.hasMaster || !status.hasSelfSigning || !status.hasUserSigning) {\n throw new Error(\"importCrossSigningKeys failed to import the keys\");\n }\n\n // Get the current device\n const device: RustSdkCryptoJs.Device = (await this.olmMachine.getDevice(\n this.olmMachine.userId,\n this.olmMachine.deviceId,\n ))!;\n try {\n // Sign the device with our cross-signing key and upload the signature\n const request: RustSdkCryptoJs.SignatureUploadRequest = await device.verify();\n await this.outgoingRequestProcessor.makeOutgoingRequest(request);\n } finally {\n device.free();\n }\n } else {\n this.logger.debug(\n \"bootstrapCrossSigning: Cross-signing private keys not found locally or in secret storage, creating new keys\",\n );\n await this.resetCrossSigning(opts.authUploadDeviceSigningKeys);\n }\n }\n\n // TODO: we might previously have bootstrapped cross-signing but not completed uploading the keys to the\n // server -- in which case we should call OlmDevice.bootstrap_cross_signing. How do we know?\n this.logger.debug(\"bootstrapCrossSigning: complete\");\n }\n\n /** Reset our cross-signing keys\n *\n * This method will:\n * * Tell the OlmMachine to create new keys\n * * Upload the new public keys and the device signature to the server\n * * Upload the private keys to SSSS, if it is set up\n */\n private async resetCrossSigning(authUploadDeviceSigningKeys?: UIAuthCallback<void>): Promise<void> {\n // XXX: We must find a way to make this atomic, currently if the user does not remember his account password\n // or 4S passphrase/key the process will fail in a bad state, with keys rotated but not uploaded or saved in 4S.\n const outgoingRequests: CrossSigningBootstrapRequests = await this.olmMachine.bootstrapCrossSigning(true);\n\n // If 4S is configured we need to update it.\n if (!(await this.secretStorage.hasKey())) {\n this.logger.warn(\n \"resetCrossSigning: Secret storage is not yet set up; not exporting keys to secret storage yet.\",\n );\n // the keys should get uploaded to 4S once that is set up.\n } else {\n // Update 4S before uploading cross-signing keys, to stay consistent with legacy that asks\n // 4S passphrase before asking for account password.\n // Ultimately should be made atomic and resistant to forgotten password/passphrase.\n this.logger.debug(\"resetCrossSigning: exporting private keys to secret storage\");\n await this.exportCrossSigningKeysToStorage();\n }\n\n this.logger.debug(\"resetCrossSigning: publishing public keys to server\");\n for (const req of [\n outgoingRequests.uploadKeysRequest,\n outgoingRequests.uploadSigningKeysRequest,\n outgoingRequests.uploadSignaturesRequest,\n ]) {\n if (req) {\n await this.outgoingRequestProcessor.makeOutgoingRequest(req, authUploadDeviceSigningKeys);\n }\n }\n }\n\n /**\n * Extract the cross-signing keys from the olm machine and save them to secret storage, if it is configured\n *\n * (If secret storage is *not* configured, we assume that the export will happen when it is set up)\n */\n private async exportCrossSigningKeysToStorage(): Promise<void> {\n const exported: RustSdkCryptoJs.CrossSigningKeyExport | undefined =\n await this.olmMachine.exportCrossSigningKeys();\n /* istanbul ignore else (this function is only called when we know the olm machine has keys) */\n if (exported?.masterKey) {\n await this.secretStorage.store(\"m.cross_signing.master\", exported.masterKey);\n } else {\n this.logger.error(`Cannot export MSK to secret storage, private key unknown`);\n }\n if (exported?.self_signing_key) {\n await this.secretStorage.store(\"m.cross_signing.self_signing\", exported.self_signing_key);\n } else {\n this.logger.error(`Cannot export SSK to secret storage, private key unknown`);\n }\n if (exported?.userSigningKey) {\n await this.secretStorage.store(\"m.cross_signing.user_signing\", exported.userSigningKey);\n } else {\n this.logger.error(`Cannot export USK to secret storage, private key unknown`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"CrossSigningIdentity.js","names":[],"sources":["../../src/rust-crypto/CrossSigningIdentity.ts"],"sourcesContent":["/*\nCopyright 2023 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 {\n type OlmMachine,\n type CrossSigningStatus,\n type CrossSigningBootstrapRequests,\n} from \"@matrix-org/matrix-sdk-crypto-wasm\";\n\nimport type * as RustSdkCryptoJs from \"@matrix-org/matrix-sdk-crypto-wasm\";\nimport { type BootstrapCrossSigningOpts } from \"../crypto-api/index.ts\";\nimport { type Logger } from \"../logger.ts\";\nimport { type OutgoingRequestProcessor } from \"./OutgoingRequestProcessor.ts\";\nimport { type UIAuthCallback } from \"../interactive-auth.ts\";\nimport { type ServerSideSecretStorage } from \"../secret-storage.ts\";\n\n/** Manages the cross-signing keys for our own user.\n *\n * @internal\n */\nexport class CrossSigningIdentity {\n public constructor(\n private readonly logger: Logger,\n private readonly olmMachine: OlmMachine,\n private readonly outgoingRequestProcessor: OutgoingRequestProcessor,\n private readonly secretStorage: ServerSideSecretStorage,\n ) {}\n\n /**\n * Initialise our cross-signing keys by creating new keys if they do not exist, and uploading to the server\n */\n public async bootstrapCrossSigning(opts: BootstrapCrossSigningOpts): Promise<void> {\n if (opts.setupNewCrossSigning) {\n await this.resetCrossSigning(opts.authUploadDeviceSigningKeys);\n return;\n }\n\n const olmDeviceStatus: CrossSigningStatus = await this.olmMachine.crossSigningStatus();\n\n // Try to fetch cross signing keys from the secret storage\n const masterKeyFromSecretStorage = await this.secretStorage.get(\"m.cross_signing.master\");\n const selfSigningKeyFromSecretStorage = await this.secretStorage.get(\"m.cross_signing.self_signing\");\n const userSigningKeyFromSecretStorage = await this.secretStorage.get(\"m.cross_signing.user_signing\");\n const privateKeysInSecretStorage = Boolean(\n masterKeyFromSecretStorage && selfSigningKeyFromSecretStorage && userSigningKeyFromSecretStorage,\n );\n\n const olmDeviceHasKeys =\n olmDeviceStatus.hasMaster && olmDeviceStatus.hasUserSigning && olmDeviceStatus.hasSelfSigning;\n\n // Log all relevant state for easier parsing of debug logs.\n this.logger.debug(\"bootstrapCrossSigning: starting\", {\n setupNewCrossSigning: opts.setupNewCrossSigning,\n olmDeviceHasMaster: olmDeviceStatus.hasMaster,\n olmDeviceHasUserSigning: olmDeviceStatus.hasUserSigning,\n olmDeviceHasSelfSigning: olmDeviceStatus.hasSelfSigning,\n privateKeysInSecretStorage,\n });\n\n if (olmDeviceHasKeys) {\n if (!(await this.secretStorage.hasKey())) {\n this.logger.warn(\n \"bootstrapCrossSigning: Olm device has private keys, but secret storage is not yet set up; doing nothing for now.\",\n );\n // the keys should get uploaded to 4S once that is set up.\n } else if (!privateKeysInSecretStorage) {\n // the device has the keys but they are not in 4S, so update it\n this.logger.debug(\"bootstrapCrossSigning: Olm device has private keys: exporting to secret storage\");\n await this.exportCrossSigningKeysToStorage();\n } else {\n this.logger.debug(\n \"bootstrapCrossSigning: Olm device has private keys and they are saved in secret storage; doing nothing\",\n );\n }\n } /* (!olmDeviceHasKeys) */ else {\n if (privateKeysInSecretStorage) {\n // they are in 4S, so import from there\n this.logger.debug(\n \"bootstrapCrossSigning: Cross-signing private keys not found locally, but they are available \" +\n \"in secret storage, reading storage and caching locally\",\n );\n const status = await this.olmMachine.importCrossSigningKeys(\n masterKeyFromSecretStorage,\n selfSigningKeyFromSecretStorage,\n userSigningKeyFromSecretStorage,\n );\n\n // Check that `importCrossSigningKeys` worked correctly (for example, it will fail silently if the\n // public keys are not available).\n if (!status.hasMaster || !status.hasSelfSigning || !status.hasUserSigning) {\n throw new Error(\"importCrossSigningKeys failed to import the keys\");\n }\n\n // Get the current device\n const device: RustSdkCryptoJs.Device = (await this.olmMachine.getDevice(\n this.olmMachine.userId,\n this.olmMachine.deviceId,\n ))!;\n try {\n // Sign the device with our cross-signing key and upload the signature\n const request: RustSdkCryptoJs.SignatureUploadRequest = await device.verify();\n await this.outgoingRequestProcessor.makeOutgoingRequest(request);\n } finally {\n device.free();\n }\n } else {\n this.logger.debug(\n \"bootstrapCrossSigning: Cross-signing private keys not found locally or in secret storage, creating new keys\",\n );\n await this.resetCrossSigning(opts.authUploadDeviceSigningKeys);\n }\n }\n\n // TODO: we might previously have bootstrapped cross-signing but not completed uploading the keys to the\n // server -- in which case we should call OlmDevice.bootstrap_cross_signing. How do we know?\n this.logger.debug(\"bootstrapCrossSigning: complete\");\n }\n\n /** Reset our cross-signing keys\n *\n * This method will:\n * * Tell the OlmMachine to create new keys\n * * Upload the new public keys and the device signature to the server\n * * Upload the private keys to SSSS, if it is set up\n */\n private async resetCrossSigning(authUploadDeviceSigningKeys?: UIAuthCallback<void>): Promise<void> {\n // XXX: We must find a way to make this atomic, currently if the user does not remember his account password\n // or 4S passphrase/key the process will fail in a bad state, with keys rotated but not uploaded or saved in 4S.\n const outgoingRequests: CrossSigningBootstrapRequests = await this.olmMachine.bootstrapCrossSigning(true);\n\n // If 4S is configured we need to update it.\n if (!(await this.secretStorage.hasKey())) {\n this.logger.warn(\n \"resetCrossSigning: Secret storage is not yet set up; not exporting keys to secret storage yet.\",\n );\n // the keys should get uploaded to 4S once that is set up.\n } else {\n // Update 4S before uploading cross-signing keys, to stay consistent with legacy that asks\n // 4S passphrase before asking for account password.\n // Ultimately should be made atomic and resistant to forgotten password/passphrase.\n this.logger.debug(\"resetCrossSigning: exporting private keys to secret storage\");\n await this.exportCrossSigningKeysToStorage();\n }\n\n this.logger.debug(\"resetCrossSigning: publishing public keys to server\");\n for (const req of [\n outgoingRequests.uploadKeysRequest,\n outgoingRequests.uploadSigningKeysRequest,\n outgoingRequests.uploadSignaturesRequest,\n ]) {\n if (req) {\n await this.outgoingRequestProcessor.makeOutgoingRequest(req, authUploadDeviceSigningKeys);\n }\n }\n }\n\n /**\n * Extract the cross-signing keys from the olm machine and save them to secret storage, if it is configured\n *\n * (If secret storage is *not* configured, we assume that the export will happen when it is set up)\n */\n private async exportCrossSigningKeysToStorage(): Promise<void> {\n const exported: RustSdkCryptoJs.CrossSigningKeyExport | undefined =\n await this.olmMachine.exportCrossSigningKeys();\n /* istanbul ignore else (this function is only called when we know the olm machine has keys) */\n if (exported?.masterKey) {\n await this.secretStorage.store(\"m.cross_signing.master\", exported.masterKey);\n } else {\n this.logger.error(`Cannot export MSK to secret storage, private key unknown`);\n }\n if (exported?.self_signing_key) {\n await this.secretStorage.store(\"m.cross_signing.self_signing\", exported.self_signing_key);\n } else {\n this.logger.error(`Cannot export SSK to secret storage, private key unknown`);\n }\n if (exported?.userSigningKey) {\n await this.secretStorage.store(\"m.cross_signing.user_signing\", exported.userSigningKey);\n } else {\n this.logger.error(`Cannot export USK to secret storage, private key unknown`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -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 2024 The Matrix.org Foundation C.I.C.
|
|
@@ -34,16 +33,16 @@ import { TypedEventEmitter } from "../models/typed-event-emitter.js";
|
|
|
34
33
|
/**
|
|
35
34
|
* The unstable URL prefix for dehydrated device endpoints
|
|
36
35
|
*/
|
|
37
|
-
export
|
|
36
|
+
export const UnstablePrefix = "/_matrix/client/unstable/org.matrix.msc3814.v1";
|
|
38
37
|
/**
|
|
39
38
|
* The name used for the dehydration key in Secret Storage
|
|
40
39
|
*/
|
|
41
|
-
|
|
40
|
+
const SECRET_STORAGE_NAME = "org.matrix.msc3814";
|
|
42
41
|
|
|
43
42
|
/**
|
|
44
43
|
* The interval between creating dehydrated devices. (one week)
|
|
45
44
|
*/
|
|
46
|
-
|
|
45
|
+
const DEHYDRATION_INTERVAL = 7 * 24 * 60 * 60 * 1000;
|
|
47
46
|
|
|
48
47
|
/**
|
|
49
48
|
* Manages dehydrated devices
|
|
@@ -60,47 +59,41 @@ var DEHYDRATION_INTERVAL = 7 * 24 * 60 * 60 * 1000;
|
|
|
60
59
|
export class DehydratedDeviceManager extends TypedEventEmitter {
|
|
61
60
|
constructor(logger, olmMachine, http, outgoingRequestProcessor, secretStorage) {
|
|
62
61
|
super();
|
|
62
|
+
/** the ID of the interval for periodically replacing the dehydrated device */
|
|
63
|
+
_defineProperty(this, "intervalId", void 0);
|
|
63
64
|
this.logger = logger;
|
|
64
65
|
this.olmMachine = olmMachine;
|
|
65
66
|
this.http = http;
|
|
66
67
|
this.outgoingRequestProcessor = outgoingRequestProcessor;
|
|
67
68
|
this.secretStorage = secretStorage;
|
|
68
|
-
/** the ID of the interval for periodically replacing the dehydrated device */
|
|
69
|
-
_defineProperty(this, "intervalId", void 0);
|
|
70
69
|
}
|
|
71
|
-
cacheKey(key) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
yield _this.olmMachine.dehydratedDevices().saveDehydratedDeviceKey(key);
|
|
75
|
-
_this.emit(CryptoEvent.DehydrationKeyCached);
|
|
76
|
-
})();
|
|
70
|
+
async cacheKey(key) {
|
|
71
|
+
await this.olmMachine.dehydratedDevices().saveDehydratedDeviceKey(key);
|
|
72
|
+
this.emit(CryptoEvent.DehydrationKeyCached);
|
|
77
73
|
}
|
|
78
74
|
|
|
79
75
|
/**
|
|
80
76
|
* Return whether the server supports dehydrated devices.
|
|
81
77
|
*/
|
|
82
|
-
isSupported() {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
} else if (err.errcode === "M_NOT_FOUND") {
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
throw error;
|
|
78
|
+
async isSupported() {
|
|
79
|
+
// call the endpoint to get a dehydrated device. If it returns an
|
|
80
|
+
// M_UNRECOGNIZED error, then dehydration is unsupported. If it returns
|
|
81
|
+
// a successful response, or an M_NOT_FOUND, then dehydration is supported.
|
|
82
|
+
// Any other exceptions are passed through.
|
|
83
|
+
try {
|
|
84
|
+
await this.http.authedRequest(Method.Get, "/dehydrated_device", undefined, undefined, {
|
|
85
|
+
prefix: UnstablePrefix
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const err = error;
|
|
89
|
+
if (err.errcode === "M_UNRECOGNIZED") {
|
|
90
|
+
return false;
|
|
91
|
+
} else if (err.errcode === "M_NOT_FOUND") {
|
|
92
|
+
return true;
|
|
101
93
|
}
|
|
102
|
-
|
|
103
|
-
}
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
104
97
|
}
|
|
105
98
|
|
|
106
99
|
/**
|
|
@@ -119,45 +112,37 @@ export class DehydratedDeviceManager extends TypedEventEmitter {
|
|
|
119
112
|
* with old code, a boolean can be given here, which will be treated as
|
|
120
113
|
* the `createNewKey` option. However, this is deprecated.
|
|
121
114
|
*/
|
|
122
|
-
start() {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
// If rehydration fails, there isn't much we can do about it. Log
|
|
141
|
-
// the error, and create a new device.
|
|
142
|
-
_this3.logger.info("dehydration: Error rehydrating device:", e);
|
|
143
|
-
_this3.emit(CryptoEvent.RehydrationError, e.message);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (opts.createNewKey) {
|
|
147
|
-
yield _this3.resetKey();
|
|
115
|
+
async start(opts = {}) {
|
|
116
|
+
if (typeof opts === "boolean") {
|
|
117
|
+
opts = {
|
|
118
|
+
createNewKey: opts
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (opts.onlyIfKeyCached && !(await this.olmMachine.dehydratedDevices().getDehydratedDeviceKey())) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.stop();
|
|
125
|
+
if (opts.rehydrate !== false) {
|
|
126
|
+
try {
|
|
127
|
+
await this.rehydrateDeviceIfAvailable();
|
|
128
|
+
} catch (e) {
|
|
129
|
+
// If rehydration fails, there isn't much we can do about it. Log
|
|
130
|
+
// the error, and create a new device.
|
|
131
|
+
this.logger.info("dehydration: Error rehydrating device:", e);
|
|
132
|
+
this.emit(CryptoEvent.RehydrationError, e.message);
|
|
148
133
|
}
|
|
149
|
-
|
|
150
|
-
|
|
134
|
+
}
|
|
135
|
+
if (opts.createNewKey) {
|
|
136
|
+
await this.resetKey();
|
|
137
|
+
}
|
|
138
|
+
await this.scheduleDeviceDehydration();
|
|
151
139
|
}
|
|
152
140
|
|
|
153
141
|
/**
|
|
154
142
|
* Return whether the dehydration key is stored in Secret Storage.
|
|
155
143
|
*/
|
|
156
|
-
isKeyStored() {
|
|
157
|
-
|
|
158
|
-
return _asyncToGenerator(function* () {
|
|
159
|
-
return Boolean(yield _this4.secretStorage.isStored(SECRET_STORAGE_NAME));
|
|
160
|
-
})();
|
|
144
|
+
async isKeyStored() {
|
|
145
|
+
return Boolean(await this.secretStorage.isStored(SECRET_STORAGE_NAME));
|
|
161
146
|
}
|
|
162
147
|
|
|
163
148
|
/**
|
|
@@ -167,15 +152,12 @@ export class DehydratedDeviceManager extends TypedEventEmitter {
|
|
|
167
152
|
*
|
|
168
153
|
* @returns The newly-generated key.
|
|
169
154
|
*/
|
|
170
|
-
resetKey() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
yield _this5.cacheKey(key);
|
|
177
|
-
return key;
|
|
178
|
-
})();
|
|
155
|
+
async resetKey() {
|
|
156
|
+
const key = RustSdkCryptoJs.DehydratedDeviceKey.createRandomKey();
|
|
157
|
+
await this.secretStorage.store(SECRET_STORAGE_NAME, key.toBase64());
|
|
158
|
+
// Also cache it in the rust SDK's crypto store.
|
|
159
|
+
await this.cacheKey(key);
|
|
160
|
+
return key;
|
|
179
161
|
}
|
|
180
162
|
|
|
181
163
|
/**
|
|
@@ -185,30 +167,27 @@ export class DehydratedDeviceManager extends TypedEventEmitter {
|
|
|
185
167
|
*
|
|
186
168
|
* @returns the key, if available, or `null` if no key is available
|
|
187
169
|
*/
|
|
188
|
-
getKey(create) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (!create) {
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
return yield _this6.resetKey();
|
|
170
|
+
async getKey(create) {
|
|
171
|
+
const cachedKey = await this.olmMachine.dehydratedDevices().getDehydratedDeviceKey();
|
|
172
|
+
if (cachedKey) return cachedKey;
|
|
173
|
+
const keyB64 = await this.secretStorage.get(SECRET_STORAGE_NAME);
|
|
174
|
+
if (keyB64 === undefined) {
|
|
175
|
+
if (!create) {
|
|
176
|
+
return null;
|
|
199
177
|
}
|
|
178
|
+
return await this.resetKey();
|
|
179
|
+
}
|
|
200
180
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
})();
|
|
181
|
+
// We successfully found the key in secret storage: decode it, and cache it in
|
|
182
|
+
// the rust SDK's crypto store.
|
|
183
|
+
const bytes = decodeBase64(keyB64);
|
|
184
|
+
try {
|
|
185
|
+
const key = RustSdkCryptoJs.DehydratedDeviceKey.createKeyFromArray(bytes);
|
|
186
|
+
await this.cacheKey(key);
|
|
187
|
+
return key;
|
|
188
|
+
} finally {
|
|
189
|
+
bytes.fill(0);
|
|
190
|
+
}
|
|
212
191
|
}
|
|
213
192
|
|
|
214
193
|
/**
|
|
@@ -219,59 +198,56 @@ export class DehydratedDeviceManager extends TypedEventEmitter {
|
|
|
219
198
|
*
|
|
220
199
|
* Returns whether or not a dehydrated device was found.
|
|
221
200
|
*/
|
|
222
|
-
rehydrateDeviceIfAvailable() {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
201
|
+
async rehydrateDeviceIfAvailable() {
|
|
202
|
+
const key = await this.getKey(false);
|
|
203
|
+
if (!key) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
let dehydratedDeviceResp;
|
|
207
|
+
try {
|
|
208
|
+
dehydratedDeviceResp = await this.http.authedRequest(Method.Get, "/dehydrated_device", undefined, undefined, {
|
|
209
|
+
prefix: UnstablePrefix
|
|
210
|
+
});
|
|
211
|
+
} catch (error) {
|
|
212
|
+
const err = error;
|
|
213
|
+
// We ignore M_NOT_FOUND (there is no dehydrated device, so nothing
|
|
214
|
+
// us to do) and M_UNRECOGNIZED (the server does not understand the
|
|
215
|
+
// endpoint). We pass through any other errors.
|
|
216
|
+
if (err.errcode === "M_NOT_FOUND" || err.errcode === "M_UNRECOGNIZED") {
|
|
217
|
+
this.logger.info("dehydration: No dehydrated device");
|
|
227
218
|
return false;
|
|
228
219
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
var rehydratedDevice = yield _this7.olmMachine.dehydratedDevices().rehydrate(key, new RustSdkCryptoJs.DeviceId(dehydratedDeviceResp.device_id), JSON.stringify(dehydratedDeviceResp.device_data));
|
|
248
|
-
_this7.logger.info("dehydration: device rehydrated");
|
|
249
|
-
var nextBatch = undefined;
|
|
250
|
-
var toDeviceCount = 0;
|
|
251
|
-
var roomKeyCount = 0;
|
|
252
|
-
var path = encodeUri("/dehydrated_device/$device_id/events", {
|
|
253
|
-
$device_id: dehydratedDeviceResp.device_id
|
|
220
|
+
throw err;
|
|
221
|
+
}
|
|
222
|
+
this.logger.info("dehydration: dehydrated device found");
|
|
223
|
+
this.emit(CryptoEvent.RehydrationStarted);
|
|
224
|
+
const rehydratedDevice = await this.olmMachine.dehydratedDevices().rehydrate(key, new RustSdkCryptoJs.DeviceId(dehydratedDeviceResp.device_id), JSON.stringify(dehydratedDeviceResp.device_data));
|
|
225
|
+
this.logger.info("dehydration: device rehydrated");
|
|
226
|
+
let nextBatch = undefined;
|
|
227
|
+
let toDeviceCount = 0;
|
|
228
|
+
let roomKeyCount = 0;
|
|
229
|
+
const path = encodeUri("/dehydrated_device/$device_id/events", {
|
|
230
|
+
$device_id: dehydratedDeviceResp.device_id
|
|
231
|
+
});
|
|
232
|
+
// eslint-disable-next-line no-constant-condition
|
|
233
|
+
while (true) {
|
|
234
|
+
const eventResp = await this.http.authedRequest(Method.Post, path, undefined, nextBatch ? {
|
|
235
|
+
next_batch: nextBatch
|
|
236
|
+
} : {}, {
|
|
237
|
+
prefix: UnstablePrefix
|
|
254
238
|
});
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
var eventResp = yield _this7.http.authedRequest(Method.Post, path, undefined, nextBatch ? {
|
|
258
|
-
next_batch: nextBatch
|
|
259
|
-
} : {}, {
|
|
260
|
-
prefix: UnstablePrefix
|
|
261
|
-
});
|
|
262
|
-
if (eventResp.events.length === 0) {
|
|
263
|
-
break;
|
|
264
|
-
}
|
|
265
|
-
toDeviceCount += eventResp.events.length;
|
|
266
|
-
nextBatch = eventResp.next_batch;
|
|
267
|
-
var roomKeyInfos = yield rehydratedDevice.receiveEvents(JSON.stringify(eventResp.events));
|
|
268
|
-
roomKeyCount += roomKeyInfos.length;
|
|
269
|
-
_this7.emit(CryptoEvent.RehydrationProgress, roomKeyCount, toDeviceCount);
|
|
239
|
+
if (eventResp.events.length === 0) {
|
|
240
|
+
break;
|
|
270
241
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
242
|
+
toDeviceCount += eventResp.events.length;
|
|
243
|
+
nextBatch = eventResp.next_batch;
|
|
244
|
+
const roomKeyInfos = await rehydratedDevice.receiveEvents(JSON.stringify(eventResp.events));
|
|
245
|
+
roomKeyCount += roomKeyInfos.length;
|
|
246
|
+
this.emit(CryptoEvent.RehydrationProgress, roomKeyCount, toDeviceCount);
|
|
247
|
+
}
|
|
248
|
+
this.logger.info(`dehydration: received ${roomKeyCount} room keys from ${toDeviceCount} to-device events`);
|
|
249
|
+
this.emit(CryptoEvent.RehydrationCompleted);
|
|
250
|
+
return true;
|
|
275
251
|
}
|
|
276
252
|
|
|
277
253
|
/**
|
|
@@ -279,35 +255,29 @@ export class DehydratedDeviceManager extends TypedEventEmitter {
|
|
|
279
255
|
*
|
|
280
256
|
* Creates and stores a new key in secret storage if none is available.
|
|
281
257
|
*/
|
|
282
|
-
createAndUploadDehydratedDevice() {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
_this8.emit(CryptoEvent.DehydratedDeviceUploaded);
|
|
291
|
-
_this8.logger.info("dehydration: uploaded device");
|
|
292
|
-
})();
|
|
258
|
+
async createAndUploadDehydratedDevice() {
|
|
259
|
+
const key = await this.getKey(true);
|
|
260
|
+
const dehydratedDevice = await this.olmMachine.dehydratedDevices().create();
|
|
261
|
+
this.emit(CryptoEvent.DehydratedDeviceCreated);
|
|
262
|
+
const request = await dehydratedDevice.keysForUpload("Dehydrated device", key);
|
|
263
|
+
await this.outgoingRequestProcessor.makeOutgoingRequest(request);
|
|
264
|
+
this.emit(CryptoEvent.DehydratedDeviceUploaded);
|
|
265
|
+
this.logger.info("dehydration: uploaded device");
|
|
293
266
|
}
|
|
294
267
|
|
|
295
268
|
/**
|
|
296
269
|
* Schedule periodic creation of dehydrated devices.
|
|
297
270
|
*/
|
|
298
|
-
scheduleDeviceDehydration() {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
});
|
|
309
|
-
}, DEHYDRATION_INTERVAL);
|
|
310
|
-
})();
|
|
271
|
+
async scheduleDeviceDehydration() {
|
|
272
|
+
// cancel any previously-scheduled tasks
|
|
273
|
+
this.stop();
|
|
274
|
+
await this.createAndUploadDehydratedDevice();
|
|
275
|
+
this.intervalId = setInterval(() => {
|
|
276
|
+
this.createAndUploadDehydratedDevice().catch(error => {
|
|
277
|
+
this.emit(CryptoEvent.DehydratedDeviceRotationError, error.message);
|
|
278
|
+
this.logger.error("Error creating dehydrated device:", error);
|
|
279
|
+
});
|
|
280
|
+
}, DEHYDRATION_INTERVAL);
|
|
311
281
|
}
|
|
312
282
|
|
|
313
283
|
/**
|
|
@@ -325,27 +295,24 @@ export class DehydratedDeviceManager extends TypedEventEmitter {
|
|
|
325
295
|
/**
|
|
326
296
|
* Delete the current dehydrated device and stop the dehydrated device manager.
|
|
327
297
|
*/
|
|
328
|
-
delete() {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
} else if (err.errcode === "M_NOT_FOUND") {
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
throw error;
|
|
298
|
+
async delete() {
|
|
299
|
+
this.stop();
|
|
300
|
+
try {
|
|
301
|
+
await this.http.authedRequest(Method.Delete, "/dehydrated_device", undefined, {}, {
|
|
302
|
+
prefix: UnstablePrefix
|
|
303
|
+
});
|
|
304
|
+
} catch (error) {
|
|
305
|
+
const err = error;
|
|
306
|
+
// If dehydrated devices aren't supported, or no dehydrated device
|
|
307
|
+
// is found, we don't consider it an error, because we we'll end up
|
|
308
|
+
// with no dehydrated device.
|
|
309
|
+
if (err.errcode === "M_UNRECOGNIZED") {
|
|
310
|
+
return;
|
|
311
|
+
} else if (err.errcode === "M_NOT_FOUND") {
|
|
312
|
+
return;
|
|
347
313
|
}
|
|
348
|
-
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
349
316
|
}
|
|
350
317
|
}
|
|
351
318
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DehydratedDeviceManager.js","names":["RustSdkCryptoJs","encodeUri","Method","decodeBase64","CryptoEvent","TypedEventEmitter","UnstablePrefix","SECRET_STORAGE_NAME","DEHYDRATION_INTERVAL","DehydratedDeviceManager","constructor","logger","olmMachine","http","outgoingRequestProcessor","secretStorage","_defineProperty","cacheKey","key","_this","_asyncToGenerator","dehydratedDevices","saveDehydratedDeviceKey","emit","DehydrationKeyCached","isSupported","_this2","authedRequest","Get","undefined","prefix","error","err","errcode","start","_arguments","arguments","_this3","opts","length","createNewKey","onlyIfKeyCached","getDehydratedDeviceKey","stop","rehydrate","rehydrateDeviceIfAvailable","e","info","RehydrationError","message","resetKey","scheduleDeviceDehydration","isKeyStored","_this4","Boolean","isStored","_this5","DehydratedDeviceKey","createRandomKey","store","toBase64","getKey","create","_this6","cachedKey","keyB64","get","bytes","createKeyFromArray","fill","_this7","dehydratedDeviceResp","RehydrationStarted","rehydratedDevice","DeviceId","device_id","JSON","stringify","device_data","nextBatch","toDeviceCount","roomKeyCount","path","$device_id","eventResp","Post","next_batch","events","roomKeyInfos","receiveEvents","RehydrationProgress","concat","RehydrationCompleted","createAndUploadDehydratedDevice","_this8","dehydratedDevice","DehydratedDeviceCreated","request","keysForUpload","makeOutgoingRequest","DehydratedDeviceUploaded","_this9","intervalId","setInterval","catch","DehydratedDeviceRotationError","clearInterval","delete","_this0","Delete"],"sources":["../../src/rust-crypto/DehydratedDeviceManager.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\nimport * as RustSdkCryptoJs from \"@matrix-org/matrix-sdk-crypto-wasm\";\n\nimport { type OutgoingRequestProcessor } from \"./OutgoingRequestProcessor.ts\";\nimport { encodeUri } from \"../utils.ts\";\nimport { type IHttpOpts, type MatrixError, type MatrixHttpApi, Method } from \"../http-api/index.ts\";\nimport { type IToDeviceEvent } from \"../sync-accumulator.ts\";\nimport { type ServerSideSecretStorage } from \"../secret-storage.ts\";\nimport { decodeBase64 } from \"../base64.ts\";\nimport { type Logger } from \"../logger.ts\";\nimport { CryptoEvent, type CryptoEventHandlerMap, type StartDehydrationOpts } from \"../crypto-api/index.ts\";\nimport { TypedEventEmitter } from \"../models/typed-event-emitter.ts\";\n\n/**\n * The response body of `GET /_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device`.\n */\ninterface DehydratedDeviceResp {\n device_id: string;\n device_data: {\n algorithm: string;\n };\n}\n/**\n * The response body of `POST /_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device/events`.\n */\ninterface DehydratedDeviceEventsResp {\n events: IToDeviceEvent[];\n next_batch: string;\n}\n\n/**\n * The unstable URL prefix for dehydrated device endpoints\n */\nexport const UnstablePrefix = \"/_matrix/client/unstable/org.matrix.msc3814.v1\";\n/**\n * The name used for the dehydration key in Secret Storage\n */\nconst SECRET_STORAGE_NAME = \"org.matrix.msc3814\";\n\n/**\n * The interval between creating dehydrated devices. (one week)\n */\nconst DEHYDRATION_INTERVAL = 7 * 24 * 60 * 60 * 1000;\n\n/**\n * Manages dehydrated devices\n *\n * We have one of these per `RustCrypto`. It's responsible for\n *\n * * determining server support for dehydrated devices\n * * creating new dehydrated devices when requested, including periodically\n * replacing the dehydrated device with a new one\n * * rehydrating a device when requested, and when present\n *\n * @internal\n */\nexport class DehydratedDeviceManager extends TypedEventEmitter<DehydratedDevicesEvents, DehydratedDevicesEventMap> {\n /** the ID of the interval for periodically replacing the dehydrated device */\n private intervalId?: ReturnType<typeof setInterval>;\n\n public constructor(\n private readonly logger: Logger,\n private readonly olmMachine: RustSdkCryptoJs.OlmMachine,\n private readonly http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,\n private readonly outgoingRequestProcessor: OutgoingRequestProcessor,\n private readonly secretStorage: ServerSideSecretStorage,\n ) {\n super();\n }\n\n private async cacheKey(key: RustSdkCryptoJs.DehydratedDeviceKey): Promise<void> {\n await this.olmMachine.dehydratedDevices().saveDehydratedDeviceKey(key);\n this.emit(CryptoEvent.DehydrationKeyCached);\n }\n\n /**\n * Return whether the server supports dehydrated devices.\n */\n public async isSupported(): Promise<boolean> {\n // call the endpoint to get a dehydrated device. If it returns an\n // M_UNRECOGNIZED error, then dehydration is unsupported. If it returns\n // a successful response, or an M_NOT_FOUND, then dehydration is supported.\n // Any other exceptions are passed through.\n try {\n await this.http.authedRequest<DehydratedDeviceResp>(\n Method.Get,\n \"/dehydrated_device\",\n undefined,\n undefined,\n {\n prefix: UnstablePrefix,\n },\n );\n } catch (error) {\n const err = error as MatrixError;\n if (err.errcode === \"M_UNRECOGNIZED\") {\n return false;\n } else if (err.errcode === \"M_NOT_FOUND\") {\n return true;\n }\n throw error;\n }\n return true;\n }\n\n /**\n * Start using device dehydration.\n *\n * - Rehydrates a dehydrated device, if one is available and `opts.rehydrate`\n * is `true`.\n * - Creates a new dehydration key, if necessary, and stores it in Secret\n * Storage.\n * - If `opts.createNewKey` is set to true, always creates a new key.\n * - If a dehydration key is not available, creates a new one.\n * - Creates a new dehydrated device, and schedules periodically creating\n * new dehydrated devices.\n *\n * @param opts - options for device dehydration. For backwards compatibility\n * with old code, a boolean can be given here, which will be treated as\n * the `createNewKey` option. However, this is deprecated.\n */\n public async start(opts: StartDehydrationOpts | boolean = {}): Promise<void> {\n if (typeof opts === \"boolean\") {\n opts = { createNewKey: opts };\n }\n\n if (opts.onlyIfKeyCached && !(await this.olmMachine.dehydratedDevices().getDehydratedDeviceKey())) {\n return;\n }\n this.stop();\n if (opts.rehydrate !== false) {\n try {\n await this.rehydrateDeviceIfAvailable();\n } catch (e) {\n // If rehydration fails, there isn't much we can do about it. Log\n // the error, and create a new device.\n this.logger.info(\"dehydration: Error rehydrating device:\", e);\n this.emit(CryptoEvent.RehydrationError, (e as Error).message);\n }\n }\n if (opts.createNewKey) {\n await this.resetKey();\n }\n await this.scheduleDeviceDehydration();\n }\n\n /**\n * Return whether the dehydration key is stored in Secret Storage.\n */\n public async isKeyStored(): Promise<boolean> {\n return Boolean(await this.secretStorage.isStored(SECRET_STORAGE_NAME));\n }\n\n /**\n * Reset the dehydration key.\n *\n * Creates a new key and stores it in secret storage.\n *\n * @returns The newly-generated key.\n */\n public async resetKey(): Promise<RustSdkCryptoJs.DehydratedDeviceKey> {\n const key = RustSdkCryptoJs.DehydratedDeviceKey.createRandomKey();\n await this.secretStorage.store(SECRET_STORAGE_NAME, key.toBase64());\n // Also cache it in the rust SDK's crypto store.\n await this.cacheKey(key);\n return key;\n }\n\n /**\n * Get and cache the encryption key from secret storage.\n *\n * If `create` is `true`, creates a new key if no existing key is present.\n *\n * @returns the key, if available, or `null` if no key is available\n */\n private async getKey(create: boolean): Promise<RustSdkCryptoJs.DehydratedDeviceKey | null> {\n const cachedKey = await this.olmMachine.dehydratedDevices().getDehydratedDeviceKey();\n if (cachedKey) return cachedKey;\n const keyB64 = await this.secretStorage.get(SECRET_STORAGE_NAME);\n if (keyB64 === undefined) {\n if (!create) {\n return null;\n }\n return await this.resetKey();\n }\n\n // We successfully found the key in secret storage: decode it, and cache it in\n // the rust SDK's crypto store.\n const bytes = decodeBase64(keyB64);\n try {\n const key = RustSdkCryptoJs.DehydratedDeviceKey.createKeyFromArray(bytes);\n await this.cacheKey(key);\n return key;\n } finally {\n bytes.fill(0);\n }\n }\n\n /**\n * Rehydrate the dehydrated device stored on the server.\n *\n * Checks if there is a dehydrated device on the server. If so, rehydrates\n * the device and processes the to-device events.\n *\n * Returns whether or not a dehydrated device was found.\n */\n public async rehydrateDeviceIfAvailable(): Promise<boolean> {\n const key = await this.getKey(false);\n if (!key) {\n return false;\n }\n\n let dehydratedDeviceResp;\n try {\n dehydratedDeviceResp = await this.http.authedRequest<DehydratedDeviceResp>(\n Method.Get,\n \"/dehydrated_device\",\n undefined,\n undefined,\n {\n prefix: UnstablePrefix,\n },\n );\n } catch (error) {\n const err = error as MatrixError;\n // We ignore M_NOT_FOUND (there is no dehydrated device, so nothing\n // us to do) and M_UNRECOGNIZED (the server does not understand the\n // endpoint). We pass through any other errors.\n if (err.errcode === \"M_NOT_FOUND\" || err.errcode === \"M_UNRECOGNIZED\") {\n this.logger.info(\"dehydration: No dehydrated device\");\n return false;\n }\n throw err;\n }\n\n this.logger.info(\"dehydration: dehydrated device found\");\n this.emit(CryptoEvent.RehydrationStarted);\n\n const rehydratedDevice = await this.olmMachine\n .dehydratedDevices()\n .rehydrate(\n key,\n new RustSdkCryptoJs.DeviceId(dehydratedDeviceResp.device_id),\n JSON.stringify(dehydratedDeviceResp.device_data),\n );\n\n this.logger.info(\"dehydration: device rehydrated\");\n\n let nextBatch: string | undefined = undefined;\n let toDeviceCount = 0;\n let roomKeyCount = 0;\n const path = encodeUri(\"/dehydrated_device/$device_id/events\", {\n $device_id: dehydratedDeviceResp.device_id,\n });\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const eventResp: DehydratedDeviceEventsResp = await this.http.authedRequest<DehydratedDeviceEventsResp>(\n Method.Post,\n path,\n undefined,\n nextBatch ? { next_batch: nextBatch } : {},\n {\n prefix: UnstablePrefix,\n },\n );\n\n if (eventResp.events.length === 0) {\n break;\n }\n toDeviceCount += eventResp.events.length;\n nextBatch = eventResp.next_batch;\n const roomKeyInfos = await rehydratedDevice.receiveEvents(JSON.stringify(eventResp.events));\n roomKeyCount += roomKeyInfos.length;\n\n this.emit(CryptoEvent.RehydrationProgress, roomKeyCount, toDeviceCount);\n }\n this.logger.info(`dehydration: received ${roomKeyCount} room keys from ${toDeviceCount} to-device events`);\n this.emit(CryptoEvent.RehydrationCompleted);\n\n return true;\n }\n\n /**\n * Creates and uploads a new dehydrated device.\n *\n * Creates and stores a new key in secret storage if none is available.\n */\n public async createAndUploadDehydratedDevice(): Promise<void> {\n const key = (await this.getKey(true))!;\n\n const dehydratedDevice = await this.olmMachine.dehydratedDevices().create();\n this.emit(CryptoEvent.DehydratedDeviceCreated);\n const request = await dehydratedDevice.keysForUpload(\"Dehydrated device\", key);\n\n await this.outgoingRequestProcessor.makeOutgoingRequest(request);\n this.emit(CryptoEvent.DehydratedDeviceUploaded);\n\n this.logger.info(\"dehydration: uploaded device\");\n }\n\n /**\n * Schedule periodic creation of dehydrated devices.\n */\n public async scheduleDeviceDehydration(): Promise<void> {\n // cancel any previously-scheduled tasks\n this.stop();\n\n await this.createAndUploadDehydratedDevice();\n this.intervalId = setInterval(() => {\n this.createAndUploadDehydratedDevice().catch((error) => {\n this.emit(CryptoEvent.DehydratedDeviceRotationError, error.message);\n this.logger.error(\"Error creating dehydrated device:\", error);\n });\n }, DEHYDRATION_INTERVAL);\n }\n\n /**\n * Stop the dehydrated device manager.\n *\n * Cancels any scheduled dehydration tasks.\n */\n public stop(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = undefined;\n }\n }\n\n /**\n * Delete the current dehydrated device and stop the dehydrated device manager.\n */\n public async delete(): Promise<void> {\n this.stop();\n try {\n await this.http.authedRequest(\n Method.Delete,\n \"/dehydrated_device\",\n undefined,\n {},\n {\n prefix: UnstablePrefix,\n },\n );\n } catch (error) {\n const err = error as MatrixError;\n // If dehydrated devices aren't supported, or no dehydrated device\n // is found, we don't consider it an error, because we we'll end up\n // with no dehydrated device.\n if (err.errcode === \"M_UNRECOGNIZED\") {\n return;\n } else if (err.errcode === \"M_NOT_FOUND\") {\n return;\n }\n throw error;\n }\n }\n}\n\n/**\n * The events fired by the DehydratedDeviceManager\n * @internal\n */\ntype DehydratedDevicesEvents =\n | CryptoEvent.DehydratedDeviceCreated\n | CryptoEvent.DehydratedDeviceUploaded\n | CryptoEvent.RehydrationStarted\n | CryptoEvent.RehydrationProgress\n | CryptoEvent.RehydrationCompleted\n | CryptoEvent.RehydrationError\n | CryptoEvent.DehydrationKeyCached\n | CryptoEvent.DehydratedDeviceRotationError;\n\n/**\n * A map of the {@link DehydratedDeviceEvents} fired by the {@link DehydratedDeviceManager} and their payloads.\n * @internal\n */\ntype DehydratedDevicesEventMap = Pick<CryptoEventHandlerMap, DehydratedDevicesEvents>;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"DehydratedDeviceManager.js","names":[],"sources":["../../src/rust-crypto/DehydratedDeviceManager.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\nimport * as RustSdkCryptoJs from \"@matrix-org/matrix-sdk-crypto-wasm\";\n\nimport { type OutgoingRequestProcessor } from \"./OutgoingRequestProcessor.ts\";\nimport { encodeUri } from \"../utils.ts\";\nimport { type IHttpOpts, type MatrixError, type MatrixHttpApi, Method } from \"../http-api/index.ts\";\nimport { type IToDeviceEvent } from \"../sync-accumulator.ts\";\nimport { type ServerSideSecretStorage } from \"../secret-storage.ts\";\nimport { decodeBase64 } from \"../base64.ts\";\nimport { type Logger } from \"../logger.ts\";\nimport { CryptoEvent, type CryptoEventHandlerMap, type StartDehydrationOpts } from \"../crypto-api/index.ts\";\nimport { TypedEventEmitter } from \"../models/typed-event-emitter.ts\";\n\n/**\n * The response body of `GET /_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device`.\n */\ninterface DehydratedDeviceResp {\n device_id: string;\n device_data: {\n algorithm: string;\n };\n}\n/**\n * The response body of `POST /_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device/events`.\n */\ninterface DehydratedDeviceEventsResp {\n events: IToDeviceEvent[];\n next_batch: string;\n}\n\n/**\n * The unstable URL prefix for dehydrated device endpoints\n */\nexport const UnstablePrefix = \"/_matrix/client/unstable/org.matrix.msc3814.v1\";\n/**\n * The name used for the dehydration key in Secret Storage\n */\nconst SECRET_STORAGE_NAME = \"org.matrix.msc3814\";\n\n/**\n * The interval between creating dehydrated devices. (one week)\n */\nconst DEHYDRATION_INTERVAL = 7 * 24 * 60 * 60 * 1000;\n\n/**\n * Manages dehydrated devices\n *\n * We have one of these per `RustCrypto`. It's responsible for\n *\n * * determining server support for dehydrated devices\n * * creating new dehydrated devices when requested, including periodically\n * replacing the dehydrated device with a new one\n * * rehydrating a device when requested, and when present\n *\n * @internal\n */\nexport class DehydratedDeviceManager extends TypedEventEmitter<DehydratedDevicesEvents, DehydratedDevicesEventMap> {\n /** the ID of the interval for periodically replacing the dehydrated device */\n private intervalId?: ReturnType<typeof setInterval>;\n\n public constructor(\n private readonly logger: Logger,\n private readonly olmMachine: RustSdkCryptoJs.OlmMachine,\n private readonly http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,\n private readonly outgoingRequestProcessor: OutgoingRequestProcessor,\n private readonly secretStorage: ServerSideSecretStorage,\n ) {\n super();\n }\n\n private async cacheKey(key: RustSdkCryptoJs.DehydratedDeviceKey): Promise<void> {\n await this.olmMachine.dehydratedDevices().saveDehydratedDeviceKey(key);\n this.emit(CryptoEvent.DehydrationKeyCached);\n }\n\n /**\n * Return whether the server supports dehydrated devices.\n */\n public async isSupported(): Promise<boolean> {\n // call the endpoint to get a dehydrated device. If it returns an\n // M_UNRECOGNIZED error, then dehydration is unsupported. If it returns\n // a successful response, or an M_NOT_FOUND, then dehydration is supported.\n // Any other exceptions are passed through.\n try {\n await this.http.authedRequest<DehydratedDeviceResp>(\n Method.Get,\n \"/dehydrated_device\",\n undefined,\n undefined,\n {\n prefix: UnstablePrefix,\n },\n );\n } catch (error) {\n const err = error as MatrixError;\n if (err.errcode === \"M_UNRECOGNIZED\") {\n return false;\n } else if (err.errcode === \"M_NOT_FOUND\") {\n return true;\n }\n throw error;\n }\n return true;\n }\n\n /**\n * Start using device dehydration.\n *\n * - Rehydrates a dehydrated device, if one is available and `opts.rehydrate`\n * is `true`.\n * - Creates a new dehydration key, if necessary, and stores it in Secret\n * Storage.\n * - If `opts.createNewKey` is set to true, always creates a new key.\n * - If a dehydration key is not available, creates a new one.\n * - Creates a new dehydrated device, and schedules periodically creating\n * new dehydrated devices.\n *\n * @param opts - options for device dehydration. For backwards compatibility\n * with old code, a boolean can be given here, which will be treated as\n * the `createNewKey` option. However, this is deprecated.\n */\n public async start(opts: StartDehydrationOpts | boolean = {}): Promise<void> {\n if (typeof opts === \"boolean\") {\n opts = { createNewKey: opts };\n }\n\n if (opts.onlyIfKeyCached && !(await this.olmMachine.dehydratedDevices().getDehydratedDeviceKey())) {\n return;\n }\n this.stop();\n if (opts.rehydrate !== false) {\n try {\n await this.rehydrateDeviceIfAvailable();\n } catch (e) {\n // If rehydration fails, there isn't much we can do about it. Log\n // the error, and create a new device.\n this.logger.info(\"dehydration: Error rehydrating device:\", e);\n this.emit(CryptoEvent.RehydrationError, (e as Error).message);\n }\n }\n if (opts.createNewKey) {\n await this.resetKey();\n }\n await this.scheduleDeviceDehydration();\n }\n\n /**\n * Return whether the dehydration key is stored in Secret Storage.\n */\n public async isKeyStored(): Promise<boolean> {\n return Boolean(await this.secretStorage.isStored(SECRET_STORAGE_NAME));\n }\n\n /**\n * Reset the dehydration key.\n *\n * Creates a new key and stores it in secret storage.\n *\n * @returns The newly-generated key.\n */\n public async resetKey(): Promise<RustSdkCryptoJs.DehydratedDeviceKey> {\n const key = RustSdkCryptoJs.DehydratedDeviceKey.createRandomKey();\n await this.secretStorage.store(SECRET_STORAGE_NAME, key.toBase64());\n // Also cache it in the rust SDK's crypto store.\n await this.cacheKey(key);\n return key;\n }\n\n /**\n * Get and cache the encryption key from secret storage.\n *\n * If `create` is `true`, creates a new key if no existing key is present.\n *\n * @returns the key, if available, or `null` if no key is available\n */\n private async getKey(create: boolean): Promise<RustSdkCryptoJs.DehydratedDeviceKey | null> {\n const cachedKey = await this.olmMachine.dehydratedDevices().getDehydratedDeviceKey();\n if (cachedKey) return cachedKey;\n const keyB64 = await this.secretStorage.get(SECRET_STORAGE_NAME);\n if (keyB64 === undefined) {\n if (!create) {\n return null;\n }\n return await this.resetKey();\n }\n\n // We successfully found the key in secret storage: decode it, and cache it in\n // the rust SDK's crypto store.\n const bytes = decodeBase64(keyB64);\n try {\n const key = RustSdkCryptoJs.DehydratedDeviceKey.createKeyFromArray(bytes);\n await this.cacheKey(key);\n return key;\n } finally {\n bytes.fill(0);\n }\n }\n\n /**\n * Rehydrate the dehydrated device stored on the server.\n *\n * Checks if there is a dehydrated device on the server. If so, rehydrates\n * the device and processes the to-device events.\n *\n * Returns whether or not a dehydrated device was found.\n */\n public async rehydrateDeviceIfAvailable(): Promise<boolean> {\n const key = await this.getKey(false);\n if (!key) {\n return false;\n }\n\n let dehydratedDeviceResp;\n try {\n dehydratedDeviceResp = await this.http.authedRequest<DehydratedDeviceResp>(\n Method.Get,\n \"/dehydrated_device\",\n undefined,\n undefined,\n {\n prefix: UnstablePrefix,\n },\n );\n } catch (error) {\n const err = error as MatrixError;\n // We ignore M_NOT_FOUND (there is no dehydrated device, so nothing\n // us to do) and M_UNRECOGNIZED (the server does not understand the\n // endpoint). We pass through any other errors.\n if (err.errcode === \"M_NOT_FOUND\" || err.errcode === \"M_UNRECOGNIZED\") {\n this.logger.info(\"dehydration: No dehydrated device\");\n return false;\n }\n throw err;\n }\n\n this.logger.info(\"dehydration: dehydrated device found\");\n this.emit(CryptoEvent.RehydrationStarted);\n\n const rehydratedDevice = await this.olmMachine\n .dehydratedDevices()\n .rehydrate(\n key,\n new RustSdkCryptoJs.DeviceId(dehydratedDeviceResp.device_id),\n JSON.stringify(dehydratedDeviceResp.device_data),\n );\n\n this.logger.info(\"dehydration: device rehydrated\");\n\n let nextBatch: string | undefined = undefined;\n let toDeviceCount = 0;\n let roomKeyCount = 0;\n const path = encodeUri(\"/dehydrated_device/$device_id/events\", {\n $device_id: dehydratedDeviceResp.device_id,\n });\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const eventResp: DehydratedDeviceEventsResp = await this.http.authedRequest<DehydratedDeviceEventsResp>(\n Method.Post,\n path,\n undefined,\n nextBatch ? { next_batch: nextBatch } : {},\n {\n prefix: UnstablePrefix,\n },\n );\n\n if (eventResp.events.length === 0) {\n break;\n }\n toDeviceCount += eventResp.events.length;\n nextBatch = eventResp.next_batch;\n const roomKeyInfos = await rehydratedDevice.receiveEvents(JSON.stringify(eventResp.events));\n roomKeyCount += roomKeyInfos.length;\n\n this.emit(CryptoEvent.RehydrationProgress, roomKeyCount, toDeviceCount);\n }\n this.logger.info(`dehydration: received ${roomKeyCount} room keys from ${toDeviceCount} to-device events`);\n this.emit(CryptoEvent.RehydrationCompleted);\n\n return true;\n }\n\n /**\n * Creates and uploads a new dehydrated device.\n *\n * Creates and stores a new key in secret storage if none is available.\n */\n public async createAndUploadDehydratedDevice(): Promise<void> {\n const key = (await this.getKey(true))!;\n\n const dehydratedDevice = await this.olmMachine.dehydratedDevices().create();\n this.emit(CryptoEvent.DehydratedDeviceCreated);\n const request = await dehydratedDevice.keysForUpload(\"Dehydrated device\", key);\n\n await this.outgoingRequestProcessor.makeOutgoingRequest(request);\n this.emit(CryptoEvent.DehydratedDeviceUploaded);\n\n this.logger.info(\"dehydration: uploaded device\");\n }\n\n /**\n * Schedule periodic creation of dehydrated devices.\n */\n public async scheduleDeviceDehydration(): Promise<void> {\n // cancel any previously-scheduled tasks\n this.stop();\n\n await this.createAndUploadDehydratedDevice();\n this.intervalId = setInterval(() => {\n this.createAndUploadDehydratedDevice().catch((error) => {\n this.emit(CryptoEvent.DehydratedDeviceRotationError, error.message);\n this.logger.error(\"Error creating dehydrated device:\", error);\n });\n }, DEHYDRATION_INTERVAL);\n }\n\n /**\n * Stop the dehydrated device manager.\n *\n * Cancels any scheduled dehydration tasks.\n */\n public stop(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = undefined;\n }\n }\n\n /**\n * Delete the current dehydrated device and stop the dehydrated device manager.\n */\n public async delete(): Promise<void> {\n this.stop();\n try {\n await this.http.authedRequest(\n Method.Delete,\n \"/dehydrated_device\",\n undefined,\n {},\n {\n prefix: UnstablePrefix,\n },\n );\n } catch (error) {\n const err = error as MatrixError;\n // If dehydrated devices aren't supported, or no dehydrated device\n // is found, we don't consider it an error, because we we'll end up\n // with no dehydrated device.\n if (err.errcode === \"M_UNRECOGNIZED\") {\n return;\n } else if (err.errcode === \"M_NOT_FOUND\") {\n return;\n }\n throw error;\n }\n }\n}\n\n/**\n * The events fired by the DehydratedDeviceManager\n * @internal\n */\ntype DehydratedDevicesEvents =\n | CryptoEvent.DehydratedDeviceCreated\n | CryptoEvent.DehydratedDeviceUploaded\n | CryptoEvent.RehydrationStarted\n | CryptoEvent.RehydrationProgress\n | CryptoEvent.RehydrationCompleted\n | CryptoEvent.RehydrationError\n | CryptoEvent.DehydrationKeyCached\n | CryptoEvent.DehydratedDeviceRotationError;\n\n/**\n * A map of the {@link DehydratedDeviceEvents} fired by the {@link DehydratedDeviceManager} and their payloads.\n * @internal\n */\ntype DehydratedDevicesEventMap = Pick<CryptoEventHandlerMap, DehydratedDevicesEvents>;\n"],"mappings":"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","ignoreList":[]}
|