diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index 18234d6de2..ddde73e322 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -3841,33 +3841,45 @@ - (void)createDirectChatWithUserId:(NSString*)userId completion:(void (^)(void)) // Create a new room by inviting the other user only if it is defined and not oneself NSArray *invite = ((userId && ![mxSession.myUser.userId isEqualToString:userId]) ? @[userId] : nil); - MXRoomCreationParameters *roomCreationParameters = [MXRoomCreationParameters new]; - roomCreationParameters.visibility = kMXRoomDirectoryVisibilityPrivate; - roomCreationParameters.inviteArray = invite; - roomCreationParameters.isDirect = (invite.count != 0); - roomCreationParameters.preset = kMXRoomPresetTrustedPrivateChat; - - [mxSession createRoomWithParameters:roomCreationParameters success:^(MXRoom *room) { - - // Open created room - [self showRoom:room.roomId andEventId:nil withMatrixSession:mxSession]; + void (^onFailure)(NSError *) = ^(NSError *error){ + NSLog(@"[AppDelegate] Create direct chat failed"); + //Alert user + [self showErrorAsAlert:error]; if (completion) { completion(); } + }; - } failure:^(NSError *error) { - - NSLog(@"[AppDelegate] Create direct chat failed"); - //Alert user - [self showErrorAsAlert:error]; + [mxSession canEnableE2EByDefaultInNewRoomWithUsers:invite success:^(BOOL canEnableE2E) { + + MXRoomCreationParameters *roomCreationParameters = [MXRoomCreationParameters new]; + roomCreationParameters.visibility = kMXRoomDirectoryVisibilityPrivate; + roomCreationParameters.inviteArray = invite; + roomCreationParameters.isDirect = (invite.count != 0); + roomCreationParameters.preset = kMXRoomPresetTrustedPrivateChat; - if (completion) + if (canEnableE2E) { - completion(); + roomCreationParameters.initialStateEvents = @[ + [MXRoomCreationParameters initialStateEventForEncryptionWithAlgorithm:kMXCryptoMegolmAlgorithm + ]]; } - }]; + + [mxSession createRoomWithParameters:roomCreationParameters success:^(MXRoom *room) { + + // Open created room + [self showRoom:room.roomId andEventId:nil withMatrixSession:mxSession]; + + if (completion) + { + completion(); + } + + } failure:onFailure]; + + } failure:onFailure]; } else if (completion) { diff --git a/Riot/Categories/MXSession+Riot.h b/Riot/Categories/MXSession+Riot.h index 9bc296a980..b907e64a18 100644 --- a/Riot/Categories/MXSession+Riot.h +++ b/Riot/Categories/MXSession+Riot.h @@ -25,4 +25,18 @@ */ - (NSUInteger)riot_missedDiscussionsCount; +/** + Decide if E2E must be enabled in a new room with a list users + + @param userIds the list of users; + + @param success A block object called when the operation succeeds. + @param failure A block object called when the operation fails. + + @return a MXHTTPOperation instance. + */ +- (MXHTTPOperation*)canEnableE2EByDefaultInNewRoomWithUsers:(NSArray*)userIds + success:(void (^)(BOOL canEnableE2E))success + failure:(void (^)(NSError *error))failure; + @end diff --git a/Riot/Categories/MXSession+Riot.m b/Riot/Categories/MXSession+Riot.m index 3d8805b5e3..1281f4db41 100644 --- a/Riot/Categories/MXSession+Riot.m +++ b/Riot/Categories/MXSession+Riot.m @@ -17,6 +17,7 @@ #import "MXSession+Riot.h" #import "MXRoom+Riot.h" +#import "Riot-Swift.h" @implementation MXSession (Riot) @@ -48,4 +49,37 @@ - (NSUInteger)riot_missedDiscussionsCount return missedDiscussionsCount; } +- (MXHTTPOperation*)canEnableE2EByDefaultInNewRoomWithUsers:(NSArray*)userIds + success:(void (^)(BOOL canEnableE2E))success + failure:(void (^)(NSError *error))failure +{ + MXHTTPOperation *operation; + if (RiotSettings.shared.enableCrossSigning) + { + // Check whether all users have uploaded device keys before. + // If so, encryption can be enabled in the new room + operation = [self.crypto downloadKeys:userIds forceDownload:NO success:^(MXUsersDevicesMap *usersDevicesInfoMap, NSDictionary *crossSigningKeysMap) { + + BOOL allUsersHaveDeviceKeys = YES; + for (NSString *userId in userIds) + { + if ([usersDevicesInfoMap deviceIdsForUser:userId].count == 0) + { + allUsersHaveDeviceKeys = NO; + break; + } + } + + success(allUsersHaveDeviceKeys); + + } failure:failure]; + } + else + { + success(NO); + } + + return operation; +} + @end diff --git a/Riot/Modules/Contacts/Details/ContactDetailsViewController.m b/Riot/Modules/Contacts/Details/ContactDetailsViewController.m index a2106226e8..a6c9684967 100644 --- a/Riot/Modules/Contacts/Details/ContactDetailsViewController.m +++ b/Riot/Modules/Contacts/Details/ContactDetailsViewController.m @@ -20,6 +20,7 @@ #import "AppDelegate.h" #import "Riot-Swift.h" +#import "MXSession+Riot.h" #import "RoomMemberTitleView.h" @@ -1040,33 +1041,52 @@ - (void)onActionButtonPressed:(id)sender { inviteArray = @[participantId]; } - - // Create a new room - MXRoomCreationParameters *roomCreationParameters = [MXRoomCreationParameters new]; - roomCreationParameters.visibility = kMXRoomDirectoryVisibilityPrivate; - roomCreationParameters.inviteArray = inviteArray; - roomCreationParameters.invite3PIDArray = invite3PIDArray; - roomCreationParameters.isDirect = YES; - roomCreationParameters.preset = kMXRoomPresetTrustedPrivateChat; - roomCreationRequest = [self.mainSession createRoomWithParameters:roomCreationParameters success:^(MXRoom *room) { - - roomCreationRequest = nil; - - [self removePendingActionMask]; - [[AppDelegate theDelegate] showRoom:room.roomId andEventId:nil withMatrixSession:self.mainSession]; - - } failure:^(NSError *error) { + MXWeakify(self); + void (^onFailure)(NSError *) = ^(NSError *error){ + MXStrongifyAndReturnIfNil(self); NSLog(@"[ContactDetailsViewController] Create room failed"); - roomCreationRequest = nil; + self->roomCreationRequest = nil; [self removePendingActionMask]; // Notify user [[AppDelegate theDelegate] showErrorAsAlert:error]; - }]; + }; + + + // Create a new room + [self.mainSession canEnableE2EByDefaultInNewRoomWithUsers:inviteArray success:^(BOOL canEnableE2E) { + MXStrongifyAndReturnIfNil(self); + + MXRoomCreationParameters *roomCreationParameters = [MXRoomCreationParameters new]; + roomCreationParameters.visibility = kMXRoomDirectoryVisibilityPrivate; + roomCreationParameters.inviteArray = inviteArray; + roomCreationParameters.invite3PIDArray = invite3PIDArray; + roomCreationParameters.isDirect = YES; + roomCreationParameters.preset = kMXRoomPresetTrustedPrivateChat; + + if (canEnableE2E && roomCreationParameters.invite3PIDArray == nil) + { + roomCreationParameters.initialStateEvents = @[ + [MXRoomCreationParameters initialStateEventForEncryptionWithAlgorithm:kMXCryptoMegolmAlgorithm + ]]; + } + + + self->roomCreationRequest = [self.mainSession createRoomWithParameters:roomCreationParameters success:^(MXRoom *room) { + + self->roomCreationRequest = nil; + + [self removePendingActionMask]; + + [[AppDelegate theDelegate] showRoom:room.roomId andEventId:nil withMatrixSession:self.mainSession]; + + } failure:onFailure]; + + } failure:onFailure]; } break; } diff --git a/Riot/Modules/StartChat/StartChatViewController.m b/Riot/Modules/StartChat/StartChatViewController.m index 9c77482440..dcf7280504 100644 --- a/Riot/Modules/StartChat/StartChatViewController.m +++ b/Riot/Modules/StartChat/StartChatViewController.m @@ -19,6 +19,7 @@ #import "AppDelegate.h" #import "Riot-Swift.h" +#import "MXSession+Riot.h" @interface StartChatViewController () { @@ -571,36 +572,51 @@ - (IBAction)onButtonPressed:(id)sender { // Ensure direct chat are created with equal ops on both sides (the trusted_private_chat preset) MXRoomPreset preset = (isDirect ? kMXRoomPresetTrustedPrivateChat : nil); - - // Create new room - MXRoomCreationParameters *roomCreationParameters = [MXRoomCreationParameters new]; - roomCreationParameters.visibility = kMXRoomDirectoryVisibilityPrivate; - roomCreationParameters.inviteArray = inviteArray.count ? inviteArray : nil; - roomCreationParameters.invite3PIDArray = invite3PIDArray.count ? invite3PIDArray : nil; - roomCreationParameters.isDirect = isDirect; - roomCreationParameters.preset = preset; - roomCreationRequest = [self.mainSession createRoomWithParameters:roomCreationParameters success:^(MXRoom *room) { + MXWeakify(self); + void (^onFailure)(NSError *) = ^(NSError *error){ + MXStrongifyAndReturnIfNil(self); - roomCreationRequest = nil; + self->createBarButtonItem.enabled = YES; + self->roomCreationRequest = nil; [self stopActivityIndicator]; - [[AppDelegate theDelegate] showRoom:room.roomId andEventId:nil withMatrixSession:self.mainSession]; + NSLog(@"[StartChatViewController] Create room failed"); - } failure:^(NSError *error) { + // Alert user + [[AppDelegate theDelegate] showErrorAsAlert:error]; + }; - createBarButtonItem.enabled = YES; + [self.mainSession canEnableE2EByDefaultInNewRoomWithUsers:kMXCryptoMegolmAlgorithm success:^(BOOL canEnableE2E) { + MXStrongifyAndReturnIfNil(self); - roomCreationRequest = nil; - [self stopActivityIndicator]; + // Create new room + MXRoomCreationParameters *roomCreationParameters = [MXRoomCreationParameters new]; + roomCreationParameters.visibility = kMXRoomDirectoryVisibilityPrivate; + roomCreationParameters.inviteArray = inviteArray.count ? inviteArray : nil; + roomCreationParameters.invite3PIDArray = invite3PIDArray.count ? invite3PIDArray : nil; + roomCreationParameters.isDirect = isDirect; + roomCreationParameters.preset = preset; - NSLog(@"[StartChatViewController] Create room failed"); + if (canEnableE2E && roomCreationParameters.invite3PIDArray == nil) + { + roomCreationParameters.initialStateEvents = @[ + [MXRoomCreationParameters initialStateEventForEncryptionWithAlgorithm:kMXCryptoMegolmAlgorithm + ]]; + } - // Alert user - [[AppDelegate theDelegate] showErrorAsAlert:error]; + self->roomCreationRequest = [self.mainSession createRoomWithParameters:roomCreationParameters success:^(MXRoom *room) { - }]; + self->roomCreationRequest = nil; + + [self stopActivityIndicator]; + + [[AppDelegate theDelegate] showRoom:room.roomId andEventId:nil withMatrixSession:self.mainSession]; + + } failure:onFailure]; + + } failure:onFailure]; } } else if (sender == self.navigationItem.leftBarButtonItem)