mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-19 08:03:50 +02:00
Merge branch 'develop' into xcode11
# Conflicts: # CHANGES.rst # Riot.xcodeproj/project.pbxproj
This commit is contained in:
@@ -29,11 +29,17 @@
|
||||
|
||||
#import "Riot-Swift.h"
|
||||
|
||||
// Dev flag for demoing what could be the settings
|
||||
// There is still a lot of TODO behind
|
||||
//#define NEW_CROSS_SIGNING_FLOW
|
||||
|
||||
enum
|
||||
{
|
||||
SECTION_CRYPTO_SESSIONS,
|
||||
SECTION_CROSSSIGNING,
|
||||
#ifdef NEW_CROSS_SIGNING_FLOW
|
||||
SECTION_SECURE_BACKUP,
|
||||
#endif
|
||||
SECTION_CRYPTOGRAPHY,
|
||||
SECTION_KEYBACKUP,
|
||||
SECTION_ADVANCED,
|
||||
@@ -46,6 +52,22 @@ enum {
|
||||
CROSSSIGNING_SECOND_ACTION, // Reset
|
||||
};
|
||||
|
||||
enum {
|
||||
SECURE_BACKUP_DESCRIPTION,
|
||||
// TODO: We can display the state of 4S both locally and on the server. Then, provide actions according to all combinations.
|
||||
// - Does the 4S contains all the 4 keys server side?
|
||||
// - Advice the user to do a recovery if there is less keys locally
|
||||
// - Advice them to do a recovery if local keys are obsolete -> We cannot know now
|
||||
// - Advice them to fix a secure backup if there is 4S but no key backup
|
||||
// - Warm them if there is no 4S and they do not have all 3 signing keys locally. They will set up a not complete secure backup
|
||||
SECURE_BACKUP_INFO,
|
||||
SECURE_BACKUP_SETUP,
|
||||
SECURE_BACKUP_RESTORE,
|
||||
SECURE_BACKUP_DELETE,
|
||||
SECURE_BACKUP_MANAGE_MANUALLY, // TODO: What to do with that?
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
CRYPTOGRAPHY_INFO,
|
||||
CRYPTOGRAPHY_EXPORT, // TODO: To move to SECTION_KEYBACKUP
|
||||
@@ -63,7 +85,9 @@ enum {
|
||||
SettingsKeyBackupTableViewSectionDelegate,
|
||||
KeyBackupSetupCoordinatorBridgePresenterDelegate,
|
||||
KeyBackupRecoverCoordinatorBridgePresenterDelegate,
|
||||
UIDocumentInteractionControllerDelegate>
|
||||
UIDocumentInteractionControllerDelegate,
|
||||
SecretsRecoveryCoordinatorBridgePresenterDelegate,
|
||||
SecureBackupSetupCoordinatorBridgePresenterDelegate>
|
||||
{
|
||||
// Current alert (if any).
|
||||
UIAlertController *currentAlert;
|
||||
@@ -71,6 +95,9 @@ UIDocumentInteractionControllerDelegate>
|
||||
// Devices
|
||||
NSMutableArray<MXDevice *> *devicesArray;
|
||||
|
||||
// SECURE_BACKUP_* rows to display
|
||||
NSArray<NSNumber *> *secureBackupSectionState;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
@@ -88,9 +115,13 @@ UIDocumentInteractionControllerDelegate>
|
||||
SettingsKeyBackupTableViewSection *keyBackupSection;
|
||||
KeyBackupSetupCoordinatorBridgePresenter *keyBackupSetupCoordinatorBridgePresenter;
|
||||
KeyBackupRecoverCoordinatorBridgePresenter *keyBackupRecoverCoordinatorBridgePresenter;
|
||||
SecretsRecoveryCoordinatorBridgePresenter *secretsRecoveryCoordinatorBridgePresenter;
|
||||
}
|
||||
|
||||
@property (nonatomic) BOOL isLoadingDevices;
|
||||
@property (nonatomic, strong) MXKeyBackupVersion *currentkeyBackupVersion;
|
||||
@property (nonatomic, strong) SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter;
|
||||
@property (nonatomic, strong) AuthenticatedSessionViewControllerFactory *authenticatedSessionViewControllerFactory;
|
||||
|
||||
@end
|
||||
|
||||
@@ -129,7 +160,8 @@ UIDocumentInteractionControllerDelegate>
|
||||
|
||||
[self.tableView registerClass:MXKTableViewCellWithLabelAndSwitch.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier]];
|
||||
[self.tableView registerNib:MXKTableViewCellWithTextView.nib forCellReuseIdentifier:[MXKTableViewCellWithTextView defaultReuseIdentifier]];
|
||||
|
||||
[self.tableView registerNib:MXKTableViewCellWithButton.nib forCellReuseIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]];
|
||||
|
||||
// Enable self sizing cells
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.estimatedRowHeight = 50;
|
||||
@@ -395,6 +427,8 @@ UIDocumentInteractionControllerDelegate>
|
||||
|
||||
- (void)reloadData
|
||||
{
|
||||
[self refreshSecureBackupSectionData];
|
||||
|
||||
// Trigger a full table reloadData
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
@@ -454,6 +488,13 @@ UIDocumentInteractionControllerDelegate>
|
||||
break;
|
||||
case MXCrossSigningStateCanCrossSign:
|
||||
crossSigningInformation = [NSBundle mxk_localizedStringForKey:@"security_settings_crosssigning_info_ok"];
|
||||
|
||||
#ifdef NEW_CROSS_SIGNING_FLOW
|
||||
if (![self.mainSession.crypto.recoveryService hasSecretLocally:MXSecretId.crossSigningMaster])
|
||||
{
|
||||
crossSigningInformation = [crossSigningInformation stringByAppendingString:@"\n\n⚠️ The MSK is missing. Verify this device again or use the Secure Backup below to synchronise your keys accross your devices"];
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -523,12 +564,88 @@ UIDocumentInteractionControllerDelegate>
|
||||
[buttonCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal];
|
||||
[buttonCell.mxkButton setTitle:btnTitle forState:UIControlStateHighlighted];
|
||||
|
||||
[buttonCell.mxkButton addTarget:self action:@selector(bootstrapCrossSigning:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[buttonCell.mxkButton addTarget:self action:@selector(setupCrossSigning:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
|
||||
- (void)bootstrapCrossSigning:(UITapGestureRecognizer *)recognizer
|
||||
- (void)setupCrossSigning:(id)sender
|
||||
{
|
||||
#ifdef NEW_CROSS_SIGNING_FLOW
|
||||
__block UIViewController *viewController;
|
||||
[self startActivityIndicator];
|
||||
|
||||
// Get credentials to set up cross-signing
|
||||
NSString *path = [NSString stringWithFormat:@"%@/keys/device_signing/upload", kMXAPIPrefixPathUnstable];
|
||||
_authenticatedSessionViewControllerFactory = [[AuthenticatedSessionViewControllerFactory alloc] initWithSession:self.mainSession];
|
||||
[_authenticatedSessionViewControllerFactory viewControllerForPath:path
|
||||
httpMethod:@"POST"
|
||||
title:@"Set up cross-signing" // TODO
|
||||
message:@"Confirm your identity by entering your account password" // TODO
|
||||
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:^{
|
||||
[self stopActivityIndicator];
|
||||
[self reloadData];
|
||||
} failure:^(NSError * _Nonnull error) {
|
||||
[self stopActivityIndicator];
|
||||
[self reloadData];
|
||||
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
}];
|
||||
}
|
||||
|
||||
} onCancelled:^{
|
||||
[self stopActivityIndicator];
|
||||
|
||||
[viewController dismissViewControllerAnimated:NO completion:nil];
|
||||
viewController = nil;
|
||||
} onFailure:^(NSError * _Nonnull error) {
|
||||
|
||||
[self stopActivityIndicator];
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
[viewController dismissViewControllerAnimated:NO completion:nil];
|
||||
viewController = nil;
|
||||
}];
|
||||
|
||||
#else
|
||||
[self displayComingSoon];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)resetCrossSigning:(id)sender
|
||||
{
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
// Double confirmation
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Are you sure?" // TODO
|
||||
message:@"Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from." // TODO
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Reset"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
// Setup and reset are the same thing
|
||||
[self setupCrossSigning:nil];
|
||||
}]];
|
||||
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:nil]];
|
||||
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
currentAlert = alertController;
|
||||
}
|
||||
|
||||
- (void)setUpcrossSigningButtonCellForReset:(MXKTableViewCellWithButton*)buttonCell
|
||||
@@ -542,11 +659,6 @@ UIDocumentInteractionControllerDelegate>
|
||||
[buttonCell.mxkButton addTarget:self action:@selector(resetCrossSigning:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
|
||||
- (void)resetCrossSigning:(UITapGestureRecognizer *)recognizer
|
||||
{
|
||||
[self displayComingSoon];
|
||||
}
|
||||
|
||||
- (void)setUpcrossSigningButtonCellForCompletingSecurity:(MXKTableViewCellWithButton*)buttonCell
|
||||
{
|
||||
NSString *btnTitle = [NSBundle mxk_localizedStringForKey:@"security_settings_crosssigning_complete_security"];
|
||||
@@ -562,6 +674,218 @@ UIDocumentInteractionControllerDelegate>
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - SSSS
|
||||
|
||||
- (void)refreshSecureBackupSectionData
|
||||
{
|
||||
// TODO
|
||||
MXRecoveryService *recoveryService = self.mainSession.crypto.recoveryService;
|
||||
if (recoveryService.hasRecovery)
|
||||
{
|
||||
secureBackupSectionState = @[
|
||||
@(SECURE_BACKUP_INFO),
|
||||
@(SECURE_BACKUP_RESTORE),
|
||||
@(SECURE_BACKUP_DELETE),
|
||||
@(SECURE_BACKUP_DESCRIPTION),
|
||||
//@(SECURE_BACKUP_MANAGE_MANUALLY),
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self.canSetupSecureBackup)
|
||||
{
|
||||
secureBackupSectionState = @[
|
||||
@(SECURE_BACKUP_INFO),
|
||||
@(SECURE_BACKUP_SETUP), // TODO: Check we have all keys locally (at least MSK, SSK & SSK)
|
||||
@(SECURE_BACKUP_DESCRIPTION),
|
||||
//@(SECURE_BACKUP_MANAGE_MANUALLY),
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
secureBackupSectionState = @[
|
||||
@(SECURE_BACKUP_INFO),
|
||||
@(SECURE_BACKUP_DESCRIPTION),
|
||||
//@(SECURE_BACKUP_MANAGE_MANUALLY),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)secureBackupSectionEnumForRow:(NSUInteger)row
|
||||
{
|
||||
if (row < secureBackupSectionState.count)
|
||||
{
|
||||
return secureBackupSectionState[row].unsignedIntegerValue;
|
||||
}
|
||||
|
||||
return SECURE_BACKUP_DESCRIPTION;
|
||||
}
|
||||
|
||||
- (NSUInteger)numberOfRowsInSecureBackupSection
|
||||
{
|
||||
return secureBackupSectionState.count;
|
||||
}
|
||||
|
||||
- (NSString*)secureBackupInformation
|
||||
{
|
||||
NSString *secureBackupInformation;
|
||||
|
||||
MXRecoveryService *recoveryService = self.mainSession.crypto.recoveryService;
|
||||
|
||||
if (recoveryService.hasRecovery)
|
||||
{
|
||||
NSMutableString *mutableString = [@"Your account has a Secure Backup.\n" mutableCopy];
|
||||
|
||||
// Check all keys that should be in the SSSSS
|
||||
// TODO: Check obsoletes ones but need spec update
|
||||
|
||||
BOOL hasWarning = NO;
|
||||
NSString *keyState = [self informationForSecret:MXSecretId.crossSigningMaster secretName:@"Cross-signing" hasWarning:&hasWarning];
|
||||
if (keyState)
|
||||
{
|
||||
[mutableString appendString:keyState];
|
||||
}
|
||||
|
||||
keyState = [self informationForSecret:MXSecretId.crossSigningSelfSigning secretName:@"Self signing" hasWarning:&hasWarning];
|
||||
if (keyState)
|
||||
{
|
||||
[mutableString appendString:keyState];
|
||||
}
|
||||
|
||||
keyState = [self informationForSecret:MXSecretId.crossSigningUserSigning secretName:@"User signing" hasWarning:&hasWarning];
|
||||
if (keyState)
|
||||
{
|
||||
[mutableString appendString:keyState];
|
||||
}
|
||||
|
||||
keyState = [self informationForSecret:MXSecretId.keyBackup secretName:@"Message Backup" hasWarning:&hasWarning];
|
||||
if (keyState)
|
||||
{
|
||||
[mutableString appendString:keyState];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self.mainSession.crypto.backup.keyBackupVersion)
|
||||
{
|
||||
[mutableString appendString:@"\n\n⚠️ The key of your current Message backup is not in the Secure Backup. Restore it first (see below)."];
|
||||
}
|
||||
else
|
||||
{
|
||||
[mutableString appendString:@"\n\n⚠️ Consider create a Message Backup (see below)."];
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasWarning)
|
||||
{
|
||||
[mutableString appendFormat:@"\n\nIf you are facing an issue, synchronise your Secure Backup."];
|
||||
}
|
||||
|
||||
secureBackupInformation = mutableString;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self.canSetupSecureBackup)
|
||||
{
|
||||
secureBackupInformation = [NSString stringWithFormat:@"No Secure Backup. Create one.\n-----\nKeys to back up: %@", recoveryService.secretsStoredLocally];
|
||||
}
|
||||
else
|
||||
{
|
||||
secureBackupInformation = [NSString stringWithFormat:@"No Secure Backup. Set up cross-signing first (see above)"];
|
||||
}
|
||||
}
|
||||
|
||||
return secureBackupInformation;
|
||||
}
|
||||
|
||||
- (nullable NSString*)informationForSecret:(NSString*)secretId secretName:(NSString*)secretName hasWarning:(BOOL*)hasWarning
|
||||
{
|
||||
NSString *information;
|
||||
|
||||
MXRecoveryService *recoveryService = self.mainSession.crypto.recoveryService;
|
||||
|
||||
if ([recoveryService hasSecretWithSecretId:secretId])
|
||||
{
|
||||
if ([recoveryService hasSecretLocally:secretId])
|
||||
{
|
||||
information = [NSString stringWithFormat:@"\n ✅ %@ is in the backup", secretName];
|
||||
}
|
||||
else
|
||||
{
|
||||
information = [NSString stringWithFormat:@"\n ⚠️ %@ is in the backup but not locally. Tap Synchronise", secretName];
|
||||
*hasWarning |= YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([recoveryService hasSecretLocally:secretId])
|
||||
{
|
||||
information = [NSString stringWithFormat:@"\n ⚠️ %@ is not in the backup. Tap Synchronise", secretName];
|
||||
*hasWarning |= YES;
|
||||
}
|
||||
}
|
||||
|
||||
return information;
|
||||
}
|
||||
|
||||
- (BOOL)canSetupSecureBackup
|
||||
{
|
||||
// Accept to create a setup only if we have the 3 cross-signing keys
|
||||
// This is the path to have a sane state
|
||||
// TODO: What about missing MSK that was not gossiped before?
|
||||
|
||||
MXRecoveryService *recoveryService = self.mainSession.crypto.recoveryService;
|
||||
|
||||
NSArray *crossSigningServiceSecrets = @[
|
||||
MXSecretId.crossSigningMaster,
|
||||
MXSecretId.crossSigningSelfSigning,
|
||||
MXSecretId.crossSigningUserSigning];
|
||||
|
||||
return ([recoveryService.secretsStoredLocally mx_intersectArray:crossSigningServiceSecrets].count
|
||||
== crossSigningServiceSecrets.count);
|
||||
}
|
||||
|
||||
- (void)setupSecureBackup
|
||||
{
|
||||
#ifdef NEW_CROSS_SIGNING_FLOW
|
||||
SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession];
|
||||
secureBackupSetupCoordinatorBridgePresenter.delegate = self;
|
||||
|
||||
[secureBackupSetupCoordinatorBridgePresenter presentFrom:self animated:YES];
|
||||
|
||||
self.secureBackupSetupCoordinatorBridgePresenter = secureBackupSetupCoordinatorBridgePresenter;
|
||||
#else
|
||||
[self displayComingSoon];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)restoreFromSecureBackup
|
||||
{
|
||||
secretsRecoveryCoordinatorBridgePresenter = [[SecretsRecoveryCoordinatorBridgePresenter alloc] initWithSession:self.mainSession recoveryGoal:SecretsRecoveryGoalRestoreSecureBackup];
|
||||
|
||||
[secretsRecoveryCoordinatorBridgePresenter presentFrom:self animated:true];
|
||||
secretsRecoveryCoordinatorBridgePresenter.delegate = self;
|
||||
}
|
||||
|
||||
- (void)deleteSecureBackup
|
||||
{
|
||||
MXRecoveryService *recoveryService = self.mainSession.crypto.recoveryService;
|
||||
if (recoveryService)
|
||||
{
|
||||
[self startActivityIndicator];
|
||||
[recoveryService deleteRecoveryWithSuccess:^{
|
||||
[self stopActivityIndicator];
|
||||
[self reloadData];
|
||||
} failure:^(NSError * _Nonnull error) {
|
||||
[self stopActivityIndicator];
|
||||
[self reloadData];
|
||||
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Segues
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
|
||||
@@ -595,6 +919,11 @@ UIDocumentInteractionControllerDelegate>
|
||||
count = devicesArray.count + 1;
|
||||
}
|
||||
break;
|
||||
#ifdef NEW_CROSS_SIGNING_FLOW
|
||||
case SECTION_SECURE_BACKUP:
|
||||
count = [self numberOfRowsInSecureBackupSection];
|
||||
break;
|
||||
#endif
|
||||
case SECTION_KEYBACKUP:
|
||||
count = keyBackupSection.numberOfRows;
|
||||
break;
|
||||
@@ -722,6 +1051,45 @@ UIDocumentInteractionControllerDelegate>
|
||||
return textViewCell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCellWithButton *)buttonCellForTableView:(UITableView*)tableView atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXKTableViewCellWithButton *cell = [self.tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier] forIndexPath:indexPath];
|
||||
|
||||
if (!cell)
|
||||
{
|
||||
cell = [[MXKTableViewCellWithButton alloc] init];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fix https://github.com/vector-im/riot-ios/issues/1354
|
||||
cell.mxkButton.titleLabel.text = nil;
|
||||
cell.mxkButton.enabled = YES;
|
||||
}
|
||||
|
||||
cell.mxkButton.titleLabel.font = [UIFont systemFontOfSize:17];
|
||||
[cell.mxkButton setTintColor:ThemeService.shared.theme.tintColor];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCellWithButton *)buttonCellWithTitle:(NSString*)title
|
||||
action:(SEL)action
|
||||
forTableView:(UITableView*)tableView
|
||||
atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXKTableViewCellWithButton *cell = [self buttonCellForTableView:tableView atIndexPath:indexPath];
|
||||
|
||||
|
||||
[cell.mxkButton setTitle:title forState:UIControlStateNormal];
|
||||
[cell.mxkButton setTitle:title forState:UIControlStateHighlighted];
|
||||
|
||||
[cell.mxkButton removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
[cell.mxkButton addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
|
||||
cell.mxkButton.accessibilityIdentifier = nil;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSInteger section = indexPath.section;
|
||||
@@ -761,6 +1129,79 @@ UIDocumentInteractionControllerDelegate>
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef NEW_CROSS_SIGNING_FLOW
|
||||
else if (section == SECTION_SECURE_BACKUP)
|
||||
{
|
||||
switch ([self secureBackupSectionEnumForRow:row])
|
||||
{
|
||||
case SECURE_BACKUP_DESCRIPTION:
|
||||
{
|
||||
// TODO
|
||||
cell = [self descriptionCellForTableView:tableView
|
||||
//withText:@"Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server."];
|
||||
//withText:@"Back up your encryption keys with your account data in case you lose access to your logins. Your keys will be secured with a unique Recovery Key."];
|
||||
withText:@"Back up your encryption keys with your account data in case you lose access to your logins. Your keys are secured with a Recovery Key or a Secret Phrase."];
|
||||
break;
|
||||
}
|
||||
case SECURE_BACKUP_INFO:
|
||||
{
|
||||
// TODO
|
||||
cell = [self descriptionCellForTableView:tableView
|
||||
withText:self.secureBackupInformation];
|
||||
break;
|
||||
}
|
||||
case SECURE_BACKUP_SETUP:
|
||||
{
|
||||
// TODO: Button or cell?
|
||||
// MXKTableViewCellWithTextView *textCell = [self textViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
// textCell.mxkTextView.text = @"Set up Secure Backup"; // TODO
|
||||
// textCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
//
|
||||
// cell = textCell;
|
||||
|
||||
MXKTableViewCellWithButton *buttonCell = [self buttonCellWithTitle:@"Set up Secure Backup" // TODO
|
||||
action:@selector(setupSecureBackup)
|
||||
forTableView:tableView
|
||||
atIndexPath:indexPath];
|
||||
|
||||
cell = buttonCell;
|
||||
break;
|
||||
}
|
||||
case SECURE_BACKUP_RESTORE:
|
||||
{
|
||||
MXKTableViewCellWithButton *buttonCell = [self buttonCellWithTitle:@"Synchronise (Restore and/or Back up)" // TODO
|
||||
action:@selector(restoreFromSecureBackup)
|
||||
forTableView:tableView
|
||||
atIndexPath:indexPath];
|
||||
|
||||
cell = buttonCell;
|
||||
break;
|
||||
}
|
||||
case SECURE_BACKUP_DELETE:
|
||||
{
|
||||
MXKTableViewCellWithButton *buttonCell = [self buttonCellWithTitle:@"Delete Secure Backup" // TODO
|
||||
action:@selector(deleteSecureBackup)
|
||||
forTableView:tableView
|
||||
atIndexPath:indexPath];
|
||||
buttonCell.mxkButton.tintColor = ThemeService.shared.theme.warningColor;
|
||||
|
||||
cell = buttonCell;
|
||||
break;
|
||||
}
|
||||
|
||||
case SECURE_BACKUP_MANAGE_MANUALLY:
|
||||
{
|
||||
MXKTableViewCellWithTextView *textCell = [self textViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
textCell.mxkTextView.text = @"Advanced: Manually manage keys"; // TODO
|
||||
textCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
|
||||
cell = textCell;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
else if (section == SECTION_KEYBACKUP)
|
||||
{
|
||||
cell = [keyBackupSection cellForRowAtRow:row];
|
||||
@@ -797,27 +1238,10 @@ UIDocumentInteractionControllerDelegate>
|
||||
}
|
||||
case CRYPTOGRAPHY_EXPORT:
|
||||
{
|
||||
MXKTableViewCellWithButton *exportKeysBtnCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]];
|
||||
if (!exportKeysBtnCell)
|
||||
{
|
||||
exportKeysBtnCell = [[MXKTableViewCellWithButton alloc] init];
|
||||
}
|
||||
else
|
||||
{
|
||||
exportKeysBtnCell.mxkButton.titleLabel.text = nil;
|
||||
exportKeysBtnCell.mxkButton.enabled = YES;
|
||||
}
|
||||
|
||||
NSString *btnTitle = NSLocalizedStringFromTable(@"security_settings_export_keys_manually", @"Vector", nil);
|
||||
[exportKeysBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal];
|
||||
[exportKeysBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateHighlighted];
|
||||
[exportKeysBtnCell.mxkButton setTintColor:ThemeService.shared.theme.tintColor];
|
||||
exportKeysBtnCell.mxkButton.titleLabel.font = [UIFont systemFontOfSize:17];
|
||||
|
||||
[exportKeysBtnCell.mxkButton removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
[exportKeysBtnCell.mxkButton addTarget:self action:@selector(exportEncryptionKeys:) forControlEvents:UIControlEventTouchUpInside];
|
||||
exportKeysBtnCell.mxkButton.accessibilityIdentifier = nil;
|
||||
|
||||
MXKTableViewCellWithButton *exportKeysBtnCell = [self buttonCellWithTitle:NSLocalizedStringFromTable(@"security_settings_export_keys_manually", @"Vector", nil)
|
||||
action:@selector(exportEncryptionKeys:)
|
||||
forTableView:tableView
|
||||
atIndexPath:indexPath];
|
||||
cell = exportKeysBtnCell;
|
||||
break;
|
||||
}
|
||||
@@ -859,6 +1283,10 @@ UIDocumentInteractionControllerDelegate>
|
||||
{
|
||||
case SECTION_CRYPTO_SESSIONS:
|
||||
return NSLocalizedStringFromTable(@"security_settings_crypto_sessions", @"Vector", nil);
|
||||
#ifdef NEW_CROSS_SIGNING_FLOW
|
||||
case SECTION_SECURE_BACKUP:
|
||||
return @"SECURE BACKUP"; // TODO
|
||||
#endif
|
||||
case SECTION_KEYBACKUP:
|
||||
return NSLocalizedStringFromTable(@"security_settings_backup", @"Vector", nil);
|
||||
case SECTION_CROSSSIGNING:
|
||||
@@ -1098,23 +1526,8 @@ UIDocumentInteractionControllerDelegate>
|
||||
|
||||
- (MXKTableViewCellWithButton *)settingsKeyBackupTableViewSection:(SettingsKeyBackupTableViewSection *)settingsKeyBackupTableViewSection buttonCellForRow:(NSInteger)buttonCellForRow
|
||||
{
|
||||
MXKTableViewCellWithButton *cell = [self.tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]];
|
||||
|
||||
if (!cell)
|
||||
{
|
||||
cell = [[MXKTableViewCellWithButton alloc] init];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fix https://github.com/vector-im/riot-ios/issues/1354
|
||||
cell.mxkButton.titleLabel.text = nil;
|
||||
cell.mxkButton.enabled = YES;
|
||||
}
|
||||
|
||||
cell.mxkButton.titleLabel.font = [UIFont systemFontOfSize:17];
|
||||
[cell.mxkButton setTintColor:ThemeService.shared.theme.tintColor];
|
||||
|
||||
return cell;
|
||||
return [self buttonCellForTableView:self.tableView
|
||||
atIndexPath:[NSIndexPath indexPathForRow:buttonCellForRow inSection:SECTION_KEYBACKUP]] ;
|
||||
}
|
||||
|
||||
- (void)settingsKeyBackupTableViewSectionShowKeyBackupSetup:(SettingsKeyBackupTableViewSection *)settingsKeyBackupTableViewSection
|
||||
@@ -1124,7 +1537,19 @@ UIDocumentInteractionControllerDelegate>
|
||||
|
||||
- (void)settingsKeyBackup:(SettingsKeyBackupTableViewSection *)settingsKeyBackupTableViewSection showKeyBackupRecover:(MXKeyBackupVersion *)keyBackupVersion
|
||||
{
|
||||
[self showKeyBackupRecover:keyBackupVersion];
|
||||
self.currentkeyBackupVersion = keyBackupVersion;
|
||||
|
||||
// If key backup key is stored in SSSS ask for secrets recovery before restoring key backup.
|
||||
if (!self.mainSession.crypto.backup.hasPrivateKeyInCryptoStore
|
||||
&& self.mainSession.crypto.recoveryService.hasRecovery
|
||||
&& [self.mainSession.crypto.recoveryService hasSecretWithSecretId:MXSecretId.keyBackup])
|
||||
{
|
||||
[self showSecretsRecovery];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self showKeyBackupRecover:keyBackupVersion fromViewController:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)settingsKeyBackup:(SettingsKeyBackupTableViewSection *)settingsKeyBackupTableViewSection showKeyBackupDeleteConfirm:(MXKeyBackupVersion *)keyBackupVersion
|
||||
@@ -1201,22 +1626,86 @@ UIDocumentInteractionControllerDelegate>
|
||||
|
||||
#pragma mark - KeyBackupRecoverCoordinatorBridgePresenter
|
||||
|
||||
- (void)showKeyBackupRecover:(MXKeyBackupVersion*)keyBackupVersion
|
||||
- (void)showKeyBackupRecover:(MXKeyBackupVersion*)keyBackupVersion fromViewController:(UIViewController*)presentingViewController
|
||||
{
|
||||
keyBackupRecoverCoordinatorBridgePresenter = [[KeyBackupRecoverCoordinatorBridgePresenter alloc] initWithSession:self.mainSession keyBackupVersion:keyBackupVersion];
|
||||
|
||||
[keyBackupRecoverCoordinatorBridgePresenter presentFrom:self animated:true];
|
||||
[keyBackupRecoverCoordinatorBridgePresenter presentFrom:presentingViewController animated:true];
|
||||
keyBackupRecoverCoordinatorBridgePresenter.delegate = self;
|
||||
}
|
||||
|
||||
- (void)pushKeyBackupRecover:(MXKeyBackupVersion*)keyBackupVersion fromNavigationController:(UINavigationController*)navigationController
|
||||
{
|
||||
keyBackupRecoverCoordinatorBridgePresenter = [[KeyBackupRecoverCoordinatorBridgePresenter alloc] initWithSession:self.mainSession keyBackupVersion:keyBackupVersion];
|
||||
|
||||
[keyBackupRecoverCoordinatorBridgePresenter pushFrom:navigationController animated:YES];
|
||||
keyBackupRecoverCoordinatorBridgePresenter.delegate = self;
|
||||
}
|
||||
|
||||
- (void)keyBackupRecoverCoordinatorBridgePresenterDidCancel:(KeyBackupRecoverCoordinatorBridgePresenter *)bridgePresenter {
|
||||
[keyBackupRecoverCoordinatorBridgePresenter dismissWithAnimated:true];
|
||||
keyBackupRecoverCoordinatorBridgePresenter = nil;
|
||||
secretsRecoveryCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
- (void)keyBackupRecoverCoordinatorBridgePresenterDidRecover:(KeyBackupRecoverCoordinatorBridgePresenter *)bridgePresenter {
|
||||
[keyBackupRecoverCoordinatorBridgePresenter dismissWithAnimated:true];
|
||||
keyBackupRecoverCoordinatorBridgePresenter = nil;
|
||||
secretsRecoveryCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
#pragma mark - KeyBackupRecoverCoordinatorBridgePresenter
|
||||
|
||||
- (void)showSecretsRecovery
|
||||
{
|
||||
secretsRecoveryCoordinatorBridgePresenter = [[SecretsRecoveryCoordinatorBridgePresenter alloc] initWithSession:self.mainSession recoveryGoal:SecretsRecoveryGoalKeyBackup];
|
||||
|
||||
[secretsRecoveryCoordinatorBridgePresenter presentFrom:self animated:true];
|
||||
secretsRecoveryCoordinatorBridgePresenter.delegate = self;
|
||||
}
|
||||
|
||||
- (void)secretsRecoveryCoordinatorBridgePresenterDelegateDidCancel:(SecretsRecoveryCoordinatorBridgePresenter *)coordinatorBridgePresenter
|
||||
{
|
||||
[secretsRecoveryCoordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
|
||||
secretsRecoveryCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
- (void)secretsRecoveryCoordinatorBridgePresenterDelegateDidComplete:(SecretsRecoveryCoordinatorBridgePresenter *)coordinatorBridgePresenter
|
||||
{
|
||||
UIViewController *presentedViewController = [coordinatorBridgePresenter toPresentable];
|
||||
|
||||
if (coordinatorBridgePresenter.recoveryGoal == SecretsRecoveryGoalKeyBackup)
|
||||
{
|
||||
// Go to the true key backup recovery screen
|
||||
if ([presentedViewController isKindOfClass:UINavigationController.class])
|
||||
{
|
||||
UINavigationController *navigationController = (UINavigationController*)self.presentedViewController;
|
||||
[self pushKeyBackupRecover:self.currentkeyBackupVersion fromNavigationController:navigationController];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self showKeyBackupRecover:self.currentkeyBackupVersion fromViewController:presentedViewController];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[secretsRecoveryCoordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
|
||||
secretsRecoveryCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - SecureBackupSetupCoordinatorBridgePresenterDelegate
|
||||
|
||||
- (void)secureBackupSetupCoordinatorBridgePresenterDelegateDidComplete:(SecureBackupSetupCoordinatorBridgePresenter *)coordinatorBridgePresenter
|
||||
{
|
||||
[self.secureBackupSetupCoordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
|
||||
self.secureBackupSetupCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
- (void)secureBackupSetupCoordinatorBridgePresenterDelegateDidCancel:(SecureBackupSetupCoordinatorBridgePresenter *)coordinatorBridgePresenter
|
||||
{
|
||||
[self.secureBackupSetupCoordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
|
||||
self.secureBackupSetupCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user