2020-01-28 20:09:51 +00:00
/ *
2020-01-28 21:05:11 +00:00
Copyright 2020 New Vector Ltd
2020-01-28 20:09:51 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : // www . apache . org / licenses / LICENSE -2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
# import "SecurityViewController.h"
2020-01-29 16:56:24 +00:00
# import "ManageSessionViewController.h"
2020-01-28 20:09:51 +00:00
# import < MatrixKit / MatrixKit . h >
# import < OLMKit / OLMKit . h >
# import "AvatarGenerator.h"
# import "ThemeService.h"
# import "Riot-Swift.h"
2020-06-30 13:04:50 +00:00
// Dev flag to have more options
// # define CROSS_SIGNING _AND _BACKUP _DEV
2020-01-28 20:09:51 +00:00
enum
{
2020-07-21 13:17:13 +00:00
SECTION_PIN _CODE ,
2020-01-30 12:14:17 +00:00
SECTION_CRYPTO _SESSIONS ,
2020-06-18 13:34:24 +00:00
SECTION_SECURE _BACKUP ,
2021-06-15 14:09:56 +00:00
SECTION_CROSSSIGNING ,
2020-03-12 10:21:47 +00:00
SECTION_CRYPTOGRAPHY ,
2020-06-30 13:04:50 +00:00
# ifdef CROSS_SIGNING _AND _BACKUP _DEV
2020-04-23 14:46:44 +00:00
SECTION_KEYBACKUP ,
2020-06-30 13:04:50 +00:00
# endif
2020-01-29 07:19:48 +00:00
SECTION_ADVANCED ,
SECTION_COUNT
2020-01-28 20:09:51 +00:00
} ;
enum {
2020-03-12 10:21:47 +00:00
CROSSSIGNING_INFO ,
2020-03-18 11:20:14 +00:00
CROSSSIGNING_FIRST _ACTION , // Bootstrap , Reset , Verify this session , Request keys
CROSSSIGNING_SECOND _ACTION , // Reset
2020-01-28 20:09:51 +00:00
} ;
2020-07-21 13:17:13 +00:00
enum {
PIN_CODE _SETTING ,
PIN_CODE _DESCRIPTION ,
2020-12-16 13:15:41 +00:00
PIN_CODE _CHANGE ,
2020-07-24 14:54:44 +00:00
PIN_CODE _BIOMETRICS ,
2020-07-21 13:17:13 +00:00
PIN_CODE _COUNT
} ;
2020-06-18 13:34:24 +00:00
2020-01-29 14:56:06 +00:00
enum {
2020-03-12 10:21:47 +00:00
CRYPTOGRAPHY_INFO ,
CRYPTOGRAPHY_EXPORT , // TODO : To move to SECTION_KEYBACKUP
CRYPTOGRAPHY_COUNT
} ;
enum {
ADVANCED_BLACKLIST _UNVERIFIED _DEVICES ,
ADVANCED_BLACKLIST _UNVERIFIED _DEVICES _DESCRIPTION ,
ADVANCED_COUNT
2020-01-29 14:56:06 +00:00
} ;
2020-01-28 20:09:51 +00:00
2020-01-28 21:36:50 +00:00
@ interface SecurityViewController ( ) <
2021-06-15 17:21:33 +00:00
SettingsSecureBackupTableViewSectionDelegate ,
2021-06-16 14:11:32 +00:00
KeyBackupSetupCoordinatorBridgePresenterDelegate ,
2020-06-30 13:04:50 +00:00
# ifdef CROSS_SIGNING _AND _BACKUP _DEV
2020-01-28 20:09:51 +00:00
SettingsKeyBackupTableViewSectionDelegate ,
KeyBackupRecoverCoordinatorBridgePresenterDelegate ,
2020-06-30 13:04:50 +00:00
# endif
2020-06-15 14:30:58 +00:00
UIDocumentInteractionControllerDelegate ,
2020-06-25 18:23:40 +00:00
SecretsRecoveryCoordinatorBridgePresenterDelegate ,
2020-07-21 13:17:13 +00:00
SecureBackupSetupCoordinatorBridgePresenterDelegate ,
2020-09-28 12:25:21 +00:00
SetPinCoordinatorBridgePresenterDelegate ,
TableViewSectionsDelegate >
2020-01-28 20:09:51 +00:00
{
// Current alert ( if any ) .
UIAlertController * currentAlert ;
// Devices
NSMutableArray < MXDevice * > * devicesArray ;
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change .
id kThemeServiceDidChangeThemeNotificationObserver ;
// The view used to export e2e keys
MXKEncryptionKeysExportView * exportView ;
// The document interaction Controller used to export e2e keys
UIDocumentInteractionController * documentInteractionController ;
NSURL * keyExportsFile ;
NSTimer * keyExportsFileDeletionTimer ;
// The current pushed view controller
UIViewController * pushedViewController ;
2021-06-15 17:21:33 +00:00
SettingsSecureBackupTableViewSection * secureBackupSection ;
2021-06-16 13:05:30 +00:00
2020-06-30 13:04:50 +00:00
# ifdef CROSS_SIGNING _AND _BACKUP _DEV
2020-01-28 20:09:51 +00:00
SettingsKeyBackupTableViewSection * keyBackupSection ;
2020-06-30 13:04:50 +00:00
# endif
2021-06-16 13:31:39 +00:00
KeyBackupSetupCoordinatorBridgePresenter * keyBackupSetupCoordinatorBridgePresenter ;
2020-01-28 20:09:51 +00:00
KeyBackupRecoverCoordinatorBridgePresenter * keyBackupRecoverCoordinatorBridgePresenter ;
2020-06-15 14:30:58 +00:00
SecretsRecoveryCoordinatorBridgePresenter * secretsRecoveryCoordinatorBridgePresenter ;
2020-01-28 20:09:51 +00:00
}
2020-09-28 12:25:21 +00:00
@ property ( nonatomic , strong ) TableViewSections * tableViewSections ;
2020-02-10 09:51:30 +00:00
@ property ( nonatomic ) BOOL isLoadingDevices ;
2020-06-15 14:30:58 +00:00
@ property ( nonatomic , strong ) MXKeyBackupVersion * currentkeyBackupVersion ;
2020-06-26 12:30:21 +00:00
@ property ( nonatomic , strong ) SecureBackupSetupCoordinatorBridgePresenter * secureBackupSetupCoordinatorBridgePresenter ;
2020-07-21 13:17:13 +00:00
@ property ( nonatomic , strong ) SetPinCoordinatorBridgePresenter * setPinCoordinatorBridgePresenter ;
2021-02-03 11:08:48 +00:00
@ property ( nonatomic , strong ) CrossSigningSetupCoordinatorBridgePresenter * crossSigningSetupCoordinatorBridgePresenter ;
2020-02-10 09:51:30 +00:00
2020-01-28 20:09:51 +00:00
@ end
@ implementation SecurityViewController
# pragma mark - Setup & Teardown
+ ( SecurityViewController * ) instantiateWithMatrixSession : ( MXSession * ) matrixSession
{
SecurityViewController * viewController = [ [ UIStoryboard storyboardWithName : @ "Security" bundle : [ NSBundle mainBundle ] ] instantiateInitialViewController ] ;
[ viewController addMatrixSession : matrixSession ] ;
return viewController ;
}
# pragma mark - View life cycle
- ( void ) finalizeInit
{
[ super finalizeInit ] ;
// Setup ` MXKViewControllerHandling` properties
self . enableBarTintColorStatusChange = NO ;
self . rageShakeManager = [ RageShakeManager sharedManager ] ;
}
- ( void ) viewDidLoad
{
[ super viewDidLoad ] ;
// Do any additional setup after loading the view , typically from a nib .
2020-01-29 07:19:48 +00:00
self . navigationItem . title = NSLocalizedStringFromTable ( @ "security_settings_title" , @ "Vector" , nil ) ;
2020-01-28 20:09:51 +00:00
// Remove back bar button title when pushing a view controller
self . navigationItem . backBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : @ "" style : UIBarButtonItemStylePlain target : nil action : nil ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
[ self . tableView registerClass : MXKTableViewCellWithLabelAndSwitch . class forCellReuseIdentifier : [ MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier ] ] ;
[ self . tableView registerNib : MXKTableViewCellWithTextView . nib forCellReuseIdentifier : [ MXKTableViewCellWithTextView defaultReuseIdentifier ] ] ;
2020-06-18 09:47:53 +00:00
[ self . tableView registerNib : MXKTableViewCellWithButton . nib forCellReuseIdentifier : [ MXKTableViewCellWithButton defaultReuseIdentifier ] ] ;
2020-01-28 20:09:51 +00:00
// Enable self sizing cells
self . tableView . rowHeight = UITableViewAutomaticDimension ;
self . tableView . estimatedRowHeight = 50 ;
if ( self . mainSession . crypto . backup )
{
MXDeviceInfo * deviceInfo = [ self . mainSession . crypto . deviceList storedDevice : self . mainSession . matrixRestClient . credentials . userId
deviceId : self . mainSession . matrixRestClient . credentials . deviceId ] ;
if ( deviceInfo )
{
2021-06-16 12:40:29 +00:00
secureBackupSection = [ [ SettingsSecureBackupTableViewSection alloc ] initWithRecoveryService : self . mainSession . crypto . recoveryService keyBackup : self . mainSession . crypto . backup userDevice : deviceInfo ] ;
2021-06-15 17:21:33 +00:00
secureBackupSection . delegate = self ;
# ifdef CROSS_SIGNING _AND _BACKUP _DEV
2020-01-28 20:09:51 +00:00
keyBackupSection = [ [ SettingsKeyBackupTableViewSection alloc ] initWithKeyBackup : self . mainSession . crypto . backup userDevice : deviceInfo ] ;
keyBackupSection . delegate = self ;
2021-06-15 17:21:33 +00:00
# endif
2020-01-28 20:09:51 +00:00
}
}
// Observe user interface theme change .
kThemeServiceDidChangeThemeNotificationObserver = [ [ NSNotificationCenter defaultCenter ] addObserverForName : kThemeServiceDidChangeThemeNotification object : nil queue : [ NSOperationQueue mainQueue ] usingBlock : ^ ( NSNotification * notif ) {
[ self userInterfaceThemeDidChange ] ;
} ] ;
[ self userInterfaceThemeDidChange ] ;
2020-09-28 12:25:21 +00:00
2020-10-08 15:34:42 +00:00
[ self registerUserDevicesChangesNotification ] ;
2020-09-28 12:25:21 +00:00
self . tableViewSections = [ TableViewSections new ] ;
self . tableViewSections . delegate = self ;
2020-10-08 15:34:42 +00:00
2020-09-28 12:25:21 +00:00
[ self updateSections ] ;
2020-01-28 20:09:51 +00:00
}
- ( void ) userInterfaceThemeDidChange
{
[ ThemeService . shared . theme applyStyleOnNavigationBar : self . navigationController . navigationBar ] ;
self . activityIndicator . backgroundColor = ThemeService . shared . theme . overlayBackgroundColor ;
// Check the table view style to select its bg color .
self . tableView . backgroundColor = ( ( self . tableView . style = = UITableViewStylePlain ) ? ThemeService . shared . theme . backgroundColor : ThemeService . shared . theme . headerBackgroundColor ) ;
self . view . backgroundColor = self . tableView . backgroundColor ;
self . tableView . separatorColor = ThemeService . shared . theme . lineBreakColor ;
2020-01-30 12:14:17 +00:00
[ self reloadData ] ;
2020-04-08 10:58:12 +00:00
[ self setNeedsStatusBarAppearanceUpdate ] ;
2020-01-28 20:09:51 +00:00
}
- ( UIStatusBarStyle ) preferredStatusBarStyle
{
return ThemeService . shared . theme . statusBarStyle ;
}
- ( void ) didReceiveMemoryWarning
{
[ super didReceiveMemoryWarning ] ;
// Dispose of any resources that can be recreated .
}
- ( void ) destroy
{
// Release the potential pushed view controller
[ self releasePushedViewController ] ;
if ( documentInteractionController )
{
[ documentInteractionController dismissPreviewAnimated : NO ] ;
[ documentInteractionController dismissMenuAnimated : NO ] ;
documentInteractionController = nil ;
}
if ( kThemeServiceDidChangeThemeNotificationObserver )
{
[ [ NSNotificationCenter defaultCenter ] removeObserver : kThemeServiceDidChangeThemeNotificationObserver ] ;
kThemeServiceDidChangeThemeNotificationObserver = nil ;
}
keyBackupSetupCoordinatorBridgePresenter = nil ;
keyBackupRecoverCoordinatorBridgePresenter = nil ;
}
- ( void ) viewWillAppear : ( BOOL ) animated
{
[ super viewWillAppear : animated ] ;
// Screen tracking
2020-01-30 12:14:17 +00:00
[ [ Analytics sharedInstance ] trackScreen : @ "Security" ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Release the potential pushed view controller
[ self releasePushedViewController ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Refresh display
2020-01-30 06:14:35 +00:00
[ self reloadData ] ;
2020-01-28 20:09:51 +00:00
// Refresh the current device information in parallel
[ self loadCurrentDeviceInformation ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Refresh devices in parallel
[ self loadDevices ] ;
2020-03-25 09:14:25 +00:00
[ self loadCrossSigning ] ;
2020-01-28 20:09:51 +00:00
}
- ( void ) viewWillDisappear : ( BOOL ) animated
{
[ super viewWillDisappear : animated ] ;
if ( currentAlert )
{
[ currentAlert dismissViewControllerAnimated : NO completion : nil ] ;
currentAlert = nil ;
}
}
# pragma mark - Internal methods
2020-09-28 12:25:21 +00:00
- ( void ) updateSections
{
NSMutableArray < Section * > * sections = [ NSMutableArray array ] ;
// Pin code section
Section * pinCodeSection = [ Section sectionWithTag : SECTION_PIN _CODE ] ;
// Header title
2021-09-21 10:56:50 +00:00
if ( [ PinCodePreferences shared ] . isBiometricsAvailable )
{
NSString * pinCodeSectionHeaderTitleFormat = NSLocalizedStringFromTable ( @ "pin_protection_settings_section_header_x" , @ "Vector" , nil ) ;
NSString * pinCodeSectionHeaderTitle = [ NSString stringWithFormat : pinCodeSectionHeaderTitleFormat , [ PinCodePreferences shared ] . localizedBiometricsName ] ;
pinCodeSection . headerTitle = pinCodeSectionHeaderTitle ;
}
2020-09-28 12:25:21 +00:00
// Rows
[ pinCodeSection addRowWithTag : PIN_CODE _SETTING ] ;
[ pinCodeSection addRowWithTag : PIN_CODE _DESCRIPTION ] ;
2020-12-16 13:15:41 +00:00
if ( [ PinCodePreferences shared ] . isPinSet ) {
[ pinCodeSection addRowWithTag : PIN_CODE _CHANGE ] ;
}
2020-09-28 13:44:07 +00:00
if ( [ PinCodePreferences shared ] . isBiometricsAvailable )
2020-09-28 12:25:21 +00:00
{
[ pinCodeSection addRowWithTag : PIN_CODE _BIOMETRICS ] ;
}
[ sections addObject : pinCodeSection ] ;
// Crypto sessions section
2021-04-01 12:16:06 +00:00
if ( RiotSettings . shared . settingsSecurityScreenShowSessions )
2020-09-28 12:25:21 +00:00
{
2021-03-31 17:04:00 +00:00
Section * sessionsSection = [ Section sectionWithTag : SECTION_CRYPTO _SESSIONS ] ;
sessionsSection . headerTitle = NSLocalizedStringFromTable ( @ "security_settings_crypto_sessions" , @ "Vector" , nil ) ;
NSUInteger sessionsSectionRowsCount ;
if ( self . showLoadingDevicesInformation )
{
sessionsSectionRowsCount = 2 ;
}
else
{
sessionsSectionRowsCount = devicesArray . count + 1 ;
}
2020-09-28 12:25:21 +00:00
2021-03-31 17:04:00 +00:00
[ sessionsSection addRowsWithCount : sessionsSectionRowsCount ] ;
[ sections addObject : sessionsSection ] ;
}
2020-09-28 12:25:21 +00:00
// Secure backup
2021-04-01 12:16:06 +00:00
Section * secureBackupSection = [ Section sectionWithTag : SECTION_SECURE _BACKUP ] ;
secureBackupSection . headerTitle = NSLocalizedStringFromTable ( @ "security_settings_secure_backup" , @ "Vector" , nil ) ;
2021-06-15 17:21:33 +00:00
[ secureBackupSection addRowsWithCount : self -> secureBackupSection . numberOfRows ] ;
[ sections addObject : secureBackupSection ] ;
2020-09-28 12:25:21 +00:00
2021-06-15 14:09:56 +00:00
// Cross - Signing
Section * crossSigningSection = [ Section sectionWithTag : SECTION_CROSSSIGNING ] ;
crossSigningSection . headerTitle = NSLocalizedStringFromTable ( @ "security_settings_crosssigning" , @ "Vector" , nil ) ;
[ crossSigningSection addRowsWithCount : [ self numberOfRowsInCrossSigningSection ] ] ;
[ sections addObject : crossSigningSection ] ;
2020-09-28 12:25:21 +00:00
// Cryptograhpy
2021-04-01 12:16:06 +00:00
Section * cryptograhpySection = [ Section sectionWithTag : SECTION_CRYPTOGRAPHY ] ;
cryptograhpySection . headerTitle = NSLocalizedStringFromTable ( @ "security_settings_cryptography" , @ "Vector" , nil ) ;
if ( RiotSettings . shared . settingsSecurityScreenShowCryptographyInfo )
2021-03-31 17:04:00 +00:00
{
[ cryptograhpySection addRowWithTag : CRYPTOGRAPHY_INFO ] ;
2021-04-01 12:16:06 +00:00
}
if ( RiotSettings . shared . settingsSecurityScreenShowCryptographyExport )
{
2021-03-31 17:04:00 +00:00
[ cryptograhpySection addRowWithTag : CRYPTOGRAPHY_EXPORT ] ;
2021-04-01 12:16:06 +00:00
}
2021-03-31 17:04:00 +00:00
2021-04-01 12:16:06 +00:00
if ( cryptograhpySection . rows . count )
{
2021-03-31 17:04:00 +00:00
[ sections addObject : cryptograhpySection ] ;
}
2021-04-01 12:16:06 +00:00
2020-09-28 12:25:21 +00:00
# ifdef CROSS_SIGNING _AND _BACKUP _DEV
// Keybackup
Section * keybackupSection = [ Section sectionWithTag : SECTION_KEYBACKUP ] ;
keybackupSection . headerTitle = NSLocalizedStringFromTable ( @ "security_settings_backup" , @ "Vector" , nil ) ;
2020-09-29 15:08:06 +00:00
[ keybackupSection addRowsWithCount : self -> keyBackupSection . numberOfRows ] ;
2020-09-28 12:25:21 +00:00
[ sections addObject : keybackupSection ] ;
# endif
// Advanced
2021-04-01 12:16:06 +00:00
Section * advancedSection = [ Section sectionWithTag : SECTION_ADVANCED ] ;
advancedSection . headerTitle = NSLocalizedStringFromTable ( @ "security_settings_advanced" , @ "Vector" , nil ) ;
if ( RiotSettings . shared . settingsSecurityScreenShowAdvancedUnverifiedDevices )
2021-03-31 17:04:00 +00:00
{
[ advancedSection addRowWithTag : ADVANCED_BLACKLIST _UNVERIFIED _DEVICES ] ;
[ advancedSection addRowWithTag : ADVANCED_BLACKLIST _UNVERIFIED _DEVICES _DESCRIPTION ] ;
2021-04-01 12:16:06 +00:00
}
if ( advancedSection . rows . count )
{
2021-03-31 17:04:00 +00:00
[ sections addObject : advancedSection ] ;
}
2021-04-01 12:16:06 +00:00
2020-09-28 12:25:21 +00:00
// Update sections
self . tableViewSections . sections = sections ;
}
2020-02-10 09:51:30 +00:00
- ( BOOL ) showLoadingDevicesInformation
{
return self . isLoadingDevices && devicesArray . count = = 0 ;
}
2020-01-28 20:09:51 +00:00
- ( void ) pushViewController : ( UIViewController * ) viewController
{
// Keep ref on pushed view controller
pushedViewController = viewController ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Hide back button title
self . navigationItem . backBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : @ "" style : UIBarButtonItemStylePlain target : nil action : nil ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
[ self . navigationController pushViewController : viewController animated : YES ] ;
}
- ( void ) releasePushedViewController
{
if ( pushedViewController )
{
if ( [ pushedViewController isKindOfClass : [ UINavigationController class ] ] )
{
UINavigationController * navigationController = ( UINavigationController * ) pushedViewController ;
for ( id subViewController in navigationController . viewControllers )
{
if ( [ subViewController respondsToSelector : @ selector ( destroy ) ] )
{
[ subViewController destroy ] ;
}
}
}
else if ( [ pushedViewController respondsToSelector : @ selector ( destroy ) ] )
{
[ ( id ) pushedViewController destroy ] ;
}
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
pushedViewController = nil ;
}
}
- ( void ) reset
{
// Remove observers
[ [ NSNotificationCenter defaultCenter ] removeObserver : self ] ;
}
- ( void ) loadCurrentDeviceInformation
{
// Refresh the current device information
MXKAccount * account = [ MXKAccountManager sharedManager ] . activeAccounts . firstObject ;
[ account loadDeviceInformation : ^ {
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Refresh all the table ( A slide down animation is observed when we limit the refresh to the concerned section ) .
// Note : The use of ' reloadData ' handles the case where the account has been logged out .
2020-01-30 06:14:35 +00:00
[ self reloadData ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
} failure : nil ] ;
}
- ( NSAttributedString * ) cryptographyInformation
{
// TODO Handle multi accounts
MXKAccount * account = [ MXKAccountManager sharedManager ] . activeAccounts . firstObject ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Crypto information
NSMutableAttributedString * cryptoInformationString = [ [ NSMutableAttributedString alloc ]
initWithString : NSLocalizedStringFromTable ( @ "settings_crypto_device_name" , @ "Vector" , nil )
attributes : @ { NSForegroundColorAttributeName : ThemeService . shared . theme . textPrimaryColor ,
NSFontAttributeName : [ UIFont systemFontOfSize : 17 ] } ] ;
[ cryptoInformationString appendAttributedString : [ [ NSMutableAttributedString alloc ]
initWithString : account . device . displayName ? account . device . displayName : @ ""
attributes : @ { NSForegroundColorAttributeName : ThemeService . shared . theme . textPrimaryColor ,
NSFontAttributeName : [ UIFont systemFontOfSize : 17 ] } ] ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
[ cryptoInformationString appendAttributedString : [ [ NSMutableAttributedString alloc ]
initWithString : NSLocalizedStringFromTable ( @ "settings_crypto_device_id" , @ "Vector" , nil )
attributes : @ { NSForegroundColorAttributeName : ThemeService . shared . theme . textPrimaryColor ,
NSFontAttributeName : [ UIFont systemFontOfSize : 17 ] } ] ] ;
[ cryptoInformationString appendAttributedString : [ [ NSMutableAttributedString alloc ]
initWithString : account . device . deviceId ? account . device . deviceId : @ ""
attributes : @ { NSForegroundColorAttributeName : ThemeService . shared . theme . textPrimaryColor ,
NSFontAttributeName : [ UIFont systemFontOfSize : 17 ] } ] ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
[ cryptoInformationString appendAttributedString : [ [ NSMutableAttributedString alloc ]
initWithString : NSLocalizedStringFromTable ( @ "settings_crypto_device_key" , @ "Vector" , nil )
attributes : @ { NSForegroundColorAttributeName : ThemeService . shared . theme . textPrimaryColor ,
NSFontAttributeName : [ UIFont systemFontOfSize : 17 ] } ] ] ;
NSString * fingerprint = account . mxSession . crypto . deviceEd25519Key ;
if ( fingerprint )
{
fingerprint = [ MXTools addWhiteSpacesToString : fingerprint every : 4 ] ;
}
[ cryptoInformationString appendAttributedString : [ [ NSMutableAttributedString alloc ]
initWithString : fingerprint ? fingerprint : @ ""
attributes : @ { NSForegroundColorAttributeName : ThemeService . shared . theme . textPrimaryColor ,
NSFontAttributeName : [ UIFont boldSystemFontOfSize : 17 ] } ] ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
return cryptoInformationString ;
}
- ( void ) loadDevices
{
2020-02-10 09:51:30 +00:00
self . isLoadingDevices = YES ;
2020-01-28 20:09:51 +00:00
// Refresh the account devices list
2020-01-28 21:36:50 +00:00
MXWeakify ( self ) ;
2020-01-28 22:27:45 +00:00
[ self . mainSession . matrixRestClient devices : ^ ( NSArray < MXDevice * > * devices ) {
2020-01-28 21:36:50 +00:00
MXStrongifyAndReturnIfNil ( self ) ;
2020-02-10 09:51:30 +00:00
self . isLoadingDevices = NO ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
if ( devices )
{
2020-01-28 21:36:50 +00:00
self -> devicesArray = [ NSMutableArray arrayWithArray : devices ] ;
2020-01-28 20:09:51 +00:00
// Sort devices according to the last seen date .
NSComparator comparator = ^ NSComparisonResult ( MXDevice * deviceA , MXDevice * deviceB ) {
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
if ( deviceA . lastSeenTs > deviceB . lastSeenTs )
{
return NSOrderedAscending ;
}
if ( deviceA . lastSeenTs < deviceB . lastSeenTs )
{
return NSOrderedDescending ;
}
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
return NSOrderedSame ;
} ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Sort devices list
2020-01-28 21:36:50 +00:00
[ self -> devicesArray sortUsingComparator : comparator ] ;
2020-01-28 20:09:51 +00:00
}
else
{
2020-01-28 21:36:50 +00:00
self -> devicesArray = nil ;
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Refresh all the table ( A slide down animation is observed when we limit the refresh to the concerned section ) .
// Note : The use of ' reloadData ' handles the case where the account has been logged out .
2020-01-30 06:14:35 +00:00
[ self reloadData ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
} failure : ^ ( NSError * error ) {
2020-01-28 21:36:50 +00:00
2020-02-10 09:51:30 +00:00
self . isLoadingDevices = NO ;
2020-01-28 20:09:51 +00:00
// Display the data that has been loaded last time
// Note : The use of ' reloadData ' handles the case where the account has been logged out .
2020-01-30 06:14:35 +00:00
[ self reloadData ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
} ] ;
}
2020-01-30 06:14:35 +00:00
- ( void ) reloadData
2020-01-28 20:09:51 +00:00
{
2020-09-28 12:25:21 +00:00
// Update table view sections and trigger a tableView reloadData
[ self updateSections ] ;
2020-01-28 20:09:51 +00:00
}
2020-03-18 11:20:14 +00:00
2020-10-08 15:34:42 +00:00
# pragma mark - Data update
- ( void ) registerUserDevicesChangesNotification
{
[ [ NSNotificationCenter defaultCenter ] addObserver : self
selector : @ selector ( onDeviceInfoTrustLevelDidChangeNotification : )
name : MXDeviceInfoTrustLevelDidChangeNotification
object : nil ] ;
[ [ NSNotificationCenter defaultCenter ] addObserver : self
selector : @ selector ( crossSigningInfoTrustLevelDidChangeNotification : )
name : MXCrossSigningInfoTrustLevelDidChangeNotification
object : nil ] ;
[ [ NSNotificationCenter defaultCenter ] addObserver : self
selector : @ selector ( onDidUpdateUsersDevicesNotification : )
name : MXDeviceListDidUpdateUsersDevicesNotification
object : nil ] ;
}
- ( void ) onDidUpdateUsersDevicesNotification : ( NSNotification * ) notification
{
NSDictionary * usersDevices = notification . userInfo ;
if ( [ usersDevices . allKeys containsObject : self . mainSession . myUserId ] )
{
[ self loadDevices ] ;
}
}
- ( void ) onDeviceInfoTrustLevelDidChangeNotification : ( NSNotification * ) notification
{
MXDeviceInfo * deviceInfo = notification . object ;
NSString * userId = deviceInfo . userId ;
if ( [ userId isEqualToString : self . mainSession . myUserId ] )
{
[ self loadDevices ] ;
}
}
- ( void ) crossSigningInfoTrustLevelDidChangeNotification : ( NSNotification * ) notification
{
MXCrossSigningInfo * crossSigningInfo = notification . object ;
NSString * userId = crossSigningInfo . userId ;
if ( [ userId isEqualToString : self . mainSession . myUserId ] )
{
[ self loadDevices ] ;
}
}
2020-03-18 11:20:14 +00:00
# pragma mark - Cross - signing
2020-03-25 09:14:25 +00:00
- ( void ) loadCrossSigning
{
MXCrossSigning * crossSigning = self . mainSession . crypto . crossSigning ;
[ crossSigning refreshStateWithSuccess : ^ ( BOOL stateUpdated ) {
if ( stateUpdated )
{
[ self reloadData ] ;
}
} failure : ^ ( NSError * _Nonnull error ) {
2021-06-03 08:30:07 +00:00
MXLogDebug ( @ "[SecurityVC] loadCrossSigning: Cannot refresh cross-signing state. Error: %@" , error ) ;
2020-03-25 09:14:25 +00:00
} ] ;
}
2020-03-18 11:20:14 +00:00
- ( NSInteger ) numberOfRowsInCrossSigningSection
{
NSInteger numberOfRowsInCrossSigningSection ;
MXCrossSigning * crossSigning = self . mainSession . crypto . crossSigning ;
switch ( crossSigning . state )
{
case MXCrossSigningStateNotBootstrapped : // Action : Bootstrap
case MXCrossSigningStateCanCrossSign : // Action : Reset
numberOfRowsInCrossSigningSection = CROSSSIGNING_FIRST _ACTION + 1 ;
break ;
case MXCrossSigningStateCrossSigningExists : // Actions : Verify this session , Reset
case MXCrossSigningStateTrustCrossSigning : // Actions : Request keys , Reset
numberOfRowsInCrossSigningSection = CROSSSIGNING_SECOND _ACTION + 1 ;
break ;
}
return numberOfRowsInCrossSigningSection ;
}
- ( NSAttributedString * ) crossSigningInformation
{
MXCrossSigning * crossSigning = self . mainSession . crypto . crossSigning ;
NSString * crossSigningInformation ;
switch ( crossSigning . state )
{
case MXCrossSigningStateNotBootstrapped :
2020-04-23 15:07:35 +00:00
crossSigningInformation = [ NSBundle mxk_localizedStringForKey : @ "security_settings_crosssigning_info_not_bootstrapped" ] ;
2020-03-18 11:20:14 +00:00
break ;
case MXCrossSigningStateCrossSigningExists :
2020-04-23 15:07:35 +00:00
crossSigningInformation = [ NSBundle mxk_localizedStringForKey : @ "security_settings_crosssigning_info_exists" ] ;
2020-03-18 11:20:14 +00:00
break ;
case MXCrossSigningStateTrustCrossSigning :
2020-04-23 15:07:35 +00:00
crossSigningInformation = [ NSBundle mxk_localizedStringForKey : @ "security_settings_crosssigning_info_trusted" ] ;
2020-03-18 11:20:14 +00:00
break ;
case MXCrossSigningStateCanCrossSign :
2020-04-23 15:07:35 +00:00
crossSigningInformation = [ NSBundle mxk_localizedStringForKey : @ "security_settings_crosssigning_info_ok" ] ;
2020-06-24 08:07:58 +00:00
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" ] ;
}
2020-03-18 11:20:14 +00:00
break ;
}
return [ [ NSAttributedString alloc ] initWithString : crossSigningInformation
attributes : @ {
NSForegroundColorAttributeName : ThemeService . shared . theme . textPrimaryColor ,
NSFontAttributeName : [ UIFont systemFontOfSize : 17 ]
} ] ;
}
- ( UITableViewCell * ) crossSigningButtonCellInTableView : ( UITableView * ) tableView forAction : ( NSInteger ) action
{
// Get a button cell
MXKTableViewCellWithButton * buttonCell = [ tableView dequeueReusableCellWithIdentifier : [ MXKTableViewCellWithButton defaultReuseIdentifier ] ] ;
if ( ! buttonCell )
{
buttonCell = [ [ MXKTableViewCellWithButton alloc ] init ] ;
}
[ buttonCell . mxkButton setTintColor : ThemeService . shared . theme . tintColor ] ;
buttonCell . mxkButton . titleLabel . font = [ UIFont systemFontOfSize : 17 ] ;
[ buttonCell . mxkButton removeTarget : self action : nil forControlEvents : UIControlEventTouchUpInside ] ;
buttonCell . mxkButton . accessibilityIdentifier = nil ;
// And customise it
MXCrossSigning * crossSigning = self . mainSession . crypto . crossSigning ;
switch ( crossSigning . state )
{
case MXCrossSigningStateNotBootstrapped : // Action : Bootstrap
[ self setUpcrossSigningButtonCellForBootstrap : buttonCell ] ;
break ;
case MXCrossSigningStateCanCrossSign : // Action : Reset
[ self setUpcrossSigningButtonCellForReset : buttonCell ] ;
break ;
case MXCrossSigningStateCrossSigningExists : // Actions : Verify this session , Reset
switch ( action )
{
case CROSSSIGNING_FIRST _ACTION :
2020-04-23 15:31:49 +00:00
[ self setUpcrossSigningButtonCellForCompletingSecurity : buttonCell ] ;
2020-03-18 11:20:14 +00:00
break ;
case CROSSSIGNING_SECOND _ACTION :
[ self setUpcrossSigningButtonCellForReset : buttonCell ] ;
break ;
}
break ;
case MXCrossSigningStateTrustCrossSigning : // Actions : Request keys , Reset
switch ( action )
{
case CROSSSIGNING_FIRST _ACTION :
2020-04-23 15:31:49 +00:00
// By verifying our device again , it will get cross - signing keys by gossiping
[ self setUpcrossSigningButtonCellForCompletingSecurity : buttonCell ] ;
2020-03-18 11:20:14 +00:00
break ;
case CROSSSIGNING_SECOND _ACTION :
[ self setUpcrossSigningButtonCellForReset : buttonCell ] ;
break ;
}
break ;
}
return buttonCell ;
}
- ( void ) setUpcrossSigningButtonCellForBootstrap : ( MXKTableViewCellWithButton * ) buttonCell
{
2020-04-23 15:07:35 +00:00
NSString * btnTitle = [ NSBundle mxk_localizedStringForKey : @ "security_settings_crosssigning_bootstrap" ] ;
2020-03-18 11:20:14 +00:00
[ buttonCell . mxkButton setTitle : btnTitle forState : UIControlStateNormal ] ;
[ buttonCell . mxkButton setTitle : btnTitle forState : UIControlStateHighlighted ] ;
2020-06-19 07:32:27 +00:00
[ buttonCell . mxkButton addTarget : self action : @ selector ( setupCrossSigning : ) forControlEvents : UIControlEventTouchUpInside ] ;
2020-03-18 11:20:14 +00:00
}
2020-06-25 15:16:25 +00:00
- ( void ) setupCrossSigning : ( id ) sender
2020-03-18 11:20:14 +00:00
{
2020-06-30 15:03:33 +00:00
[ self setupCrossSigningWithTitle : @ "Set up cross-signing" // TODO
message : NSLocalizedStringFromTable ( @ "security_settings_user_password_description" , @ "Vector" , nil )
success : ^ {
} failure : ^ ( NSError * error ) {
} ] ;
}
- ( void ) setupCrossSigningWithTitle : ( NSString * ) title
message : ( NSString * ) message
success : ( void ( ^ ) ( void ) ) success
2021-02-03 11:08:48 +00:00
failure : ( void ( ^ ) ( NSError * error ) ) failure
2020-03-18 11:20:14 +00:00
{
2020-06-26 05:42:37 +00:00
[ self startActivityIndicator ] ;
2021-02-03 11:08:48 +00:00
MXWeakify ( self ) ;
void ( ^ animationCompletion ) ( void ) = ^ void ( ) {
MXStrongifyAndReturnIfNil ( self ) ;
[ self stopActivityIndicator ] ;
[ self . crossSigningSetupCoordinatorBridgePresenter dismissWithAnimated : YES completion : ^ { } ] ;
self . crossSigningSetupCoordinatorBridgePresenter = nil ;
} ;
CrossSigningSetupCoordinatorBridgePresenter * crossSigningSetupCoordinatorBridgePresenter = [ [ CrossSigningSetupCoordinatorBridgePresenter alloc ] initWithSession : self . mainSession ] ;
[ crossSigningSetupCoordinatorBridgePresenter presentWith : title
message : message
from : self
animated : YES
success : ^ {
animationCompletion ( ) ;
[ self reloadData ] ;
success ( ) ;
} cancel : ^ {
animationCompletion ( ) ;
failure ( nil ) ;
} failure : ^ ( NSError * _Nonnull error ) {
animationCompletion ( ) ;
[ self reloadData ] ;
[ [ AppDelegate theDelegate ] showErrorAsAlert : error ] ;
failure ( error ) ;
2020-06-26 05:42:37 +00:00
} ] ;
2021-02-03 11:08:48 +00:00
self . crossSigningSetupCoordinatorBridgePresenter = crossSigningSetupCoordinatorBridgePresenter ;
2020-06-19 07:32:27 +00:00
}
2020-06-25 15:16:32 +00:00
- ( void ) resetCrossSigning : ( id ) sender
2020-06-19 07:32:27 +00:00
{
[ currentAlert dismissViewControllerAnimated : NO completion : nil ] ;
// Double confirmation
UIAlertController * alertController = [ UIAlertController alertControllerWithTitle : @ "Are you sure?" // TODO
2020-06-26 05:42:37 +00:00
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
2020-06-19 07:32:27 +00:00
preferredStyle : UIAlertControllerStyleAlert ] ;
[ alertController addAction : [ UIAlertAction actionWithTitle : @ "Reset"
style : UIAlertActionStyleDefault
handler : ^ ( UIAlertAction * action )
{
// Setup and reset are the same thing
2020-06-25 15:17:04 +00:00
[ self setupCrossSigning : nil ] ;
2020-06-19 07:32:27 +00:00
} ] ] ;
[ alertController addAction : [ UIAlertAction actionWithTitle : [ NSBundle mxk_localizedStringForKey : @ "cancel" ]
style : UIAlertActionStyleCancel
handler : nil ] ] ;
[ self presentViewController : alertController animated : YES completion : nil ] ;
currentAlert = alertController ;
2020-03-18 11:20:14 +00:00
}
- ( void ) setUpcrossSigningButtonCellForReset : ( MXKTableViewCellWithButton * ) buttonCell
{
2020-04-23 15:07:35 +00:00
NSString * btnTitle = [ NSBundle mxk_localizedStringForKey : @ "security_settings_crosssigning_reset" ] ;
2020-03-18 11:20:14 +00:00
[ buttonCell . mxkButton setTitle : btnTitle forState : UIControlStateNormal ] ;
[ buttonCell . mxkButton setTitle : btnTitle forState : UIControlStateHighlighted ] ;
buttonCell . mxkButton . tintColor = ThemeService . shared . theme . warningColor ;
[ buttonCell . mxkButton addTarget : self action : @ selector ( resetCrossSigning : ) forControlEvents : UIControlEventTouchUpInside ] ;
}
2020-04-23 15:31:49 +00:00
- ( void ) setUpcrossSigningButtonCellForCompletingSecurity : ( MXKTableViewCellWithButton * ) buttonCell
2020-03-18 11:20:14 +00:00
{
2020-04-23 15:31:49 +00:00
NSString * btnTitle = [ NSBundle mxk_localizedStringForKey : @ "security_settings_crosssigning_complete_security" ] ;
2020-03-18 11:20:14 +00:00
[ buttonCell . mxkButton setTitle : btnTitle forState : UIControlStateNormal ] ;
[ buttonCell . mxkButton setTitle : btnTitle forState : UIControlStateHighlighted ] ;
2020-04-23 15:31:49 +00:00
[ buttonCell . mxkButton addTarget : self action : @ selector ( presentCompleteSecurity ) forControlEvents : UIControlEventTouchUpInside ] ;
2020-03-18 11:20:14 +00:00
}
- ( void ) displayComingSoon
{
2020-04-23 15:07:35 +00:00
[ [ AppDelegate theDelegate ] showAlertWithTitle : nil message : [ NSBundle mxk_localizedStringForKey : @ "security_settings_coming_soon" ] ] ;
2020-03-18 11:20:14 +00:00
}
2020-06-18 13:34:24 +00:00
# pragma mark - SSSS
2020-06-24 07:35:46 +00:00
- ( 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 ;
2020-06-25 15:16:44 +00:00
MXRecoveryService * recoveryService = self . mainSession . crypto . recoveryService ;
2020-06-24 07:35:46 +00:00
if ( [ recoveryService hasSecretWithSecretId : secretId ] )
{
if ( [ recoveryService hasSecretLocally : secretId ] )
{
information = [ NSString stringWithFormat : @ "\n ✅ %@ is in the backup" , secretName ] ;
}
else
{
2020-06-24 08:07:58 +00:00
information = [ NSString stringWithFormat : @ "\n ⚠️ %@ is in the backup but not locally. Tap Synchronise" , secretName ] ;
2020-06-24 07:35:46 +00:00
* 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
MXRecoveryService * recoveryService = self . mainSession . crypto . recoveryService ;
NSArray * crossSigningServiceSecrets = @ [
MXSecretId . crossSigningMaster ,
MXSecretId . crossSigningSelfSigning ,
MXSecretId . crossSigningUserSigning ] ;
return ( [ recoveryService . secretsStoredLocally mx_intersectArray : crossSigningServiceSecrets ] . count
= = crossSigningServiceSecrets . count ) ;
}
2020-06-19 07:32:27 +00:00
- ( void ) setupSecureBackup
{
2020-06-30 15:03:33 +00:00
if ( self . canSetupSecureBackup )
{
[ self setupSecureBackup2 ] ;
}
else
{
// Set up cross - signing first
[ self setupCrossSigningWithTitle : NSLocalizedStringFromTable ( @ "secure_key_backup_setup_intro_title" , @ "Vector" , nil )
message : NSLocalizedStringFromTable ( @ "security_settings_user_password_description" , @ "Vector" , nil )
success : ^ {
[ self setupSecureBackup2 ] ;
} failure : ^ ( NSError * error ) {
} ] ;
}
}
- ( void ) setupSecureBackup2
2020-06-19 07:32:27 +00:00
{
2021-06-16 07:53:31 +00:00
SecureBackupSetupCoordinatorBridgePresenter * secureBackupSetupCoordinatorBridgePresenter = [ [ SecureBackupSetupCoordinatorBridgePresenter alloc ] initWithSession : self . mainSession allowOverwrite : YES ] ;
2020-06-25 18:23:40 +00:00
secureBackupSetupCoordinatorBridgePresenter . delegate = self ;
[ secureBackupSetupCoordinatorBridgePresenter presentFrom : self animated : YES ] ;
self . secureBackupSetupCoordinatorBridgePresenter = secureBackupSetupCoordinatorBridgePresenter ;
2020-06-19 07:32:27 +00:00
}
2020-06-18 13:34:24 +00:00
2020-01-28 20:09:51 +00:00
# pragma mark - Segues
- ( void ) prepareForSegue : ( UIStoryboardSegue * ) segue sender : ( id ) sender
{
// Keep ref on destinationViewController
[ super prepareForSegue : segue sender : sender ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// FIXME add night mode
}
# pragma mark - UITableView data source
- ( NSInteger ) numberOfSectionsInTableView : ( UITableView * ) tableView
{
2020-09-28 12:25:21 +00:00
return self . tableViewSections . sections . count ;
2020-01-28 20:09:51 +00:00
}
- ( NSInteger ) tableView : ( UITableView * ) tableView numberOfRowsInSection : ( NSInteger ) section
{
2020-09-28 12:25:21 +00:00
Section * tableSection = [ self . tableViewSections sectionAtIndex : section ] ;
return tableSection . rows . count ;
2020-01-28 20:09:51 +00:00
}
- ( MXKTableViewCellWithLabelAndSwitch * ) getLabelAndSwitchCell : ( UITableView * ) tableview forIndexPath : ( NSIndexPath * ) indexPath
{
MXKTableViewCellWithLabelAndSwitch * cell = [ tableview dequeueReusableCellWithIdentifier : [ MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier ] forIndexPath : indexPath ] ;
2020-01-28 21:36:50 +00:00
2020-04-22 13:15:30 +00:00
cell . mxkLabelLeadingConstraint . constant = cell . vc_separatorInset . left ;
2020-01-28 20:09:51 +00:00
cell . mxkSwitchTrailingConstraint . constant = 15 ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
cell . mxkLabel . textColor = ThemeService . shared . theme . textPrimaryColor ;
2020-01-28 21:36:50 +00:00
2020-09-28 15:05:11 +00:00
[ cell . mxkSwitch removeTarget : self action : nil forControlEvents : UIControlEventValueChanged ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
// Force layout before reusing a cell ( fix switch displayed outside the screen )
[ cell layoutIfNeeded ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
return cell ;
}
- ( MXKTableViewCell * ) getDefaultTableViewCell : ( UITableView * ) tableView
{
MXKTableViewCell * cell = [ tableView dequeueReusableCellWithIdentifier : [ MXKTableViewCell defaultReuseIdentifier ] ] ;
if ( ! cell )
{
cell = [ [ MXKTableViewCell alloc ] init ] ;
}
else
{
cell . selectionStyle = UITableViewCellSelectionStyleDefault ;
cell . accessoryType = UITableViewCellAccessoryNone ;
cell . accessoryView = nil ;
2020-01-29 08:32:50 +00:00
cell . imageView . image = nil ;
2020-01-28 20:09:51 +00:00
}
cell . textLabel . accessibilityIdentifier = nil ;
cell . textLabel . font = [ UIFont systemFontOfSize : 17 ] ;
cell . textLabel . textColor = ThemeService . shared . theme . textPrimaryColor ;
cell . contentView . backgroundColor = UIColor . clearColor ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
return cell ;
}
2020-01-29 08:32:50 +00:00
- ( MXKTableViewCell * ) deviceCellWithDevice : ( MXDevice * ) device forTableView : ( UITableView * ) tableView
{
MXKTableViewCell * cell = [ self getDefaultTableViewCell : tableView ] ;
NSString * name = device . displayName ;
NSString * deviceId = device . deviceId ;
cell . textLabel . text = ( name . length ? [ NSString stringWithFormat : @ "%@ (%@)" , name , deviceId ] : [ NSString stringWithFormat : @ "(%@)" , deviceId ] ) ;
cell . textLabel . numberOfLines = 0 ;
2020-07-16 21:16:11 +00:00
[ cell vc_setAccessoryDisclosureIndicatorWithCurrentTheme ] ;
2020-01-29 08:32:50 +00:00
if ( [ deviceId isEqualToString : self . mainSession . matrixRestClient . credentials . deviceId ] )
{
cell . textLabel . font = [ UIFont boldSystemFontOfSize : 17 ] ;
}
cell . imageView . image = [ self shieldImageForDevice : deviceId ] ;
return cell ;
}
- ( UIImage * ) shieldImageForDevice : ( NSString * ) deviceId
{
2020-04-23 13:50:01 +00:00
if ( ! self . mainSession . crypto . crossSigning . canCrossSign )
{
2020-04-28 14:15:31 +00:00
if ( [ deviceId isEqualToString : self . mainSession . myDeviceId ] )
{
return [ UIImage imageNamed : @ "encryption_warning" ] ;
}
else
{
return [ UIImage imageNamed : @ "encryption_normal" ] ;
}
2020-04-23 13:50:01 +00:00
}
2020-01-29 08:32:50 +00:00
UIImage * shieldImageForDevice = [ UIImage imageNamed : @ "encryption_warning" ] ;
MXDeviceInfo * device = [ self . mainSession . crypto deviceWithDeviceId : deviceId ofUser : self . mainSession . myUser . userId ] ;
if ( device . trustLevel . isVerified )
{
shieldImageForDevice = [ UIImage imageNamed : @ "encryption_trusted" ] ;
}
return shieldImageForDevice ;
}
2020-01-29 07:19:48 +00:00
- ( MXKTableViewCell * ) descriptionCellForTableView : ( UITableView * ) tableView withText : ( NSString * ) text
{
MXKTableViewCell * cell = [ self getDefaultTableViewCell : tableView ] ;
cell . textLabel . text = text ;
cell . textLabel . textColor = ThemeService . shared . theme . textPrimaryColor ;
cell . textLabel . numberOfLines = 0 ;
cell . contentView . backgroundColor = ThemeService . shared . theme . headerBackgroundColor ;
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
return cell ;
}
2020-01-28 20:09:51 +00:00
- ( MXKTableViewCellWithTextView * ) textViewCellForTableView : ( UITableView * ) tableView atIndexPath : ( NSIndexPath * ) indexPath
{
MXKTableViewCellWithTextView * textViewCell = [ tableView dequeueReusableCellWithIdentifier : [ MXKTableViewCellWithTextView defaultReuseIdentifier ] forIndexPath : indexPath ] ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
textViewCell . mxkTextView . textColor = ThemeService . shared . theme . textPrimaryColor ;
textViewCell . mxkTextView . font = [ UIFont systemFontOfSize : 17 ] ;
textViewCell . mxkTextView . backgroundColor = [ UIColor clearColor ] ;
2020-04-22 13:15:30 +00:00
textViewCell . mxkTextViewLeadingConstraint . constant = tableView . vc_separatorInset . left ;
textViewCell . mxkTextViewTrailingConstraint . constant = tableView . vc_separatorInset . right ;
2020-01-28 20:09:51 +00:00
textViewCell . mxkTextView . accessibilityIdentifier = nil ;
2020-01-28 21:36:50 +00:00
2020-01-28 20:09:51 +00:00
return textViewCell ;
}
2021-06-16 09:27:07 +00:00
- ( MXKTableViewCell * ) descriptionCellForTableView : ( UITableView * ) tableView atIndexPath : ( NSIndexPath * ) indexPath
{
MXKTableViewCell * cell = [ self getDefaultTableViewCell : tableView ] ;
cell . textLabel . textColor = ThemeService . shared . theme . textPrimaryColor ;
cell . textLabel . numberOfLines = 0 ;
cell . contentView . backgroundColor = ThemeService . shared . theme . headerBackgroundColor ;
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
return cell ;
}
2020-06-18 09:47:53 +00:00
- ( 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 ;
}
2020-01-28 20:09:51 +00:00
- ( UITableViewCell * ) tableView : ( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) indexPath
{
2020-09-28 12:25:21 +00:00
NSIndexPath * tagsIndexPath = [ self . tableViewSections tagsIndexPathFromTableViewIndexPath : indexPath ] ;
NSInteger section = tagsIndexPath . section ;
NSInteger row = tagsIndexPath . row ;
2020-01-28 20:09:51 +00:00
// set the cell to a default value to avoid application crashes
UITableViewCell * cell = [ [ UITableViewCell alloc ] init ] ;
cell . backgroundColor = [ UIColor redColor ] ;
2020-01-28 21:36:50 +00:00
MXSession * session = self . mainSession ;
2020-07-21 13:17:13 +00:00
if ( section = = SECTION_PIN _CODE )
{
2020-07-24 14:54:44 +00:00
if ( indexPath . row = = PIN_CODE _SETTING )
2020-07-21 13:17:13 +00:00
{
2020-07-24 14:54:44 +00:00
if ( [ PinCodePreferences shared ] . forcePinProtection )
2020-07-21 13:17:13 +00:00
{
cell = [ self getDefaultTableViewCell : tableView ] ;
cell . textLabel . text = NSLocalizedStringFromTable ( @ "pin_protection_settings_enabled_forced" , @ "Vector" , nil ) ;
}
2020-07-24 14:54:44 +00:00
else
2020-07-21 13:17:13 +00:00
{
MXKTableViewCellWithLabelAndSwitch * switchCell = [ self getLabelAndSwitchCell : tableView forIndexPath : indexPath ] ;
switchCell . mxkLabel . text = NSLocalizedStringFromTable ( @ "pin_protection_settings_enable_pin" , @ "Vector" , nil ) ;
switchCell . mxkSwitch . on = [ PinCodePreferences shared ] . isPinSet ;
[ switchCell . mxkSwitch addTarget : self action : @ selector ( enablePinCodeSwitchValueChanged : ) forControlEvents : UIControlEventValueChanged ] ;
cell = switchCell ;
}
2020-08-12 10:17:59 +00:00
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
2020-07-24 14:54:44 +00:00
}
else if ( indexPath . row = = PIN_CODE _DESCRIPTION )
{
if ( [ PinCodePreferences shared ] . isPinSet )
2020-07-21 13:17:13 +00:00
{
cell = [ self descriptionCellForTableView : tableView
withText : NSLocalizedStringFromTable ( @ "pin_protection_settings_section_footer" , @ "Vector" , nil ) ] ;
}
2020-07-24 14:54:44 +00:00
else
{
cell = [ self descriptionCellForTableView : tableView withText : nil ] ;
}
}
2020-12-16 13:15:41 +00:00
else if ( indexPath . row = = PIN_CODE _CHANGE )
{
cell = [ self buttonCellWithTitle : NSLocalizedStringFromTable ( @ "pin_protection_settings_change_pin" , @ "Vector" , nil ) action : @ selector ( changePinCode : ) forTableView : tableView atIndexPath : indexPath ] ;
}
2020-07-24 14:54:44 +00:00
else if ( indexPath . row = = PIN_CODE _BIOMETRICS )
{
MXKTableViewCellWithLabelAndSwitch * switchCell = [ self getLabelAndSwitchCell : tableView forIndexPath : indexPath ] ;
NSString * format = NSLocalizedStringFromTable ( @ "biometrics_settings_enable_x" , @ "Vector" , nil ) ;
switchCell . mxkLabel . text = [ NSString stringWithFormat : format , [ PinCodePreferences shared ] . localizedBiometricsName ] ;
switchCell . mxkSwitch . on = [ PinCodePreferences shared ] . isBiometricsSet ;
switchCell . mxkSwitch . enabled = [ PinCodePreferences shared ] . isBiometricsAvailable ;
[ switchCell . mxkSwitch addTarget : self action : @ selector ( enableBiometricsSwitchValueChanged : ) forControlEvents : UIControlEventValueChanged ] ;
cell = switchCell ;
2020-07-21 13:17:13 +00:00
}
}
else if ( section = = SECTION_CRYPTO _SESSIONS )
2020-01-28 20:09:51 +00:00
{
2020-02-10 09:51:30 +00:00
if ( self . showLoadingDevicesInformation )
2020-01-28 20:09:51 +00:00
{
2020-02-10 09:51:30 +00:00
if ( indexPath . row = = 0 )
{
cell = [ self descriptionCellForTableView : tableView
withText : NSLocalizedStringFromTable ( @ "security_settings_crypto_sessions_loading" , @ "Vector" , nil ) ] ;
}
else
{
cell = [ self descriptionCellForTableView : tableView
2020-06-30 16:12:50 +00:00
withText : NSLocalizedStringFromTable ( @ "security_settings_crypto_sessions_description_2" , @ "Vector" , nil ) ] ;
2020-02-10 09:51:30 +00:00
}
2020-01-28 20:09:51 +00:00
}
2020-02-10 09:51:30 +00:00
else
2020-01-28 20:09:51 +00:00
{
2020-02-10 09:51:30 +00:00
if ( row < devicesArray . count )
{
cell = [ self deviceCellWithDevice : devicesArray [ row ] forTableView : tableView ] ;
}
else if ( row = = devicesArray . count )
{
cell = [ self descriptionCellForTableView : tableView
2020-06-30 16:12:50 +00:00
withText : NSLocalizedStringFromTable ( @ "security_settings_crypto_sessions_description_2" , @ "Vector" , nil ) ] ;
2020-02-10 09:51:30 +00:00
}
2020-01-28 20:09:51 +00:00
}
2020-01-29 07:19:48 +00:00
}
2020-06-18 13:34:24 +00:00
else if ( section = = SECTION_SECURE _BACKUP )
{
2021-06-15 17:21:33 +00:00
cell = [ secureBackupSection cellForRowAtRow : row ] ;
2020-06-18 13:34:24 +00:00
}
2020-06-30 13:04:50 +00:00
# ifdef CROSS_SIGNING _AND _BACKUP _DEV
2020-03-12 10:21:47 +00:00
else if ( section = = SECTION_KEYBACKUP )
{
cell = [ keyBackupSection cellForRowAtRow : row ] ;
}
2021-06-15 14:09:56 +00:00
# endif
2020-03-12 10:21:47 +00:00
else if ( section = = SECTION_CROSSSIGNING )
2020-01-29 07:19:48 +00:00
{
switch ( row )
2020-01-28 20:09:51 +00:00
{
2020-03-12 10:21:47 +00:00
case CROSSSIGNING_INFO :
2020-01-28 20:09:51 +00:00
{
2020-03-12 10:21:47 +00:00
MXKTableViewCellWithTextView * cryptoCell = [ self textViewCellForTableView : tableView atIndexPath : indexPath ] ;
2020-03-18 08:41:27 +00:00
cryptoCell . mxkTextView . attributedText = [ self crossSigningInformation ] ;
2020-03-12 10:21:47 +00:00
cell = cryptoCell ;
2020-01-29 07:19:48 +00:00
break ;
2020-01-28 20:09:51 +00:00
}
2020-03-18 11:20:14 +00:00
case CROSSSIGNING_FIRST _ACTION :
cell = [ self crossSigningButtonCellInTableView : tableView forAction : CROSSSIGNING_FIRST _ACTION ] ;
break ;
case CROSSSIGNING_SECOND _ACTION :
cell = [ self crossSigningButtonCellInTableView : tableView forAction : CROSSSIGNING_SECOND _ACTION ] ;
2020-01-29 07:19:48 +00:00
break ;
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:05:11 +00:00
}
2020-03-12 10:21:47 +00:00
else if ( section = = SECTION_CRYPTOGRAPHY )
2020-01-29 07:19:48 +00:00
{
2020-01-29 14:56:06 +00:00
switch ( row )
{
2020-03-12 10:21:47 +00:00
case CRYPTOGRAPHY_INFO :
2020-01-29 14:56:06 +00:00
{
MXKTableViewCellWithTextView * cryptoCell = [ self textViewCellForTableView : tableView atIndexPath : indexPath ] ;
cryptoCell . mxkTextView . attributedText = [ self cryptographyInformation ] ;
cell = cryptoCell ;
break ;
}
2020-03-12 10:21:47 +00:00
case CRYPTOGRAPHY_EXPORT :
2020-01-29 14:56:06 +00:00
{
2020-06-18 09:47:53 +00:00
MXKTableViewCellWithButton * exportKeysBtnCell = [ self buttonCellWithTitle : NSLocalizedStringFromTable ( @ "security_settings_export_keys_manually" , @ "Vector" , nil )
action : @ selector ( exportEncryptionKeys : )
forTableView : tableView
atIndexPath : indexPath ] ;
2020-01-29 14:56:06 +00:00
cell = exportKeysBtnCell ;
break ;
}
}
2020-01-29 07:19:48 +00:00
}
2020-03-12 10:21:47 +00:00
else if ( section = = SECTION_ADVANCED )
{
switch ( row )
{
case ADVANCED_BLACKLIST _UNVERIFIED _DEVICES :
{
MXKTableViewCellWithLabelAndSwitch * labelAndSwitchCell = [ self getLabelAndSwitchCell : tableView forIndexPath : indexPath ] ;
labelAndSwitchCell . mxkLabel . text = NSLocalizedStringFromTable ( @ "security_settings_blacklist_unverified_devices" , @ "Vector" , nil ) ;
labelAndSwitchCell . mxkSwitch . on = session . crypto . globalBlacklistUnverifiedDevices ;
labelAndSwitchCell . mxkSwitch . onTintColor = ThemeService . shared . theme . tintColor ;
labelAndSwitchCell . mxkSwitch . enabled = YES ;
2020-09-28 15:05:11 +00:00
[ labelAndSwitchCell . mxkSwitch addTarget : self action : @ selector ( toggleBlacklistUnverifiedDevices : ) forControlEvents : UIControlEventValueChanged ] ;
2020-03-12 10:21:47 +00:00
cell = labelAndSwitchCell ;
break ;
}
case ADVANCED_BLACKLIST _UNVERIFIED _DEVICES _DESCRIPTION :
{
cell = [ self descriptionCellForTableView : tableView
withText : NSLocalizedStringFromTable ( @ "security_settings_blacklist_unverified_devices_description" , @ "Vector" , nil ) ] ;
break ;
}
}
}
2020-01-28 21:05:11 +00:00
return cell ;
}
- ( nullable NSString * ) tableView : ( UITableView * ) tableView titleForHeaderInSection : ( NSInteger ) section
{
2020-09-28 12:25:21 +00:00
Section * tableSection = [ self . tableViewSections sectionAtIndex : section ] ;
return tableSection . headerTitle ;
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:05:11 +00:00
- ( void ) tableView : ( UITableView * ) tableView willDisplayHeaderView : ( UIView * ) view forSection : ( NSInteger ) section
2020-01-28 20:09:51 +00:00
{
2020-01-28 21:05:11 +00:00
if ( [ view isKindOfClass : UITableViewHeaderFooterView . class ] )
2020-01-28 20:09:51 +00:00
{
2020-01-28 21:05:11 +00:00
// Customize label style
UITableViewHeaderFooterView * tableViewHeaderFooterView = ( UITableViewHeaderFooterView * ) view ;
tableViewHeaderFooterView . textLabel . textColor = ThemeService . shared . theme . textPrimaryColor ;
tableViewHeaderFooterView . textLabel . font = [ UIFont systemFontOfSize : 15 ] ;
2020-01-28 20:09:51 +00:00
}
}
2020-01-28 21:05:11 +00:00
# pragma mark - UITableView delegate
2020-01-28 20:09:51 +00:00
2020-01-28 21:05:11 +00:00
- ( void ) tableView : ( UITableView * ) tableView willDisplayCell : ( UITableViewCell * ) cell forRowAtIndexPath : ( NSIndexPath * ) indexPath ;
2020-01-28 20:09:51 +00:00
{
2020-01-28 21:05:11 +00:00
cell . backgroundColor = ThemeService . shared . theme . backgroundColor ;
2020-01-28 21:36:50 +00:00
2020-01-28 21:05:11 +00:00
if ( cell . selectionStyle ! = UITableViewCellSelectionStyleNone )
2020-01-28 21:36:50 +00:00
{
2020-01-28 21:05:11 +00:00
// Update the selected background view
if ( ThemeService . shared . theme . selectedBackgroundColor )
2020-01-28 20:09:51 +00:00
{
2020-01-28 21:05:11 +00:00
cell . selectedBackgroundView = [ [ UIView alloc ] init ] ;
cell . selectedBackgroundView . backgroundColor = ThemeService . shared . theme . selectedBackgroundColor ;
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:05:11 +00:00
else
2020-01-28 20:09:51 +00:00
{
2020-01-28 21:05:11 +00:00
if ( tableView . style = = UITableViewStylePlain )
{
cell . selectedBackgroundView = nil ;
}
else
{
cell . selectedBackgroundView . backgroundColor = nil ;
}
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:05:11 +00:00
}
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:05:11 +00:00
- ( CGFloat ) tableView : ( UITableView * ) tableView heightForHeaderInSection : ( NSInteger ) section
2020-01-28 20:09:51 +00:00
{
2020-01-30 12:14:17 +00:00
if ( section = = SECTION_CRYPTO _SESSIONS )
2020-01-29 07:19:48 +00:00
{
return 44 ;
}
2020-01-28 21:05:11 +00:00
return 24 ;
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:05:11 +00:00
- ( CGFloat ) tableView : ( UITableView * ) tableView heightForFooterInSection : ( NSInteger ) section
2020-01-28 20:09:51 +00:00
{
2020-01-28 21:05:11 +00:00
return 24 ;
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:05:11 +00:00
- ( void ) tableView : ( UITableView * ) tableView didSelectRowAtIndexPath : ( NSIndexPath * ) indexPath
2020-01-28 20:09:51 +00:00
{
2020-01-28 21:05:11 +00:00
if ( self . tableView = = tableView )
2020-01-28 20:09:51 +00:00
{
2020-09-28 12:25:21 +00:00
NSIndexPath * tagsIndexPath = [ self . tableViewSections tagsIndexPathFromTableViewIndexPath : indexPath ] ;
NSInteger section = tagsIndexPath . section ;
NSInteger row = tagsIndexPath . row ;
2020-01-28 21:05:11 +00:00
2020-01-30 12:14:17 +00:00
if ( section = = SECTION_CRYPTO _SESSIONS )
2020-01-28 20:09:51 +00:00
{
2020-01-29 07:19:48 +00:00
NSUInteger deviceIndex = row ;
if ( deviceIndex < devicesArray . count )
2020-01-28 21:05:11 +00:00
{
2020-04-23 13:50:01 +00:00
MXDevice * device = devicesArray [ deviceIndex ] ;
2020-01-29 16:56:24 +00:00
2020-04-24 16:47:57 +00:00
if ( self . mainSession . crypto . crossSigning . state = = MXCrossSigningStateNotBootstrapped )
{
// Display the device details . The verification will fail there .
ManageSessionViewController * viewController = [ ManageSessionViewController instantiateWithMatrixSession : self . mainSession andDevice : device ] ;
[ self pushViewController : viewController ] ;
}
else if ( self . mainSession . crypto . crossSigning . canCrossSign )
2020-04-23 13:50:01 +00:00
{
ManageSessionViewController * viewController = [ ManageSessionViewController instantiateWithMatrixSession : self . mainSession andDevice : device ] ;
[ self pushViewController : viewController ] ;
}
else
{
if ( [ device . deviceId isEqualToString : self . mainSession . matrixRestClient . credentials . deviceId ] )
{
[ self presentCompleteSecurity ] ;
}
else
{
[ self presentShouldCompleteSecurityAlert ] ;
}
}
2020-01-28 21:05:11 +00:00
}
2020-01-28 20:09:51 +00:00
}
2020-01-28 21:36:50 +00:00
2020-01-28 21:05:11 +00:00
[ tableView deselectRowAtIndexPath : indexPath animated : YES ] ;
2020-01-28 20:09:51 +00:00
}
}
2020-04-23 13:50:01 +00:00
- ( void ) presentCompleteSecurity
{
[ [ AppDelegate theDelegate ] presentCompleteSecurityForSession : self . mainSession ] ;
}
- ( void ) presentShouldCompleteSecurityAlert
{
[ currentAlert dismissViewControllerAnimated : NO completion : nil ] ;
UIAlertController * alertController = [ UIAlertController alertControllerWithTitle : NSLocalizedStringFromTable ( @ "security_settings_complete_security_alert_title" , @ "Vector" , nil )
message : NSLocalizedStringFromTable ( @ "security_settings_complete_security_alert_message" , @ "Vector" , nil )
preferredStyle : UIAlertControllerStyleAlert ] ;
[ alertController addAction : [ UIAlertAction actionWithTitle : [ NSBundle mxk_localizedStringForKey : @ "ok" ]
style : UIAlertActionStyleDefault
handler : ^ ( UIAlertAction * action ) {
[ self presentCompleteSecurity ] ;
} ] ] ;
[ alertController addAction : [ UIAlertAction actionWithTitle : NSLocalizedStringFromTable ( @ "later" , @ "Vector" , nil )
style : UIAlertActionStyleCancel
handler : nil ] ] ;
[ self presentViewController : alertController animated : YES completion : nil ] ;
currentAlert = alertController ;
[ currentAlert mxk_setAccessibilityIdentifier : @ "SettingsVCCompleteSecurity" ] ;
}
2020-01-28 21:36:50 +00:00
# pragma mark - UIDocumentInteractionControllerDelegate
- ( void ) documentInteractionController : ( UIDocumentInteractionController * ) controller didEndSendingToApplication : ( NSString * ) application
{
// If iOS wants to call this method , this is the right time to remove the file
[ self deleteKeyExportFile ] ;
}
- ( void ) documentInteractionControllerDidDismissOptionsMenu : ( UIDocumentInteractionController * ) controller
{
documentInteractionController = nil ;
}
2020-01-28 21:05:11 +00:00
# pragma mark - actions
2020-01-28 20:09:51 +00:00
2020-01-28 21:05:11 +00:00
- ( void ) exportEncryptionKeys : ( UITapGestureRecognizer * ) recognizer
2020-01-28 20:09:51 +00:00
{
2020-01-28 21:05:11 +00:00
[ currentAlert dismissViewControllerAnimated : NO completion : nil ] ;
2020-01-28 20:09:51 +00:00
2020-01-28 21:05:11 +00:00
exportView = [ [ MXKEncryptionKeysExportView alloc ] initWithMatrixSession : self . mainSession ] ;
currentAlert = exportView . alertController ;
2020-01-28 20:09:51 +00:00
2020-01-28 21:05:11 +00:00
// Use a temporary file for the export
keyExportsFile = [ NSURL fileURLWithPath : [ NSTemporaryDirectory ( ) stringByAppendingPathComponent : @ "riot-keys.txt" ] ] ;
2020-01-28 20:09:51 +00:00
2020-01-28 21:05:11 +00:00
// Make sure the file is empty
[ self deleteKeyExportFile ] ;
2020-01-28 20:09:51 +00:00
2020-01-28 21:05:11 +00:00
// Show the export dialog
2020-01-28 21:36:50 +00:00
MXWeakify ( self ) ;
2020-01-28 21:05:11 +00:00
[ exportView showInViewController : self toExportKeysToFile : keyExportsFile onComplete : ^ ( BOOL success ) {
2020-01-28 21:36:50 +00:00
MXStrongifyAndReturnIfNil ( self ) ;
self -> currentAlert = nil ;
self -> exportView = nil ;
2020-01-28 21:05:11 +00:00
2020-01-28 21:36:50 +00:00
if ( success )
2020-01-28 21:05:11 +00:00
{
2020-01-28 21:36:50 +00:00
// Let another app handling this file
self -> documentInteractionController = [ UIDocumentInteractionController interactionControllerWithURL : self -> keyExportsFile ] ;
[ self -> documentInteractionController setDelegate : self ] ;
2020-01-28 21:05:11 +00:00
2020-01-28 21:36:50 +00:00
if ( [ self -> documentInteractionController presentOptionsMenuFromRect : self . view . bounds inView : self . view animated : YES ] )
2020-01-28 21:05:11 +00:00
{
2020-01-28 21:36:50 +00:00
// We want to delete the temp keys file after it has been processed by the other app .
// We use [ UIDocumentInteractionControllerDelegate didEndSendingToApplication ] for that
// but it is not reliable for all cases ( see http : // stackoverflow . com / a / 21867096 ) .
// So , arm a timer to auto delete the file after 10 mins .
self -> keyExportsFileDeletionTimer = [ NSTimer scheduledTimerWithTimeInterval : 600 target : self selector : @ selector ( deleteKeyExportFile ) userInfo : self repeats : NO ] ;
}
else
{
self -> documentInteractionController = nil ;
[ self deleteKeyExportFile ] ;
2020-01-28 21:05:11 +00:00
}
}
} ] ;
}
- ( void ) deleteKeyExportFile
{
// Cancel the deletion timer if it is still here
if ( keyExportsFileDeletionTimer )
{
[ keyExportsFileDeletionTimer invalidate ] ;
keyExportsFileDeletionTimer = nil ;
}
// And delete the file
if ( keyExportsFile && [ [ NSFileManager defaultManager ] fileExistsAtPath : keyExportsFile . path ] )
{
[ [ NSFileManager defaultManager ] removeItemAtPath : keyExportsFile . path error : nil ] ;
2020-01-28 20:09:51 +00:00
}
}
2020-01-28 21:36:50 +00:00
- ( void ) toggleBlacklistUnverifiedDevices : ( id ) sender
{
UISwitch * switchButton = ( UISwitch * ) sender ;
2020-01-28 21:05:11 +00:00
2020-01-28 21:36:50 +00:00
self . mainSession . crypto . globalBlacklistUnverifiedDevices = switchButton . on ;
2020-01-28 21:05:11 +00:00
2020-01-28 21:36:50 +00:00
[ self . tableView reloadData ] ;
2020-01-28 20:09:51 +00:00
}
2020-07-21 13:17:13 +00:00
- ( void ) enablePinCodeSwitchValueChanged : ( UISwitch * ) sender
{
SetPinCoordinatorViewMode viewMode = sender . isOn ? SetPinCoordinatorViewModeSetPin : SetPinCoordinatorViewModeConfirmPinToDeactivate ;
self . setPinCoordinatorBridgePresenter = [ [ SetPinCoordinatorBridgePresenter alloc ] initWithSession : self . mainSession viewMode : viewMode ] ;
self . setPinCoordinatorBridgePresenter . delegate = self ;
[ self . setPinCoordinatorBridgePresenter presentFrom : self animated : YES ] ;
}
2020-01-28 21:36:50 +00:00
2020-07-24 14:54:44 +00:00
- ( void ) enableBiometricsSwitchValueChanged : ( UISwitch * ) sender
{
SetPinCoordinatorViewMode viewMode = sender . isOn ? SetPinCoordinatorViewModeSetupBiometricsFromSettings : SetPinCoordinatorViewModeConfirmBiometricsToDeactivate ;
self . setPinCoordinatorBridgePresenter = [ [ SetPinCoordinatorBridgePresenter alloc ] initWithSession : self . mainSession viewMode : viewMode ] ;
self . setPinCoordinatorBridgePresenter . delegate = self ;
[ self . setPinCoordinatorBridgePresenter presentFrom : self animated : YES ] ;
}
2020-12-16 13:15:41 +00:00
- ( void ) changePinCode : ( UIButton * ) sender
{
SetPinCoordinatorViewMode viewMode = SetPinCoordinatorViewModeChangePin ;
self . setPinCoordinatorBridgePresenter = [ [ SetPinCoordinatorBridgePresenter alloc ] initWithSession : self . mainSession viewMode : viewMode ] ;
self . setPinCoordinatorBridgePresenter . delegate = self ;
[ self . setPinCoordinatorBridgePresenter presentFrom : self animated : YES ] ;
}
2021-06-15 17:21:33 +00:00
# pragma mark - SettingsSecureBackupTableViewSectionDelegate
- ( void ) settingsSecureBackupTableViewSectionDidUpdate : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection
{
[ self reloadData ] ;
}
- ( MXKTableViewCellWithTextView * ) settingsSecureBackupTableViewSection : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection textCellForRow : ( NSInteger ) textCellForRow
{
MXKTableViewCellWithTextView * cell ;
NSIndexPath * indexPath = [ self . tableViewSections exactIndexPathForRowTag : textCellForRow sectionTag : SECTION_SECURE _BACKUP ] ;
if ( indexPath )
{
cell = [ self textViewCellForTableView : self . tableView atIndexPath : indexPath ] ;
}
return cell ;
}
2021-06-16 16:03:46 +00:00
- ( MXKTableViewCell * ) settingsSecureBackupTableViewSection : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection descriptionCellForRow : ( NSInteger ) textCellForRow
2021-06-16 09:27:07 +00:00
{
2021-06-16 16:03:46 +00:00
MXKTableViewCell * cell ;
2021-06-16 09:27:07 +00:00
NSIndexPath * indexPath = [ self . tableViewSections exactIndexPathForRowTag : textCellForRow sectionTag : SECTION_SECURE _BACKUP ] ;
if ( indexPath )
{
cell = [ self descriptionCellForTableView : self . tableView atIndexPath : indexPath ] ;
}
return cell ;
}
2021-06-15 17:21:33 +00:00
- ( MXKTableViewCellWithButton * ) settingsSecureBackupTableViewSection : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection buttonCellForRow : ( NSInteger ) buttonCellForRow
{
MXKTableViewCellWithButton * cell ;
NSIndexPath * indexPath = [ self . tableViewSections exactIndexPathForRowTag : buttonCellForRow sectionTag : SECTION_SECURE _BACKUP ] ;
if ( indexPath )
{
cell = [ self buttonCellForTableView : self . tableView atIndexPath : indexPath ] ;
}
return cell ;
}
2021-06-16 07:53:31 +00:00
- ( void ) settingsSecureBackupTableViewSectionShowSecureBackupReset : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection
{
[ self setupSecureBackup ] ;
}
2021-06-16 06:18:23 +00:00
- ( void ) settingsSecureBackupTableViewSectionShowKeyBackupCreate : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection
2021-06-15 17:21:33 +00:00
{
[ self showKeyBackupSetupFromSignOutFlow : NO ] ;
}
- ( void ) settingsSecureBackupTableViewSection : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection showKeyBackupRecover : ( MXKeyBackupVersion * ) 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 ) settingsSecureBackupTableViewSection : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection showKeyBackupDeleteConfirm : ( MXKeyBackupVersion * ) keyBackupVersion
{
MXWeakify ( self ) ;
[ currentAlert dismissViewControllerAnimated : NO completion : nil ] ;
currentAlert =
[ UIAlertController alertControllerWithTitle : NSLocalizedStringFromTable ( @ "settings_key_backup_delete_confirmation_prompt_title" , @ "Vector" , nil )
message : NSLocalizedStringFromTable ( @ "settings_key_backup_delete_confirmation_prompt_msg" , @ "Vector" , nil )
preferredStyle : UIAlertControllerStyleAlert ] ;
[ currentAlert addAction : [ UIAlertAction actionWithTitle : [ NSBundle mxk_localizedStringForKey : @ "cancel" ]
style : UIAlertActionStyleCancel
handler : ^ ( UIAlertAction * action ) {
MXStrongifyAndReturnIfNil ( self ) ;
self -> currentAlert = nil ;
} ] ] ;
[ currentAlert addAction : [ UIAlertAction actionWithTitle : NSLocalizedStringFromTable ( @ "settings_key_backup_button_delete" , @ "Vector" , nil )
style : UIAlertActionStyleDefault
handler : ^ ( UIAlertAction * action ) {
MXStrongifyAndReturnIfNil ( self ) ;
self -> currentAlert = nil ;
2021-06-16 13:05:30 +00:00
[ self -> secureBackupSection deleteKeyBackupWithKeyBackupVersion : keyBackupVersion ] ;
2021-06-15 17:21:33 +00:00
} ] ] ;
[ currentAlert mxk_setAccessibilityIdentifier : @ "SettingsVCDeleteKeyBackup" ] ;
[ self presentViewController : currentAlert animated : YES completion : nil ] ;
}
- ( void ) settingsSecureBackupTableViewSection : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection showActivityIndicator : ( BOOL ) show
{
if ( show )
{
[ self startActivityIndicator ] ;
}
else
{
[ self stopActivityIndicator ] ;
}
}
- ( void ) settingsSecureBackupTableViewSection : ( SettingsSecureBackupTableViewSection * ) settingsSecureBackupTableViewSection showError : ( NSError * ) error
{
[ [ AppDelegate theDelegate ] showErrorAsAlert : error ] ;
}
2021-06-16 13:05:30 +00:00
# pragma mark - KeyBackupRecoverCoordinatorBridgePresenter
- ( void ) showKeyBackupSetupFromSignOutFlow : ( BOOL ) showFromSignOutFlow
{
keyBackupSetupCoordinatorBridgePresenter = [ [ KeyBackupSetupCoordinatorBridgePresenter alloc ] initWithSession : self . mainSession ] ;
[ keyBackupSetupCoordinatorBridgePresenter presentFrom : self
isStartedFromSignOut : showFromSignOutFlow
animated : true ] ;
keyBackupSetupCoordinatorBridgePresenter . delegate = self ;
}
- ( void ) keyBackupSetupCoordinatorBridgePresenterDelegateDidCancel : ( KeyBackupSetupCoordinatorBridgePresenter * ) bridgePresenter {
[ keyBackupSetupCoordinatorBridgePresenter dismissWithAnimated : true ] ;
keyBackupSetupCoordinatorBridgePresenter = nil ;
}
- ( void ) keyBackupSetupCoordinatorBridgePresenterDelegateDidSetupRecoveryKey : ( KeyBackupSetupCoordinatorBridgePresenter * ) bridgePresenter {
[ keyBackupSetupCoordinatorBridgePresenter dismissWithAnimated : true ] ;
keyBackupSetupCoordinatorBridgePresenter = nil ;
[ secureBackupSection reload ] ;
}
2021-06-15 17:21:33 +00:00
2020-01-28 20:09:51 +00:00
# pragma mark - SettingsKeyBackupTableViewSectionDelegate
2020-06-30 13:04:50 +00:00
# ifdef CROSS_SIGNING _AND _BACKUP _DEV
2020-01-28 20:09:51 +00:00
- ( void ) settingsKeyBackupTableViewSectionDidUpdate : ( SettingsKeyBackupTableViewSection * ) settingsKeyBackupTableViewSection
{
2020-09-28 15:22:43 +00:00
[ self reloadData ] ;
2020-01-28 20:09:51 +00:00
}
- ( MXKTableViewCellWithTextView * ) settingsKeyBackupTableViewSection : ( SettingsKeyBackupTableViewSection * ) settingsKeyBackupTableViewSection textCellForRow : ( NSInteger ) textCellForRow
{
2020-09-28 14:21:41 +00:00
MXKTableViewCellWithTextView * cell ;
2020-09-28 12:25:21 +00:00
NSIndexPath * indexPath = [ self . tableViewSections exactIndexPathForRowTag : textCellForRow sectionTag : SECTION_KEYBACKUP ] ;
2020-09-28 14:21:41 +00:00
if ( indexPath )
{
cell = [ self textViewCellForTableView : self . tableView atIndexPath : indexPath ] ;
}
return cell ;
2020-01-28 20:09:51 +00:00
}
- ( MXKTableViewCellWithButton * ) settingsKeyBackupTableViewSection : ( SettingsKeyBackupTableViewSection * ) settingsKeyBackupTableViewSection buttonCellForRow : ( NSInteger ) buttonCellForRow
{
2020-09-28 14:21:41 +00:00
MXKTableViewCellWithButton * cell ;
2020-09-28 12:25:21 +00:00
NSIndexPath * indexPath = [ self . tableViewSections exactIndexPathForRowTag : buttonCellForRow sectionTag : SECTION_KEYBACKUP ] ;
2020-09-28 14:21:41 +00:00
if ( indexPath )
{
2021-06-15 14:07:30 +00:00
cell = [ self buttonCellForTableView : self . tableView atIndexPath : indexPath ] ;
2020-09-28 14:21:41 +00:00
}
return cell ;
2020-01-28 20:09:51 +00:00
}
- ( void ) settingsKeyBackupTableViewSectionShowKeyBackupSetup : ( SettingsKeyBackupTableViewSection * ) settingsKeyBackupTableViewSection
{
[ self showKeyBackupSetupFromSignOutFlow : NO ] ;
}
- ( void ) settingsKeyBackup : ( SettingsKeyBackupTableViewSection * ) settingsKeyBackupTableViewSection showKeyBackupRecover : ( MXKeyBackupVersion * ) keyBackupVersion
{
2020-06-15 14:30:58 +00:00
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 ] ;
}
2020-01-28 20:09:51 +00:00
}
- ( void ) settingsKeyBackup : ( SettingsKeyBackupTableViewSection * ) settingsKeyBackupTableViewSection showKeyBackupDeleteConfirm : ( MXKeyBackupVersion * ) keyBackupVersion
{
MXWeakify ( self ) ;
[ currentAlert dismissViewControllerAnimated : NO completion : nil ] ;
currentAlert =
[ UIAlertController alertControllerWithTitle : NSLocalizedStringFromTable ( @ "settings_key_backup_delete_confirmation_prompt_title" , @ "Vector" , nil )
message : NSLocalizedStringFromTable ( @ "settings_key_backup_delete_confirmation_prompt_msg" , @ "Vector" , nil )
preferredStyle : UIAlertControllerStyleAlert ] ;
[ currentAlert addAction : [ UIAlertAction actionWithTitle : [ NSBundle mxk_localizedStringForKey : @ "cancel" ]
style : UIAlertActionStyleCancel
handler : ^ ( UIAlertAction * action ) {
MXStrongifyAndReturnIfNil ( self ) ;
self -> currentAlert = nil ;
} ] ] ;
[ currentAlert addAction : [ UIAlertAction actionWithTitle : NSLocalizedStringFromTable ( @ "settings_key_backup_button_delete" , @ "Vector" , nil )
style : UIAlertActionStyleDefault
handler : ^ ( UIAlertAction * action ) {
MXStrongifyAndReturnIfNil ( self ) ;
self -> currentAlert = nil ;
[ self -> keyBackupSection deleteWithKeyBackupVersion : keyBackupVersion ] ;
} ] ] ;
[ currentAlert mxk_setAccessibilityIdentifier : @ "SettingsVCDeleteKeyBackup" ] ;
[ self presentViewController : currentAlert animated : YES completion : nil ] ;
}
- ( void ) settingsKeyBackup : ( SettingsKeyBackupTableViewSection * ) settingsKeyBackupTableViewSection showActivityIndicator : ( BOOL ) show
{
if ( show )
{
[ self startActivityIndicator ] ;
}
else
{
[ self stopActivityIndicator ] ;
}
}
- ( void ) settingsKeyBackup : ( SettingsKeyBackupTableViewSection * ) settingsKeyBackupTableViewSection showError : ( NSError * ) error
{
[ [ AppDelegate theDelegate ] showErrorAsAlert : error ] ;
}
2020-06-30 13:04:50 +00:00
# endif
2020-01-28 20:09:51 +00:00
# pragma mark - KeyBackupRecoverCoordinatorBridgePresenter
2020-06-15 14:30:58 +00:00
- ( void ) showKeyBackupRecover : ( MXKeyBackupVersion * ) keyBackupVersion fromViewController : ( UIViewController * ) presentingViewController
2020-01-28 20:09:51 +00:00
{
keyBackupRecoverCoordinatorBridgePresenter = [ [ KeyBackupRecoverCoordinatorBridgePresenter alloc ] initWithSession : self . mainSession keyBackupVersion : keyBackupVersion ] ;
2020-06-15 14:30:58 +00:00
[ 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 ] ;
2020-01-28 20:09:51 +00:00
keyBackupRecoverCoordinatorBridgePresenter . delegate = self ;
}
- ( void ) keyBackupRecoverCoordinatorBridgePresenterDidCancel : ( KeyBackupRecoverCoordinatorBridgePresenter * ) bridgePresenter {
[ keyBackupRecoverCoordinatorBridgePresenter dismissWithAnimated : true ] ;
keyBackupRecoverCoordinatorBridgePresenter = nil ;
2020-06-15 14:30:58 +00:00
secretsRecoveryCoordinatorBridgePresenter = nil ;
2020-01-28 20:09:51 +00:00
}
- ( void ) keyBackupRecoverCoordinatorBridgePresenterDidRecover : ( KeyBackupRecoverCoordinatorBridgePresenter * ) bridgePresenter {
[ keyBackupRecoverCoordinatorBridgePresenter dismissWithAnimated : true ] ;
keyBackupRecoverCoordinatorBridgePresenter = nil ;
2020-06-15 14:30:58 +00:00
secretsRecoveryCoordinatorBridgePresenter = nil ;
}
# pragma mark - KeyBackupRecoverCoordinatorBridgePresenter
- ( void ) showSecretsRecovery
{
2021-06-16 05:44:12 +00:00
secretsRecoveryCoordinatorBridgePresenter = [ [ SecretsRecoveryCoordinatorBridgePresenter alloc ] initWithSession : self . mainSession recoveryGoal : SecretsRecoveryGoalBridgeKeyBackup ] ;
2020-06-15 14:30:58 +00:00
[ 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 ] ;
2021-06-16 05:44:12 +00:00
if ( coordinatorBridgePresenter . recoveryGoal = = SecretsRecoveryGoalBridgeKeyBackup )
2020-06-15 14:30:58 +00:00
{
2020-06-18 13:34:24 +00:00
// 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 ] ;
}
2020-06-15 14:30:58 +00:00
}
else
{
2020-06-18 13:34:24 +00:00
[ secretsRecoveryCoordinatorBridgePresenter dismissWithAnimated : YES completion : nil ] ;
secretsRecoveryCoordinatorBridgePresenter = nil ;
2020-06-15 14:30:58 +00:00
}
2020-01-28 20:09:51 +00:00
}
2020-06-26 12:36:27 +00:00
# pragma mark - SecureBackupSetupCoordinatorBridgePresenterDelegate
2020-06-26 05:42:37 +00:00
2020-06-26 12:36:27 +00:00
- ( void ) secureBackupSetupCoordinatorBridgePresenterDelegateDidComplete : ( SecureBackupSetupCoordinatorBridgePresenter * ) coordinatorBridgePresenter
2020-06-26 05:42:37 +00:00
{
[ self . secureBackupSetupCoordinatorBridgePresenter dismissWithAnimated : YES completion : nil ] ;
self . secureBackupSetupCoordinatorBridgePresenter = nil ;
}
2020-06-26 12:36:27 +00:00
- ( void ) secureBackupSetupCoordinatorBridgePresenterDelegateDidCancel : ( SecureBackupSetupCoordinatorBridgePresenter * ) coordinatorBridgePresenter
2020-06-26 05:42:37 +00:00
{
[ self . secureBackupSetupCoordinatorBridgePresenter dismissWithAnimated : YES completion : nil ] ;
self . secureBackupSetupCoordinatorBridgePresenter = nil ;
2020-01-28 20:09:51 +00:00
}
2020-07-21 13:17:13 +00:00
# pragma mark - SetPinCoordinatorBridgePresenterDelegate
- ( void ) setPinCoordinatorBridgePresenterDelegateDidComplete : ( SetPinCoordinatorBridgePresenter * ) coordinatorBridgePresenter
{
[ self . tableView reloadData ] ;
[ self dismissViewControllerAnimated : YES completion : nil ] ;
}
- ( void ) setPinCoordinatorBridgePresenterDelegateDidCancel : ( SetPinCoordinatorBridgePresenter * ) coordinatorBridgePresenter
{
[ self . tableView reloadData ] ;
[ self dismissViewControllerAnimated : YES completion : nil ] ;
}
2020-09-28 12:25:21 +00:00
# pragma mark - TableViewSectionsDelegate
- ( void ) tableViewSectionsDidUpdateSections : ( TableViewSections * ) sections
{
[ self . tableView reloadData ] ;
}
2020-01-28 20:09:51 +00:00
@ end