diff --git a/Riot/Modules/Home/HomeViewController.m b/Riot/Modules/Home/HomeViewController.m index 5cd7c8d5d..7176613ba 100644 --- a/Riot/Modules/Home/HomeViewController.m +++ b/Riot/Modules/Home/HomeViewController.m @@ -44,6 +44,9 @@ @property (nonatomic, strong) SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter; @property (nonatomic, strong) SecureBackupBannerCell *secureBackupBannerPrototypeCell; +@property (nonatomic, strong) KeyVerificationSetupBannerCell *keyVerificationSetupBannerPrototypeCell; +@property (nonatomic, strong) AuthenticatedSessionViewControllerFactory *authenticatedSessionViewControllerFactory; + @end @implementation HomeViewController @@ -79,6 +82,9 @@ // Register key backup banner cells [self.recentsTableView registerNib:SecureBackupBannerCell.nib forCellReuseIdentifier:SecureBackupBannerCell.defaultReuseIdentifier]; + // Register key verification banner cells + [self.recentsTableView registerNib:KeyVerificationSetupBannerCell.nib forCellReuseIdentifier:KeyVerificationSetupBannerCell.defaultReuseIdentifier]; + // Change the table data source. It must be the home view controller itself. self.recentsTableView.dataSource = self; } @@ -153,6 +159,15 @@ return _secureBackupBannerPrototypeCell; } +- (KeyVerificationSetupBannerCell *)keyVerificationSetupBannerPrototypeCell +{ + if (!_keyVerificationSetupBannerPrototypeCell) + { + _keyVerificationSetupBannerPrototypeCell = [self.recentsTableView dequeueReusableCellWithIdentifier:KeyVerificationSetupBannerCell.defaultReuseIdentifier]; + } + return _keyVerificationSetupBannerPrototypeCell; +} + - (void)presentSecureBackupSetup { SecureBackupSetupCoordinatorBridgePresenter *keyBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession]; @@ -289,7 +304,9 @@ { if ((indexPath.section == recentsDataSource.conversationSection && !recentsDataSource.conversationCellDataArray.count) || (indexPath.section == recentsDataSource.peopleSection && !recentsDataSource.peopleCellDataArray.count) - || (indexPath.section == recentsDataSource.secureBackupBannerSection)) + || (indexPath.section == recentsDataSource.secureBackupBannerSection) + || (indexPath.section == recentsDataSource.keyVerificationBannerSection) + ) { return [recentsDataSource tableView:tableView cellForRowAtIndexPath:indexPath]; } @@ -365,12 +382,22 @@ { return [recentsDataSource cellHeightAtIndexPath:indexPath]; } - else if (indexPath.section == recentsDataSource.secureBackupBannerSection) + else if (indexPath.section == recentsDataSource.secureBackupBannerSection || indexPath.section == recentsDataSource.keyVerificationBannerSection) { CGFloat height = 0.0; - SecureBackupBannerCell *sizingCell = self.secureBackupBannerPrototypeCell; - [sizingCell configureFor:recentsDataSource.secureBackupBannerDisplay]; + UITableViewCell *sizingCell; + + if (indexPath.section == recentsDataSource.secureBackupBannerSection) + { + SecureBackupBannerCell *secureBackupBannerCell = self.secureBackupBannerPrototypeCell; + [secureBackupBannerCell configureFor:recentsDataSource.secureBackupBannerDisplay]; + sizingCell = secureBackupBannerCell; + } + else if (indexPath.section == recentsDataSource.keyVerificationBannerSection) + { + sizingCell = self.keyVerificationSetupBannerPrototypeCell; + } [sizingCell layoutIfNeeded]; @@ -408,7 +435,8 @@ - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { // No header in key banner section - if (section == recentsDataSource.secureBackupBannerSection) + if (section == recentsDataSource.secureBackupBannerSection + || section == recentsDataSource.keyVerificationBannerSection) { return 0.0; } @@ -430,6 +458,10 @@ break; } } + else if (indexPath.section == recentsDataSource.keyVerificationBannerSection) + { + [self showKeyVerificationSetup]; + } } #pragma mark - UICollectionViewDataSource @@ -691,4 +723,83 @@ self.secureBackupSetupCoordinatorBridgePresenter = nil; } +#pragma mark - Key verification setup + +- (void)showKeyVerificationSetup +{ + [self setupCrossSigningWithTitle:NSLocalizedStringFromTable(@"key_verification_setup_banner_title", @"Vector", nil) message:NSLocalizedStringFromTable(@"security_settings_user_password_description", @"Vector", nil) success:^{ + + } failure:^(NSError *error) { + + }]; +} + +- (void)setupCrossSigningWithTitle:(NSString*)title + message:(NSString*)message + success:(void (^)(void))success + failure:(void (^)(NSError *error))failure +{ + __block UIViewController *viewController; + [self startActivityIndicator]; + self.view.userInteractionEnabled = NO; + + void (^animationCompletion)(void) = ^void () { + [self stopActivityIndicator]; + self.view.userInteractionEnabled = YES; + }; + + // Get credentials to set up cross-signing + NSString *path = [NSString stringWithFormat:@"%@/keys/device_signing/upload", kMXAPIPrefixPathUnstable]; + self.authenticatedSessionViewControllerFactory = [[AuthenticatedSessionViewControllerFactory alloc] initWithSession:self.mainSession]; + [self.authenticatedSessionViewControllerFactory viewControllerForPath:path + httpMethod:@"POST" + title:title + message:message + onViewController:^(UIViewController * _Nonnull theViewController) + { + viewController = theViewController; + [self presentViewController:viewController animated:YES completion:nil]; + + } onAuthenticated:^(NSDictionary * _Nonnull authParams) { + + [viewController dismissViewControllerAnimated:NO completion:nil]; + viewController = nil; + + MXCrossSigning *crossSigning = self.mainSession.crypto.crossSigning; + if (crossSigning) + { + [crossSigning setupWithAuthParams:authParams success:^{ + animationCompletion(); + + // TODO: Remove this line and refresh key verification setup banner by listening to a local notification cross-signing state change (Add this behavior into the SDK). + [self->recentsDataSource setDelegate:self andRecentsDataSourceMode:RecentsDataSourceModeHome]; + + [self refreshRecentsTable]; + success(); + } failure:^(NSError * _Nonnull error) { + animationCompletion(); + [self refreshRecentsTable]; + + [[AppDelegate theDelegate] showErrorAsAlert:error]; + failure(error); + }]; + } + + } onCancelled:^{ + animationCompletion(); + + [viewController dismissViewControllerAnimated:NO completion:nil]; + viewController = nil; + failure(nil); + } onFailure:^(NSError * _Nonnull error) { + + animationCompletion(); + [[AppDelegate theDelegate] showErrorAsAlert:error]; + + [viewController dismissViewControllerAnimated:NO completion:nil]; + viewController = nil; + failure(error); + }]; +} + @end diff --git a/Riot/Modules/KeyVerification/Banners/KeyVerificationSetupBannerCell.swift b/Riot/Modules/KeyVerification/Banners/KeyVerificationSetupBannerCell.swift index 568dc0e86..11719b516 100644 --- a/Riot/Modules/KeyVerification/Banners/KeyVerificationSetupBannerCell.swift +++ b/Riot/Modules/KeyVerification/Banners/KeyVerificationSetupBannerCell.swift @@ -58,6 +58,7 @@ final class KeyVerificationSetupBannerCell: MXKTableViewCell, Themable { override func awakeFromNib() { super.awakeFromNib() + // TODO: Image size is too small, use an higher resolution one. let shieldImage = Asset.Images.encryptionNormal.image.withRenderingMode(.alwaysTemplate) self.shieldImageView.image = shieldImage