Skip to content

Commit

Permalink
Merge branch 'release/0.25.2/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
pixlwave committed Feb 21, 2023
2 parents c98a2d6 + ee07c36 commit 765768f
Show file tree
Hide file tree
Showing 33 changed files with 399 additions and 162 deletions.
18 changes: 18 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
## Changes in 0.25.2 (2023-02-21)

🙌 Improvements

- Polls: add fallback text for poll ended events. ([#1713](https://github.com/matrix-org/matrix-ios-sdk/pull/1713))
- Push Rules: Apply push rules client side for encrypted rooms, including mentions and keywords. ([#1714](https://github.com/matrix-org/matrix-ios-sdk/pull/1714))
- Typealias MXResponse to Swift.Result ([#1715](https://github.com/matrix-org/matrix-ios-sdk/pull/1715))
- CryptoV2: Unify verification event processing ([#1717](https://github.com/matrix-org/matrix-ios-sdk/pull/1717))
- Encryption: add encryption to rooms' last messages.
WARNING: the migration to this database version will cause an initial full sync. ([#1718](https://github.com/matrix-org/matrix-ios-sdk/pull/1718))

🐛 Bugfixes

- Avoid sending a verification cancel request while the session is closed
Fix of some retain cycles ([#1716](https://github.com/matrix-org/matrix-ios-sdk/pull/1716))
- Fix an issue where MXMediaLoader would not start downloading until the end of the scroll. ([#1721](https://github.com/matrix-org/matrix-ios-sdk/pull/1721))


## Changes in 0.25.1 (2023-02-07)

✨ Features
Expand Down
2 changes: 1 addition & 1 deletion MatrixSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "MatrixSDK"
s.version = "0.25.1"
s.version = "0.25.2"
s.summary = "The iOS SDK to build apps compatible with Matrix (https://www.matrix.org)"

s.description = <<-DESC
Expand Down
2 changes: 1 addition & 1 deletion MatrixSDK/Background/Crypto/MXLegacyBackgroundCrypto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class MXLegacyBackgroundCrypto: MXBackgroundCrypto {
let decryptionResult = MXEventDecryptionResult()
decryptionResult.clearEvent = olmResult.payload
decryptionResult.senderCurve25519Key = olmResult.senderKey
decryptionResult.claimedEd25519Key = olmResult.keysClaimed["ed25519"] as? String
decryptionResult.claimedEd25519Key = olmResult.keysClaimed?["ed25519"] as? String
decryptionResult.forwardingCurve25519KeyChain = olmResult.forwardingCurve25519KeyChain
decryptionResult.isUntrusted = olmResult.isUntrusted
event.setClearData(decryptionResult)
Expand Down
4 changes: 2 additions & 2 deletions MatrixSDK/Background/MXBackgroundPushRulesManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ import Foundation
.roomMemberCount: memberCountConditionChecker,
.senderNotificationPermission: permissionConditionChecker
]

let eventDictionary = event.jsonDictionary()
// getting the unencrypted event if present or fallback
let eventDictionary = (event.clear ?? event).jsonDictionary()
let equivalentCondition = MXPushRuleCondition()

for rule in flatRules.filter({ $0.enabled }) {
Expand Down
16 changes: 11 additions & 5 deletions MatrixSDK/Background/MXBackgroundSyncService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,9 @@ public enum MXBackgroundSyncServiceError: Error {
}()

pushRulesManager = MXBackgroundPushRulesManager(withCredentials: credentials)
if let accountData = syncResponseStoreManager.syncResponseStore.accountData {
pushRulesManager.handleAccountData(accountData)
} else if let accountData = store.userAccountData ?? nil {
pushRulesManager.handleAccountData(accountData)
}
MXLog.debug("[MXBackgroundSyncService] init complete")
super.init()
syncPushRuleManagerWithAccountData()
}

/// Fetch event with given event and room identifiers. It performs a sync if the event not found in session store.
Expand Down Expand Up @@ -500,5 +496,15 @@ public enum MXBackgroundSyncServiceError: Error {
MXLog.debug("[MXBackgroundSyncService] updateBackgroundServiceStoresIfNeeded: Reset MXBackgroundCryptoStore")
crypto.reset()
}

syncPushRuleManagerWithAccountData()
}

private func syncPushRuleManagerWithAccountData() {
if let accountData = syncResponseStoreManager.syncResponseStore.accountData {
pushRulesManager.handleAccountData(accountData)
} else if let accountData = store.userAccountData ?? nil {
pushRulesManager.handleAccountData(accountData)
}
}
}
78 changes: 33 additions & 45 deletions MatrixSDK/Contrib/Swift/MXResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@

import Foundation




/**
Captures the result of an API call and it's associated success data.
Expand Down Expand Up @@ -47,43 +44,45 @@ import Foundation
}
*/
@frozen public enum MXResponse<T> {
case success(T)
case failure(Error)
// Note: Additional cases break binary compatibility

public typealias MXResponse<T> = Result<T, Error>

public extension MXResponse {
/// Indicates whether the API call was successful
public var isSuccess: Bool {
var isSuccess: Bool {
switch self {
case .success: return true
default: return false
case .success:
return true
default:
return false
}
}

/// The response's success value, if applicable
public var value: T? {
var value: Success? {
switch self {
case .success(let value): return value
default: return nil
case .success(let value):
return value
default:
return nil
}
}

/// Indicates whether the API call failed
public var isFailure: Bool {
return !isSuccess
var isFailure: Bool {
!isSuccess
}

/// The response's error value, if applicable
public var error: Error? {
var error: Error? {
switch self {
case .failure(let error): return error
default: return nil
case .failure(let error):
return error
default:
return nil
}
}
}



/**
Represents an error that was unexpectedly nil.
Expand All @@ -93,13 +92,11 @@ import Foundation
*/
internal struct _MXUnknownError : Error {
var localizedDescription: String {
return "error object was unexpectedly nil"
"error object was unexpectedly nil"
}
}


private extension MXResponse {

/**
Take the value from an optional, if it's available.
Otherwise, return a failure with _MXUnknownError
Expand All @@ -108,8 +105,8 @@ private extension MXResponse {
- returns: `.success(value)` if the value is not `nil`, otherwise `.failure(_MXUnkownError())`
*/
static func fromOptional(value: Any?) -> MXResponse<T> {
if let value = value as? T {
static func fromOptional(value: Any?) -> MXResponse<Success> {
if let value = value as? Success {
return .success(value)
} else {
return .failure(_MXUnknownError())
Expand All @@ -124,33 +121,25 @@ private extension MXResponse {
- returns: `.failure(error)` if the value is not `nil`, otherwise `.failure(_MXUnkownError())`
*/
static func fromOptional(error: Error?) -> MXResponse<T> {
return .failure(error ?? _MXUnknownError())
static func fromOptional(error: Error?) -> MXResponse<Success> {
.failure(error ?? _MXUnknownError())
}
}



public extension MXResponse where T: MXSummable {
static func +(lhs: MXResponse<T>, rhs: MXResponse<T>) -> MXResponse<T> {

public extension MXResponse where Success: MXSummable {
static func +(lhs: Self, rhs: Self) -> Self {
// Once there is an error, the result will be an error
switch (lhs, rhs) {
case (.failure(_), _):
return lhs
case (_, .failure(_)):
return rhs
case (.success(let lhsT), .success(let rhsT)):
return .success(lhsT + rhsT)
case (.failure(_), _):
return lhs
case (_, .failure(_)):
return rhs
case (.success(let lhsT), .success(let rhsT)):
return .success(lhsT + rhsT)
}
}
}






/**
Return a closure that accepts any object, converts it to a MXResponse value, and then
executes the provided completion block
Expand All @@ -167,7 +156,6 @@ public extension MXResponse where T: MXSummable {
- returns: a block that accepts an optional value from the API, wraps it in an `MXResponse`, and then passes it to `completion`
## Usage Example:
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ actor MXRoomEventDecryption: MXRoomEventDecrypting {
event.content?["algorithm"] as? String == kMXCryptoMegolmAlgorithm,
let sessionId = sessionId(for: event)
else {
log.debug("Ignoring unencrypted or non-room event `\(eventId)`")
if !event.isEncrypted {
log.debug("Ignoring unencrypted event`\(eventId)`")
} else if event.clear != nil {
log.debug("Ignoring already decrypted event`\(eventId)`")
} else {
log.debug("Ignoring non-room event `\(eventId)`")
}

let result = MXEventDecryptionResult()
result.clearEvent = event.clear?.jsonDictionary()
Expand Down
36 changes: 29 additions & 7 deletions MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,13 @@ extension MXCryptoMachine: MXCryptoRoomEventDecrypting {
log.failure("Invalid event")
throw Error.invalidEvent
}
return try machine.decryptRoomEvent(event: eventString, roomId: roomId, handleVerificatonEvents: true)
return try machine.decryptRoomEvent(
event: eventString,
roomId: roomId,
// Handling verification events automatically during event decryption is now a deprecated behavior,
// all verification events are handled manually via `receiveVerificationEvent`
handleVerificatonEvents: false
)
}

func requestRoomKey(event: MXEvent) async throws {
Expand Down Expand Up @@ -521,12 +527,9 @@ extension MXCryptoMachine: MXCryptoCrossSigning {
}

extension MXCryptoMachine: MXCryptoVerifying {
func receiveUnencryptedVerificationEvent(event: MXEvent, roomId: String) async throws {
guard let string = event.jsonString() else {
throw Error.invalidEvent
}

try machine.receiveUnencryptedVerificationEvent(event: string, roomId: roomId)
func receiveVerificationEvent(event: MXEvent, roomId: String) async throws {
let event = try verificationEventString(for: event)
try machine.receiveVerificationEvent(event: event, roomId: roomId)

// Out-of-sync check if there are any verification events to sent out as a result of
// the event just received
Expand Down Expand Up @@ -641,6 +644,25 @@ extension MXCryptoMachine: MXCryptoVerifying {
try await group.waitForAll()
}
}

private func verificationEventString(for event: MXEvent) throws -> String {
guard var dictionary = event.jsonDictionary() else {
throw Error.invalidEvent
}

// If this is a decrypted event, we need to swap out `type` and `content` properties
// as this is what the crypto machine expects decrypted events to look like
if let clear = event.clear {
dictionary["type"] = clear.type
dictionary["content"] = clear.content
}

guard let string = MXTools.serialiseJSONObject(dictionary) else {
throw Error.invalidEvent
}

return string
}
}

extension MXCryptoMachine: MXCryptoBackup {
Expand Down
2 changes: 1 addition & 1 deletion MatrixSDK/Crypto/CryptoMachine/MXCryptoProtocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ protocol MXCryptoCrossSigning: MXCryptoUserIdentitySource {
/// Verification functionality
protocol MXCryptoVerifying: MXCryptoIdentity {
func downloadKeysIfNecessary(users: [String]) async throws
func receiveUnencryptedVerificationEvent(event: MXEvent, roomId: String) async throws
func receiveVerificationEvent(event: MXEvent, roomId: String) async throws
func requestSelfVerification(methods: [String]) async throws -> VerificationRequestProtocol
func requestVerification(userId: String, roomId: String, methods: [String]) async throws -> VerificationRequestProtocol
func requestVerification(userId: String, deviceId: String, methods: [String]) async throws -> VerificationRequestProtocol
Expand Down
25 changes: 16 additions & 9 deletions MatrixSDK/Crypto/CryptoMachine/MXCryptoRequests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct MXCryptoRequests {
}

func sendToDevice(request: ToDeviceRequest) async throws {
return try await performCallbackRequest {
try await performCallbackRequest {
restClient.sendDirectToDevice(
payload: .init(
eventType: request.eventType,
Expand All @@ -54,7 +54,7 @@ struct MXCryptoRequests {
}

func uploadKeys(request: UploadKeysRequest) async throws -> MXKeysUploadResponse {
return try await performCallbackRequest {
try await performCallbackRequest {
restClient.uploadKeys(
request.deviceKeys,
oneTimeKeys: request.oneTimeKeys,
Expand Down Expand Up @@ -101,25 +101,32 @@ struct MXCryptoRequests {
}

func claimKeys(request: ClaimKeysRequest) async throws -> MXKeysClaimResponse {
return try await performCallbackRequest {
try await performCallbackRequest {
restClient.claimOneTimeKeys(for: request.devices, completion: $0)
}
}

@MainActor
// Calling methods on `MXRoom` has various state side effects so should be called on the main thread
func roomMessage(request: RoomMessageRequest) async throws -> String? {
var event: MXEvent?
return try await performCallbackRequest {
try await withCheckedThrowingContinuation { continuation in
var event: MXEvent?
request.room.sendEvent(
MXEventType(identifier: request.eventType),
content: request.content,
localEcho: &event,
completion: $0
)
localEcho: &event) { response in
switch response {
case .success(let value):
continuation.resume(returning: value)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}

func backupKeys(request: KeysBackupRequest) async throws -> [AnyHashable: Any] {
return try await performCallbackRequest { continuation in
try await performCallbackRequest { continuation in
restClient.sendKeysBackup(
request.keysBackupData,
version: request.version,
Expand Down
2 changes: 2 additions & 0 deletions MatrixSDK/Crypto/KeyBackup/Engine/MXNativeKeyBackupEngine.m
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ - (BOOL)enableBackupWithKeyBackupVersion:(MXKeyBackupVersion *)keyBackupVersion
self.crypto.store.backupVersion = keyBackupVersion.version;
Class algorithmClass = AlgorithmClassesByName[keyBackupVersion.algorithm];
// store the desired backup algorithm
MXWeakify(self);
self.keyBackupAlgorithm = [[algorithmClass alloc] initWithCrypto:self.crypto authData:authData keyGetterBlock:^NSData * _Nullable{
MXStrongifyAndReturnValueIfNil(self, nil);
return self.privateKey;
}];
MXLogDebug(@"[MXNativeKeyBackupEngine] enableBackupWithVersion: Algorithm set to: %@", self.keyBackupAlgorithm);
Expand Down
3 changes: 3 additions & 0 deletions MatrixSDK/Crypto/MXCrypto.m
Original file line number Diff line number Diff line change
Expand Up @@ -2665,8 +2665,11 @@ - (void)registerEventHandlers
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onToDeviceEvent:) name:kMXSessionOnToDeviceEventNotification object:self.mxSession];

// Observe membership changes
MXWeakify(self);
self->roomMembershipEventsListener = [self.mxSession listenToEventsOfTypes:@[kMXEventTypeStringRoomEncryption, kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXTimelineDirection direction, id customObject) {

MXStrongifyAndReturnIfNil(self);

if (direction == MXTimelineDirectionForwards)
{
if (event.eventType == MXEventTypeRoomEncryption)
Expand Down
Loading

0 comments on commit 765768f

Please sign in to comment.