From b0a5fb00a4fe5ba7dfe7506dcfad1550d69c8452 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 5 Jun 2024 15:09:46 +0200 Subject: [PATCH 01/14] Fix | Share room keys with dehydrated devices with rust stack --- .../MXKeysQueryResponse+Extensions.swift | 24 +++++ .../Categories/MXRestClient+Extensions.swift | 71 ++++++++++++++ MatrixSDK/Contrib/Swift/MXRestClient.swift | 4 + .../CryptoMachine/MXCryptoRequests.swift | 6 +- MatrixSDK/JSONModels/MXJSONModels.h | 19 ++++ MatrixSDK/JSONModels/MXJSONModels.m | 95 +++++++++++++++++++ MatrixSDK/MXRestClient.h | 4 + MatrixSDK/MXRestClient.m | 45 +++++++++ 8 files changed, 265 insertions(+), 3 deletions(-) diff --git a/MatrixSDK/Categories/MXKeysQueryResponse+Extensions.swift b/MatrixSDK/Categories/MXKeysQueryResponse+Extensions.swift index 61565fb97f..aba66c39ab 100644 --- a/MatrixSDK/Categories/MXKeysQueryResponse+Extensions.swift +++ b/MatrixSDK/Categories/MXKeysQueryResponse+Extensions.swift @@ -39,3 +39,27 @@ extension MXKeysQueryResponse : MXSummable { return keysQueryResponse as! Self } } + + +extension MXKeysQueryResponseRaw : MXSummable { + + public static func +(lhs: MXKeysQueryResponseRaw, rhs: MXKeysQueryResponseRaw) -> Self { + let keysQueryResponse = MXKeysQueryResponseRaw() + + // Casts to original objc NSDictionary are annoying + // but we want to reuse our implementation of NSDictionary.+ + let deviceKeysMap = (lhs.deviceKeys as NSDictionary? ?? NSDictionary()) + + (rhs.deviceKeys as NSDictionary? ?? NSDictionary()) + keysQueryResponse.deviceKeys = deviceKeysMap as? [String : Any] + + let crossSigningKeys = (lhs.crossSigningKeys as NSDictionary? ?? NSDictionary()) + + (rhs.crossSigningKeys as NSDictionary? ?? NSDictionary()) + keysQueryResponse.crossSigningKeys = crossSigningKeys as? [String: MXCrossSigningInfo] + + let failures = (lhs.failures as NSDictionary? ?? NSDictionary()) + + (rhs.failures as NSDictionary? ?? NSDictionary()) + keysQueryResponse.failures = failures as? [AnyHashable : Any] + + return keysQueryResponse as! Self + } +} diff --git a/MatrixSDK/Categories/MXRestClient+Extensions.swift b/MatrixSDK/Categories/MXRestClient+Extensions.swift index 7252d26b31..37bc63c3ec 100644 --- a/MatrixSDK/Categories/MXRestClient+Extensions.swift +++ b/MatrixSDK/Categories/MXRestClient+Extensions.swift @@ -89,4 +89,75 @@ public extension MXRestClient { return operation } + + /// Download users keys by chunks. + /// + /// - Parameters: + /// - users: list of users to get keys for. + /// - token: sync token to pass in the query request, to help. + /// - chunkSize: max number of users to ask for in one CS API request. + /// - success: A block object called when the operation succeeds. + /// - failure: A block object called when the operation fails. + /// - Returns: a MXHTTPOperation instance. + func downloadKeysByChunkRaw(forUsers users: [String], + token: String?, + chunkSize: Int = 250, + success: @escaping (_ keysQueryResponse: MXKeysQueryResponseRaw) -> Void, + failure: @escaping (_ error: NSError?) -> Void) -> MXHTTPOperation { + + // Do not chunk if not needed + if users.count <= chunkSize { + return self.downloadKeysRaw(forUsers: users, token: token) { response in + switch response { + case .success(let keysQueryResponse): + success(keysQueryResponse) + case .failure(let error): + failure(error as NSError) + } + } + } + + MXLog.debug("[MXRestClient+Extensions] downloadKeysByChunk: \(users.count) users with chunkSize:\(chunkSize)") + + // An arbitrary MXHTTPOperation. It will not cancel requests + // but it will avoid to call callbacks in case of a cancellation is requested + let operation = MXHTTPOperation() + + let group = DispatchGroup() + var responses = [MXResponse]() + users.chunked(into: chunkSize).forEach { chunkedUsers in + group.enter() + self.downloadKeysRaw(forUsers: chunkedUsers, token: token) { response in + switch response { + case .success(let keysQueryResponse): + MXLog.debug("[MXRestClient+Extensions] downloadKeysByChunk: Got intermediate response. Got device keys for %@ users. Got cross-signing keys for %@ users \(String(describing: keysQueryResponse.deviceKeys.keys.count)) \(String(describing: keysQueryResponse.crossSigningKeys.count))") + case .failure(let error): + MXLog.debug("[MXRestClient+Extensions] downloadKeysByChunk: Got intermediate error. Error: \(error)") + } + + responses.append(response) + group.leave() + } + } + + group.notify(queue: self.completionQueue) { + MXLog.debug("[MXRestClient+Extensions] downloadKeysByChunk: Got all responses") + + guard operation.isCancelled == false else { + MXLog.debug("[MXRestClient+Extensions] downloadKeysByChunk: Request was cancelled") + return + } + + // Gather all responses in one + let response = responses.reduce(.success(MXKeysQueryResponseRaw()), +) + switch response { + case .success(let keysQueryResponse): + success(keysQueryResponse) + case .failure(let error): + failure(error as NSError) + } + } + + return operation + } } diff --git a/MatrixSDK/Contrib/Swift/MXRestClient.swift b/MatrixSDK/Contrib/Swift/MXRestClient.swift index 33308654fa..58c958cda8 100644 --- a/MatrixSDK/Contrib/Swift/MXRestClient.swift +++ b/MatrixSDK/Contrib/Swift/MXRestClient.swift @@ -1848,6 +1848,10 @@ public extension MXRestClient { return __downloadKeys(forUsers: userIds, token: token, success: currySuccess(completion), failure: curryFailure(completion)) } + @nonobjc @discardableResult func downloadKeysRaw(forUsers userIds: [String], token: String? = nil, completion: @escaping (_ response: MXResponse) -> Void) -> MXHTTPOperation { + return __downloadKeysRaw(forUsers: userIds, token: token, success: currySuccess(completion), failure: curryFailure(completion)) + } + /** Claim one-time keys. diff --git a/MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift b/MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift index 5703725543..a721e00972 100644 --- a/MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift +++ b/MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift @@ -21,13 +21,13 @@ import MatrixSDKCrypto /// to the native REST API client struct MXCryptoRequests { private let restClient: MXRestClient - private let queryScheduler: MXKeysQueryScheduler + private let queryScheduler: MXKeysQueryScheduler init(restClient: MXRestClient) { self.restClient = restClient self.queryScheduler = .init { users in try await performCallbackRequest { completion in - _ = restClient.downloadKeysByChunk( + _ = restClient.downloadKeysByChunkRaw( forUsers: users, token: nil, success: { @@ -96,7 +96,7 @@ struct MXCryptoRequests { } } - func queryKeys(users: [String]) async throws -> MXKeysQueryResponse { + func queryKeys(users: [String]) async throws -> MXKeysQueryResponseRaw { try await queryScheduler.query(users: Set(users)) } diff --git a/MatrixSDK/JSONModels/MXJSONModels.h b/MatrixSDK/JSONModels/MXJSONModels.h index 2a758f1f38..715faa2a9c 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.h +++ b/MatrixSDK/JSONModels/MXJSONModels.h @@ -1125,6 +1125,25 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringGlobal; @end +@interface MXKeysQueryResponseRaw : MXJSONModel + + /** + The device keys per devices per users. + */ + @property (nonatomic) NSDictionary *deviceKeys; + + /** + Cross-signing keys per users. + */ + @property (nonatomic) NSDictionary *crossSigningKeys; + + /** + The failures sorted by homeservers. + */ + @property (nonatomic) NSDictionary *failures; + +@end + /** `MXKeysClaimResponse` represents the response to /keys/claim request made by [MXRestClient claimOneTimeKeysForUsersDevices]. diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index 0052544372..8b97ebd37e 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -1247,6 +1247,101 @@ - (NSDictionary *)JSONDictionary @end +@interface MXKeysQueryResponseRaw () +@end + +@implementation MXKeysQueryResponseRaw + ++ (id)modelFromJSON:(NSDictionary *)JSONDictionary +{ + MXKeysQueryResponseRaw *keysQueryResponse = [[MXKeysQueryResponseRaw alloc] init]; + if (keysQueryResponse) + { + + if ([JSONDictionary[@"device_keys"] isKindOfClass:NSDictionary.class]) + { + keysQueryResponse.deviceKeys = JSONDictionary[@"device_keys"]; + } + + MXJSONModelSetDictionary(keysQueryResponse.failures, JSONDictionary[@"failures"]); + + // Extract cross-signing keys + NSMutableDictionary *crossSigningKeys = [NSMutableDictionary dictionary]; + + // Gather all of them by type by user + NSDictionary*> *allKeys = + @{ + MXCrossSigningKeyType.master: [self extractUserKeysFromJSON:JSONDictionary[@"master_keys"]] ?: @{}, + MXCrossSigningKeyType.selfSigning: [self extractUserKeysFromJSON:JSONDictionary[@"self_signing_keys"]] ?: @{}, + MXCrossSigningKeyType.userSigning: [self extractUserKeysFromJSON:JSONDictionary[@"user_signing_keys"]] ?: @{}, + }; + + // Package them into a `userId -> MXCrossSigningInfo` dictionary + for (NSString *keyType in allKeys) + { + NSDictionary *keys = allKeys[keyType]; + for (NSString *userId in keys) + { + MXCrossSigningInfo *crossSigningInfo = crossSigningKeys[userId]; + if (!crossSigningInfo) + { + crossSigningInfo = [[MXCrossSigningInfo alloc] initWithUserId:userId]; + crossSigningKeys[userId] = crossSigningInfo; + } + + [crossSigningInfo addCrossSigningKey:keys[userId] type:keyType]; + } + } + + keysQueryResponse.crossSigningKeys = crossSigningKeys; + } + + return keysQueryResponse; +} + ++ (NSDictionary*)extractUserKeysFromJSON:(NSDictionary *)keysJSONDictionary +{ + NSMutableDictionary *keys = [NSMutableDictionary dictionary]; + for (NSString *userId in keysJSONDictionary) + { + MXCrossSigningKey *key; + MXJSONModelSetMXJSONModel(key, MXCrossSigningKey, keysJSONDictionary[userId]); + if (key) + { + keys[userId] = key; + } + } + + if (!keys.count) + { + keys = nil; + } + + return keys; +} + +- (NSDictionary *)JSONDictionary +{ + + 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": self.deviceKeys.copy ?: @{}, + @"failures": self.failures.copy ?: @{}, + @"master_keys": master.copy ?: @{}, + @"self_signing_keys": selfSigning.copy ?: @{}, + @"user_signing_keys": userSigning.copy ?: @{} + }; +} + +@end @interface MXKeysClaimResponse () /** diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index 981c3fc992..f47eae634d 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -2485,6 +2485,10 @@ Note: Clients should consider avoiding this endpoint for URLs posted in encrypte success:(void (^)(MXKeysQueryResponse *keysQueryResponse))success failure:(void (^)(NSError *error))failure NS_REFINED_FOR_SWIFT; +- (MXHTTPOperation*)downloadKeysRawForUsers:(NSArray*)userIds + token:(NSString*)token + success:(void (^)(MXKeysQueryResponseRaw *keysQueryResponse))success + failure:(void (^)(NSError *error))failure NS_REFINED_FOR_SWIFT; /** * Claim one-time keys. diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index fc73875a27..7c7929607f 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -4925,6 +4925,51 @@ - (MXHTTPOperation*)downloadKeysForUsers:(NSArray*)userIds }]; } +- (MXHTTPOperation*)downloadKeysRawForUsers:(NSArray*)userIds + token:(NSString *)token + success:(void (^)(MXKeysQueryResponseRaw *keysQueryResponse))success + failure:(void (^)(NSError *error))failure +{ + NSString *path = [NSString stringWithFormat:@"%@/keys/query", kMXAPIPrefixPathR0]; + + NSMutableDictionary *downloadQuery = [NSMutableDictionary dictionary]; + for (NSString *userID in userIds) + { + downloadQuery[userID] = @[]; + } + + NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:@{ + @"device_keys": downloadQuery + }]; + + if (token) + { + parameters[@"token"] = token; + } + + MXWeakify(self); + return [httpClient requestWithMethod:@"POST" + path: path + parameters:parameters + success:^(NSDictionary *JSONResponse) { + MXStrongifyAndReturnIfNil(self); + + if (success) + { + __block MXKeysQueryResponseRaw *keysQueryResponse; + [self dispatchProcessing:^{ + MXJSONModelSetMXJSONModel(keysQueryResponse, MXKeysQueryResponseRaw, JSONResponse); + } andCompletion:^{ + success(keysQueryResponse); + }]; + } + } + failure:^(NSError *error) { + MXStrongifyAndReturnIfNil(self); + [self dispatchFailure:error inBlock:failure]; + }]; +} + - (MXHTTPOperation *)claimOneTimeKeysForUsersDevices:(MXUsersDevicesMap *)usersDevicesKeyTypesMap success:(void (^)(MXKeysClaimResponse *))success failure:(void (^)(NSError *))failure { NSString *path = [NSString stringWithFormat:@"%@/keys/claim", kMXAPIPrefixPathR0]; From b2833e040ea106f852d29c96cf3dbd58d97be5cb Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 18 Jun 2024 16:35:02 +0200 Subject: [PATCH 02/14] Prepare for new sprint From 50dba6b471db8e30b2b956132a3a19d0bba31a68 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 19 Jun 2024 17:12:26 +0200 Subject: [PATCH 03/14] Fix CallKit audio session late init Signed-off-by: Nicolas Buquet --- MatrixSDK/VoIP/CallKit/MXCallKitAdapter.m | 8 ++++++++ changelog.d/pr-1866.bugfix | 1 + 2 files changed, 9 insertions(+) create mode 100644 changelog.d/pr-1866.bugfix diff --git a/MatrixSDK/VoIP/CallKit/MXCallKitAdapter.m b/MatrixSDK/VoIP/CallKit/MXCallKitAdapter.m index 84ea69a403..6fbb55d98a 100644 --- a/MatrixSDK/VoIP/CallKit/MXCallKitAdapter.m +++ b/MatrixSDK/VoIP/CallKit/MXCallKitAdapter.m @@ -226,6 +226,14 @@ - (void)reportIncomingCall:(MXCall *)call { update.supportsUngrouping = NO; update.supportsDTMF = NO; + // If the user tap the "Answer" button from Element's timeline, very often, he can't hear the other user. + // It's because the audio session is not configured at the beginiing of the call. + // It's a flaw in CallKit implementation. + // The audio session need to be configured earlier, like here. + // + // See https://developer.apple.com/forums/thread/64544 (7th post from Apple Engineer) + [self.audioSessionConfigurator configureAudioSessionForVideoCall:call.isVideoCall]; + [self.provider reportNewIncomingCallWithUUID:callUUID update:update completion:^(NSError * _Nullable error) { if (error) { diff --git a/changelog.d/pr-1866.bugfix b/changelog.d/pr-1866.bugfix new file mode 100644 index 0000000000..7d63fd13c5 --- /dev/null +++ b/changelog.d/pr-1866.bugfix @@ -0,0 +1 @@ +Fix CallKit audio session late init in VoIP call. \ No newline at end of file From 04e422e1f70eb3c32b9d0067cf9721bdc295caa0 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 24 Jun 2024 16:57:25 +0200 Subject: [PATCH 04/14] Expose MXRoomPowerLevels Swift wrappers to Element (#1869) Signed-off-by: Nicolas Buquet Co-authored-by: Nicolas Buquet --- MatrixSDK/Contrib/Swift/JSONModels/MXRoomPowerLevels.swift | 4 ++-- changelog.d/pr-1869.change | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelog.d/pr-1869.change diff --git a/MatrixSDK/Contrib/Swift/JSONModels/MXRoomPowerLevels.swift b/MatrixSDK/Contrib/Swift/JSONModels/MXRoomPowerLevels.swift index 47cd8bbd58..f2a3e30e71 100644 --- a/MatrixSDK/Contrib/Swift/JSONModels/MXRoomPowerLevels.swift +++ b/MatrixSDK/Contrib/Swift/JSONModels/MXRoomPowerLevels.swift @@ -25,7 +25,7 @@ extension MXRoomPowerLevels { - parameter eventType: the type of event. - returns: the required minimum power level. */ - @nonobjc func minimumPowerLevelForSendingMessageEvent(_ eventType: MXEventType) -> Int { + @nonobjc public func minimumPowerLevelForSendingMessageEvent(_ eventType: MXEventType) -> Int { return __minimumPowerLevelForSendingEvent(asMessage: eventType.identifier) } @@ -36,7 +36,7 @@ extension MXRoomPowerLevels { - parameter eventType: the type of event. - returns: the required minimum power level. */ - @nonobjc func minimumPowerLevelForSendingStateEvent(_ eventType: MXEventType) -> Int { + @nonobjc public func minimumPowerLevelForSendingStateEvent(_ eventType: MXEventType) -> Int { return __minimumPowerLevelForSendingEvent(asStateEvent: eventType.identifier) } diff --git a/changelog.d/pr-1869.change b/changelog.d/pr-1869.change new file mode 100644 index 0000000000..f921d5ad7e --- /dev/null +++ b/changelog.d/pr-1869.change @@ -0,0 +1 @@ +Expose MXRroomPowerLevels Swift wrappers to Element \ No newline at end of file From 537b404886546dadefb632d843a21ac6742ec1d7 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 2 Jul 2024 16:10:05 +0200 Subject: [PATCH 05/14] implemented for the preview url API --- MatrixSDK/MXEnumConstants.h | 5 +++ MatrixSDK/MXEnumConstants.m | 1 + MatrixSDK/MXRestClient.h | 6 ++++ MatrixSDK/MXRestClient.m | 68 +++++++++++++++++++++++++------------ 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/MatrixSDK/MXEnumConstants.h b/MatrixSDK/MXEnumConstants.h index f41f89023d..6151c12625 100644 --- a/MatrixSDK/MXEnumConstants.h +++ b/MatrixSDK/MXEnumConstants.h @@ -33,6 +33,11 @@ FOUNDATION_EXPORT NSString *const kMXContentUriScheme; */ FOUNDATION_EXPORT NSString *const kMXContentPrefixPath; +/** + A constant representing the default prefix of the Matrix authenticated content repository path. + */ +FOUNDATION_EXPORT NSString *const kMXAuthenticatedContentPrefixPath; + /** A constant representing the URI path for as-yet unspecified of the AntiVirus Client-Server HTTP API. */ diff --git a/MatrixSDK/MXEnumConstants.m b/MatrixSDK/MXEnumConstants.m index 88cb32e176..5853507c4a 100644 --- a/MatrixSDK/MXEnumConstants.m +++ b/MatrixSDK/MXEnumConstants.m @@ -23,6 +23,7 @@ */ NSString *const kMXContentUriScheme = @"mxc://"; NSString *const kMXContentPrefixPath = @"_matrix/media/r0"; +NSString *const kMXAuthenticatedContentPrefixPath = @"_matrix/client/unstable/org.matrix.msc3916/media"; /** Prefix used in path of antivirus server API requests. diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index a44ccbfa54..d6b91d6726 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -229,6 +229,12 @@ extern NSString *const kMXCredentialsNewRefreshTokenDataKey; */ @property (nonatomic) NSString *contentPathPrefix; +/** + The Matrix content repository prefix to use for authenticated access. + By default, it is defined by the constant kMXContentPrefixPath. + */ +@property (nonatomic) NSString *authenticatedContentPathPrefix; + /** The current trusted certificate (if any). */ diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index a4c50fbfc5..e3820cce25 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -145,7 +145,7 @@ @interface MXRestClient () @end @implementation MXRestClient -@synthesize credentials, apiPathPrefix, contentPathPrefix, completionQueue, antivirusServerPathPrefix; +@synthesize credentials, apiPathPrefix, contentPathPrefix, authenticatedContentPathPrefix, completionQueue, antivirusServerPathPrefix; + (dispatch_queue_t)refreshQueue { @@ -198,6 +198,7 @@ -(id)initWithCredentials:(MXCredentials*)inCredentials apiPathPrefix = kMXAPIPrefixPathR0; antivirusServerPathPrefix = kMXAntivirusAPIPrefixPathUnstable; contentPathPrefix = kMXContentPrefixPath; + authenticatedContentPathPrefix = kMXAuthenticatedContentPrefixPath; credentials = inCredentials; _identityServer = credentials.identityServer; @@ -4500,26 +4501,51 @@ - (MXHTTPOperation *)previewForURL:(NSURL *)url parameters[@"url"] = [url absoluteString]; MXWeakify(self); - return [httpClient requestWithMethod:@"GET" - path:[NSString stringWithFormat:@"%@/preview_url", contentPathPrefix] - parameters:parameters - success:^(NSDictionary *JSONResponse) { - MXStrongifyAndReturnIfNil(self); - - if (success) - { - __block MXURLPreview *urlPreview; - [self dispatchProcessing:^{ - MXJSONModelSetMXJSONModel(urlPreview, MXURLPreview, JSONResponse); - } andCompletion:^{ - success(urlPreview); - }]; - } - } - failure:^(NSError *error) { - MXStrongifyAndReturnIfNil(self); - [self dispatchFailure:error inBlock:failure]; - }]; + MXHTTPOperation* operation; + operation = [httpClient requestWithMethod:@"GET" + path:[NSString stringWithFormat:@"%@/preview_url", authenticatedContentPathPrefix] + parameters:parameters + needsAuthentication:YES + success:^(NSDictionary *JSONResponse) { + MXStrongifyAndReturnIfNil(self); + + if (success) + { + __block MXURLPreview *urlPreview; + [self dispatchProcessing:^{ + MXJSONModelSetMXJSONModel(urlPreview, MXURLPreview, JSONResponse); + } andCompletion:^{ + success(urlPreview); + }]; + } + } + failure:^(NSError *error) { + return; + MXStrongifyAndReturnIfNil(self); + MXWeakify(self); + MXHTTPOperation* fallbackOperation = [self->httpClient requestWithMethod:@"GET" + path:[NSString stringWithFormat:@"%@/preview_url", self->contentPathPrefix] + parameters:parameters + success:^(NSDictionary *JSONResponse) { + MXStrongifyAndReturnIfNil(self); + + if (success) + { + __block MXURLPreview *urlPreview; + [self dispatchProcessing:^{ + MXJSONModelSetMXJSONModel(urlPreview, MXURLPreview, JSONResponse); + } andCompletion:^{ + success(urlPreview); + }]; + } + } + failure:^(NSError *error) { + MXStrongifyAndReturnIfNil(self); + [self dispatchFailure:error inBlock:failure]; + }]; + [operation mutateTo: fallbackOperation]; + }]; + return operation; } #pragma mark - Antivirus server API From ab2914275e48b888ae05331c6a4c0d9ebd3b3654 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Wed, 3 Jul 2024 12:17:11 +0200 Subject: [PATCH 06/14] removing return used for testing --- MatrixSDK/MXRestClient.m | 1 - 1 file changed, 1 deletion(-) diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index e3820cce25..863fdf8077 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -4520,7 +4520,6 @@ - (MXHTTPOperation *)previewForURL:(NSURL *)url } } failure:^(NSError *error) { - return; MXStrongifyAndReturnIfNil(self); MXWeakify(self); MXHTTPOperation* fallbackOperation = [self->httpClient requestWithMethod:@"GET" From 15e214c95c2b9d97aae69b3adec5dfe23f61ecd0 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Wed, 3 Jul 2024 13:10:26 +0200 Subject: [PATCH 07/14] using rest client instead of the home server directly --- MatrixSDK/MXSession.m | 2 +- MatrixSDK/Utils/Media/MXMediaManager.h | 9 +++++---- MatrixSDK/Utils/Media/MXMediaManager.m | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 7288253866..18550d042f 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -231,7 +231,7 @@ - (id)initWithMatrixRestClient:(MXRestClient*)mxRestClient { matrixRestClient = mxRestClient; _threePidAddManager = [[MX3PidAddManager alloc] initWithMatrixSession:self]; - mediaManager = [[MXMediaManager alloc] initWithHomeServer:matrixRestClient.homeserver]; + mediaManager = [[MXMediaManager alloc] initWithRestClient:matrixRestClient]; rooms = [NSMutableDictionary dictionary]; roomSummaries = [NSMutableDictionary dictionary]; _roomSummaryUpdateDelegate = [MXRoomSummaryUpdater roomSummaryUpdaterForSession:self]; diff --git a/MatrixSDK/Utils/Media/MXMediaManager.h b/MatrixSDK/Utils/Media/MXMediaManager.h index 325cbe6487..c7ba628dee 100644 --- a/MatrixSDK/Utils/Media/MXMediaManager.h +++ b/MatrixSDK/Utils/Media/MXMediaManager.h @@ -19,6 +19,7 @@ #import #import "MXMediaLoader.h" #import "MXEnumConstants.h" +#import "MXRestClient.h" #if TARGET_OS_IPHONE #import @@ -49,15 +50,15 @@ extern NSString *const kMXMediaManagerDefaultCacheFolder; Create an instance based on a homeserver url. This homeserver URL is required to resolve the Matrix Content URI (in the form of "mxc://..."). - @param homeserverURL the homeserver URL. + @param restClient the REST client. @return a MXMediaManager instance. */ -- (id)initWithHomeServer:(NSString *)homeserverURL; +- (id)initWithRestClient:(MXRestClient *)restClient; /** - The homeserver URL. + The rest client.. */ -@property (nonatomic, readonly) NSString *homeserverURL; +@property (nonatomic, readonly) MXRestClient *restClient; /** Antivirus scanner used to scan medias. diff --git a/MatrixSDK/Utils/Media/MXMediaManager.m b/MatrixSDK/Utils/Media/MXMediaManager.m index ef73ade893..12e593562f 100644 --- a/MatrixSDK/Utils/Media/MXMediaManager.m +++ b/MatrixSDK/Utils/Media/MXMediaManager.m @@ -49,12 +49,12 @@ @implementation MXMediaManager -- (id)initWithHomeServer:(NSString *)homeserverURL +- (id)initWithRestClient:(MXRestClient *)restClient { self = [super init]; if (self) { - _homeserverURL = homeserverURL; + _restClient = restClient; _scanManager = nil; } return self; @@ -376,7 +376,7 @@ - (NSString*)urlOfContent:(NSString*)mxContentURI } else { - mxMediaPrefix = [NSString stringWithFormat:@"%@/%@/download/", _homeserverURL, kMXContentPrefixPath]; + mxMediaPrefix = [NSString stringWithFormat:@"%@/%@/download/", _restClient.homeserver, kMXContentPrefixPath]; } contentURL = [mxContentURI stringByReplacingOccurrencesOfString:kMXContentUriScheme withString:mxMediaPrefix]; @@ -415,7 +415,7 @@ - (NSString*)urlOfContentThumbnail:(NSString*)mxContentURI } else { - mxThumbnailPrefix = [NSString stringWithFormat:@"%@/%@/thumbnail/", _homeserverURL, kMXContentPrefixPath]; + mxThumbnailPrefix = [NSString stringWithFormat:@"%@/%@/thumbnail/", _restClient.homeserver, kMXContentPrefixPath]; } NSString *thumbnailURL = [mxContentURI stringByReplacingOccurrencesOfString:kMXContentUriScheme withString:mxThumbnailPrefix]; @@ -447,7 +447,7 @@ - (NSString*)urlOfContentThumbnail:(NSString*)mxContentURI - (NSString *)urlOfIdenticon:(NSString *)identiconString { - return [NSString stringWithFormat:@"%@/%@/identicon/%@", _homeserverURL, kMXContentPrefixPath, [identiconString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]]; + return [NSString stringWithFormat:@"%@/%@/identicon/%@", _restClient.homeserver, kMXContentPrefixPath, [identiconString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]]; } From 4d22f5e5035f1cd9755b6c63cdb33e0188685edc Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Wed, 3 Jul 2024 13:25:35 +0200 Subject: [PATCH 08/14] added the access token to the media loader request --- MatrixSDK/Utils/Media/MXMediaLoader.h | 7 +++++++ MatrixSDK/Utils/Media/MXMediaLoader.m | 6 ++++-- MatrixSDK/Utils/Media/MXMediaManager.m | 6 +++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/MatrixSDK/Utils/Media/MXMediaLoader.h b/MatrixSDK/Utils/Media/MXMediaLoader.h index 0144719859..b51fde8c18 100644 --- a/MatrixSDK/Utils/Media/MXMediaLoader.h +++ b/MatrixSDK/Utils/Media/MXMediaLoader.h @@ -129,6 +129,11 @@ extern NSString *const kMXMediaUploadIdPrefix; NSTimer* progressCheckTimer; } +/** + The access token. + */ +@property (nonatomic, readonly) NSString* accessToken; + /** The current state of the loader. */ @@ -177,6 +182,8 @@ extern NSString *const kMXMediaUploadIdPrefix; @property (readonly) CGFloat uploadInitialRange; @property (readonly) CGFloat uploadRange; +- (id)initWithAccessToken:(NSString *) accessToken; + /** Cancel the operation. */ diff --git a/MatrixSDK/Utils/Media/MXMediaLoader.m b/MatrixSDK/Utils/Media/MXMediaLoader.m index 9c0cabd8e7..0152d71038 100644 --- a/MatrixSDK/Utils/Media/MXMediaLoader.m +++ b/MatrixSDK/Utils/Media/MXMediaLoader.m @@ -41,11 +41,12 @@ @implementation MXMediaLoader @synthesize statisticsDict; -- (id)init +- (id)initWithAccessToken:(NSString *) accessToken { if (self = [super init]) { _state = MXMediaLoaderStateIdle; + _accessToken = accessToken; } return self; } @@ -144,6 +145,7 @@ - (void)downloadMediaFromURL:(NSString *)url // Use an HTTP POST method to send this data as JSON object. request.HTTPMethod = @"POST"; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + [request setValue: [NSString stringWithFormat:@"Bearer %@", _accessToken] forHTTPHeaderField: @"Authorization"]; request.HTTPBody = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil]; } @@ -378,7 +380,7 @@ - (id)initForUploadWithMatrixSession:(MXSession*)matrixSession initialRange:(CGF { // Create a unique upload Id _uploadId = [NSString stringWithFormat:@"%@%@", kMXMediaUploadIdPrefix, [[NSProcessInfo processInfo] globallyUniqueString]]; - + _accessToken = matrixSession.matrixRestClient.credentials.accessToken; mxSession = matrixSession; _uploadInitialRange = initialRange; _uploadRange = range; diff --git a/MatrixSDK/Utils/Media/MXMediaManager.m b/MatrixSDK/Utils/Media/MXMediaManager.m index 12e593562f..337ed7dfa6 100644 --- a/MatrixSDK/Utils/Media/MXMediaManager.m +++ b/MatrixSDK/Utils/Media/MXMediaManager.m @@ -495,6 +495,7 @@ - (MXMediaLoader*)downloadMediaFromMatrixContentURI:(NSString *)mxContentURI withData:nil andIdentifier:downloadId saveAtFilePath:filePath + accessToken: _restClient.credentials.accessToken scanManager:_scanManager success:success failure:failure]; @@ -535,6 +536,7 @@ - (MXMediaLoader*)downloadThumbnailFromMatrixContentURI:(NSString *)mxContentURI withData:nil andIdentifier:downloadId saveAtFilePath:filePath + accessToken: _restClient.credentials.accessToken scanManager:_scanManager success:success failure:failure]; @@ -545,6 +547,7 @@ + (MXMediaLoader*)downloadMedia:(NSString *)mediaURL withData:(NSDictionary *)data andIdentifier:(NSString *)downloadId saveAtFilePath:(NSString *)filePath + accessToken:(NSString *)accessToken scanManager:(MXScanManager *)scanManager success:(void (^)(NSString *outputFilePath))success failure:(void (^)(NSError *error))failure @@ -592,7 +595,7 @@ + (MXMediaLoader*)downloadMedia:(NSString *)mediaURL else { // Create a media loader to download data - mediaLoader = [[MXMediaLoader alloc] init]; + mediaLoader = [[MXMediaLoader alloc] initWithAccessToken:accessToken]; // Report this loader if (!downloadTable) { @@ -705,6 +708,7 @@ - (MXMediaLoader*)downloadEncryptedMediaFromMatrixContentFile:(MXEncryptedConten withData:dataToPost andIdentifier:downloadId saveAtFilePath:filePath + accessToken: _restClient.credentials.accessToken scanManager:_scanManager success:success failure:failure]; From 1c1760f8de52fa479f852c5e66cea975e50f39a0 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 5 Jul 2024 15:58:37 +0200 Subject: [PATCH 09/14] implementation based on the server version --- MatrixSDK/JSONModels/MXMatrixVersions.h | 6 ++++ MatrixSDK/JSONModels/MXMatrixVersions.m | 9 ++++- MatrixSDK/MXRestClient.h | 4 +++ MatrixSDK/MXRestClient.m | 46 ++++++++----------------- MatrixSDK/Utils/Media/MXMediaManager.m | 8 +++++ 5 files changed, 41 insertions(+), 32 deletions(-) diff --git a/MatrixSDK/JSONModels/MXMatrixVersions.h b/MatrixSDK/JSONModels/MXMatrixVersions.h index b2a0bb1111..2e3d79ffed 100644 --- a/MatrixSDK/JSONModels/MXMatrixVersions.h +++ b/MatrixSDK/JSONModels/MXMatrixVersions.h @@ -35,6 +35,7 @@ struct MXMatrixClientServerAPIVersionStruct __unsafe_unretained NSString * const v1_1; __unsafe_unretained NSString * const v1_2; __unsafe_unretained NSString * const v1_3; + __unsafe_unretained NSString * const v1_11; }; extern const struct MXMatrixClientServerAPIVersionStruct MXMatrixClientServerAPIVersion; @@ -123,6 +124,11 @@ extern const struct MXMatrixVersionsFeatureStruct MXMatrixVersionsFeature; */ @property (nonatomic, readonly) BOOL supportsRedactionWithRelationsUnstable; +/** + Indicate if the server supports MSC3916 + */ +@property (nonatomic, readonly) BOOL supportsAuthenticatedMedia; + @end NS_ASSUME_NONNULL_END diff --git a/MatrixSDK/JSONModels/MXMatrixVersions.m b/MatrixSDK/JSONModels/MXMatrixVersions.m index 2dd5fb81f0..68f5eb996a 100644 --- a/MatrixSDK/JSONModels/MXMatrixVersions.m +++ b/MatrixSDK/JSONModels/MXMatrixVersions.m @@ -27,7 +27,9 @@ .r0_6_1 = @"r0.6.1", .v1_1 = @"v1.1", .v1_2 = @"v1.2", - .v1_3 = @"v1.3" + .v1_3 = @"v1.3", + // missing versions not considered + .v1_11 = @"v1.11" }; const struct MXMatrixVersionsFeatureStruct MXMatrixVersionsFeature = { @@ -145,6 +147,11 @@ - (BOOL)supportsRedactionWithRelationsUnstable return [self serverSupportsFeature:kJSONKeyMSC3912Unstable]; } +- (BOOL)supportsAuthenticatedMedia +{ + return [self serverSupportsVersion:MXMatrixClientServerAPIVersion.v1_11]; +} + #pragma mark - Private - (BOOL)serverSupportsVersion:(NSString *)version diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index d6b91d6726..8c28d094ef 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -251,6 +251,10 @@ extern NSString *const kMXCredentialsNewRefreshTokenDataKey; */ @property (nonatomic, copy) NSSet *acceptableContentTypes; +/** + Supported server versions of the matrix server, only for internal use of the SDK, use the stored version on the app side. + */ +@property (nonatomic, readonly, nullable) MXMatrixVersions *supportedVersions; /** Create an instance based on homeserver url. diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 863fdf8077..184a86654c 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -142,10 +142,11 @@ @interface MXRestClient () */ dispatch_queue_t processingQueue; } +@property(nonatomic, nullable, readwrite) MXMatrixVersions *supportedVersions; @end @implementation MXRestClient -@synthesize credentials, apiPathPrefix, contentPathPrefix, authenticatedContentPathPrefix, completionQueue, antivirusServerPathPrefix; +@synthesize credentials, apiPathPrefix, contentPathPrefix, authenticatedContentPathPrefix, completionQueue, antivirusServerPathPrefix, supportedVersions; + (dispatch_queue_t)refreshQueue { @@ -530,6 +531,7 @@ - (MXHTTPOperation*)supportedMatrixVersions:(void (^)(MXMatrixVersions *matrixVe [self dispatchProcessing:^{ MXJSONModelSetMXJSONModel(matrixVersions, MXMatrixVersions, JSONResponse); } andCompletion:^{ + self.supportedVersions = matrixVersions; success(matrixVersions); }]; } @@ -4499,14 +4501,18 @@ - (MXHTTPOperation *)previewForURL:(NSURL *)url { NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"url"] = [url absoluteString]; + NSString* path = contentPathPrefix; + if (supportedVersions && [supportedVersions supportsAuthenticatedMedia]) + { + path = authenticatedContentPathPrefix; + } MXWeakify(self); - MXHTTPOperation* operation; - operation = [httpClient requestWithMethod:@"GET" - path:[NSString stringWithFormat:@"%@/preview_url", authenticatedContentPathPrefix] - parameters:parameters - needsAuthentication:YES - success:^(NSDictionary *JSONResponse) { + + return [httpClient requestWithMethod:@"GET" + path:[NSString stringWithFormat:@"%@/preview_url", path] + parameters:parameters + success:^(NSDictionary *JSONResponse) { MXStrongifyAndReturnIfNil(self); if (success) @@ -4519,32 +4525,10 @@ - (MXHTTPOperation *)previewForURL:(NSURL *)url }]; } } - failure:^(NSError *error) { + failure:^(NSError *error) { MXStrongifyAndReturnIfNil(self); - MXWeakify(self); - MXHTTPOperation* fallbackOperation = [self->httpClient requestWithMethod:@"GET" - path:[NSString stringWithFormat:@"%@/preview_url", self->contentPathPrefix] - parameters:parameters - success:^(NSDictionary *JSONResponse) { - MXStrongifyAndReturnIfNil(self); - - if (success) - { - __block MXURLPreview *urlPreview; - [self dispatchProcessing:^{ - MXJSONModelSetMXJSONModel(urlPreview, MXURLPreview, JSONResponse); - } andCompletion:^{ - success(urlPreview); - }]; - } - } - failure:^(NSError *error) { - MXStrongifyAndReturnIfNil(self); - [self dispatchFailure:error inBlock:failure]; - }]; - [operation mutateTo: fallbackOperation]; + [self dispatchFailure:error inBlock:failure]; }]; - return operation; } #pragma mark - Antivirus server API diff --git a/MatrixSDK/Utils/Media/MXMediaManager.m b/MatrixSDK/Utils/Media/MXMediaManager.m index 337ed7dfa6..0cc74081a8 100644 --- a/MatrixSDK/Utils/Media/MXMediaManager.m +++ b/MatrixSDK/Utils/Media/MXMediaManager.m @@ -377,6 +377,10 @@ - (NSString*)urlOfContent:(NSString*)mxContentURI else { mxMediaPrefix = [NSString stringWithFormat:@"%@/%@/download/", _restClient.homeserver, kMXContentPrefixPath]; + if (_restClient.supportedVersions && [_restClient.supportedVersions supportsAuthenticatedMedia]) + { + mxMediaPrefix = [NSString stringWithFormat:@"%@/%@/download/", _restClient.homeserver, kMXAuthenticatedContentPrefixPath]; + } } contentURL = [mxContentURI stringByReplacingOccurrencesOfString:kMXContentUriScheme withString:mxMediaPrefix]; @@ -416,6 +420,10 @@ - (NSString*)urlOfContentThumbnail:(NSString*)mxContentURI else { mxThumbnailPrefix = [NSString stringWithFormat:@"%@/%@/thumbnail/", _restClient.homeserver, kMXContentPrefixPath]; + if (_restClient.supportedVersions && [_restClient.supportedVersions supportsAuthenticatedMedia]) + { + mxThumbnailPrefix = [NSString stringWithFormat:@"%@/%@/thumbnail/", _restClient.homeserver, kMXAuthenticatedContentPrefixPath]; + } } NSString *thumbnailURL = [mxContentURI stringByReplacingOccurrencesOfString:kMXContentUriScheme withString:mxThumbnailPrefix]; From 10835525a6fcb30dc0475a36173a6285b8f59d76 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 5 Jul 2024 16:03:59 +0200 Subject: [PATCH 10/14] access token fix and using the stable endpoint prefix --- MatrixSDK/MXEnumConstants.m | 2 +- MatrixSDK/Utils/Media/MXMediaLoader.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MatrixSDK/MXEnumConstants.m b/MatrixSDK/MXEnumConstants.m index 5853507c4a..10f20274e2 100644 --- a/MatrixSDK/MXEnumConstants.m +++ b/MatrixSDK/MXEnumConstants.m @@ -23,7 +23,7 @@ */ NSString *const kMXContentUriScheme = @"mxc://"; NSString *const kMXContentPrefixPath = @"_matrix/media/r0"; -NSString *const kMXAuthenticatedContentPrefixPath = @"_matrix/client/unstable/org.matrix.msc3916/media"; +NSString *const kMXAuthenticatedContentPrefixPath = @"_matrix/client/v1/media"; /** Prefix used in path of antivirus server API requests. diff --git a/MatrixSDK/Utils/Media/MXMediaLoader.m b/MatrixSDK/Utils/Media/MXMediaLoader.m index 0152d71038..d65f10937b 100644 --- a/MatrixSDK/Utils/Media/MXMediaLoader.m +++ b/MatrixSDK/Utils/Media/MXMediaLoader.m @@ -140,12 +140,12 @@ - (void)downloadMediaFromURL:(NSString *)url [request setValue:value forHTTPHeaderField:key]; }]; + [request setValue: [NSString stringWithFormat:@"Bearer %@", _accessToken] forHTTPHeaderField: @"Authorization"]; if (data) { // Use an HTTP POST method to send this data as JSON object. request.HTTPMethod = @"POST"; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; - [request setValue: [NSString stringWithFormat:@"Bearer %@", _accessToken] forHTTPHeaderField: @"Authorization"]; request.HTTPBody = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil]; } From 66f05d0468390bdddf838b73135353408fa5390c Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 5 Jul 2024 16:09:51 +0200 Subject: [PATCH 11/14] documentation --- MatrixSDK/Utils/Media/MXMediaManager.m | 1 + 1 file changed, 1 insertion(+) diff --git a/MatrixSDK/Utils/Media/MXMediaManager.m b/MatrixSDK/Utils/Media/MXMediaManager.m index 0cc74081a8..4aac77d3da 100644 --- a/MatrixSDK/Utils/Media/MXMediaManager.m +++ b/MatrixSDK/Utils/Media/MXMediaManager.m @@ -455,6 +455,7 @@ - (NSString*)urlOfContentThumbnail:(NSString*)mxContentURI - (NSString *)urlOfIdenticon:(NSString *)identiconString { + // Deprecated API, not need to use authenticated for this. return [NSString stringWithFormat:@"%@/%@/identicon/%@", _restClient.homeserver, kMXContentPrefixPath, [identiconString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]]; } From 389fdfad3c763fcc7a5080e5648cf5f7f6765b9a Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 5 Jul 2024 17:11:30 +0200 Subject: [PATCH 12/14] code improvement --- MatrixSDK/MXRestClient.h | 4 ++-- MatrixSDK/MXRestClient.m | 12 ++++-------- MatrixSDK/Utils/Media/MXMediaLoader.h | 5 ----- MatrixSDK/Utils/Media/MXMediaLoader.m | 7 +++++++ MatrixSDK/Utils/Media/MXMediaManager.m | 4 ++-- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index 8c28d094ef..7952d9b043 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -231,7 +231,7 @@ extern NSString *const kMXCredentialsNewRefreshTokenDataKey; /** The Matrix content repository prefix to use for authenticated access. - By default, it is defined by the constant kMXContentPrefixPath. + By default, it is defined by the constant kMXAuthenticatedContentPrefixPath. */ @property (nonatomic) NSString *authenticatedContentPathPrefix; @@ -254,7 +254,7 @@ extern NSString *const kMXCredentialsNewRefreshTokenDataKey; /** Supported server versions of the matrix server, only for internal use of the SDK, use the stored version on the app side. */ -@property (nonatomic, readonly, nullable) MXMatrixVersions *supportedVersions; +@property (readonly) BOOL isUsingAuthenticatedMedia; /** Create an instance based on homeserver url. diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 184a86654c..2691d211f1 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -142,11 +142,11 @@ @interface MXRestClient () */ dispatch_queue_t processingQueue; } -@property(nonatomic, nullable, readwrite) MXMatrixVersions *supportedVersions; +@property(readwrite) BOOL isUsingAuthenticatedMedia; @end @implementation MXRestClient -@synthesize credentials, apiPathPrefix, contentPathPrefix, authenticatedContentPathPrefix, completionQueue, antivirusServerPathPrefix, supportedVersions; +@synthesize credentials, apiPathPrefix, contentPathPrefix, authenticatedContentPathPrefix, completionQueue, antivirusServerPathPrefix, isUsingAuthenticatedMedia; + (dispatch_queue_t)refreshQueue { @@ -531,7 +531,7 @@ - (MXHTTPOperation*)supportedMatrixVersions:(void (^)(MXMatrixVersions *matrixVe [self dispatchProcessing:^{ MXJSONModelSetMXJSONModel(matrixVersions, MXMatrixVersions, JSONResponse); } andCompletion:^{ - self.supportedVersions = matrixVersions; + self->isUsingAuthenticatedMedia = matrixVersions.supportsAuthenticatedMedia; success(matrixVersions); }]; } @@ -4501,11 +4501,7 @@ - (MXHTTPOperation *)previewForURL:(NSURL *)url { NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"url"] = [url absoluteString]; - NSString* path = contentPathPrefix; - if (supportedVersions && [supportedVersions supportsAuthenticatedMedia]) - { - path = authenticatedContentPathPrefix; - } + NSString* path = isUsingAuthenticatedMedia ? authenticatedContentPathPrefix : contentPathPrefix; MXWeakify(self); diff --git a/MatrixSDK/Utils/Media/MXMediaLoader.h b/MatrixSDK/Utils/Media/MXMediaLoader.h index b51fde8c18..2a254c587d 100644 --- a/MatrixSDK/Utils/Media/MXMediaLoader.h +++ b/MatrixSDK/Utils/Media/MXMediaLoader.h @@ -129,11 +129,6 @@ extern NSString *const kMXMediaUploadIdPrefix; NSTimer* progressCheckTimer; } -/** - The access token. - */ -@property (nonatomic, readonly) NSString* accessToken; - /** The current state of the loader. */ diff --git a/MatrixSDK/Utils/Media/MXMediaLoader.m b/MatrixSDK/Utils/Media/MXMediaLoader.m index d65f10937b..d10fbca68b 100644 --- a/MatrixSDK/Utils/Media/MXMediaLoader.m +++ b/MatrixSDK/Utils/Media/MXMediaLoader.m @@ -37,6 +37,13 @@ NSString *const kMXMediaUploadIdPrefix = @"upload-"; + +@interface MXMediaLoader() + +@property (nonatomic, readonly) NSString* accessToken; + +@end + @implementation MXMediaLoader @synthesize statisticsDict; diff --git a/MatrixSDK/Utils/Media/MXMediaManager.m b/MatrixSDK/Utils/Media/MXMediaManager.m index 4aac77d3da..2d40b97564 100644 --- a/MatrixSDK/Utils/Media/MXMediaManager.m +++ b/MatrixSDK/Utils/Media/MXMediaManager.m @@ -377,7 +377,7 @@ - (NSString*)urlOfContent:(NSString*)mxContentURI else { mxMediaPrefix = [NSString stringWithFormat:@"%@/%@/download/", _restClient.homeserver, kMXContentPrefixPath]; - if (_restClient.supportedVersions && [_restClient.supportedVersions supportsAuthenticatedMedia]) + if (_restClient.isUsingAuthenticatedMedia) { mxMediaPrefix = [NSString stringWithFormat:@"%@/%@/download/", _restClient.homeserver, kMXAuthenticatedContentPrefixPath]; } @@ -420,7 +420,7 @@ - (NSString*)urlOfContentThumbnail:(NSString*)mxContentURI else { mxThumbnailPrefix = [NSString stringWithFormat:@"%@/%@/thumbnail/", _restClient.homeserver, kMXContentPrefixPath]; - if (_restClient.supportedVersions && [_restClient.supportedVersions supportsAuthenticatedMedia]) + if (_restClient.isUsingAuthenticatedMedia) { mxThumbnailPrefix = [NSString stringWithFormat:@"%@/%@/thumbnail/", _restClient.homeserver, kMXAuthenticatedContentPrefixPath]; } From 6c4bb3dd1407f0f3c5f72d87a332069a7a2958bc Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 23 Jul 2024 12:49:37 +0200 Subject: [PATCH 13/14] version++ --- CHANGES.md | 11 +++++++++++ MatrixSDK.podspec | 2 +- MatrixSDK/MatrixSDKVersion.m | 2 +- changelog.d/pr-1866.bugfix | 1 - changelog.d/pr-1869.change | 1 - 5 files changed, 13 insertions(+), 4 deletions(-) delete mode 100644 changelog.d/pr-1866.bugfix delete mode 100644 changelog.d/pr-1869.change diff --git a/CHANGES.md b/CHANGES.md index e1305179bf..21cc3f8e7b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,14 @@ +## Changes in 0.27.12 (2024-07-23) + +🙌 Improvements + +- Expose MXRroomPowerLevels Swift wrappers to Element ([#1869](https://github.com/matrix-org/matrix-ios-sdk/pull/1869)) + +🐛 Bugfixes + +- Fix CallKit audio session late init in VoIP call. ([#1866](https://github.com/matrix-org/matrix-ios-sdk/pull/1866)) + + ## Changes in 0.27.11 (2024-06-18) No significant changes. diff --git a/MatrixSDK.podspec b/MatrixSDK.podspec index d786dc03b5..8f4f9387ec 100644 --- a/MatrixSDK.podspec +++ b/MatrixSDK.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "MatrixSDK" - s.version = "0.27.11" + s.version = "0.27.12" s.summary = "The iOS SDK to build apps compatible with Matrix (https://www.matrix.org)" s.description = <<-DESC diff --git a/MatrixSDK/MatrixSDKVersion.m b/MatrixSDK/MatrixSDKVersion.m index 36379dc577..9def75d184 100644 --- a/MatrixSDK/MatrixSDKVersion.m +++ b/MatrixSDK/MatrixSDKVersion.m @@ -16,4 +16,4 @@ #import -NSString *const MatrixSDKVersion = @"0.27.11"; +NSString *const MatrixSDKVersion = @"0.27.12"; diff --git a/changelog.d/pr-1866.bugfix b/changelog.d/pr-1866.bugfix deleted file mode 100644 index 7d63fd13c5..0000000000 --- a/changelog.d/pr-1866.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix CallKit audio session late init in VoIP call. \ No newline at end of file diff --git a/changelog.d/pr-1869.change b/changelog.d/pr-1869.change deleted file mode 100644 index f921d5ad7e..0000000000 --- a/changelog.d/pr-1869.change +++ /dev/null @@ -1 +0,0 @@ -Expose MXRroomPowerLevels Swift wrappers to Element \ No newline at end of file From 4f9bdfc199fff8e9898817e7677c022c58c6b1e2 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 23 Jul 2024 13:39:31 +0200 Subject: [PATCH 14/14] finish version++ --- Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podfile.lock b/Podfile.lock index 2ad77539d2..43b858befb 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -73,4 +73,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 37ab0de0200808bcd3335a637e31736df60fc62e -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2