diff --git a/Riot/Managers/UserSessions/UserSessionsService.swift b/Riot/Managers/UserSessions/UserSessionsService.swift index 576e0d22f..7a68d9752 100644 --- a/Riot/Managers/UserSessions/UserSessionsService.swift +++ b/Riot/Managers/UserSessions/UserSessionsService.swift @@ -155,7 +155,7 @@ class UserSessionsService: NSObject { let isSessionStateValid: Bool switch mxSession.state { - case .closed, .unauthenticated: + case .closed: isSessionStateValid = false default: isSessionStateValid = true diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index fd6354ad3..37ca135d3 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -1372,9 +1372,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni else { void(^findRoom)(void) = ^{ - if ([_masterTabBarController.selectedViewController isKindOfClass:MXKActivityHandlingViewController.class]) + if ([_masterTabBarController.selectedViewController conformsToProtocol:@protocol(MXKViewControllerActivityHandling)]) { - MXKActivityHandlingViewController *homeViewController = (MXKActivityHandlingViewController*)_masterTabBarController.selectedViewController; + UIViewController *homeViewController = (UIViewController*)_masterTabBarController.selectedViewController; [homeViewController startActivityIndicator]; @@ -1651,11 +1651,13 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni // Try to get more information about the room before opening its preview [roomPreviewData peekInRoom:^(BOOL succeeded) { MXStrongifyAndReturnIfNil(self); - - MXKViewController *homeViewController = (MXKViewController*)self.masterTabBarController.selectedViewController; - - // Note: the activity indicator will not disappear if the session is not ready - [homeViewController stopActivityIndicator]; + if ([self.masterTabBarController.selectedViewController conformsToProtocol:@protocol(MXKViewControllerActivityHandling)]) + { + UIViewController *homeViewController = (UIViewController*)self.masterTabBarController.selectedViewController; + + // Note: the activity indicator will not disappear if the session is not ready + [homeViewController stopActivityIndicator]; + } // If no data is available for this room, we name it with the known room alias (if any). if (!succeeded && self->universalLinkFragmentPendingRoomAlias[roomIdOrAlias]) diff --git a/Riot/Modules/Home/VersionCheck/HomeViewControllerWithBannerWrapperViewController.swift b/Riot/Modules/Home/VersionCheck/HomeViewControllerWithBannerWrapperViewController.swift index 85abec4d1..bae7d1ead 100644 --- a/Riot/Modules/Home/VersionCheck/HomeViewControllerWithBannerWrapperViewController.swift +++ b/Riot/Modules/Home/VersionCheck/HomeViewControllerWithBannerWrapperViewController.swift @@ -16,8 +16,8 @@ import Foundation -class HomeViewControllerWithBannerWrapperViewController: MXKActivityHandlingViewController, BannerPresentationProtocol { - +class HomeViewControllerWithBannerWrapperViewController: UIViewController, MXKViewControllerActivityHandling, BannerPresentationProtocol { + @objc let homeViewController: HomeViewController private var bannerContainerView: UIView! private var stackView: UIStackView! @@ -85,4 +85,22 @@ class HomeViewControllerWithBannerWrapperViewController: MXKActivityHandlingView bannerView.removeFromSuperview() } } + + // MARK: - MXKViewControllerActivityHandling + var activityIndicator: UIActivityIndicatorView! { + get { + return homeViewController.activityIndicator + } + set { + homeViewController.activityIndicator = newValue + } + } + + func startActivityIndicator() { + homeViewController.startActivityIndicator() + } + + func stopActivityIndicator() { + homeViewController.stopActivityIndicator() + } } diff --git a/Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m b/Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m index acccd6a29..18d65c927 100644 --- a/Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m +++ b/Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m @@ -1453,7 +1453,7 @@ return NO; } andPersistentTokenDataHandler:^(void (^handler)(NSArray *credentials, void (^completion)(BOOL didUpdateCredentials))) { [[MXKAccountManager sharedManager] readAndWriteCredentials:handler]; - }]; + } andUnauthenticatedHandler: nil]; MXWeakify(self); [[MXKAccountManager sharedManager].dehydrationService rehydrateDeviceWithMatrixRestClient:mxRestClient dehydrationKey:keyData success:^(NSString * deviceId) { diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h index 5e928299c..b9eea90a4 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h @@ -359,4 +359,8 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer success:(void (^)(void))success failure:(void (^)(NSError *error))failure; +/** + Handle unauthenticated errors from the server triggering hard/soft logouts as appropriate. + */ +- (void)handleUnauthenticated:(MXError *)error andCompletion:(void (^)(void))completion; @end diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 25482b6b5..69db12322 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -959,9 +959,6 @@ static NSArray *initialSyncSilentErrorsHTTPStatusCodes; } } - - - - (void)deletePusher { if (self.pushNotificationServiceIsActive) @@ -1670,16 +1667,6 @@ static NSArray *initialSyncSilentErrorsHTTPStatusCodes; { isPauseRequested = NO; } - else if (mxSession.state == MXSessionStateUnauthenticated) - { - // Logout this account - [[MXKAccountManager sharedManager] removeAccount:self sendLogoutRequest:NO completion:nil]; - } - else if (mxSession.state == MXSessionStateSoftLogout) - { - // Soft logout this account - [[MXKAccountManager sharedManager] softLogout:self]; - } } - (void)prepareRESTClient @@ -1688,9 +1675,9 @@ static NSArray *initialSyncSilentErrorsHTTPStatusCodes; { return; } - + MXWeakify(self); mxRestClient = [[MXRestClient alloc] initWithCredentials:self.mxCredentials andOnUnrecognizedCertificateBlock:^BOOL(NSData *certificate) { - + MXStrongifyAndReturnValueIfNil(self, NO); if (_onCertificateChangeBlock) { if (_onCertificateChangeBlock (self, certificate)) @@ -1713,9 +1700,29 @@ static NSArray *initialSyncSilentErrorsHTTPStatusCodes; } andPersistentTokenDataHandler:^(void (^handler)(NSArray *credentials, void (^completion)(BOOL didUpdateCredentials))) { [MXKAccountManager.sharedManager readAndWriteCredentials:handler]; + } andUnauthenticatedHandler:^(MXError *error, void (^completion)(void)) { + MXStrongifyAndReturnIfNil(self); + [self handleUnauthenticated:error andCompletion:completion]; }]; } + +- (void)handleUnauthenticated:(MXError *)error andCompletion:(void (^)(void))completion +{ + if (error.httpResponse.statusCode == 401 + && [error.userInfo[kMXErrorSoftLogoutKey] isEqual:@(YES)]) + { + MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: soft logout."); + [[MXKAccountManager sharedManager] softLogout:self]; + completion(); + } + else + { + MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: hard logout."); + [[MXKAccountManager sharedManager] removeAccount:self sendLogoutRequest:NO completion:completion]; + } +} + - (void)onDateTimeFormatUpdate { if ([mxSession.roomSummaryUpdateDelegate isKindOfClass:MXKEventFormatter.class]) diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index e28b861a8..b6a921b77 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -56,22 +56,11 @@ class NotificationService: UNNotificationServiceExtension { guard let userAccount = userAccount else { return nil } - let restClient = MXRestClient(credentials: userAccount.mxCredentials, unrecognizedCertificateHandler: nil) { persistTokenDataHandler in + let restClient = MXRestClient(credentials: userAccount.mxCredentials, unrecognizedCertificateHandler: nil, persistentTokenDataHandler: { persistTokenDataHandler in MXKAccountManager.shared().readAndWriteCredentials(persistTokenDataHandler) - } - restClient.refreshTokensFailedHandler = { mxError in - MXLog.debug("[NotificationService] mxRestClient: The rest client is no longer authenticated.") - if let mxError = mxError, - mxError.httpResponse.statusCode == 401, - let softLogout = mxError.userInfo[kMXErrorSoftLogoutKey] as? Bool, - softLogout { - MXLog.debug("[NotificationService] mxRestClient: soft logout"); - userAccount.softLogout() - } else { - MXLog.debug("[NotificationService] mxRestClient: full logout"); - MXKAccountManager.shared().removeAccount(userAccount, completion: nil) - } - } + }, unauthenticatedHandler: { error, completion in + userAccount.handleUnauthenticated(error, andCompletion: completion) + }) return restClient }() @@ -191,6 +180,8 @@ class NotificationService: UNNotificationServiceExtension { self.logMemory() NotificationService.backgroundSyncService = MXBackgroundSyncService(withCredentials: userAccount.mxCredentials, persistTokenDataHandler: { persistTokenDataHandler in MXKAccountManager.shared().readAndWriteCredentials(persistTokenDataHandler) + }, unauthenticatedHandler: { error, completion in + userAccount.handleUnauthenticated(error, andCompletion: completion) }) MXLog.debug("[NotificationService] setup: MXBackgroundSyncService init: AFTER") self.logMemory() diff --git a/RiotShareExtension/Shared/ShareDataSource.m b/RiotShareExtension/Shared/ShareDataSource.m index 7bfcfab73..9f213a840 100644 --- a/RiotShareExtension/Shared/ShareDataSource.m +++ b/RiotShareExtension/Shared/ShareDataSource.m @@ -81,10 +81,11 @@ NSMutableArray *cellData = [NSMutableArray array]; - // Add a fake matrix session to each room summary to provide it a REST client (used to handle correctly the room avatar). - MXSession *session = [[MXSession alloc] initWithMatrixRestClient:[[MXRestClient alloc] initWithCredentials:self.credentials andOnUnrecognizedCertificateBlock:nil andPersistentTokenDataHandler:^(void (^handler)(NSArray *credentials, void (^completion)(BOOL didUpdateCredentials))) { + MXRestClient *mxRestClient = [[MXRestClient alloc] initWithCredentials:self.credentials andOnUnrecognizedCertificateBlock:nil andPersistentTokenDataHandler:^(void (^handler)(NSArray *credentials, void (^completion)(BOOL didUpdateCredentials))) { [[MXKAccountManager sharedManager] readAndWriteCredentials:handler]; - }]]; + } andUnauthenticatedHandler:nil]; + // Add a fake matrix session to each room summary to provide it a REST client (used to handle correctly the room avatar). + MXSession *session = [[MXSession alloc] initWithMatrixRestClient:mxRestClient]; for (MXRoomSummary *roomSummary in roomsSummaries) { diff --git a/RiotShareExtension/Shared/ShareManager.m b/RiotShareExtension/Shared/ShareManager.m index ee306286d..bfb58e8bc 100644 --- a/RiotShareExtension/Shared/ShareManager.m +++ b/RiotShareExtension/Shared/ShareManager.m @@ -78,9 +78,14 @@ - (void)shareViewController:(ShareViewController *)shareViewController didRequestShareForRoomIdentifiers:(NSSet *)roomIdentifiers { - MXSession *session = [[MXSession alloc] initWithMatrixRestClient:[[MXRestClient alloc] initWithCredentials:self.userAccount.mxCredentials andOnUnrecognizedCertificateBlock:nil andPersistentTokenDataHandler:^(void (^handler)(NSArray *credentials, void (^completion)(BOOL didUpdateCredentials))) { + MXWeakify(self); + MXRestClient *restClient = [[MXRestClient alloc] initWithCredentials:self.userAccount.mxCredentials andOnUnrecognizedCertificateBlock:nil andPersistentTokenDataHandler:^(void (^handler)(NSArray *credentials, void (^completion)(BOOL didUpdateCredentials))) { [[MXKAccountManager sharedManager] readAndWriteCredentials:handler]; - }]]; + } andUnauthenticatedHandler:^(MXError *error, void (^completion)(void)) { + MXStrongifyAndReturnIfNil(self); + [self.userAccount handleUnauthenticated:error andCompletion:completion]; + }]; + MXSession *session = [[MXSession alloc] initWithMatrixRestClient:restClient]; [MXFileStore setPreloadOptions:0]; MXWeakify(session);