diff --git a/CHANGELOG.md b/CHANGELOG.md index cd40fce12..1dcbb2c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # UNRELEASED +**BREAKING CHANGES** + +- `OlmMachine.importBackedUpRoomKeys` now takes a `backupVersion` argument. + +**Other changes** + +- Update matrix-rust-sdk to `7e44fbca7`, which includes: + + - Avoid emitting entries from `identities_stream_raw` and `devices_stream` when + we receive a `/keys/query` response which shows that no devices changed. + ([#3442](https://github.com/matrix-org/matrix-rust-sdk/pull/3442)). + + - Fix to a bug introduced in matrix-sdk-crypto-wasm v4.10.0 which caused + keys that had been imported from key backup to be backed up again, when + using the in-memory datastore. + # matrix-sdk-crypto-wasm v4.10.0 - Expose new constructor function `OlmMachine.openWithKey()`. @@ -19,7 +35,7 @@ - Add a constructor for the `Curve25519PublicKey` type. This allows us to create a `Curve25519PublicKey` from a Base64 string on the Javascript side. -- Update matrix-rust-sdk to `7a887766c`, which includes: +- Update matrix-rust-sdk to `d7a887766c`, which includes: - Add data types to parse the QR code data for the QR code login defined in [MSC4108](https://github.com/matrix-org/matrix-spec-proposals/pull/4108) diff --git a/Cargo.lock b/Cargo.lock index 0e5707bed..f319d2225 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -846,7 +846,7 @@ dependencies = [ [[package]] name = "matrix-sdk-common" version = "0.7.0" -source = "git+https://github.com/matrix-org/matrix-rust-sdk#d7a887766ce6d69a2c0487e48d91d350f171303b" +source = "git+https://github.com/matrix-org/matrix-rust-sdk#7e44fbca799a93e5ef9c74e97b61a75293cfbfec" dependencies = [ "async-trait", "futures-core", @@ -868,7 +868,7 @@ dependencies = [ [[package]] name = "matrix-sdk-crypto" version = "0.7.0" -source = "git+https://github.com/matrix-org/matrix-rust-sdk#d7a887766ce6d69a2c0487e48d91d350f171303b" +source = "git+https://github.com/matrix-org/matrix-rust-sdk#7e44fbca799a93e5ef9c74e97b61a75293cfbfec" dependencies = [ "aes", "as_variant", @@ -935,7 +935,7 @@ dependencies = [ [[package]] name = "matrix-sdk-indexeddb" version = "0.7.0" -source = "git+https://github.com/matrix-org/matrix-rust-sdk#d7a887766ce6d69a2c0487e48d91d350f171303b" +source = "git+https://github.com/matrix-org/matrix-rust-sdk#7e44fbca799a93e5ef9c74e97b61a75293cfbfec" dependencies = [ "anyhow", "async-trait", @@ -963,7 +963,7 @@ dependencies = [ [[package]] name = "matrix-sdk-qrcode" version = "0.7.0" -source = "git+https://github.com/matrix-org/matrix-rust-sdk#d7a887766ce6d69a2c0487e48d91d350f171303b" +source = "git+https://github.com/matrix-org/matrix-rust-sdk#7e44fbca799a93e5ef9c74e97b61a75293cfbfec" dependencies = [ "byteorder", "qrcode", @@ -975,7 +975,7 @@ dependencies = [ [[package]] name = "matrix-sdk-store-encryption" version = "0.7.0" -source = "git+https://github.com/matrix-org/matrix-rust-sdk#d7a887766ce6d69a2c0487e48d91d350f171303b" +source = "git+https://github.com/matrix-org/matrix-rust-sdk#7e44fbca799a93e5ef9c74e97b61a75293cfbfec" dependencies = [ "base64", "blake3", diff --git a/src/machine.rs b/src/machine.rs index 9be619096..80b5526a2 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -15,7 +15,7 @@ use matrix_sdk_common::ruma::{ }; use matrix_sdk_crypto::{ backups::MegolmV1BackupKey, - olm::BackedUpRoomKey, + olm::{BackedUpRoomKey, ExportedRoomKey}, store::{DeviceChanges, IdentityChanges}, types::RoomKeyBackupInfo, CryptoStoreError, EncryptionSyncChanges, GossippedSecret, @@ -1052,11 +1052,12 @@ impl OlmMachine { &self, backed_up_room_keys: &Map, progress_listener: Option, + backup_version: String, ) -> Result { let me = self.inner.clone(); // convert the js-side data into rust data - let mut keys: BTreeMap<_, BTreeMap<_, _>> = BTreeMap::new(); + let mut keys = Vec::new(); let mut failures = 0; for backed_up_room_keys_entry in backed_up_room_keys.entries() { let backed_up_room_keys_entry: Array = backed_up_room_keys_entry?.dyn_into()?; @@ -1071,7 +1072,11 @@ impl OlmMachine { if let Ok(key) = serde_wasm_bindgen::from_value::(room_room_keys_entry.get(1)) { - keys.entry(room_id.clone()).or_default().insert(session_id.into(), key); + keys.push(ExportedRoomKey::from_backed_up_room_key( + room_id.clone(), + session_id.into(), + key, + )); } else { failures += 1; } @@ -1080,8 +1085,8 @@ impl OlmMachine { Ok(future_to_promise(async move { let result: RoomKeyImportResult = me - .backup_machine() - .import_backed_up_room_keys(keys, |progress, total_valid| { + .store() + .import_room_keys(keys, Some(&backup_version), |progress, total_valid| { if let Some(callback) = &progress_listener { callback .call3( diff --git a/tests/machine.test.ts b/tests/machine.test.ts index f5b13589b..141161e12 100644 --- a/tests/machine.test.ts +++ b/tests/machine.test.ts @@ -1257,7 +1257,7 @@ describe(OlmMachine.name, () => { const progressListener = jest.fn(); const m2 = await machine(); await m2.saveBackupDecryptionKey(keyBackupKey, "1"); - const result = await m2.importBackedUpRoomKeys(decryptedKeyMap, progressListener); + const result = await m2.importBackedUpRoomKeys(decryptedKeyMap, progressListener, "1"); expect(result.importedCount).toStrictEqual(1); expect(result.totalCount).toStrictEqual(1); expect(result.keys()).toMatchObject( @@ -1442,27 +1442,32 @@ describe(OlmMachine.name, () => { test("Updating devices should call devicesUpdatedCallback", async () => { const userId = new UserId("@alice:example.org"); const deviceId = new DeviceId("ABCDEF"); - const machine = await OlmMachine.initialize(userId, deviceId); + const firstMachine = await OlmMachine.initialize(userId, deviceId); const callback = jest.fn().mockImplementation(() => Promise.resolve(undefined)); - machine.registerDevicesUpdatedCallback(callback); + firstMachine.registerDevicesUpdatedCallback(callback); - const outgoingRequests = await machine.outgoingRequests(); + const secondDeviceId = new DeviceId("GHIJKL"); + const secondMachine = await OlmMachine.initialize(userId, secondDeviceId); + + // Fish the KeysUploadRequest out of secondMachine's outgoingRequests. let deviceKeys; - // outgoingRequests will have a KeysUploadRequest before the - // KeysQueryRequest, so we grab the device upload and put it in the - // response to the /keys/query - for (const request of outgoingRequests) { + for (const request of await secondMachine.outgoingRequests()) { if (request instanceof KeysUploadRequest) { deviceKeys = JSON.parse(request.body).device_keys; - } else if (request instanceof KeysQueryRequest) { - await machine.markRequestAsSent( + } + } + + // ... and feed it into firstMachine's KeysQueryRequest + for (const request of await firstMachine.outgoingRequests()) { + if (request instanceof KeysQueryRequest) { + await firstMachine.markRequestAsSent( request.id, request.type, JSON.stringify({ device_keys: { "@alice:example.org": { - ABCDEF: deviceKeys, + GHIJKL: deviceKeys, }, }, }),