diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index 8f4089d882..b8880a7f4d 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -1874,6 +1874,8 @@ ED51943A28462D130006EEC6 /* MXRoomStateUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED51943828462D130006EEC6 /* MXRoomStateUnitTests.swift */; }; ED51943C284630090006EEC6 /* MXRestClientStub.m in Sources */ = {isa = PBXBuildFile; fileRef = ED51943B284630090006EEC6 /* MXRestClientStub.m */; }; ED51943D284630090006EEC6 /* MXRestClientStub.m in Sources */ = {isa = PBXBuildFile; fileRef = ED51943B284630090006EEC6 /* MXRestClientStub.m */; }; + ED555F59298BB27200C5BD63 /* MXKeysQueryResponseUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED555F58298BB27200C5BD63 /* MXKeysQueryResponseUnitTests.swift */; }; + ED555F5A298BB27200C5BD63 /* MXKeysQueryResponseUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED555F58298BB27200C5BD63 /* MXKeysQueryResponseUnitTests.swift */; }; ED558068296F0361003443E3 /* MXCryptoMigrationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED558067296F0361003443E3 /* MXCryptoMigrationStore.swift */; }; ED558069296F0361003443E3 /* MXCryptoMigrationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED558067296F0361003443E3 /* MXCryptoMigrationStore.swift */; }; ED55806D296F0E3A003443E3 /* MXCryptoMigrationStoreUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED55806C296F0E3A003443E3 /* MXCryptoMigrationStoreUnitTests.swift */; }; @@ -3095,6 +3097,7 @@ ED51943828462D130006EEC6 /* MXRoomStateUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXRoomStateUnitTests.swift; sourceTree = ""; }; ED51943B284630090006EEC6 /* MXRestClientStub.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MXRestClientStub.m; sourceTree = ""; }; ED51943E284630100006EEC6 /* MXRestClientStub.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXRestClientStub.h; sourceTree = ""; }; + ED555F58298BB27200C5BD63 /* MXKeysQueryResponseUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXKeysQueryResponseUnitTests.swift; sourceTree = ""; }; ED558067296F0361003443E3 /* MXCryptoMigrationStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXCryptoMigrationStore.swift; sourceTree = ""; }; ED55806C296F0E3A003443E3 /* MXCryptoMigrationStoreUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXCryptoMigrationStoreUnitTests.swift; sourceTree = ""; }; ED55806F296F1BEE003443E3 /* MXCryptoMigrationV2Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXCryptoMigrationV2Tests.swift; sourceTree = ""; }; @@ -5782,6 +5785,7 @@ children = ( 321809B819EEBF3000377451 /* MXEventTests.m */, EDB4209827DF842F0036AF39 /* MXEventFixtures.swift */, + ED555F58298BB27200C5BD63 /* MXKeysQueryResponseUnitTests.swift */, ); path = JSONModels; sourceTree = ""; @@ -7369,6 +7373,7 @@ 32B090FD26201C8D002924AA /* MXAsyncTaskQueueUnitTests.swift in Sources */, 322A51D81D9E846800C8536D /* MXCryptoTests.m in Sources */, B146D4FF21A5C0BD00D8C2C6 /* MXMediaScanStoreUnitTests.m in Sources */, + ED555F59298BB27200C5BD63 /* MXKeysQueryResponseUnitTests.swift in Sources */, 32BD34BE1E84134A006EDC0D /* MatrixSDKTestsE2EData.m in Sources */, EDC8C40E2968C37F003792C5 /* MXKeysQuerySchedulerUnitTests.swift in Sources */, ED751DAE28EDEC7E003748C3 /* MXKeyVerificationStateResolverUnitTests.swift in Sources */, @@ -8035,6 +8040,7 @@ 32B4778E2638133D00EA5800 /* MXFilterUnitTests.m in Sources */, 32B090FE26201C8D002924AA /* MXAsyncTaskQueueUnitTests.swift in Sources */, B1E09A242397FCE90057C069 /* MXPeekingRoomTests.m in Sources */, + ED555F5A298BB27200C5BD63 /* MXKeysQueryResponseUnitTests.swift in Sources */, B1E09A452397FD990057C069 /* MXLazyLoadingTests.m in Sources */, EDC8C40D2968C37E003792C5 /* MXKeysQuerySchedulerUnitTests.swift in Sources */, ED751DAF28EDEC7E003748C3 /* MXKeyVerificationStateResolverUnitTests.swift in Sources */, diff --git a/MatrixSDK/Categories/MXRestClient+Extensions.swift b/MatrixSDK/Categories/MXRestClient+Extensions.swift index d032754b89..7252d26b31 100644 --- a/MatrixSDK/Categories/MXRestClient+Extensions.swift +++ b/MatrixSDK/Categories/MXRestClient+Extensions.swift @@ -35,7 +35,7 @@ public extension MXRestClient { failure: @escaping (_ error: NSError?) -> Void) -> MXHTTPOperation { // Do not chunk if not needed - if users.count < chunkSize { + if users.count <= chunkSize { return self.downloadKeys(forUsers: users, token: token) { response in switch response { case .success(let keysQueryResponse): diff --git a/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift b/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift index b9c4dfb444..c44dc643f8 100644 --- a/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift +++ b/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift @@ -128,6 +128,7 @@ struct MXRoomEventEncryption: MXRoomEventEncrypting { for: room, historyVisibility: state.historyVisibility ) + log.debug("Collected \(users.count) eligible users") let settings = try encryptionSettings(for: state) try await handler.shareRoomKeysIfNecessary( @@ -135,6 +136,8 @@ struct MXRoomEventEncryption: MXRoomEventEncrypting { users: users, settings: settings ) + + log.debug("Encryption and room keys up to date") } /// Make sure that we recognize (and store if necessary) the claimed room encryption algorithm diff --git a/MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift b/MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift index 6c954d981d..8f060f0859 100644 --- a/MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift +++ b/MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift @@ -189,6 +189,8 @@ extension MXCryptoMachine: MXCryptoSyncing { } func downloadKeysIfNecessary(users: [String]) async throws { + log.debug("Checking if keys need to be downloaded for \(users.count) user(s)") + try machine.updateTrackedUsers(users: users) // Out-of-sync check if there is a pending outgoing request for some of these users @@ -384,15 +386,22 @@ extension MXCryptoMachine: MXCryptoRoomEventEncrypting { users: [String], settings: EncryptionSettings ) async throws { + log.debug("Checking room keys in room \(roomId)") + try await sessionsQueue.sync { [weak self] in - try await self?.downloadKeysIfNecessary(users: users) + self?.log.debug("Fetching missing sessions") try await self?.getMissingSessions(users: users) } + log.debug("Acquiring room lock for room \(roomId)") let roomQueue = await roomQueues.getQueue(for: roomId) + try await roomQueue.sync { [weak self] in + self?.log.debug("Sharing room keys") try await self?.shareRoomKey(roomId: roomId, users: users, settings: settings) } + + log.debug("All room keys have been shared") } func encryptRoomEvent( @@ -423,13 +432,22 @@ extension MXCryptoMachine: MXCryptoRoomEventEncrypting { let request = try machine.getMissingSessions(users: users), case .keysClaim = request else { + log.debug("No sessions are missing") return } + + log.debug("Claiming new keys") try await handleRequest(request) } private func shareRoomKey(roomId: String, users: [String], settings: EncryptionSettings) async throws { let requests = try machine.shareRoomKey(roomId: roomId, users: users, settings: settings) + guard !requests.isEmpty else { + log.debug("Room keys do not need to be shared") + return + } + + log.debug("Sharing room keys via \(requests.count) request(s") try await withThrowingTaskGroup(of: Void.self) { [weak self] group in guard let self = self else { return } @@ -445,6 +463,8 @@ extension MXCryptoMachine: MXCryptoRoomEventEncrypting { try await group.waitForAll() } + + log.debug("All room keys have been shared") } } diff --git a/MatrixSDK/Crypto/Devices/Data/MXDeviceInfo.m b/MatrixSDK/Crypto/Devices/Data/MXDeviceInfo.m index 4f6961bd1f..0364b1f8dd 100644 --- a/MatrixSDK/Crypto/Devices/Data/MXDeviceInfo.m +++ b/MatrixSDK/Crypto/Devices/Data/MXDeviceInfo.m @@ -144,7 +144,7 @@ - (NSDictionary *)JSONDictionary JSONDictionary[@"unsigned"] = _unsignedData; } - return JSONDictionary; + return JSONDictionary.copy; } - (NSDictionary *)signalableJSONDictionary @@ -165,7 +165,7 @@ - (NSDictionary *)signalableJSONDictionary signalableJSONDictionary[@"keys"] = _keys; } - return signalableJSONDictionary; + return signalableJSONDictionary.copy; } diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index 71c438b153..60a3e7b82f 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -98,7 +98,7 @@ - (NSDictionary *)JSONDictionary if (_avatarUrl) { jsonDictionary[@"avatar_url"] = _avatarUrl; } if (_roomTypeString) { jsonDictionary[@"room_type"] = _roomTypeString; } - return jsonDictionary; + return jsonDictionary.copy; } @end @@ -1126,11 +1126,6 @@ - (NSDictionary *)JSONDictionary @end @interface MXKeysQueryResponse () - -/** - The original JSON used to create the response model - */ -@property (nonatomic, copy) NSDictionary *responseJSON; @end @implementation MXKeysQueryResponse @@ -1140,8 +1135,6 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary MXKeysQueryResponse *keysQueryResponse = [[MXKeysQueryResponse alloc] init]; if (keysQueryResponse) { - keysQueryResponse.responseJSON = JSONDictionary; - // Devices keys NSMutableDictionary *map = [NSMutableDictionary dictionary]; @@ -1225,7 +1218,31 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary - (NSDictionary *)JSONDictionary { - return self.responseJSON; + NSMutableDictionary *deviceKeys = [[NSMutableDictionary alloc] init]; + for (NSString *userId in self.deviceKeys.userIds) { + NSMutableDictionary *devices = [[NSMutableDictionary alloc] init]; + for (NSString *deviceId in [self.deviceKeys deviceIdsForUser:userId]) { + devices[deviceId] = [self.deviceKeys objectForDevice:deviceId forUser:userId].JSONDictionary.copy; + } + deviceKeys[userId] = devices.copy; + } + + NSMutableDictionary *master = [[NSMutableDictionary alloc] init]; + NSMutableDictionary *selfSigning = [[NSMutableDictionary alloc] init]; + NSMutableDictionary *userSigning = [[NSMutableDictionary alloc] init]; + for (NSString *userId in self.crossSigningKeys) { + master[userId] = self.crossSigningKeys[userId].masterKeys.JSONDictionary.copy; + selfSigning[userId] = self.crossSigningKeys[userId].selfSignedKeys.JSONDictionary.copy; + userSigning[userId] = self.crossSigningKeys[userId].userSignedKeys.JSONDictionary.copy; + } + + return @{ + @"device_keys": deviceKeys.copy ?: @{}, + @"failures": self.failures.copy ?: @{}, + @"master_keys": master.copy ?: @{}, + @"self_signing_keys": selfSigning.copy ?: @{}, + @"user_signing_keys": userSigning.copy ?: @{} + }; } @end @@ -2203,7 +2220,7 @@ - (NSDictionary *)JSONDictionary { dictionary[@"passphrase"] = self.passphrase; } - return dictionary; + return dictionary.copy; } @end diff --git a/MatrixSDKTests/JSONModels/MXKeysQueryResponseUnitTests.swift b/MatrixSDKTests/JSONModels/MXKeysQueryResponseUnitTests.swift new file mode 100644 index 0000000000..b7c9b31720 --- /dev/null +++ b/MatrixSDKTests/JSONModels/MXKeysQueryResponseUnitTests.swift @@ -0,0 +1,435 @@ +// +// Copyright 2023 The Matrix.org Foundation C.I.C +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +@testable import MatrixSDK + +#if DEBUG + +class MXKeysQueryResponseUnitTests: XCTestCase { + + private func makeCrossSigningInfo(userId: String) -> MXCrossSigningInfo { + .init( + userIdentity: .init( + identity: .other( + userId: userId, + masterKey: MXCrossSigningKey( + userId: userId, + usage: ["master"], + keys: "\(userId)-MSK" + ).jsonString(), + selfSigningKey: MXCrossSigningKey( + userId: userId, + usage: ["self_signing"], + keys: "\(userId)-SSK" + ).jsonString() + ), + isVerified: true + ) + ) + } + + private func makeOwnCrossSigningInfo(userId: String) -> MXCrossSigningInfo { + .init( + userIdentity: .init( + identity: .own( + userId: userId, + trustsOurOwnDevice: true, + masterKey: MXCrossSigningKey( + userId: userId, + usage: ["master"], + keys: "\(userId)-MSK" + ).jsonString(), + selfSigningKey: MXCrossSigningKey( + userId: userId, + usage: ["self_signing"], + keys: "\(userId)-SSK" + ).jsonString(), + userSigningKey: MXCrossSigningKey( + userId: userId, + usage: ["user_signing"], + keys: "\(userId)-USK" + ).jsonString() + ), + isVerified: true + ) + ) + } + + func test_emptyJSON() { + let response = MXKeysQueryResponse() + XCTAssertEqual(response.jsonDictionary() as NSDictionary, [ + "device_keys": [:], + "failures": [:], + "master_keys": [:], + "self_signing_keys": [:], + "user_signing_keys": [:], + ]) + } + + func test_deviceKeys() { + let response = MXKeysQueryResponse() + response.deviceKeys = MXUsersDevicesMap(map: [ + "Alice": [ + "DeviceA": MXDeviceInfo(deviceId: "DeviceA"), + "DeviceB": MXDeviceInfo(deviceId: "DeviceB"), + ], + "Bob": [ + "DeviceC": MXDeviceInfo(deviceId: "DeviceC"), + ], + ]) + + let keys = response.jsonDictionary()?["device_keys"] as? NSDictionary + + XCTAssertEqual(keys, [ + "Alice": [ + "DeviceA": [ + "device_id": "DeviceA" + ], + "DeviceB": [ + "device_id": "DeviceB" + ], + ], + "Bob": [ + "DeviceC": [ + "device_id": "DeviceC" + ], + ], + ]) + } + + func test_failures() { + let response = MXKeysQueryResponse() + response.failures = [ + "matrix:org": "123", + "element.io": "456", + ] + + let failures = response.jsonDictionary()["failures"] as? NSDictionary + + XCTAssertEqual(failures, [ + "matrix:org": "123", + "element.io": "456", + ]) + } + + func test_masterKeys() { + let response = MXKeysQueryResponse() + response.crossSigningKeys = [ + "Alice": makeCrossSigningInfo(userId: "Alice"), + "Bob": makeCrossSigningInfo(userId: "Bob") + ] + + let master = response.jsonDictionary()["master_keys"] as? NSDictionary + + XCTAssertEqual(master, [ + "Alice": [ + "user_id": "Alice", + "usage": ["master"], + "keys": [ + "ed25519:Alice-MSK": "Alice-MSK" + ], + "signatures": [:] + ], + "Bob": [ + "user_id": "Bob", + "usage": ["master"], + "keys": [ + "ed25519:Bob-MSK": "Bob-MSK" + ], + "signatures": [:] + ], + ]) + } + + func test_selfSigningKeys() { + let response = MXKeysQueryResponse() + response.crossSigningKeys = [ + "Alice": makeCrossSigningInfo(userId: "Alice"), + "Bob": makeCrossSigningInfo(userId: "Bob") + ] + + let master = response.jsonDictionary()["self_signing_keys"] as? NSDictionary + + XCTAssertEqual(master, [ + "Alice": [ + "user_id": "Alice", + "usage": ["self_signing"], + "keys": [ + "ed25519:Alice-SSK": "Alice-SSK" + ], + "signatures": [:] + ], + "Bob": [ + "user_id": "Bob", + "usage": ["self_signing"], + "keys": [ + "ed25519:Bob-SSK": "Bob-SSK" + ], + "signatures": [:] + ], + ]) + } + + func test_userSigningKeys() { + let response = MXKeysQueryResponse() + response.crossSigningKeys = [ + "Charlie": makeOwnCrossSigningInfo(userId: "Charlie") + ] + + let master = response.jsonDictionary()["user_signing_keys"] as? NSDictionary + + XCTAssertEqual(master, [ + "Charlie": [ + "user_id": "Charlie", + "usage": ["user_signing"], + "keys": [ + "ed25519:Charlie-USK": "Charlie-USK" + ], + "signatures": [:] + ], + ]) + } + + func test_canCombineResponses() { + let empty = MXKeysQueryResponse() + let first = MXKeysQueryResponse() + first.deviceKeys = MXUsersDevicesMap(map: [ + "Alice": [ + "DeviceA": MXDeviceInfo(deviceId: "DeviceA"), + "DeviceB": MXDeviceInfo(deviceId: "DeviceB"), + ], + "Bob": [ + "DeviceC": MXDeviceInfo(deviceId: "DeviceC"), + ], + ]) + first.crossSigningKeys = [ + "Alice": makeCrossSigningInfo(userId: "Alice"), + "Bob": makeCrossSigningInfo(userId: "Bob") + ] + + let second = MXKeysQueryResponse() + second.deviceKeys = MXUsersDevicesMap(map: [ + "Charlie": [ + "DeviceD": MXDeviceInfo(deviceId: "DeviceD"), + ], + ]) + second.crossSigningKeys = [ + "Charlie": makeOwnCrossSigningInfo(userId: "Charlie") + ] + + // Empty responses combine into empty json + let result1 = (empty + empty).jsonDictionary() as? NSDictionary + XCTAssertEqual(result1, [ + "device_keys": [:], + "failures": [:], + "master_keys": [:], + "self_signing_keys": [:], + "user_signing_keys": [:], + ]) + + // We combine empty and full response, result is equal to the second response + let result2 = (empty + first).jsonDictionary() as? NSDictionary + XCTAssertEqual(result2, [ + "device_keys": [ + "Alice": [ + "DeviceA": [ + "device_id": "DeviceA" + ], + "DeviceB": [ + "device_id": "DeviceB" + ], + ], + "Bob": [ + "DeviceC": [ + "device_id": "DeviceC" + ], + ], + ], + "failures": [:], + "master_keys": [ + "Alice": [ + "user_id": "Alice", + "usage": ["master"], + "keys": [ + "ed25519:Alice-MSK": "Alice-MSK" + ], + "signatures": [:] + ], + "Bob": [ + "user_id": "Bob", + "usage": ["master"], + "keys": [ + "ed25519:Bob-MSK": "Bob-MSK" + ], + "signatures": [:] + ], + ], + "self_signing_keys": [ + "Alice": [ + "user_id": "Alice", + "usage": ["self_signing"], + "keys": [ + "ed25519:Alice-SSK": "Alice-SSK" + ], + "signatures": [:] + ], + "Bob": [ + "user_id": "Bob", + "usage": ["self_signing"], + "keys": [ + "ed25519:Bob-SSK": "Bob-SSK" + ], + "signatures": [:] + ], + ], + "user_signing_keys": [:], + ]) + + // We combine anoter empty and full response, result is equal to the second response + let result3 = (second + empty).jsonDictionary() as? NSDictionary + XCTAssertEqual(result3, [ + "device_keys": [ + "Charlie": [ + "DeviceD": [ + "device_id": "DeviceD" + ], + ], + ], + "failures": [:], + "master_keys": [ + "Charlie": [ + "user_id": "Charlie", + "usage": ["master"], + "keys": [ + "ed25519:Charlie-MSK": "Charlie-MSK" + ], + "signatures": [:] + ], + ], + "self_signing_keys": [ + "Charlie": [ + "user_id": "Charlie", + "usage": ["self_signing"], + "keys": [ + "ed25519:Charlie-SSK": "Charlie-SSK" + ], + "signatures": [:] + ], + ], + "user_signing_keys": [ + "Charlie": [ + "user_id": "Charlie", + "usage": ["user_signing"], + "keys": [ + "ed25519:Charlie-USK": "Charlie-USK" + ], + "signatures": [:] + ], + ], + ]) + + // We combine two non-empty responses, result has all the data of both + let result4 = (first + second).jsonDictionary() as? NSDictionary + XCTAssertEqual(result4, [ + "device_keys": [ + "Alice": [ + "DeviceA": [ + "device_id": "DeviceA" + ], + "DeviceB": [ + "device_id": "DeviceB" + ], + ], + "Bob": [ + "DeviceC": [ + "device_id": "DeviceC" + ], + ], + "Charlie": [ + "DeviceD": [ + "device_id": "DeviceD" + ], + ], + ], + "failures": [:], + "master_keys": [ + "Alice": [ + "user_id": "Alice", + "usage": ["master"], + "keys": [ + "ed25519:Alice-MSK": "Alice-MSK" + ], + "signatures": [:] + ], + "Bob": [ + "user_id": "Bob", + "usage": ["master"], + "keys": [ + "ed25519:Bob-MSK": "Bob-MSK" + ], + "signatures": [:] + ], + "Charlie": [ + "user_id": "Charlie", + "usage": ["master"], + "keys": [ + "ed25519:Charlie-MSK": "Charlie-MSK" + ], + "signatures": [:] + ], + ], + "self_signing_keys": [ + "Alice": [ + "user_id": "Alice", + "usage": ["self_signing"], + "keys": [ + "ed25519:Alice-SSK": "Alice-SSK" + ], + "signatures": [:] + ], + "Bob": [ + "user_id": "Bob", + "usage": ["self_signing"], + "keys": [ + "ed25519:Bob-SSK": "Bob-SSK" + ], + "signatures": [:] + ], + "Charlie": [ + "user_id": "Charlie", + "usage": ["self_signing"], + "keys": [ + "ed25519:Charlie-SSK": "Charlie-SSK" + ], + "signatures": [:] + ], + ], + "user_signing_keys": [ + "Charlie": [ + "user_id": "Charlie", + "usage": ["user_signing"], + "keys": [ + "ed25519:Charlie-USK": "Charlie-USK" + ], + "signatures": [:] + ], + ], + ]) + } +} + +#endif diff --git a/MatrixSDKTests/TestPlans/UnitTests.xctestplan b/MatrixSDKTests/TestPlans/UnitTests.xctestplan index ef3434c5b9..f3645e682f 100644 --- a/MatrixSDKTests/TestPlans/UnitTests.xctestplan +++ b/MatrixSDKTests/TestPlans/UnitTests.xctestplan @@ -66,6 +66,7 @@ "MXKeyVerificationManagerV2UnitTests", "MXKeyVerificationRequestV2UnitTests", "MXKeyVerificationStateResolverUnitTests", + "MXKeysQueryResponseUnitTest", "MXKeysQuerySchedulerUnitTests", "MXMediaScanStoreUnitTests", "MXMegolmDecryptionUnitTests", diff --git a/MatrixSDKTests/TestPlans/UnitTestsWithSanitizers.xctestplan b/MatrixSDKTests/TestPlans/UnitTestsWithSanitizers.xctestplan index e0c6681590..2ca30c4c4c 100644 --- a/MatrixSDKTests/TestPlans/UnitTestsWithSanitizers.xctestplan +++ b/MatrixSDKTests/TestPlans/UnitTestsWithSanitizers.xctestplan @@ -74,6 +74,7 @@ "MXKeyVerificationManagerV2UnitTests", "MXKeyVerificationRequestV2UnitTests", "MXKeyVerificationStateResolverUnitTests", + "MXKeysQueryResponseUnitTests", "MXKeysQuerySchedulerUnitTests", "MXMediaScanStoreUnitTests", "MXMegolmDecryptionUnitTests", diff --git a/changelog.d/pr-1707.change b/changelog.d/pr-1707.change new file mode 100644 index 0000000000..631b03b6be --- /dev/null +++ b/changelog.d/pr-1707.change @@ -0,0 +1 @@ +CryptoV2: Fix JSONDictionary of keys query responses