matrix-js-sdk 41.5.0 → 41.6.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 +7 -0
- package/lib/ReEmitter.js +1 -1
- package/lib/ReEmitter.js.map +1 -1
- package/lib/ToDeviceMessageQueue.js +2 -2
- package/lib/ToDeviceMessageQueue.js.map +1 -1
- package/lib/autodiscovery.js +0 -1
- package/lib/autodiscovery.js.map +1 -1
- package/lib/client.js +112 -165
- package/lib/client.js.map +1 -1
- package/lib/common-crypto/CryptoBackend.js +0 -2
- package/lib/common-crypto/CryptoBackend.js.map +1 -1
- package/lib/content-helpers.js +3 -5
- package/lib/content-helpers.js.map +1 -1
- package/lib/content-repo.js +7 -1
- package/lib/content-repo.js.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store-backend.js +9 -11
- package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store.js +0 -2
- package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -1
- package/lib/crypto/store/localStorage-crypto-store.js +11 -9
- package/lib/crypto/store/localStorage-crypto-store.js.map +1 -1
- package/lib/crypto/store/memory-crypto-store.js +11 -9
- package/lib/crypto/store/memory-crypto-store.js.map +1 -1
- package/lib/crypto-api/index.js +58 -58
- package/lib/crypto-api/index.js.map +1 -1
- package/lib/embedded.js +29 -45
- package/lib/embedded.js.map +1 -1
- package/lib/extensible_events_v1/MessageEvent.js +15 -15
- package/lib/extensible_events_v1/MessageEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollEndEvent.js +8 -8
- package/lib/extensible_events_v1/PollEndEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollResponseEvent.js +0 -1
- package/lib/extensible_events_v1/PollResponseEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollStartEvent.js +28 -28
- package/lib/extensible_events_v1/PollStartEvent.js.map +1 -1
- package/lib/feature.js +5 -1
- package/lib/feature.js.map +1 -1
- package/lib/filter-component.js +4 -1
- package/lib/filter-component.js.map +1 -1
- package/lib/filter.js +1 -3
- package/lib/filter.js.map +1 -1
- package/lib/http-api/errors.js +20 -16
- package/lib/http-api/errors.js.map +1 -1
- package/lib/http-api/fetch.js +4 -6
- package/lib/http-api/fetch.js.map +1 -1
- package/lib/http-api/refresh.js +10 -12
- package/lib/http-api/refresh.js.map +1 -1
- package/lib/interactive-auth.js +1 -11
- package/lib/interactive-auth.js.map +1 -1
- package/lib/logger.js +0 -2
- package/lib/logger.js.map +1 -1
- package/lib/matrixrtc/CallMembership.js +43 -57
- package/lib/matrixrtc/CallMembership.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSession.js +19 -24
- package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSessionManager.js +2 -3
- package/lib/matrixrtc/MatrixRTCSessionManager.js.map +1 -1
- package/lib/matrixrtc/MembershipManager.js +23 -30
- package/lib/matrixrtc/MembershipManager.js.map +1 -1
- package/lib/matrixrtc/MembershipManagerActionScheduler.js +1 -2
- package/lib/matrixrtc/MembershipManagerActionScheduler.js.map +1 -1
- package/lib/matrixrtc/RTCEncryptionManager.js +8 -11
- package/lib/matrixrtc/RTCEncryptionManager.js.map +1 -1
- package/lib/matrixrtc/ToDeviceKeyTransport.js +4 -4
- package/lib/matrixrtc/ToDeviceKeyTransport.js.map +1 -1
- package/lib/matrixrtc/utils.js +7 -1
- package/lib/matrixrtc/utils.js.map +1 -1
- package/lib/models/MSC3089TreeSpace.js +5 -7
- package/lib/models/MSC3089TreeSpace.js.map +1 -1
- package/lib/models/beacon.js +5 -11
- package/lib/models/beacon.js.map +1 -1
- package/lib/models/device.js +0 -7
- package/lib/models/device.js.map +1 -1
- package/lib/models/event-context.js +1 -2
- package/lib/models/event-context.js.map +1 -1
- package/lib/models/event-timeline-set.js +16 -26
- package/lib/models/event-timeline-set.js.map +1 -1
- package/lib/models/event-timeline.js +8 -15
- package/lib/models/event-timeline.js.map +1 -1
- package/lib/models/event.js +20 -37
- package/lib/models/event.js.map +1 -1
- package/lib/models/invites-ignorer.js +8 -12
- package/lib/models/invites-ignorer.js.map +1 -1
- package/lib/models/poll.js +7 -13
- package/lib/models/poll.js.map +1 -1
- package/lib/models/read-receipt.js +8 -4
- package/lib/models/read-receipt.js.map +1 -1
- package/lib/models/related-relations.js +0 -2
- package/lib/models/related-relations.js.map +1 -1
- package/lib/models/relations-container.js +4 -6
- package/lib/models/relations-container.js.map +1 -1
- package/lib/models/relations.js +7 -10
- package/lib/models/relations.js.map +1 -1
- package/lib/models/room-member.js +2 -24
- package/lib/models/room-member.js.map +1 -1
- package/lib/models/room-receipts.js +25 -22
- package/lib/models/room-receipts.js.map +1 -1
- package/lib/models/room-state.js +2 -2
- package/lib/models/room-state.js.map +1 -1
- package/lib/models/room-sticky-events.js +20 -5
- package/lib/models/room-sticky-events.js.map +1 -1
- package/lib/models/room.js +82 -105
- package/lib/models/room.js.map +1 -1
- package/lib/models/thread.js +12 -57
- package/lib/models/thread.js.map +1 -1
- package/lib/models/user.js +1 -20
- package/lib/models/user.js.map +1 -1
- package/lib/oidc/authorize.js +23 -32
- package/lib/oidc/authorize.js.map +1 -1
- package/lib/oidc/tokenRefresher.js +8 -11
- package/lib/oidc/tokenRefresher.js.map +1 -1
- package/lib/pushprocessor.js +8 -5
- package/lib/pushprocessor.js.map +1 -1
- package/lib/receipt-accumulator.js +12 -3
- package/lib/receipt-accumulator.js.map +1 -1
- package/lib/rendezvous/MSC4108SignInWithQR.d.ts.map +1 -1
- package/lib/rendezvous/MSC4108SignInWithQR.js +10 -23
- package/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -1
- package/lib/rendezvous/channels/MSC4108SecureChannel.js +5 -10
- package/lib/rendezvous/channels/MSC4108SecureChannel.js.map +1 -1
- package/lib/rendezvous/transports/MSC4108RendezvousSession.js +5 -15
- package/lib/rendezvous/transports/MSC4108RendezvousSession.js.map +1 -1
- package/lib/room-hierarchy.js +7 -12
- package/lib/room-hierarchy.js.map +1 -1
- package/lib/rust-crypto/DehydratedDeviceManager.js +2 -3
- package/lib/rust-crypto/DehydratedDeviceManager.js.map +1 -1
- package/lib/rust-crypto/KeyClaimManager.js +1 -2
- package/lib/rust-crypto/KeyClaimManager.js.map +1 -1
- package/lib/rust-crypto/OutgoingRequestProcessor.js +11 -4
- package/lib/rust-crypto/OutgoingRequestProcessor.js.map +1 -1
- package/lib/rust-crypto/OutgoingRequestsManager.js +12 -12
- package/lib/rust-crypto/OutgoingRequestsManager.js.map +1 -1
- package/lib/rust-crypto/PerSessionKeyBackupDownloader.js +3 -5
- package/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +1 -1
- package/lib/rust-crypto/RoomEncryptor.js +6 -6
- package/lib/rust-crypto/RoomEncryptor.js.map +1 -1
- package/lib/rust-crypto/backup.js +22 -16
- package/lib/rust-crypto/backup.js.map +1 -1
- package/lib/rust-crypto/device-converter.js +13 -4
- package/lib/rust-crypto/device-converter.js.map +1 -1
- package/lib/rust-crypto/index.js +1 -3
- package/lib/rust-crypto/index.js.map +1 -1
- package/lib/rust-crypto/libolm_migration.js +13 -15
- package/lib/rust-crypto/libolm_migration.js.map +1 -1
- package/lib/rust-crypto/rust-crypto.js +52 -59
- package/lib/rust-crypto/rust-crypto.js.map +1 -1
- package/lib/rust-crypto/verification.js +10 -10
- package/lib/rust-crypto/verification.js.map +1 -1
- package/lib/scheduler.js +2 -2
- package/lib/scheduler.js.map +1 -1
- package/lib/secret-storage.js +16 -10
- package/lib/secret-storage.js.map +1 -1
- package/lib/serverCapabilities.js +2 -5
- package/lib/serverCapabilities.js.map +1 -1
- package/lib/sliding-sync-sdk.js +4 -9
- package/lib/sliding-sync-sdk.js.map +1 -1
- package/lib/sliding-sync.js +4 -9
- package/lib/sliding-sync.js.map +1 -1
- package/lib/store/indexeddb-local-backend.js +13 -8
- package/lib/store/indexeddb-local-backend.js.map +1 -1
- package/lib/store/indexeddb-remote-backend.js +6 -7
- package/lib/store/indexeddb-remote-backend.js.map +1 -1
- package/lib/store/indexeddb-store-worker.js +1 -2
- package/lib/store/indexeddb-store-worker.js.map +1 -1
- package/lib/store/indexeddb.js +4 -2
- package/lib/store/indexeddb.js.map +1 -1
- package/lib/store/memory.js +0 -4
- package/lib/store/memory.js.map +1 -1
- package/lib/sync-accumulator.js +2 -4
- package/lib/sync-accumulator.js.map +1 -1
- package/lib/sync.js +36 -43
- package/lib/sync.js.map +1 -1
- package/lib/timeline-window.js +2 -6
- package/lib/timeline-window.js.map +1 -1
- package/lib/utils/decryptAESSecretStorageItem.js +5 -1
- package/lib/utils/decryptAESSecretStorageItem.js.map +1 -1
- package/lib/utils/encryptAESSecretStorageItem.js +5 -1
- package/lib/utils/encryptAESSecretStorageItem.js.map +1 -1
- package/lib/utils.js +35 -20
- package/lib/utils.js.map +1 -1
- package/lib/webrtc/call.js +13 -45
- package/lib/webrtc/call.js.map +1 -1
- package/lib/webrtc/callEventHandler.js +0 -5
- package/lib/webrtc/callEventHandler.js.map +1 -1
- package/lib/webrtc/callFeed.js +0 -15
- package/lib/webrtc/callFeed.js.map +1 -1
- package/lib/webrtc/groupCall.js +82 -89
- package/lib/webrtc/groupCall.js.map +1 -1
- package/lib/webrtc/groupCallEventHandler.js +6 -7
- package/lib/webrtc/groupCallEventHandler.js.map +1 -1
- package/lib/webrtc/mediaHandler.js +8 -15
- package/lib/webrtc/mediaHandler.js.map +1 -1
- package/lib/webrtc/stats/callStatsReportGatherer.js +2 -5
- package/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -1
- package/lib/webrtc/stats/connectionStatsReportBuilder.js +5 -1
- package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +1 -1
- package/lib/webrtc/stats/groupCallStats.js +3 -4
- package/lib/webrtc/stats/groupCallStats.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 +1 -1
- package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +1 -1
- package/package.json +3 -3
- package/src/rendezvous/MSC4108SignInWithQR.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libolm_migration.js","names":["RustSdkCryptoJs","MigrationState","IndexedDBCryptoStore","requestKeyBackupVersion","sleep","encodeBase64","decryptAESSecretStorageItem","migrateFromLegacyCrypto","_x","_migrateFromLegacyCrypto","apply","arguments","_asyncToGenerator","args","_args$legacyMigration2","logger","legacyStore","initAsync","containsData","startup","accountPickle","doTxn","STORE_ACCOUNT","txn","getAccount","acctPickle","debug","migrationState","getMigrationState","MEGOLM_SESSIONS_MIGRATED","nOlmSessions","countOlmSessions","nMegolmSessions","countMegolmSessions","totalSteps","info","concat","stepsDone","onProgress","steps","_args$legacyMigration","legacyMigrationProgressListener","call","pickleKey","TextEncoder","encode","legacyPickleKey","slice","NOT_STARTED","migrateBaseData","http","userId","deviceId","storeHandle","INITIAL_DATA_MIGRATED","setMigrationState","migrateOlmSessions","OLM_SESSIONS_MIGRATED","migrateMegolmSessions","_x2","_x3","_x4","_x5","_x6","_x7","_x8","_migrateBaseData","migrationData","BaseMigrationData","UserId","DeviceId","a","pickledAccount","recoveryKey","getAndDecryptCachedSecretKey","backupCallDone","backupInfo","e","algorithm","_backupInfo$auth_data","decryptionKey","BackupDecryptionKey","fromBase64","publicKey","auth_data","public_key","isValid","megolmV1PublicKey","publicKeyBase64","backupVersion","version","backupRecoveryKey","warn","privateCrossSigningMasterKey","privateCrossSigningSelfSigningKey","privateCrossSigningUserSigningKey","Migration","_x9","_x0","_countOlmSessions","nSessions","STORE_SESSIONS","countEndToEndSessions","n","_x1","_x10","_countMegolmSessions","countEndToEndInboundGroupSessions","_x11","_x12","_x13","_x14","_x15","_migrateOlmSessions","onBatchDone","batch","getEndToEndSessionsBatch","length","session","pickledSession","PickledSession","senderKey","deviceKey","pickle","lastUseTime","creationTime","Date","lastReceivedMessageTs","push","deleteEndToEndSessionsBatch","_x16","_x17","_x18","_x19","_x20","_migrateMegolmSessions","getEndToEndInboundGroupSessionsBatch","_sessionData$keysClai","sessionData","PickledInboundGroupSession","roomId","RoomId","room_id","senderSigningKey","keysClaimed","backedUp","needsBackup","imported","untrusted","deleteEndToEndInboundGroupSessionsBatch","migrateRoomSettingsFromLegacyCrypto","_x21","_migrateRoomSettingsFromLegacyCrypto","_ref","olmMachine","ROOM_SETTINGS_MIGRATED","rooms","STORE_ROOMS","getEndToEndRooms","result","Object","keys","legacySettings","entries","rustSettings","RoomSettings","EncryptionAlgorithm","MegolmV1AesSha2","sessionRotationPeriodMs","rotation_period_ms","sessionRotationPeriodMessages","rotation_period_msgs","setRoomSettings","JSON","stringify","_x22","_x23","_x24","_getAndDecryptCachedSecretKey","name","key","Promise","resolve","getSecretStorePrivateKey","ciphertext","iv","mac","Uint8Array","undefined","migrateLegacyLocalTrustIfNeeded","_x25","_migrateLegacyLocalTrustIfNeeded","legacyCryptoStore","rustCrypto","rustOwnIdentity","getOwnIdentity","isVerified","legacyLocallyTrustedMSK","getLegacyTrustedPublicMasterKeyBase64","mskInfo","parse","masterKey","error","rustSeenMSK","values","verify","_x26","_getLegacyTrustedPublicMasterKeyBase","maybeTrustedKeys","getCrossSigningKeys","msk","master"],"sources":["../../src/rust-crypto/libolm_migration.ts"],"sourcesContent":["/*\nCopyright 2023-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 Logger } from \"../logger.ts\";\nimport { type CryptoStore, MigrationState, type SecretStorePrivateKeys } from \"../crypto/store/base.ts\";\nimport { IndexedDBCryptoStore } from \"../crypto/store/indexeddb-crypto-store.ts\";\nimport { type IHttpOpts, type MatrixHttpApi } from \"../http-api/index.ts\";\nimport { requestKeyBackupVersion } from \"./backup.ts\";\nimport { type CrossSigningKeyInfo, type Curve25519AuthData } from \"../crypto-api/index.ts\";\nimport { type RustCrypto } from \"./rust-crypto.ts\";\nimport { type KeyBackupInfo } from \"../crypto-api/keybackup.ts\";\nimport { sleep } from \"../utils.ts\";\nimport { encodeBase64 } from \"../base64.ts\";\nimport decryptAESSecretStorageItem from \"../utils/decryptAESSecretStorageItem.ts\";\nimport { type AESEncryptedSecretStoragePayload } from \"../@types/AESEncryptedSecretStoragePayload.ts\";\n\ninterface LegacyRoomEncryption {\n algorithm: string;\n rotation_period_ms?: number;\n rotation_period_msgs?: number;\n}\n\n/**\n * Determine if any data needs migrating from the legacy store, and do so.\n *\n * This migrates the base account data, and olm and megolm sessions. It does *not* migrate the room list, which should\n * happen after an `OlmMachine` is created, via {@link migrateRoomSettingsFromLegacyCrypto}.\n *\n * @param args - Arguments object.\n */\nexport async function migrateFromLegacyCrypto(args: {\n /** A `Logger` instance that will be used for debug output. */\n logger: Logger;\n\n /**\n * Low-level HTTP interface: used to make outgoing requests required by the rust SDK.\n * We expect it to set the access token, etc.\n */\n http: MatrixHttpApi<IHttpOpts & { onlyData: true }>;\n\n /** Store to migrate data from. */\n legacyStore: CryptoStore;\n\n /** Pickle key for `legacyStore`. */\n legacyPickleKey?: string;\n\n /** Local user's User ID. */\n userId: string;\n\n /** Local user's Device ID. */\n deviceId: string;\n\n /** Rust crypto store to migrate data into. */\n storeHandle: RustSdkCryptoJs.StoreHandle;\n\n /**\n * A callback which will receive progress updates on migration from `legacyStore`.\n *\n * Called with (-1, -1) to mark the end of migration.\n */\n legacyMigrationProgressListener?: (progress: number, total: number) => void;\n}): Promise<void> {\n const { logger, legacyStore } = args;\n\n // initialise the rust matrix-sdk-crypto-wasm, if it hasn't already been done\n await RustSdkCryptoJs.initAsync();\n\n if (!(await legacyStore.containsData())) {\n // This store was never used. Nothing to migrate.\n return;\n }\n\n await legacyStore.startup();\n\n let accountPickle: string | null = null;\n await legacyStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n legacyStore.getAccount(txn, (acctPickle) => {\n accountPickle = acctPickle;\n });\n });\n if (!accountPickle) {\n // This store is not properly set up. Nothing to migrate.\n logger.debug(\"Legacy crypto store is not set up (no account found). Not migrating.\");\n return;\n }\n\n let migrationState = await legacyStore.getMigrationState();\n\n if (migrationState >= MigrationState.MEGOLM_SESSIONS_MIGRATED) {\n // All migration is done for now. The room list comes later, once we have an OlmMachine.\n return;\n }\n\n const nOlmSessions = await countOlmSessions(logger, legacyStore);\n const nMegolmSessions = await countMegolmSessions(logger, legacyStore);\n const totalSteps = 1 + nOlmSessions + nMegolmSessions;\n logger.info(\n `Migrating data from legacy crypto store. ${nOlmSessions} olm sessions and ${nMegolmSessions} megolm sessions to migrate.`,\n );\n\n let stepsDone = 0;\n function onProgress(steps: number): void {\n stepsDone += steps;\n args.legacyMigrationProgressListener?.(stepsDone, totalSteps);\n }\n onProgress(0);\n\n const pickleKey = new TextEncoder().encode(args.legacyPickleKey).slice();\n\n if (migrationState === MigrationState.NOT_STARTED) {\n logger.info(\"Migrating data from legacy crypto store. Step 1: base data\");\n await migrateBaseData(args.http, args.userId, args.deviceId, legacyStore, pickleKey, args.storeHandle, logger);\n\n migrationState = MigrationState.INITIAL_DATA_MIGRATED;\n await legacyStore.setMigrationState(migrationState);\n }\n onProgress(1);\n\n if (migrationState === MigrationState.INITIAL_DATA_MIGRATED) {\n logger.info(\n `Migrating data from legacy crypto store. Step 2: olm sessions (${nOlmSessions} sessions to migrate).`,\n );\n await migrateOlmSessions(logger, legacyStore, pickleKey, args.storeHandle, onProgress);\n\n migrationState = MigrationState.OLM_SESSIONS_MIGRATED;\n await legacyStore.setMigrationState(migrationState);\n }\n\n if (migrationState === MigrationState.OLM_SESSIONS_MIGRATED) {\n logger.info(\n `Migrating data from legacy crypto store. Step 3: megolm sessions (${nMegolmSessions} sessions to migrate).`,\n );\n await migrateMegolmSessions(logger, legacyStore, pickleKey, args.storeHandle, onProgress);\n\n migrationState = MigrationState.MEGOLM_SESSIONS_MIGRATED;\n await legacyStore.setMigrationState(migrationState);\n }\n\n // Migration is done.\n args.legacyMigrationProgressListener?.(-1, -1);\n logger.info(\"Migration from legacy crypto store complete\");\n}\n\nasync function migrateBaseData(\n http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,\n userId: string,\n deviceId: string,\n legacyStore: CryptoStore,\n pickleKey: Uint8Array<ArrayBuffer>,\n storeHandle: RustSdkCryptoJs.StoreHandle,\n logger: Logger,\n): Promise<void> {\n const migrationData = new RustSdkCryptoJs.BaseMigrationData();\n migrationData.userId = new RustSdkCryptoJs.UserId(userId);\n migrationData.deviceId = new RustSdkCryptoJs.DeviceId(deviceId);\n\n await legacyStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) =>\n legacyStore.getAccount(txn, (a) => {\n migrationData.pickledAccount = a ?? \"\";\n }),\n );\n\n const recoveryKey = await getAndDecryptCachedSecretKey(legacyStore, pickleKey, \"m.megolm_backup.v1\");\n\n // If we have a backup recovery key, we need to try to figure out which backup version it is for.\n // All we can really do is ask the server for the most recent version and check if the cached key we have matches.\n // It is possible that the backup has changed since last time his session was opened.\n if (recoveryKey) {\n let backupCallDone = false;\n let backupInfo: KeyBackupInfo | null = null;\n while (!backupCallDone) {\n try {\n backupInfo = await requestKeyBackupVersion(http);\n backupCallDone = true;\n } catch (e) {\n logger.info(\"Failed to get backup version during migration, retrying in 2 seconds\", e);\n // Retry until successful, use simple constant delay\n await sleep(2000);\n }\n }\n if (backupInfo && backupInfo.algorithm == \"m.megolm_backup.v1.curve25519-aes-sha2\") {\n // check if the recovery key matches, as the active backup version may have changed since the key was cached\n // and the migration started.\n try {\n const decryptionKey = RustSdkCryptoJs.BackupDecryptionKey.fromBase64(recoveryKey);\n const publicKey = (backupInfo.auth_data as Curve25519AuthData)?.public_key;\n const isValid = decryptionKey.megolmV1PublicKey.publicKeyBase64 == publicKey;\n if (isValid) {\n migrationData.backupVersion = backupInfo.version;\n migrationData.backupRecoveryKey = recoveryKey;\n } else {\n logger.debug(\n \"The backup key to migrate does not match the active backup version\",\n `Cached pub key: ${decryptionKey.megolmV1PublicKey.publicKeyBase64}`,\n `Active pub key: ${publicKey}`,\n );\n }\n } catch (e) {\n logger.warn(\"Failed to check if the backup key to migrate matches the active backup version\", e);\n }\n }\n }\n\n migrationData.privateCrossSigningMasterKey = await getAndDecryptCachedSecretKey(legacyStore, pickleKey, \"master\");\n migrationData.privateCrossSigningSelfSigningKey = await getAndDecryptCachedSecretKey(\n legacyStore,\n pickleKey,\n \"self_signing\",\n );\n migrationData.privateCrossSigningUserSigningKey = await getAndDecryptCachedSecretKey(\n legacyStore,\n pickleKey,\n \"user_signing\",\n );\n await RustSdkCryptoJs.Migration.migrateBaseData(migrationData, pickleKey, storeHandle, logger);\n}\n\nasync function countOlmSessions(logger: Logger, legacyStore: CryptoStore): Promise<number> {\n logger.debug(\"Counting olm sessions to be migrated\");\n let nSessions: number;\n await legacyStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_SESSIONS], (txn) =>\n legacyStore.countEndToEndSessions(txn, (n) => (nSessions = n)),\n );\n return nSessions!;\n}\n\nasync function countMegolmSessions(logger: Logger, legacyStore: CryptoStore): Promise<number> {\n logger.debug(\"Counting megolm sessions to be migrated\");\n return await legacyStore.countEndToEndInboundGroupSessions();\n}\n\nasync function migrateOlmSessions(\n logger: Logger,\n legacyStore: CryptoStore,\n pickleKey: Uint8Array,\n storeHandle: RustSdkCryptoJs.StoreHandle,\n onBatchDone: (batchSize: number) => void,\n): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const batch = await legacyStore.getEndToEndSessionsBatch();\n if (batch === null) return;\n\n logger.debug(`Migrating batch of ${batch.length} olm sessions`);\n const migrationData: RustSdkCryptoJs.PickledSession[] = [];\n for (const session of batch) {\n const pickledSession = new RustSdkCryptoJs.PickledSession();\n pickledSession.senderKey = session.deviceKey!;\n pickledSession.pickle = session.session!;\n pickledSession.lastUseTime = pickledSession.creationTime = new Date(session.lastReceivedMessageTs!);\n migrationData.push(pickledSession);\n }\n\n await RustSdkCryptoJs.Migration.migrateOlmSessions(migrationData, pickleKey, storeHandle, logger);\n await legacyStore.deleteEndToEndSessionsBatch(batch);\n onBatchDone(batch.length);\n }\n}\n\nasync function migrateMegolmSessions(\n logger: Logger,\n legacyStore: CryptoStore,\n pickleKey: Uint8Array,\n storeHandle: RustSdkCryptoJs.StoreHandle,\n onBatchDone: (batchSize: number) => void,\n): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const batch = await legacyStore.getEndToEndInboundGroupSessionsBatch();\n if (batch === null) return;\n\n logger.debug(`Migrating batch of ${batch.length} megolm sessions`);\n const migrationData: RustSdkCryptoJs.PickledInboundGroupSession[] = [];\n for (const session of batch) {\n const sessionData = session.sessionData!;\n\n const pickledSession = new RustSdkCryptoJs.PickledInboundGroupSession();\n pickledSession.pickle = sessionData.session;\n pickledSession.roomId = new RustSdkCryptoJs.RoomId(sessionData.room_id);\n pickledSession.senderKey = session.senderKey;\n pickledSession.senderSigningKey = sessionData.keysClaimed?.[\"ed25519\"];\n pickledSession.backedUp = !session.needsBackup;\n\n // The Rust SDK `imported` flag is used to indicate the authenticity status of a Megolm\n // session, which tells us whether we can reliably tell which Olm device is the owner\n // (creator) of the session.\n //\n // If `imported` is true, then we have no cryptographic proof that the session is owned\n // by the device with the identity key `senderKey`.\n //\n // Only Megolm sessions received directly from the owning device via an encrypted\n // `m.room_key` to-device message should have `imported` flag set to false. Megolm\n // sessions received by any other currently available means (i.e. from a\n // `m.forwarded_room_key`, from v1 asymmetric server-side key backup, imported from a\n // file, etc) should have the `imported` flag set to true.\n //\n // Messages encrypted with such Megolm sessions will have a grey shield in the UI\n // (\"Authenticity of this message cannot be guaranteed\").\n //\n // However, we don't want to bluntly mark all sessions as `imported` during migration\n // because users will suddenly start seeing all their historic messages decorated with a\n // grey shield, which would be seen as a non-actionable regression.\n //\n // In the legacy crypto stack, the flag encoding similar information was called\n // `InboundGroupSessionData.untrusted`. The value of this flag was set as follows:\n //\n // - For outbound Megolm sessions created by our own device, `untrusted` is `undefined`.\n // - For Megolm sessions received via a `m.room_key` to-device message, `untrusted` is\n // `undefined`.\n // - For Megolm sessions received via a `m.forwarded_room_key` to-device message,\n // `untrusted` is `true`.\n // - For Megolm sessions imported from a (v1 asymmetric / \"legacy\") server-side key\n // backup, `untrusted` is `true`.\n // - For Megolm sessions imported from a file, untrusted is `undefined`.\n //\n // The main difference between the legacy crypto stack and the Rust crypto stack is that\n // the Rust stack considers sessions imported from a file as `imported` (not\n // authenticated). This is because the Megolm session export file format does not\n // encode this authenticity information.\n //\n // Given this migration is only a one-time thing, we make a concession to accept the\n // loss of information in this case, to avoid degrading UX in a non-actionable way.\n pickledSession.imported = sessionData.untrusted === true;\n\n migrationData.push(pickledSession);\n }\n\n await RustSdkCryptoJs.Migration.migrateMegolmSessions(migrationData, pickleKey, storeHandle, logger);\n await legacyStore.deleteEndToEndInboundGroupSessionsBatch(batch);\n onBatchDone(batch.length);\n }\n}\n\n/**\n * Determine if any room settings need migrating from the legacy store, and do so.\n *\n * @param args - Arguments object.\n */\nexport async function migrateRoomSettingsFromLegacyCrypto({\n logger,\n legacyStore,\n olmMachine,\n}: {\n /** A `Logger` instance that will be used for debug output. */\n logger: Logger;\n\n /** Store to migrate data from. */\n legacyStore: CryptoStore;\n\n /** OlmMachine to store the new data on. */\n olmMachine: RustSdkCryptoJs.OlmMachine;\n}): Promise<void> {\n if (!(await legacyStore.containsData())) {\n // This store was never used. Nothing to migrate.\n return;\n }\n\n const migrationState = await legacyStore.getMigrationState();\n\n if (migrationState >= MigrationState.ROOM_SETTINGS_MIGRATED) {\n // We've already migrated the room settings.\n return;\n }\n\n let rooms: Record<string, LegacyRoomEncryption> = {};\n\n await legacyStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ROOMS], (txn) => {\n legacyStore.getEndToEndRooms(txn, (result) => {\n rooms = result;\n });\n });\n\n logger.debug(`Migrating ${Object.keys(rooms).length} sets of room settings`);\n for (const [roomId, legacySettings] of Object.entries(rooms)) {\n try {\n const rustSettings = new RustSdkCryptoJs.RoomSettings();\n\n if (legacySettings.algorithm !== \"m.megolm.v1.aes-sha2\") {\n logger.warn(`Room ${roomId}: ignoring room with invalid algorithm ${legacySettings.algorithm}`);\n continue;\n }\n rustSettings.algorithm = RustSdkCryptoJs.EncryptionAlgorithm.MegolmV1AesSha2;\n rustSettings.sessionRotationPeriodMs = legacySettings.rotation_period_ms;\n rustSettings.sessionRotationPeriodMessages = legacySettings.rotation_period_msgs;\n await olmMachine.setRoomSettings(new RustSdkCryptoJs.RoomId(roomId), rustSettings);\n\n // We don't attempt to clear out the settings from the old store, or record where we've gotten up to,\n // which means that if the app gets restarted while we're in the middle of this migration, we'll start\n // again from scratch. So be it. Given that legacy crypto loads the whole room list into memory on startup\n // anyway, we know it can't be that big.\n } catch (e) {\n logger.warn(`Room ${roomId}: ignoring settings ${JSON.stringify(legacySettings)} which caused error ${e}`);\n }\n }\n\n logger.debug(`Completed room settings migration`);\n await legacyStore.setMigrationState(MigrationState.ROOM_SETTINGS_MIGRATED);\n}\n\nasync function getAndDecryptCachedSecretKey(\n legacyStore: CryptoStore,\n legacyPickleKey: Uint8Array<ArrayBuffer>,\n name: string,\n): Promise<string | undefined> {\n const key = await new Promise<any>((resolve) => {\n legacyStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n legacyStore.getSecretStorePrivateKey(txn, resolve, name as keyof SecretStorePrivateKeys);\n });\n });\n\n if (key && key.ciphertext && key.iv && key.mac) {\n return await decryptAESSecretStorageItem(key as AESEncryptedSecretStoragePayload, legacyPickleKey, name);\n } else if (key instanceof Uint8Array) {\n // This is a legacy backward compatibility case where the key was stored in clear.\n return encodeBase64(key);\n } else {\n return undefined;\n }\n}\n\n/**\n * Check if the user's published identity (ie, public cross-signing keys) was trusted by the legacy session,\n * and if so mark it as trusted in the Rust session if needed.\n *\n * By default, if the legacy session didn't have the private MSK, the migrated session will revert to unverified,\n * even if the user has verified the session in the past.\n *\n * This only occurs if the private MSK was not cached in the crypto store (USK and SSK private keys won't help\n * to establish trust: the trust is rooted in the MSK).\n *\n * Rust crypto will only consider the current session as trusted if we import the private MSK itself.\n *\n * We could prompt the user to verify the session again, but it's probably better to just mark the user identity\n * as locally verified if it was before.\n *\n * See https://github.com/element-hq/element-web/issues/27079\n *\n * @param args - Argument object.\n */\nexport async function migrateLegacyLocalTrustIfNeeded(args: {\n /** The legacy crypto store that is migrated. */\n legacyCryptoStore: CryptoStore;\n /** The migrated rust crypto stack. */\n rustCrypto: RustCrypto;\n /** The logger to use */\n logger: Logger;\n}): Promise<void> {\n const { legacyCryptoStore, rustCrypto, logger } = args;\n // Get the public cross-signing identity from rust.\n const rustOwnIdentity = await rustCrypto.getOwnIdentity();\n if (!rustOwnIdentity) {\n // There are no cross-signing keys published server side, so nothing to do here.\n return;\n }\n if (rustOwnIdentity.isVerified()) {\n // The rust session already trusts the keys, so again, nothing to do.\n return;\n }\n\n const legacyLocallyTrustedMSK = await getLegacyTrustedPublicMasterKeyBase64(legacyCryptoStore);\n if (!legacyLocallyTrustedMSK) {\n // The user never verified their identity in the legacy session, so nothing to do.\n return;\n }\n\n const mskInfo: CrossSigningKeyInfo = JSON.parse(rustOwnIdentity.masterKey);\n if (!mskInfo.keys || Object.keys(mskInfo.keys).length === 0) {\n // This should not happen, but let's be safe\n logger.error(\"Post Migration | Unexpected error: no master key in the rust session.\");\n return;\n }\n const rustSeenMSK = Object.values(mskInfo.keys)[0];\n\n if (rustSeenMSK && rustSeenMSK == legacyLocallyTrustedMSK) {\n logger.info(`Post Migration: Migrating legacy trusted MSK: ${legacyLocallyTrustedMSK} to locally verified.`);\n // Let's mark the user identity as locally verified as part of the migration.\n await rustOwnIdentity!.verify();\n // As well as marking the MSK as trusted, `OlmMachine.verify` returns a\n // `SignatureUploadRequest` which will publish a signature of the MSK using\n // this device. In this case, we ignore the request: since the user hasn't\n // actually re-verified the MSK, we don't publish a new signature. (`.verify`\n // doesn't store the signature, and if we drop the request here it won't be\n // retried.)\n //\n // Not publishing the signature is consistent with the behaviour of\n // matrix-crypto-sdk when the private key is imported via\n // `importCrossSigningKeys`, and when the identity is verified via interactive\n // verification.\n //\n // [Aside: device signatures on the MSK are not considered by the rust-sdk to\n // establish the trust of the user identity so in any case, what we actually do\n // here is somewhat moot.]\n }\n}\n\n/**\n * Checks if the legacy store has a trusted public master key, and returns it if so.\n *\n * @param legacyStore - The legacy store to check.\n *\n * @returns `null` if there were no cross signing keys or if they were not trusted. The trusted public master key if it was.\n */\nasync function getLegacyTrustedPublicMasterKeyBase64(legacyStore: CryptoStore): Promise<string | null> {\n let maybeTrustedKeys: string | null = null;\n await legacyStore.doTxn(\"readonly\", \"account\", (txn) => {\n legacyStore.getCrossSigningKeys(txn, (keys) => {\n // can be an empty object after resetting cross-signing keys, see storeTrustedSelfKeys\n const msk = keys?.master;\n if (msk && Object.keys(msk.keys).length != 0) {\n // `msk.keys` is an object with { [`ed25519:${pubKey}`]: pubKey }\n maybeTrustedKeys = Object.values(msk.keys)[0];\n }\n });\n });\n\n return maybeTrustedKeys;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"libolm_migration.js","names":["RustSdkCryptoJs","MigrationState","IndexedDBCryptoStore","requestKeyBackupVersion","sleep","encodeBase64","decryptAESSecretStorageItem","migrateFromLegacyCrypto","_x","_migrateFromLegacyCrypto","apply","arguments","_asyncToGenerator","args","_args$legacyMigration2","logger","legacyStore","initAsync","containsData","startup","accountPickle","doTxn","STORE_ACCOUNT","txn","getAccount","acctPickle","debug","migrationState","getMigrationState","MEGOLM_SESSIONS_MIGRATED","nOlmSessions","countOlmSessions","nMegolmSessions","countMegolmSessions","totalSteps","info","concat","stepsDone","onProgress","steps","_args$legacyMigration","legacyMigrationProgressListener","call","pickleKey","TextEncoder","encode","legacyPickleKey","slice","NOT_STARTED","migrateBaseData","http","userId","deviceId","storeHandle","INITIAL_DATA_MIGRATED","setMigrationState","migrateOlmSessions","OLM_SESSIONS_MIGRATED","migrateMegolmSessions","_x2","_x3","_x4","_x5","_x6","_x7","_x8","_migrateBaseData","migrationData","BaseMigrationData","UserId","DeviceId","a","pickledAccount","recoveryKey","getAndDecryptCachedSecretKey","backupCallDone","backupInfo","e","algorithm","_backupInfo$auth_data","decryptionKey","BackupDecryptionKey","fromBase64","publicKey","auth_data","public_key","isValid","megolmV1PublicKey","publicKeyBase64","backupVersion","version","backupRecoveryKey","warn","privateCrossSigningMasterKey","privateCrossSigningSelfSigningKey","privateCrossSigningUserSigningKey","Migration","_x9","_x0","_countOlmSessions","nSessions","STORE_SESSIONS","countEndToEndSessions","n","_x1","_x10","_countMegolmSessions","countEndToEndInboundGroupSessions","_x11","_x12","_x13","_x14","_x15","_migrateOlmSessions","onBatchDone","batch","getEndToEndSessionsBatch","length","session","pickledSession","PickledSession","senderKey","deviceKey","pickle","lastUseTime","creationTime","Date","lastReceivedMessageTs","push","deleteEndToEndSessionsBatch","_x16","_x17","_x18","_x19","_x20","_migrateMegolmSessions","getEndToEndInboundGroupSessionsBatch","_sessionData$keysClai","sessionData","PickledInboundGroupSession","roomId","RoomId","room_id","senderSigningKey","keysClaimed","backedUp","needsBackup","imported","untrusted","deleteEndToEndInboundGroupSessionsBatch","migrateRoomSettingsFromLegacyCrypto","_x21","_migrateRoomSettingsFromLegacyCrypto","_ref","olmMachine","ROOM_SETTINGS_MIGRATED","rooms","STORE_ROOMS","getEndToEndRooms","result","Object","keys","_ref4","entries","_ref3","_slicedToArray","legacySettings","rustSettings","RoomSettings","EncryptionAlgorithm","MegolmV1AesSha2","sessionRotationPeriodMs","rotation_period_ms","sessionRotationPeriodMessages","rotation_period_msgs","setRoomSettings","JSON","stringify","_x22","_x23","_x24","_getAndDecryptCachedSecretKey","name","key","Promise","resolve","getSecretStorePrivateKey","ciphertext","iv","mac","Uint8Array","undefined","migrateLegacyLocalTrustIfNeeded","_x25","_migrateLegacyLocalTrustIfNeeded","legacyCryptoStore","rustCrypto","rustOwnIdentity","getOwnIdentity","isVerified","legacyLocallyTrustedMSK","getLegacyTrustedPublicMasterKeyBase64","mskInfo","parse","masterKey","error","rustSeenMSK","values","verify","_x26","_getLegacyTrustedPublicMasterKeyBase","maybeTrustedKeys","getCrossSigningKeys","msk","master"],"sources":["../../src/rust-crypto/libolm_migration.ts"],"sourcesContent":["/*\nCopyright 2023-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 Logger } from \"../logger.ts\";\nimport { type CryptoStore, MigrationState, type SecretStorePrivateKeys } from \"../crypto/store/base.ts\";\nimport { IndexedDBCryptoStore } from \"../crypto/store/indexeddb-crypto-store.ts\";\nimport { type IHttpOpts, type MatrixHttpApi } from \"../http-api/index.ts\";\nimport { requestKeyBackupVersion } from \"./backup.ts\";\nimport { type CrossSigningKeyInfo, type Curve25519AuthData } from \"../crypto-api/index.ts\";\nimport { type RustCrypto } from \"./rust-crypto.ts\";\nimport { type KeyBackupInfo } from \"../crypto-api/keybackup.ts\";\nimport { sleep } from \"../utils.ts\";\nimport { encodeBase64 } from \"../base64.ts\";\nimport decryptAESSecretStorageItem from \"../utils/decryptAESSecretStorageItem.ts\";\nimport { type AESEncryptedSecretStoragePayload } from \"../@types/AESEncryptedSecretStoragePayload.ts\";\n\ninterface LegacyRoomEncryption {\n algorithm: string;\n rotation_period_ms?: number;\n rotation_period_msgs?: number;\n}\n\n/**\n * Determine if any data needs migrating from the legacy store, and do so.\n *\n * This migrates the base account data, and olm and megolm sessions. It does *not* migrate the room list, which should\n * happen after an `OlmMachine` is created, via {@link migrateRoomSettingsFromLegacyCrypto}.\n *\n * @param args - Arguments object.\n */\nexport async function migrateFromLegacyCrypto(args: {\n /** A `Logger` instance that will be used for debug output. */\n logger: Logger;\n\n /**\n * Low-level HTTP interface: used to make outgoing requests required by the rust SDK.\n * We expect it to set the access token, etc.\n */\n http: MatrixHttpApi<IHttpOpts & { onlyData: true }>;\n\n /** Store to migrate data from. */\n legacyStore: CryptoStore;\n\n /** Pickle key for `legacyStore`. */\n legacyPickleKey?: string;\n\n /** Local user's User ID. */\n userId: string;\n\n /** Local user's Device ID. */\n deviceId: string;\n\n /** Rust crypto store to migrate data into. */\n storeHandle: RustSdkCryptoJs.StoreHandle;\n\n /**\n * A callback which will receive progress updates on migration from `legacyStore`.\n *\n * Called with (-1, -1) to mark the end of migration.\n */\n legacyMigrationProgressListener?: (progress: number, total: number) => void;\n}): Promise<void> {\n const { logger, legacyStore } = args;\n\n // initialise the rust matrix-sdk-crypto-wasm, if it hasn't already been done\n await RustSdkCryptoJs.initAsync();\n\n if (!(await legacyStore.containsData())) {\n // This store was never used. Nothing to migrate.\n return;\n }\n\n await legacyStore.startup();\n\n let accountPickle: string | null = null;\n await legacyStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n legacyStore.getAccount(txn, (acctPickle) => {\n accountPickle = acctPickle;\n });\n });\n if (!accountPickle) {\n // This store is not properly set up. Nothing to migrate.\n logger.debug(\"Legacy crypto store is not set up (no account found). Not migrating.\");\n return;\n }\n\n let migrationState = await legacyStore.getMigrationState();\n\n if (migrationState >= MigrationState.MEGOLM_SESSIONS_MIGRATED) {\n // All migration is done for now. The room list comes later, once we have an OlmMachine.\n return;\n }\n\n const nOlmSessions = await countOlmSessions(logger, legacyStore);\n const nMegolmSessions = await countMegolmSessions(logger, legacyStore);\n const totalSteps = 1 + nOlmSessions + nMegolmSessions;\n logger.info(\n `Migrating data from legacy crypto store. ${nOlmSessions} olm sessions and ${nMegolmSessions} megolm sessions to migrate.`,\n );\n\n let stepsDone = 0;\n function onProgress(steps: number): void {\n stepsDone += steps;\n args.legacyMigrationProgressListener?.(stepsDone, totalSteps);\n }\n onProgress(0);\n\n const pickleKey = new TextEncoder().encode(args.legacyPickleKey).slice();\n\n if (migrationState === MigrationState.NOT_STARTED) {\n logger.info(\"Migrating data from legacy crypto store. Step 1: base data\");\n await migrateBaseData(args.http, args.userId, args.deviceId, legacyStore, pickleKey, args.storeHandle, logger);\n\n migrationState = MigrationState.INITIAL_DATA_MIGRATED;\n await legacyStore.setMigrationState(migrationState);\n }\n onProgress(1);\n\n if (migrationState === MigrationState.INITIAL_DATA_MIGRATED) {\n logger.info(\n `Migrating data from legacy crypto store. Step 2: olm sessions (${nOlmSessions} sessions to migrate).`,\n );\n await migrateOlmSessions(logger, legacyStore, pickleKey, args.storeHandle, onProgress);\n\n migrationState = MigrationState.OLM_SESSIONS_MIGRATED;\n await legacyStore.setMigrationState(migrationState);\n }\n\n if (migrationState === MigrationState.OLM_SESSIONS_MIGRATED) {\n logger.info(\n `Migrating data from legacy crypto store. Step 3: megolm sessions (${nMegolmSessions} sessions to migrate).`,\n );\n await migrateMegolmSessions(logger, legacyStore, pickleKey, args.storeHandle, onProgress);\n\n migrationState = MigrationState.MEGOLM_SESSIONS_MIGRATED;\n await legacyStore.setMigrationState(migrationState);\n }\n\n // Migration is done.\n args.legacyMigrationProgressListener?.(-1, -1);\n logger.info(\"Migration from legacy crypto store complete\");\n}\n\nasync function migrateBaseData(\n http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,\n userId: string,\n deviceId: string,\n legacyStore: CryptoStore,\n pickleKey: Uint8Array<ArrayBuffer>,\n storeHandle: RustSdkCryptoJs.StoreHandle,\n logger: Logger,\n): Promise<void> {\n const migrationData = new RustSdkCryptoJs.BaseMigrationData();\n migrationData.userId = new RustSdkCryptoJs.UserId(userId);\n migrationData.deviceId = new RustSdkCryptoJs.DeviceId(deviceId);\n\n await legacyStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) =>\n legacyStore.getAccount(txn, (a) => {\n migrationData.pickledAccount = a ?? \"\";\n }),\n );\n\n const recoveryKey = await getAndDecryptCachedSecretKey(legacyStore, pickleKey, \"m.megolm_backup.v1\");\n\n // If we have a backup recovery key, we need to try to figure out which backup version it is for.\n // All we can really do is ask the server for the most recent version and check if the cached key we have matches.\n // It is possible that the backup has changed since last time his session was opened.\n if (recoveryKey) {\n let backupCallDone = false;\n let backupInfo: KeyBackupInfo | null = null;\n while (!backupCallDone) {\n try {\n backupInfo = await requestKeyBackupVersion(http);\n backupCallDone = true;\n } catch (e) {\n logger.info(\"Failed to get backup version during migration, retrying in 2 seconds\", e);\n // Retry until successful, use simple constant delay\n await sleep(2000);\n }\n }\n if (backupInfo && backupInfo.algorithm == \"m.megolm_backup.v1.curve25519-aes-sha2\") {\n // check if the recovery key matches, as the active backup version may have changed since the key was cached\n // and the migration started.\n try {\n const decryptionKey = RustSdkCryptoJs.BackupDecryptionKey.fromBase64(recoveryKey);\n const publicKey = (backupInfo.auth_data as Curve25519AuthData)?.public_key;\n const isValid = decryptionKey.megolmV1PublicKey.publicKeyBase64 == publicKey;\n if (isValid) {\n migrationData.backupVersion = backupInfo.version;\n migrationData.backupRecoveryKey = recoveryKey;\n } else {\n logger.debug(\n \"The backup key to migrate does not match the active backup version\",\n `Cached pub key: ${decryptionKey.megolmV1PublicKey.publicKeyBase64}`,\n `Active pub key: ${publicKey}`,\n );\n }\n } catch (e) {\n logger.warn(\"Failed to check if the backup key to migrate matches the active backup version\", e);\n }\n }\n }\n\n migrationData.privateCrossSigningMasterKey = await getAndDecryptCachedSecretKey(legacyStore, pickleKey, \"master\");\n migrationData.privateCrossSigningSelfSigningKey = await getAndDecryptCachedSecretKey(\n legacyStore,\n pickleKey,\n \"self_signing\",\n );\n migrationData.privateCrossSigningUserSigningKey = await getAndDecryptCachedSecretKey(\n legacyStore,\n pickleKey,\n \"user_signing\",\n );\n await RustSdkCryptoJs.Migration.migrateBaseData(migrationData, pickleKey, storeHandle, logger);\n}\n\nasync function countOlmSessions(logger: Logger, legacyStore: CryptoStore): Promise<number> {\n logger.debug(\"Counting olm sessions to be migrated\");\n let nSessions: number;\n await legacyStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_SESSIONS], (txn) =>\n legacyStore.countEndToEndSessions(txn, (n) => (nSessions = n)),\n );\n return nSessions!;\n}\n\nasync function countMegolmSessions(logger: Logger, legacyStore: CryptoStore): Promise<number> {\n logger.debug(\"Counting megolm sessions to be migrated\");\n return await legacyStore.countEndToEndInboundGroupSessions();\n}\n\nasync function migrateOlmSessions(\n logger: Logger,\n legacyStore: CryptoStore,\n pickleKey: Uint8Array,\n storeHandle: RustSdkCryptoJs.StoreHandle,\n onBatchDone: (batchSize: number) => void,\n): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const batch = await legacyStore.getEndToEndSessionsBatch();\n if (batch === null) return;\n\n logger.debug(`Migrating batch of ${batch.length} olm sessions`);\n const migrationData: RustSdkCryptoJs.PickledSession[] = [];\n for (const session of batch) {\n const pickledSession = new RustSdkCryptoJs.PickledSession();\n pickledSession.senderKey = session.deviceKey!;\n pickledSession.pickle = session.session!;\n pickledSession.lastUseTime = pickledSession.creationTime = new Date(session.lastReceivedMessageTs!);\n migrationData.push(pickledSession);\n }\n\n await RustSdkCryptoJs.Migration.migrateOlmSessions(migrationData, pickleKey, storeHandle, logger);\n await legacyStore.deleteEndToEndSessionsBatch(batch);\n onBatchDone(batch.length);\n }\n}\n\nasync function migrateMegolmSessions(\n logger: Logger,\n legacyStore: CryptoStore,\n pickleKey: Uint8Array,\n storeHandle: RustSdkCryptoJs.StoreHandle,\n onBatchDone: (batchSize: number) => void,\n): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const batch = await legacyStore.getEndToEndInboundGroupSessionsBatch();\n if (batch === null) return;\n\n logger.debug(`Migrating batch of ${batch.length} megolm sessions`);\n const migrationData: RustSdkCryptoJs.PickledInboundGroupSession[] = [];\n for (const session of batch) {\n const sessionData = session.sessionData!;\n\n const pickledSession = new RustSdkCryptoJs.PickledInboundGroupSession();\n pickledSession.pickle = sessionData.session;\n pickledSession.roomId = new RustSdkCryptoJs.RoomId(sessionData.room_id);\n pickledSession.senderKey = session.senderKey;\n pickledSession.senderSigningKey = sessionData.keysClaimed?.[\"ed25519\"];\n pickledSession.backedUp = !session.needsBackup;\n\n // The Rust SDK `imported` flag is used to indicate the authenticity status of a Megolm\n // session, which tells us whether we can reliably tell which Olm device is the owner\n // (creator) of the session.\n //\n // If `imported` is true, then we have no cryptographic proof that the session is owned\n // by the device with the identity key `senderKey`.\n //\n // Only Megolm sessions received directly from the owning device via an encrypted\n // `m.room_key` to-device message should have `imported` flag set to false. Megolm\n // sessions received by any other currently available means (i.e. from a\n // `m.forwarded_room_key`, from v1 asymmetric server-side key backup, imported from a\n // file, etc) should have the `imported` flag set to true.\n //\n // Messages encrypted with such Megolm sessions will have a grey shield in the UI\n // (\"Authenticity of this message cannot be guaranteed\").\n //\n // However, we don't want to bluntly mark all sessions as `imported` during migration\n // because users will suddenly start seeing all their historic messages decorated with a\n // grey shield, which would be seen as a non-actionable regression.\n //\n // In the legacy crypto stack, the flag encoding similar information was called\n // `InboundGroupSessionData.untrusted`. The value of this flag was set as follows:\n //\n // - For outbound Megolm sessions created by our own device, `untrusted` is `undefined`.\n // - For Megolm sessions received via a `m.room_key` to-device message, `untrusted` is\n // `undefined`.\n // - For Megolm sessions received via a `m.forwarded_room_key` to-device message,\n // `untrusted` is `true`.\n // - For Megolm sessions imported from a (v1 asymmetric / \"legacy\") server-side key\n // backup, `untrusted` is `true`.\n // - For Megolm sessions imported from a file, untrusted is `undefined`.\n //\n // The main difference between the legacy crypto stack and the Rust crypto stack is that\n // the Rust stack considers sessions imported from a file as `imported` (not\n // authenticated). This is because the Megolm session export file format does not\n // encode this authenticity information.\n //\n // Given this migration is only a one-time thing, we make a concession to accept the\n // loss of information in this case, to avoid degrading UX in a non-actionable way.\n pickledSession.imported = sessionData.untrusted === true;\n\n migrationData.push(pickledSession);\n }\n\n await RustSdkCryptoJs.Migration.migrateMegolmSessions(migrationData, pickleKey, storeHandle, logger);\n await legacyStore.deleteEndToEndInboundGroupSessionsBatch(batch);\n onBatchDone(batch.length);\n }\n}\n\n/**\n * Determine if any room settings need migrating from the legacy store, and do so.\n *\n * @param args - Arguments object.\n */\nexport async function migrateRoomSettingsFromLegacyCrypto({\n logger,\n legacyStore,\n olmMachine,\n}: {\n /** A `Logger` instance that will be used for debug output. */\n logger: Logger;\n\n /** Store to migrate data from. */\n legacyStore: CryptoStore;\n\n /** OlmMachine to store the new data on. */\n olmMachine: RustSdkCryptoJs.OlmMachine;\n}): Promise<void> {\n if (!(await legacyStore.containsData())) {\n // This store was never used. Nothing to migrate.\n return;\n }\n\n const migrationState = await legacyStore.getMigrationState();\n\n if (migrationState >= MigrationState.ROOM_SETTINGS_MIGRATED) {\n // We've already migrated the room settings.\n return;\n }\n\n let rooms: Record<string, LegacyRoomEncryption> = {};\n\n await legacyStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ROOMS], (txn) => {\n legacyStore.getEndToEndRooms(txn, (result) => {\n rooms = result;\n });\n });\n\n logger.debug(`Migrating ${Object.keys(rooms).length} sets of room settings`);\n for (const [roomId, legacySettings] of Object.entries(rooms)) {\n try {\n const rustSettings = new RustSdkCryptoJs.RoomSettings();\n\n if (legacySettings.algorithm !== \"m.megolm.v1.aes-sha2\") {\n logger.warn(`Room ${roomId}: ignoring room with invalid algorithm ${legacySettings.algorithm}`);\n continue;\n }\n rustSettings.algorithm = RustSdkCryptoJs.EncryptionAlgorithm.MegolmV1AesSha2;\n rustSettings.sessionRotationPeriodMs = legacySettings.rotation_period_ms;\n rustSettings.sessionRotationPeriodMessages = legacySettings.rotation_period_msgs;\n await olmMachine.setRoomSettings(new RustSdkCryptoJs.RoomId(roomId), rustSettings);\n\n // We don't attempt to clear out the settings from the old store, or record where we've gotten up to,\n // which means that if the app gets restarted while we're in the middle of this migration, we'll start\n // again from scratch. So be it. Given that legacy crypto loads the whole room list into memory on startup\n // anyway, we know it can't be that big.\n } catch (e) {\n logger.warn(`Room ${roomId}: ignoring settings ${JSON.stringify(legacySettings)} which caused error ${e}`);\n }\n }\n\n logger.debug(`Completed room settings migration`);\n await legacyStore.setMigrationState(MigrationState.ROOM_SETTINGS_MIGRATED);\n}\n\nasync function getAndDecryptCachedSecretKey(\n legacyStore: CryptoStore,\n legacyPickleKey: Uint8Array<ArrayBuffer>,\n name: string,\n): Promise<string | undefined> {\n const key = await new Promise<any>((resolve) => {\n legacyStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n legacyStore.getSecretStorePrivateKey(txn, resolve, name as keyof SecretStorePrivateKeys);\n });\n });\n\n if (key && key.ciphertext && key.iv && key.mac) {\n return await decryptAESSecretStorageItem(key as AESEncryptedSecretStoragePayload, legacyPickleKey, name);\n } else if (key instanceof Uint8Array) {\n // This is a legacy backward compatibility case where the key was stored in clear.\n return encodeBase64(key);\n } else {\n return undefined;\n }\n}\n\n/**\n * Check if the user's published identity (ie, public cross-signing keys) was trusted by the legacy session,\n * and if so mark it as trusted in the Rust session if needed.\n *\n * By default, if the legacy session didn't have the private MSK, the migrated session will revert to unverified,\n * even if the user has verified the session in the past.\n *\n * This only occurs if the private MSK was not cached in the crypto store (USK and SSK private keys won't help\n * to establish trust: the trust is rooted in the MSK).\n *\n * Rust crypto will only consider the current session as trusted if we import the private MSK itself.\n *\n * We could prompt the user to verify the session again, but it's probably better to just mark the user identity\n * as locally verified if it was before.\n *\n * See https://github.com/element-hq/element-web/issues/27079\n *\n * @param args - Argument object.\n */\nexport async function migrateLegacyLocalTrustIfNeeded(args: {\n /** The legacy crypto store that is migrated. */\n legacyCryptoStore: CryptoStore;\n /** The migrated rust crypto stack. */\n rustCrypto: RustCrypto;\n /** The logger to use */\n logger: Logger;\n}): Promise<void> {\n const { legacyCryptoStore, rustCrypto, logger } = args;\n // Get the public cross-signing identity from rust.\n const rustOwnIdentity = await rustCrypto.getOwnIdentity();\n if (!rustOwnIdentity) {\n // There are no cross-signing keys published server side, so nothing to do here.\n return;\n }\n if (rustOwnIdentity.isVerified()) {\n // The rust session already trusts the keys, so again, nothing to do.\n return;\n }\n\n const legacyLocallyTrustedMSK = await getLegacyTrustedPublicMasterKeyBase64(legacyCryptoStore);\n if (!legacyLocallyTrustedMSK) {\n // The user never verified their identity in the legacy session, so nothing to do.\n return;\n }\n\n const mskInfo: CrossSigningKeyInfo = JSON.parse(rustOwnIdentity.masterKey);\n if (!mskInfo.keys || Object.keys(mskInfo.keys).length === 0) {\n // This should not happen, but let's be safe\n logger.error(\"Post Migration | Unexpected error: no master key in the rust session.\");\n return;\n }\n const rustSeenMSK = Object.values(mskInfo.keys)[0];\n\n if (rustSeenMSK && rustSeenMSK == legacyLocallyTrustedMSK) {\n logger.info(`Post Migration: Migrating legacy trusted MSK: ${legacyLocallyTrustedMSK} to locally verified.`);\n // Let's mark the user identity as locally verified as part of the migration.\n await rustOwnIdentity!.verify();\n // As well as marking the MSK as trusted, `OlmMachine.verify` returns a\n // `SignatureUploadRequest` which will publish a signature of the MSK using\n // this device. In this case, we ignore the request: since the user hasn't\n // actually re-verified the MSK, we don't publish a new signature. (`.verify`\n // doesn't store the signature, and if we drop the request here it won't be\n // retried.)\n //\n // Not publishing the signature is consistent with the behaviour of\n // matrix-crypto-sdk when the private key is imported via\n // `importCrossSigningKeys`, and when the identity is verified via interactive\n // verification.\n //\n // [Aside: device signatures on the MSK are not considered by the rust-sdk to\n // establish the trust of the user identity so in any case, what we actually do\n // here is somewhat moot.]\n }\n}\n\n/**\n * Checks if the legacy store has a trusted public master key, and returns it if so.\n *\n * @param legacyStore - The legacy store to check.\n *\n * @returns `null` if there were no cross signing keys or if they were not trusted. The trusted public master key if it was.\n */\nasync function getLegacyTrustedPublicMasterKeyBase64(legacyStore: CryptoStore): Promise<string | null> {\n let maybeTrustedKeys: string | null = null;\n await legacyStore.doTxn(\"readonly\", \"account\", (txn) => {\n legacyStore.getCrossSigningKeys(txn, (keys) => {\n // can be an empty object after resetting cross-signing keys, see storeTrustedSelfKeys\n const msk = keys?.master;\n if (msk && Object.keys(msk.keys).length != 0) {\n // `msk.keys` is an object with { [`ed25519:${pubKey}`]: pubKey }\n maybeTrustedKeys = Object.values(msk.keys)[0];\n }\n });\n });\n\n return maybeTrustedKeys;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
1
2
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
3
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
4
|
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; }
|
|
@@ -72,13 +73,6 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
72
73
|
cryptoCallbacks) {
|
|
73
74
|
var enableEncryptedStateEvents = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
|
|
74
75
|
super();
|
|
75
|
-
this.logger = logger;
|
|
76
|
-
this.olmMachine = olmMachine;
|
|
77
|
-
this.http = http;
|
|
78
|
-
this.userId = userId;
|
|
79
|
-
this.secretStorage = secretStorage;
|
|
80
|
-
this.cryptoCallbacks = cryptoCallbacks;
|
|
81
|
-
this.enableEncryptedStateEvents = enableEncryptedStateEvents;
|
|
82
76
|
/**
|
|
83
77
|
* The number of iterations to use when deriving a recovery key from a passphrase.
|
|
84
78
|
*/
|
|
@@ -89,14 +83,6 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
89
83
|
_defineProperty(this, "stopped", false);
|
|
90
84
|
/** mapping of roomId → encryptor class */
|
|
91
85
|
_defineProperty(this, "roomEncryptors", {});
|
|
92
|
-
_defineProperty(this, "eventDecryptor", void 0);
|
|
93
|
-
_defineProperty(this, "keyClaimManager", void 0);
|
|
94
|
-
_defineProperty(this, "outgoingRequestProcessor", void 0);
|
|
95
|
-
_defineProperty(this, "crossSigningIdentity", void 0);
|
|
96
|
-
_defineProperty(this, "backupManager", void 0);
|
|
97
|
-
_defineProperty(this, "outgoingRequestsManager", void 0);
|
|
98
|
-
_defineProperty(this, "perSessionBackupDownloader", void 0);
|
|
99
|
-
_defineProperty(this, "dehydratedDeviceManager", void 0);
|
|
100
86
|
_defineProperty(this, "reemitter", new TypedReEmitter(this));
|
|
101
87
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
102
88
|
//
|
|
@@ -108,6 +94,13 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
108
94
|
* The verification methods we offer to the other side during an interactive verification.
|
|
109
95
|
*/
|
|
110
96
|
_defineProperty(this, "_supportedVerificationMethods", ALL_VERIFICATION_METHODS);
|
|
97
|
+
this.logger = logger;
|
|
98
|
+
this.olmMachine = olmMachine;
|
|
99
|
+
this.http = http;
|
|
100
|
+
this.userId = userId;
|
|
101
|
+
this.secretStorage = secretStorage;
|
|
102
|
+
this.cryptoCallbacks = cryptoCallbacks;
|
|
103
|
+
this.enableEncryptedStateEvents = enableEncryptedStateEvents;
|
|
111
104
|
this.outgoingRequestProcessor = new OutgoingRequestProcessor(logger, olmMachine, http);
|
|
112
105
|
this.outgoingRequestsManager = new OutgoingRequestsManager(this.logger, olmMachine, this.outgoingRequestProcessor);
|
|
113
106
|
this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor);
|
|
@@ -466,7 +459,9 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
466
459
|
if (downloadUncached && untrackedUsers.size >= 1) {
|
|
467
460
|
var queryResult = yield _this13.downloadDeviceList(untrackedUsers);
|
|
468
461
|
Object.entries(queryResult.device_keys).forEach(_ref => {
|
|
469
|
-
var
|
|
462
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
463
|
+
userId = _ref2[0],
|
|
464
|
+
deviceKeys = _ref2[1];
|
|
470
465
|
return deviceMapByUserId.set(userId, deviceKeysToDeviceMap(deviceKeys));
|
|
471
466
|
});
|
|
472
467
|
}
|
|
@@ -663,10 +658,9 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
663
658
|
isCrossSigningReady() {
|
|
664
659
|
var _this22 = this;
|
|
665
660
|
return _asyncToGenerator(function* () {
|
|
666
|
-
var
|
|
667
|
-
privateKeysInSecretStorage,
|
|
668
|
-
privateKeysCachedLocally
|
|
669
|
-
} = yield _this22.getCrossSigningStatus();
|
|
661
|
+
var _yield$_this22$getCro = yield _this22.getCrossSigningStatus(),
|
|
662
|
+
privateKeysInSecretStorage = _yield$_this22$getCro.privateKeysInSecretStorage,
|
|
663
|
+
privateKeysCachedLocally = _yield$_this22$getCro.privateKeysCachedLocally;
|
|
670
664
|
var hasKeysInCache = Boolean(privateKeysCachedLocally.masterKey) && Boolean(privateKeysCachedLocally.selfSigningKey) && Boolean(privateKeysCachedLocally.userSigningKey);
|
|
671
665
|
var identity = yield _this22.getOwnIdentity();
|
|
672
666
|
|
|
@@ -787,11 +781,10 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
787
781
|
var _arguments5 = arguments,
|
|
788
782
|
_this27 = this;
|
|
789
783
|
return _asyncToGenerator(function* () {
|
|
790
|
-
var {
|
|
791
|
-
createSecretStorageKey,
|
|
792
|
-
setupNewSecretStorage,
|
|
793
|
-
setupNewKeyBackup
|
|
794
|
-
} = _arguments5.length > 0 && _arguments5[0] !== undefined ? _arguments5[0] : {};
|
|
784
|
+
var _ref3 = _arguments5.length > 0 && _arguments5[0] !== undefined ? _arguments5[0] : {},
|
|
785
|
+
createSecretStorageKey = _ref3.createSecretStorageKey,
|
|
786
|
+
setupNewSecretStorage = _ref3.setupNewSecretStorage,
|
|
787
|
+
setupNewKeyBackup = _ref3.setupNewKeyBackup;
|
|
795
788
|
// If an AES Key is already stored in the secret storage and setupNewSecretStorage is not set
|
|
796
789
|
// we don't want to create a new key
|
|
797
790
|
var isNewSecretStorageKeyNeeded = setupNewSecretStorage || !(yield _this27.secretStorageHasAESKey());
|
|
@@ -889,7 +882,8 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
889
882
|
// See if we already have an AES secret-storage key.
|
|
890
883
|
var secretStorageKeyTuple = yield _this30.secretStorage.getKey();
|
|
891
884
|
if (!secretStorageKeyTuple) return false;
|
|
892
|
-
var
|
|
885
|
+
var _secretStorageKeyTupl = _slicedToArray(secretStorageKeyTuple, 2),
|
|
886
|
+
keyInfo = _secretStorageKeyTupl[1];
|
|
893
887
|
|
|
894
888
|
// Check if the key is an AES key
|
|
895
889
|
return keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES;
|
|
@@ -1050,11 +1044,10 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
1050
1044
|
return _asyncToGenerator(function* () {
|
|
1051
1045
|
var txId = secureRandomString(32);
|
|
1052
1046
|
// Send the verification request content to the DM room
|
|
1053
|
-
var {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
});
|
|
1047
|
+
var _yield$_this35$http$a = yield _this35.http.authedRequest(Method.Put, "/_matrix/client/v3/rooms/".concat(encodeURIComponent(roomId), "/send/m.room.message/").concat(encodeURIComponent(txId)), undefined, verificationEventContent, {
|
|
1048
|
+
prefix: ""
|
|
1049
|
+
}),
|
|
1050
|
+
eventId = _yield$_this35$http$a.event_id;
|
|
1058
1051
|
return eventId;
|
|
1059
1052
|
})();
|
|
1060
1053
|
}
|
|
@@ -1085,7 +1078,10 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
1085
1078
|
throw new Error("cannot request verification for this device when there is no existing cross-signing key");
|
|
1086
1079
|
}
|
|
1087
1080
|
try {
|
|
1088
|
-
var
|
|
1081
|
+
var _yield$userIdentity$r = yield userIdentity.requestVerification(_this36._supportedVerificationMethods.map(verificationMethodIdentifierToMethod)),
|
|
1082
|
+
_yield$userIdentity$r2 = _slicedToArray(_yield$userIdentity$r, 2),
|
|
1083
|
+
request = _yield$userIdentity$r2[0],
|
|
1084
|
+
outgoingRequest = _yield$userIdentity$r2[1];
|
|
1089
1085
|
yield _this36.outgoingRequestProcessor.makeOutgoingRequest(outgoingRequest);
|
|
1090
1086
|
return _this36.makeVerificationRequest(request);
|
|
1091
1087
|
} finally {
|
|
@@ -1114,7 +1110,10 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
1114
1110
|
throw new Error("Not a known device");
|
|
1115
1111
|
}
|
|
1116
1112
|
try {
|
|
1117
|
-
var
|
|
1113
|
+
var _device$requestVerifi = device.requestVerification(_this37._supportedVerificationMethods.map(verificationMethodIdentifierToMethod)),
|
|
1114
|
+
_device$requestVerifi2 = _slicedToArray(_device$requestVerifi, 2),
|
|
1115
|
+
request = _device$requestVerifi2[0],
|
|
1116
|
+
outgoingRequest = _device$requestVerifi2[1];
|
|
1118
1117
|
yield _this37.outgoingRequestProcessor.makeOutgoingRequest(outgoingRequest);
|
|
1119
1118
|
return _this37.makeVerificationRequest(request);
|
|
1120
1119
|
} finally {
|
|
@@ -1327,10 +1326,8 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
1327
1326
|
return _asyncToGenerator(function* () {
|
|
1328
1327
|
// Get the decryption key from the crypto store
|
|
1329
1328
|
var backupKeys = yield _this50.olmMachine.getBackupKeys();
|
|
1330
|
-
var
|
|
1331
|
-
|
|
1332
|
-
backupVersion
|
|
1333
|
-
} = backupKeys;
|
|
1329
|
+
var decryptionKey = backupKeys.decryptionKey,
|
|
1330
|
+
backupVersion = backupKeys.backupVersion;
|
|
1334
1331
|
if (!decryptionKey || !backupVersion) throw new Error("No decryption key found in crypto store");
|
|
1335
1332
|
var decodedDecryptionKey = decodeBase64(decryptionKey.toBase64());
|
|
1336
1333
|
var backupInfo = yield _this50.backupManager.requestKeyBackupVersion(backupVersion);
|
|
@@ -1405,10 +1402,8 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
1405
1402
|
var _this55 = this;
|
|
1406
1403
|
return _asyncToGenerator(function* () {
|
|
1407
1404
|
var logger = new LogSpan(_this55.logger, "encryptToDeviceMessages");
|
|
1408
|
-
var uniqueUsers = new Set(devices.map(
|
|
1409
|
-
var
|
|
1410
|
-
userId
|
|
1411
|
-
} = _ref2;
|
|
1405
|
+
var uniqueUsers = new Set(devices.map(_ref4 => {
|
|
1406
|
+
var userId = _ref4.userId;
|
|
1412
1407
|
return userId;
|
|
1413
1408
|
}));
|
|
1414
1409
|
|
|
@@ -1421,11 +1416,9 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
1421
1416
|
eventType: EventType.RoomMessageEncrypted
|
|
1422
1417
|
};
|
|
1423
1418
|
yield Promise.all(devices.map(/*#__PURE__*/function () {
|
|
1424
|
-
var
|
|
1425
|
-
var
|
|
1426
|
-
|
|
1427
|
-
deviceId
|
|
1428
|
-
} = _ref3;
|
|
1419
|
+
var _ref6 = _asyncToGenerator(function* (_ref5) {
|
|
1420
|
+
var userId = _ref5.userId,
|
|
1421
|
+
deviceId = _ref5.deviceId;
|
|
1429
1422
|
var device = yield _this55.olmMachine.getDevice(new RustSdkCryptoJs.UserId(userId), new RustSdkCryptoJs.DeviceId(deviceId));
|
|
1430
1423
|
if (device) {
|
|
1431
1424
|
var encryptedPayload = JSON.parse(yield device.encryptToDeviceEvent(eventType, payload));
|
|
@@ -1439,7 +1432,7 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
1439
1432
|
}
|
|
1440
1433
|
});
|
|
1441
1434
|
return function (_x) {
|
|
1442
|
-
return
|
|
1435
|
+
return _ref6.apply(this, arguments);
|
|
1443
1436
|
};
|
|
1444
1437
|
}()));
|
|
1445
1438
|
return batch;
|
|
@@ -1557,15 +1550,15 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
1557
1550
|
* @param devices - the received device list updates
|
|
1558
1551
|
* @returns A list of processed to-device messages.
|
|
1559
1552
|
*/
|
|
1560
|
-
receiveSyncChanges(
|
|
1553
|
+
receiveSyncChanges(_ref7) {
|
|
1561
1554
|
var _this59 = this;
|
|
1562
1555
|
return _asyncToGenerator(function* () {
|
|
1563
|
-
var
|
|
1564
|
-
|
|
1565
|
-
oneTimeKeysCounts = new Map(),
|
|
1566
|
-
unusedFallbackKeys,
|
|
1567
|
-
devices =
|
|
1568
|
-
|
|
1556
|
+
var events = _ref7.events,
|
|
1557
|
+
_ref7$oneTimeKeysCoun = _ref7.oneTimeKeysCounts,
|
|
1558
|
+
oneTimeKeysCounts = _ref7$oneTimeKeysCoun === void 0 ? new Map() : _ref7$oneTimeKeysCoun,
|
|
1559
|
+
unusedFallbackKeys = _ref7.unusedFallbackKeys,
|
|
1560
|
+
_ref7$devices = _ref7.devices,
|
|
1561
|
+
devices = _ref7$devices === void 0 ? new RustSdkCryptoJs.DeviceLists() : _ref7$devices;
|
|
1569
1562
|
return yield _this59.olmMachine.receiveSyncChanges(events ? JSON.stringify(events) : "[]", devices, oneTimeKeysCounts, unusedFallbackKeys);
|
|
1570
1563
|
})();
|
|
1571
1564
|
}
|
|
@@ -2021,14 +2014,14 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
2021
2014
|
// transaction_id is provided in case of remote echo {@link https://spec.matrix.org/v1.7/client-server-api/#local-echo}
|
|
2022
2015
|
if (event.isState() || !!event.getUnsigned().transaction_id) return;
|
|
2023
2016
|
var processEvent = /*#__PURE__*/function () {
|
|
2024
|
-
var
|
|
2017
|
+
var _ref8 = _asyncToGenerator(function* (evt) {
|
|
2025
2018
|
// Process only verification event
|
|
2026
2019
|
if (isVerificationEvent(event)) {
|
|
2027
2020
|
yield _this72.onKeyVerificationEvent(evt);
|
|
2028
2021
|
}
|
|
2029
2022
|
});
|
|
2030
2023
|
return function processEvent(_x2) {
|
|
2031
|
-
return
|
|
2024
|
+
return _ref8.apply(this, arguments);
|
|
2032
2025
|
};
|
|
2033
2026
|
}();
|
|
2034
2027
|
|
|
@@ -2129,15 +2122,15 @@ export class RustCrypto extends TypedEventEmitter {
|
|
|
2129
2122
|
}
|
|
2130
2123
|
class EventDecryptor {
|
|
2131
2124
|
constructor(logger, olmMachine, perSessionBackupDownloader) {
|
|
2132
|
-
this.logger = logger;
|
|
2133
|
-
this.olmMachine = olmMachine;
|
|
2134
|
-
this.perSessionBackupDownloader = perSessionBackupDownloader;
|
|
2135
2125
|
/**
|
|
2136
2126
|
* Events which we couldn't decrypt due to unknown sessions / indexes.
|
|
2137
2127
|
*
|
|
2138
2128
|
* Map from roomId to sessionId to Set of MatrixEvents
|
|
2139
2129
|
*/
|
|
2140
2130
|
_defineProperty(this, "eventsPendingKey", new MapWithDefault(() => new MapWithDefault(() => new Set())));
|
|
2131
|
+
this.logger = logger;
|
|
2132
|
+
this.olmMachine = olmMachine;
|
|
2133
|
+
this.perSessionBackupDownloader = perSessionBackupDownloader;
|
|
2141
2134
|
}
|
|
2142
2135
|
attemptEventDecryption(event, isolationMode) {
|
|
2143
2136
|
var _this76 = this;
|