diff --git a/CHANGES.rst b/CHANGES.rst index 0b1fb0bed..a09fb1333 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,10 @@ +Changes in 0.9.2 (2019-07-) +=============================================== + +Improvements: + * Upgrade MatrixKit version ([v0.10.2](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.10.2)). + * Soft logout: Support soft logout (#2540). + Changes in 0.9.1 (2019-07-17) =============================================== diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index db380b2ec..9e6cf8f5b 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -2770,7 +2770,10 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN // Remove inApp notifications toggle change MXKAccount *account = notif.object; - [account removeObserver:self forKeyPath:@"enableInAppNotifications"]; + if (!account.isSoftLogout) + { + [account removeObserver:self forKeyPath:@"enableInAppNotifications"]; + } // Clear Modular data [[WidgetManager sharedManager] deleteDataForUser:account.mxCredentials.userId]; @@ -2781,6 +2784,16 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN [self logoutWithConfirmation:NO completion:nil]; } }]; + + // Add observer to handle soft logout + [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountManagerDidSoftlogoutAccountNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + + MXKAccount *account = notif.object; + [self removeMatrixSession:account.mxSession]; + + // Return to authentication screen + [self.masterTabBarController showAuthenticationScreenAfterSoftLogout:account.mxCredentials]; + }]; [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionIgnoredUsersDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull notif) { diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index f13c54309..6dc4d294c 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -115,6 +115,18 @@ "auth_add_email_and_phone_warning" = "Registration with email and phone number at once is not supported yet until the api exists. Only the phone number will be taken into account. You may add your email to your profile in settings."; "auth_accept_policies" = "Please review and accept the policies of this homeserver:"; "auth_autodiscover_invalid_response" = "Invalid homeserver discovery response"; +"auth_softlogout_signed_out" = "You’re signed out"; +"auth_softlogout_sign_in" = "Sign In"; +"auth_softlogout_reason" = "Your homeserver (%1$@) admin has signed you out of your account %2$@ (%3$@)."; +"auth_softlogout_recover_encryption_keys" = "Sign in to recover encryption keys stored exclusively on this device. You need them to read all of your secure messages on any device."; +"auth_softlogout_clear_data" = "Clear personal data"; +"auth_softlogout_clear_data_message_1" = "Warning: Your personal data (including encryption keys) is still stored on this device."; +"auth_softlogout_clear_data_message_2" = "Clear it if you're finished using this device, or want to sign in to another account."; +"auth_softlogout_clear_data_button" = "Clear all data"; +"auth_softlogout_clear_data_sign_out_title" = "Are you sure?"; +"auth_softlogout_clear_data_sign_out_msg" = "Are you sure you want to clear all data currently stored on this device? Sign in again to access your account data and messages."; +"auth_softlogout_clear_data_sign_out" = "Sign out"; + // Chat creation "room_creation_title" = "New Chat"; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index 0738f3685..b1f9b8633 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -226,6 +226,50 @@ internal enum VectorL10n { internal static var authSkip: String { return VectorL10n.tr("Vector", "auth_skip") } + /// Clear personal data + internal static var authSoftlogoutClearData: String { + return VectorL10n.tr("Vector", "auth_softlogout_clear_data") + } + /// Clear all data + internal static var authSoftlogoutClearDataButton: String { + return VectorL10n.tr("Vector", "auth_softlogout_clear_data_button") + } + /// Warning: Your personal data (including encryption keys) is still stored on this device. + internal static var authSoftlogoutClearDataMessage1: String { + return VectorL10n.tr("Vector", "auth_softlogout_clear_data_message_1") + } + /// Clear it if you're finished using this device, or want to sign in to another account. + internal static var authSoftlogoutClearDataMessage2: String { + return VectorL10n.tr("Vector", "auth_softlogout_clear_data_message_2") + } + /// Sign out + internal static var authSoftlogoutClearDataSignOut: String { + return VectorL10n.tr("Vector", "auth_softlogout_clear_data_sign_out") + } + /// Are you sure you want to clear all data currently stored on this device? Sign in again to access your account data and messages. + internal static var authSoftlogoutClearDataSignOutMsg: String { + return VectorL10n.tr("Vector", "auth_softlogout_clear_data_sign_out_msg") + } + /// Are you sure? + internal static var authSoftlogoutClearDataSignOutTitle: String { + return VectorL10n.tr("Vector", "auth_softlogout_clear_data_sign_out_title") + } + /// Your homeserver (%1$@) admin has signed you out of your account %2$@ (%3$@). + internal static func authSoftlogoutReason(_ p1: String, _ p2: String, _ p3: String) -> String { + return VectorL10n.tr("Vector", "auth_softlogout_reason", p1, p2, p3) + } + /// Sign in to recover encryption keys stored exclusively on this device. You need them to read all of your secure messages on any device. + internal static var authSoftlogoutRecoverEncryptionKeys: String { + return VectorL10n.tr("Vector", "auth_softlogout_recover_encryption_keys") + } + /// Sign In + internal static var authSoftlogoutSignIn: String { + return VectorL10n.tr("Vector", "auth_softlogout_sign_in") + } + /// You’re signed out + internal static var authSoftlogoutSignedOut: String { + return VectorL10n.tr("Vector", "auth_softlogout_signed_out") + } /// Submit internal static var authSubmit: String { return VectorL10n.tr("Vector", "auth_submit") diff --git a/Riot/Modules/Authentication/AuthenticationViewController.h b/Riot/Modules/Authentication/AuthenticationViewController.h index 5358f20f6..9c24ea4f1 100644 --- a/Riot/Modules/Authentication/AuthenticationViewController.h +++ b/Riot/Modules/Authentication/AuthenticationViewController.h @@ -41,5 +41,9 @@ @property (weak, nonatomic) IBOutlet UIView *homeServerSeparator; @property (weak, nonatomic) IBOutlet UIView *identityServerSeparator; +@property (weak, nonatomic) IBOutlet UIView *softLogoutClearDataContainer; +@property (weak, nonatomic) IBOutlet UILabel *softLogoutClearDataLabel; +@property (weak, nonatomic) IBOutlet UIButton *softLogoutClearDataButton; + @end diff --git a/Riot/Modules/Authentication/AuthenticationViewController.m b/Riot/Modules/Authentication/AuthenticationViewController.m index fb73984d6..03d34371e 100644 --- a/Riot/Modules/Authentication/AuthenticationViewController.m +++ b/Riot/Modules/Authentication/AuthenticationViewController.m @@ -1,7 +1,8 @@ /* Copyright 2015 OpenMarket Ltd Copyright 2017 Vector Creations Ltd - + Copyright 2019 New Vector Ltd + 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 @@ -107,6 +108,14 @@ [self.customServersTickButton setImage:[UIImage imageNamed:@"selection_untick"] forState:UIControlStateHighlighted]; [self hideCustomServers:YES]; + + // Soft logout section + self.softLogoutClearDataButton.layer.cornerRadius = 5; + self.softLogoutClearDataButton.clipsToBounds = YES; + [self.softLogoutClearDataButton setTitle:NSLocalizedStringFromTable(@"auth_softlogout_clear_data_button", @"Vector", nil) forState:UIControlStateNormal]; + [self.softLogoutClearDataButton setTitle:NSLocalizedStringFromTable(@"auth_softlogout_clear_data_button", @"Vector", nil) forState:UIControlStateHighlighted]; + self.softLogoutClearDataButton.enabled = YES; + self.softLogoutClearDataContainer.hidden = YES; // The view controller dismiss itself on successful login. self.delegate = self; @@ -194,7 +203,10 @@ self.identityServerLabel.textColor = ThemeService.shared.theme.textSecondaryColor; self.activityIndicator.backgroundColor = ThemeService.shared.theme.overlayBackgroundColor; - + + self.softLogoutClearDataLabel.textColor = ThemeService.shared.theme.textPrimaryColor; + self.softLogoutClearDataButton.backgroundColor = ThemeService.shared.theme.warningColor; + [self.authInputsView customizeViewRendering]; [self setNeedsStatusBarAppearanceUpdate]; @@ -288,6 +300,7 @@ } [self updateForgotPwdButtonVisibility]; + [self updateSoftLogoutClearDataContainerVisibility]; } - (void)setAuthInputsView:(MXKAuthInputsView *)authInputsView @@ -366,7 +379,7 @@ // The right bar button is used to switch the authentication type. if (self.authType == MXKAuthenticationTypeLogin) { - if (!authInputsview.isSingleSignOnRequired) + if (!authInputsview.isSingleSignOnRequired && !self.softLogoutCredentials) { self.rightBarButtonItem.title = NSLocalizedStringFromTable(@"auth_register", @"Vector", nil); } @@ -395,12 +408,103 @@ } } +- (void)setSoftLogoutCredentials:(MXCredentials *)softLogoutCredentials +{ + [super setSoftLogoutCredentials:softLogoutCredentials]; + + // Customise the screen for soft logout + self.customServersTickButton.hidden = YES; + self.rightBarButtonItem.title = nil; + self.mainNavigationItem.title = NSLocalizedStringFromTable(@"auth_softlogout_signed_out", @"Vector", nil); + + [self showSoftLogoutClearDataContainer]; +} + +- (void)showSoftLogoutClearDataContainer +{ + NSMutableAttributedString *message = [[NSMutableAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"auth_softlogout_clear_data", @"Vector", nil) + attributes:@{ + NSFontAttributeName: [UIFont boldSystemFontOfSize:14] + }]; + + [message appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\n"]]; + + NSString *string = [NSString stringWithFormat:@"%@\n\n%@", + NSLocalizedStringFromTable(@"auth_softlogout_clear_data_message_1", @"Vector", nil), + NSLocalizedStringFromTable(@"auth_softlogout_clear_data_message_2", @"Vector", nil)]; + + [message appendAttributedString:[[NSAttributedString alloc] initWithString:string + attributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:14] + }]]; + self.softLogoutClearDataLabel.attributedText = message; + + self.softLogoutClearDataContainer.hidden = NO; + [self refreshContentViewHeightConstraint]; +} + +- (void)updateSoftLogoutClearDataContainerVisibility +{ + // Do not display it in case of forget password flow + if (self.softLogoutCredentials && self.authType == MXKAuthenticationTypeLogin) + { + self.softLogoutClearDataContainer.hidden = NO; + } + else + { + self.softLogoutClearDataContainer.hidden = YES; + } +} + +- (void)showClearDataAfterSoftLogoutConfirmation +{ + // Request confirmation + if (alert) + { + [alert dismissViewControllerAnimated:NO completion:nil]; + } + + alert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"auth_softlogout_clear_data_sign_out_title", @"Vector", nil) + message:NSLocalizedStringFromTable(@"auth_softlogout_clear_data_sign_out_msg", @"Vector", nil) + preferredStyle:UIAlertControllerStyleAlert]; + + + [alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"auth_softlogout_clear_data_sign_out", @"Vector", nil) style:UIAlertActionStyleDestructive + handler:^(UIAlertAction * action) + { + [self clearDataAfterSoftLogout]; + }]]; + + MXWeakify(self); + [alert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) + { + MXStrongifyAndReturnIfNil(self); + self->alert = nil; + }]]; + + [self presentViewController:alert animated:YES completion:nil]; +} + +- (void)clearDataAfterSoftLogout +{ + NSLog(@"[AuthenticationVC] clearDataAfterSoftLogout %@", self.softLogoutCredentials.userId); + + // Use AppDelegate so that we reset app settings and this auth screen + [[AppDelegate theDelegate] logoutSendingRequestServer:YES completion:^(BOOL isLoggedOut) { + NSLog(@"[AuthenticationVC] Complete. isLoggedOut: %@", @(isLoggedOut)); + }]; +} + + - (void)handleAuthenticationSession:(MXAuthenticationSession *)authSession { [super handleAuthenticationSession:authSession]; // Hide "Forgot password" and "Log in" buttons in case of SSO [self updateForgotPwdButtonVisibility]; + [self updateSoftLogoutClearDataContainerVisibility]; AuthInputsView *authInputsview; if ([self.authInputsView isKindOfClass:AuthInputsView.class]) @@ -529,10 +633,16 @@ [ThemeService.shared.theme applyStyleOnNavigationBar:self.navigationController.navigationBar]; } + else if (sender == self.softLogoutClearDataButton) + { + [self showClearDataAfterSoftLogoutConfirmation]; + } else { [super onButtonPressed:sender]; } + + [self updateSoftLogoutClearDataContainerVisibility]; } - (void)onFailureDuringAuthRequest:(NSError *)error @@ -540,7 +650,7 @@ // Homeserver migration: When the default homeserver url is different from matrix.org, // the login (or forgot pwd) process with an existing matrix.org accounts will then fail. // Patch: Falling back to matrix.org HS so we don't break everyone's logins - if ([self.homeServerTextField.text isEqualToString:self.defaultHomeServerUrl] && ![self.defaultHomeServerUrl isEqualToString:@"https://matrix.org"]) + if ([self.homeServerTextField.text isEqualToString:self.defaultHomeServerUrl] && ![self.defaultHomeServerUrl isEqualToString:@"https://matrix.org"] && !self.softLogoutCredentials) { MXError *mxError = [[MXError alloc] initWithNSError:error]; @@ -710,7 +820,13 @@ } } } - + + if (!self.softLogoutClearDataContainer.isHidden) + { + // The soft logout clear data section adds more height + constant += self.softLogoutClearDataContainer.frame.size.height; + } + self.contentViewHeightConstraint.constant = constant; } diff --git a/Riot/Modules/Authentication/AuthenticationViewController.xib b/Riot/Modules/Authentication/AuthenticationViewController.xib index 71887099d..aa204d4d7 100644 --- a/Riot/Modules/Authentication/AuthenticationViewController.xib +++ b/Riot/Modules/Authentication/AuthenticationViewController.xib @@ -1,11 +1,11 @@ - + - + @@ -42,6 +42,9 @@ + + + @@ -345,17 +348,66 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Riot/Modules/Authentication/Views/AuthInputsView.m b/Riot/Modules/Authentication/Views/AuthInputsView.m index 5685a9f43..64341f17d 100644 --- a/Riot/Modules/Authentication/Views/AuthInputsView.m +++ b/Riot/Modules/Authentication/Views/AuthInputsView.m @@ -1,6 +1,7 @@ /* Copyright 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd + Copyright 2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -54,6 +55,7 @@ @end @implementation AuthInputsView +@synthesize softLogoutCredentials; + (UINib *)nib { @@ -487,6 +489,15 @@ } } } + + // For soft logout, pass the device_id currently used + if (parameters && self.softLogoutCredentials) + { + NSMutableDictionary *parametersWithDeviceId = [parameters mutableCopy]; + parametersWithDeviceId[@"device_id"] = self.softLogoutCredentials.deviceId; + parameters = parametersWithDeviceId; + } + } else if (type == MXKAuthenticationTypeRegister) { @@ -725,7 +736,12 @@ { // Note: this use case was not tested yet. parameters = @{ - @"auth": @{@"session":currentSession.session, @"username": self.userLoginTextField.text, @"password": self.passWordTextField.text, @"type": kMXLoginFlowTypePassword} + @"auth": @{ + @"session":currentSession.session, + @"username": self.userLoginTextField.text, + @"password": self.passWordTextField.text, + @"type": kMXLoginFlowTypePassword + } }; } else if ([self isFlowSupported:kMXLoginFlowTypeTerms] && ![self isFlowCompleted:kMXLoginFlowTypeTerms]) @@ -936,6 +952,71 @@ return YES; } +- (void)setSoftLogoutCredentials:(MXCredentials *)credentials +{ + softLogoutCredentials = credentials; + self.userLoginTextField.text = softLogoutCredentials.userId; + self.userLoginContainer.hidden = YES; + self.phoneContainer.hidden = YES; + + [self displaySoftLogoutMessage]; +} + +- (void)displaySoftLogoutMessage +{ + // Take some shortcuts and make some assumptions (Riot uses MXFileStore and MXRealmCryptoStore) to + // retrieve data to display as quick as possible + MXRealmCryptoStore *cryptoStore = [[MXRealmCryptoStore alloc] initWithCredentials:self.softLogoutCredentials]; + BOOL keyBackupNeeded = [cryptoStore inboundGroupSessionsToBackup:1].count > 0; + + MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:softLogoutCredentials]; + [fileStore asyncUsersWithUserIds:@[softLogoutCredentials.userId] success:^(NSArray * _Nonnull users) { + + MXUser *myUser = users.firstObject; + [fileStore close]; + + [self displaySoftLogoutMessageWithUserDisplayname:myUser.displayname andKeyBackupNeeded:keyBackupNeeded]; + + } failure:^(NSError * _Nonnull error) { + NSLog(@"[AuthInputsView] displaySoftLogoutMessage: Cannot load displayname. Error: %@", error); + [self displaySoftLogoutMessageWithUserDisplayname:nil andKeyBackupNeeded:keyBackupNeeded]; + }]; +} + +- (void)displaySoftLogoutMessageWithUserDisplayname:(NSString*)userDisplayname andKeyBackupNeeded:(BOOL)keyBackupNeeded +{ + // Use messageLabel for this message + self.messageLabelTopConstraint.constant = 8; + self.messageLabel.textColor = ThemeService.shared.theme.textPrimaryColor; + self.messageLabel.hidden = NO; + + NSMutableAttributedString *message = [[NSMutableAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"auth_softlogout_sign_in", @"Vector", nil) + attributes:@{ + NSFontAttributeName: [UIFont boldSystemFontOfSize:14] + }]; + + [message appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\n"]]; + + NSString *string = [NSString stringWithFormat:NSLocalizedStringFromTable(@"auth_softlogout_reason", @"Vector", nil), + softLogoutCredentials.homeServerName, userDisplayname, softLogoutCredentials.userId]; + [message appendAttributedString:[[NSAttributedString alloc] initWithString:string + attributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:14] + }]]; + + if (keyBackupNeeded) + { + [message appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\n"]]; + string = NSLocalizedStringFromTable(@"auth_softlogout_recover_encryption_keys", @"Vector", nil); + [message appendAttributedString:[[NSAttributedString alloc] initWithString:string + attributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:14] + }]]; + } + + self.messageLabel.attributedText = message; +} + - (BOOL)areAllRequiredFieldsSet { // Keep enable the submit button. diff --git a/Riot/Modules/TabBar/MasterTabBarController.h b/Riot/Modules/TabBar/MasterTabBarController.h index 2a5f59710..8f17d2d0e 100644 --- a/Riot/Modules/TabBar/MasterTabBarController.h +++ b/Riot/Modules/TabBar/MasterTabBarController.h @@ -63,6 +63,13 @@ */ - (void)showAuthenticationScreenWithRegistrationParameters:(NSDictionary*)parameters; +/** + Display the authentication screen in order to login back a soft logout session. + + @param softLogoutCredentials the credentials of the soft logout session. + */ +- (void)showAuthenticationScreenAfterSoftLogout:(MXCredentials*)softLogoutCredentials; + /** Open the room with the provided identifier in a specific matrix session. diff --git a/Riot/Modules/TabBar/MasterTabBarController.m b/Riot/Modules/TabBar/MasterTabBarController.m index c85c8b969..218101ca5 100644 --- a/Riot/Modules/TabBar/MasterTabBarController.m +++ b/Riot/Modules/TabBar/MasterTabBarController.m @@ -39,9 +39,11 @@ // Observer that checks when the Authentification view controller has gone. id authViewControllerObserver; + id authViewRemovedAccountObserver; // The parameters to pass to the Authentification view controller. NSDictionary *authViewControllerRegistrationParameters; + MXCredentials *softLogoutCredentials; // The recents data source shared between all the view controllers of the tab bar. RecentsDataSource *recentsDataSource; @@ -142,11 +144,25 @@ [super viewDidAppear:animated]; // Check whether we're not logged in + BOOL authIsShown = NO; if (![MXKAccountManager sharedManager].accounts.count) { [self showAuthenticationScreen]; + authIsShown = YES; } - else + else if (![MXKAccountManager sharedManager].activeAccounts.count) + { + // Display a login screen if the account is soft logout + // Note: We support only one account + MXKAccount *account = [MXKAccountManager sharedManager].accounts.firstObject; + if (account.isSoftLogout) + { + [self showAuthenticationScreenAfterSoftLogout:account.mxCredentials]; + authIsShown = YES; + } + } + + if (!authIsShown) { // Check whether the user has been already prompted to send crash reports. // (Check whether 'enableCrashReport' flag has been set once) @@ -216,6 +232,11 @@ [[NSNotificationCenter defaultCenter] removeObserver:authViewControllerObserver]; authViewControllerObserver = nil; } + if (authViewRemovedAccountObserver) + { + [[NSNotificationCenter defaultCenter] removeObserver:authViewRemovedAccountObserver]; + authViewRemovedAccountObserver = nil; + } if (kThemeServiceDidChangeThemeNotificationObserver) { @@ -401,6 +422,25 @@ } } +- (void)showAuthenticationScreenAfterSoftLogout:(MXCredentials*)credentials; +{ + NSLog(@"[MasterTabBarController] showAuthenticationScreenAfterSoftLogout"); + + softLogoutCredentials = credentials; + + // Check whether an authentication screen is not already shown or preparing + if (!self.authViewController && !isAuthViewControllerPreparing) + { + isAuthViewControllerPreparing = YES; + + [[AppDelegate theDelegate] restoreInitialDisplay:^{ + + [self performSegueWithIdentifier:@"showAuth" sender:self]; + + }]; + } +} + - (void)selectRoomWithId:(NSString*)roomId andEventId:(NSString*)eventId inMatrixSession:(MXSession*)matrixSession { [self selectRoomWithId:roomId andEventId:eventId inMatrixSession:matrixSession completion:nil]; @@ -630,6 +670,15 @@ [[NSNotificationCenter defaultCenter] removeObserver:authViewControllerObserver]; authViewControllerObserver = nil; }]; + + authViewRemovedAccountObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountManagerDidRemoveAccountNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + + // The user has cleared data for their soft logged out account + _authViewController = nil; + + [[NSNotificationCenter defaultCenter] removeObserver:authViewRemovedAccountObserver]; + authViewRemovedAccountObserver = nil; + }]; // Forward parameters if any if (authViewControllerRegistrationParameters) @@ -637,6 +686,11 @@ _authViewController.externalRegistrationParameters = authViewControllerRegistrationParameters; authViewControllerRegistrationParameters = nil; } + if (softLogoutCredentials) + { + _authViewController.softLogoutCredentials = softLogoutCredentials; + softLogoutCredentials = nil; + } } else if ([[segue identifier] isEqualToString:@"showUnifiedSearch"]) {