Merge branch 'charlesmchen/deregistration'

pull/1/head
Matthew Chen 7 years ago
commit 9e2716d5a8

@ -231,6 +231,7 @@
34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E3E5671EC4B19400495BAC /* AudioProgressView.swift */; }; 34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E3E5671EC4B19400495BAC /* AudioProgressView.swift */; };
34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */; }; 34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */; };
34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */; }; 34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */; };
34E5DC8220D8050D00C08145 /* RegistrationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E5DC8120D8050D00C08145 /* RegistrationUtils.m */; };
34E88D262098C5AE00A608F4 /* ContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E88D252098C5AE00A608F4 /* ContactViewController.swift */; }; 34E88D262098C5AE00A608F4 /* ContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E88D252098C5AE00A608F4 /* ContactViewController.swift */; };
34E8A8D12085238A00B272B1 /* ProtoParsingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E8A8D02085238900B272B1 /* ProtoParsingTest.m */; }; 34E8A8D12085238A00B272B1 /* ProtoParsingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E8A8D02085238900B272B1 /* ProtoParsingTest.m */; };
34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F308A11ECB469700BB7697 /* OWSBezierPathView.m */; }; 34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F308A11ECB469700BB7697 /* OWSBezierPathView.m */; };
@ -894,6 +895,8 @@
34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIDiskUsage.m; sourceTree = "<group>"; }; 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIDiskUsage.m; sourceTree = "<group>"; };
34E3EF0E1EFC2684007F6822 /* DebugUIPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIPage.h; sourceTree = "<group>"; }; 34E3EF0E1EFC2684007F6822 /* DebugUIPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIPage.h; sourceTree = "<group>"; };
34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIPage.m; sourceTree = "<group>"; }; 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIPage.m; sourceTree = "<group>"; };
34E5DC8020D8050D00C08145 /* RegistrationUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationUtils.h; sourceTree = "<group>"; };
34E5DC8120D8050D00C08145 /* RegistrationUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationUtils.m; sourceTree = "<group>"; };
34E88D252098C5AE00A608F4 /* ContactViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactViewController.swift; sourceTree = "<group>"; }; 34E88D252098C5AE00A608F4 /* ContactViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactViewController.swift; sourceTree = "<group>"; };
34E8A8D02085238900B272B1 /* ProtoParsingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProtoParsingTest.m; sourceTree = "<group>"; }; 34E8A8D02085238900B272B1 /* ProtoParsingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProtoParsingTest.m; sourceTree = "<group>"; };
34F308A01ECB469700BB7697 /* OWSBezierPathView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBezierPathView.h; sourceTree = "<group>"; }; 34F308A01ECB469700BB7697 /* OWSBezierPathView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBezierPathView.h; sourceTree = "<group>"; };
@ -2115,6 +2118,8 @@
4579431C1E7C8CE9008ED0C0 /* Pastelog.h */, 4579431C1E7C8CE9008ED0C0 /* Pastelog.h */,
4579431D1E7C8CE9008ED0C0 /* Pastelog.m */, 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */,
450DF2041E0D74AC003D14BE /* Platform.swift */, 450DF2041E0D74AC003D14BE /* Platform.swift */,
34E5DC8020D8050D00C08145 /* RegistrationUtils.h */,
34E5DC8120D8050D00C08145 /* RegistrationUtils.m */,
4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */, 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */,
FCFA64B11A24F29E0007FB87 /* UI Categories */, FCFA64B11A24F29E0007FB87 /* UI Categories */,
); );
@ -3235,6 +3240,7 @@
452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */, 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */,
D221A09A169C9E5E00537ABF /* main.m in Sources */, D221A09A169C9E5E00537ABF /* main.m in Sources */,
34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */, 34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */,
34E5DC8220D8050D00C08145 /* RegistrationUtils.m in Sources */,
452EA09E1EA7ABE00078744B /* AttachmentPointerView.swift in Sources */, 452EA09E1EA7ABE00078744B /* AttachmentPointerView.swift in Sources */,
45638BDC1F3DD0D400128435 /* DebugUICalling.swift in Sources */, 45638BDC1F3DD0D400128435 /* DebugUICalling.swift in Sources */,
45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */, 45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */,

@ -14,6 +14,7 @@
#import "PrivacySettingsTableViewController.h" #import "PrivacySettingsTableViewController.h"
#import "ProfileViewController.h" #import "ProfileViewController.h"
#import "PushManager.h" #import "PushManager.h"
#import "RegistrationUtils.h"
#import "Signal-Swift.h" #import "Signal-Swift.h"
#import <SignalMessaging/Environment.h> #import <SignalMessaging/Environment.h>
#import <SignalMessaging/OWSContactsManager.h> #import <SignalMessaging/OWSContactsManager.h>
@ -144,19 +145,25 @@
cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel *accessoryLabel = [UILabel new]; UILabel *accessoryLabel = [UILabel new];
accessoryLabel.font = [UIFont ows_regularFontWithSize:18.f]; accessoryLabel.font = [UIFont ows_regularFontWithSize:18.f];
switch ([TSSocketManager sharedManager].state) { if (TSAccountManager.sharedInstance.isDeregistered) {
case SocketManagerStateClosed: accessoryLabel.text = NSLocalizedString(
accessoryLabel.text = NSLocalizedString(@"NETWORK_STATUS_OFFLINE", @""); @"NETWORK_STATUS_DEREGISTERED", @"Error indicating that this device is no longer registered.");
accessoryLabel.textColor = [UIColor ows_redColor]; accessoryLabel.textColor = [UIColor ows_redColor];
break; } else {
case SocketManagerStateConnecting: switch ([TSSocketManager sharedManager].state) {
accessoryLabel.text = NSLocalizedString(@"NETWORK_STATUS_CONNECTING", @""); case SocketManagerStateClosed:
accessoryLabel.textColor = [UIColor ows_yellowColor]; accessoryLabel.text = NSLocalizedString(@"NETWORK_STATUS_OFFLINE", @"");
break; accessoryLabel.textColor = [UIColor ows_redColor];
case SocketManagerStateOpen: break;
accessoryLabel.text = NSLocalizedString(@"NETWORK_STATUS_CONNECTED", @""); case SocketManagerStateConnecting:
accessoryLabel.textColor = [UIColor ows_greenColor]; accessoryLabel.text = NSLocalizedString(@"NETWORK_STATUS_CONNECTING", @"");
break; accessoryLabel.textColor = [UIColor ows_yellowColor];
break;
case SocketManagerStateOpen:
accessoryLabel.text = NSLocalizedString(@"NETWORK_STATUS_CONNECTED", @"");
accessoryLabel.textColor = [UIColor ows_greenColor];
break;
}
} }
[accessoryLabel sizeToFit]; [accessoryLabel sizeToFit];
cell.accessoryView = accessoryLabel; cell.accessoryView = accessoryLabel;
@ -227,12 +234,23 @@
cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.selectionStyle = UITableViewCellSelectionStyleNone;
const CGFloat kButtonHeight = 40.f; const CGFloat kButtonHeight = 40.f;
OWSFlatButton *button = [OWSFlatButton buttonWithTitle:NSLocalizedString(@"SETTINGS_DELETE_ACCOUNT_BUTTON", @"") OWSFlatButton *button;
font:[OWSFlatButton fontForHeight:kButtonHeight] if (TSAccountManager.sharedInstance.isDeregistered) {
titleColor:[UIColor whiteColor] button = [OWSFlatButton
backgroundColor:[UIColor ows_destructiveRedColor] buttonWithTitle:NSLocalizedString(@"SETTINGS_REREGISTER_BUTTON", @"Label for re-registration button.")
target:self font:[OWSFlatButton fontForHeight:kButtonHeight]
selector:@selector(unregisterUser)]; titleColor:[UIColor whiteColor]
backgroundColor:[UIColor ows_destructiveRedColor]
target:self
selector:@selector(reregisterUser)];
} else {
button = [OWSFlatButton buttonWithTitle:NSLocalizedString(@"SETTINGS_DELETE_ACCOUNT_BUTTON", @"")
font:[OWSFlatButton fontForHeight:kButtonHeight]
titleColor:[UIColor whiteColor]
backgroundColor:[UIColor ows_destructiveRedColor]
target:self
selector:@selector(unregisterUser)];
}
[cell.contentView addSubview:button]; [cell.contentView addSubview:button];
[button autoSetDimension:ALDimensionHeight toSize:kButtonHeight]; [button autoSetDimension:ALDimensionHeight toSize:kButtonHeight];
[button autoVCenterInSuperview]; [button autoVCenterInSuperview];
@ -390,7 +408,7 @@
[self dismissViewControllerAnimated:YES completion:nil]; [self dismissViewControllerAnimated:YES completion:nil];
} }
#pragma mark - Table view data source #pragma mark - Unregister & Re-register
- (void)unregisterUser - (void)unregisterUser
{ {
@ -427,6 +445,11 @@
}]; }];
} }
- (void)reregisterUser
{
[RegistrationUtils showReregistrationUIFromViewController:self];
}
#pragma mark - Socket Status Notifications #pragma mark - Socket Status Notifications
- (void)observeNotifications - (void)observeNotifications

@ -24,14 +24,6 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface TSAccountManager (DebugUI)
- (void)resetForRegistration;
@end
#pragma mark -
@interface OWSStorage (DebugUI) @interface OWSStorage (DebugUI)
- (NSData *)databasePassword; - (NSData *)databasePassword;
@ -147,7 +139,12 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)reregister + (void)reregister
{ {
DDLogInfo(@"%@ re-registering.", self.logTag); DDLogInfo(@"%@ re-registering.", self.logTag);
[[TSAccountManager sharedInstance] resetForRegistration];
if (![[TSAccountManager sharedInstance] resetForReregistration]) {
OWSFail(@"%@ could not reset for re-registration.", self.logTag);
return;
}
[[Environment current].preferences unsetRecordedAPNSTokens]; [[Environment current].preferences unsetRecordedAPNSTokens];
RegistrationViewController *viewController = [RegistrationViewController new]; RegistrationViewController *viewController = [RegistrationViewController new];

@ -11,6 +11,7 @@
#import "OWSPrimaryStorage.h" #import "OWSPrimaryStorage.h"
#import "ProfileViewController.h" #import "ProfileViewController.h"
#import "PushManager.h" #import "PushManager.h"
#import "RegistrationUtils.h"
#import "Signal-Swift.h" #import "Signal-Swift.h"
#import "SignalApp.h" #import "SignalApp.h"
#import "TSAccountManager.h" #import "TSAccountManager.h"
@ -25,6 +26,7 @@
#import <SignalServiceKit/OWSBlockingManager.h> #import <SignalServiceKit/OWSBlockingManager.h>
#import <SignalServiceKit/OWSMessageSender.h> #import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSMessageUtils.h> #import <SignalServiceKit/OWSMessageUtils.h>
#import <SignalServiceKit/TSAccountManager.h>
#import <SignalServiceKit/TSOutgoingMessage.h> #import <SignalServiceKit/TSOutgoingMessage.h>
#import <SignalServiceKit/Threading.h> #import <SignalServiceKit/Threading.h>
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
@ -73,6 +75,7 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
// Views // Views
@property (nonatomic) NSLayoutConstraint *hideDeregisteredViewConstraint;
@property (nonatomic) NSLayoutConstraint *hideArchiveReminderViewConstraint; @property (nonatomic) NSLayoutConstraint *hideArchiveReminderViewConstraint;
@property (nonatomic) NSLayoutConstraint *hideMissingContactsPermissionViewConstraint; @property (nonatomic) NSLayoutConstraint *hideMissingContactsPermissionViewConstraint;
@ -159,6 +162,10 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
selector:@selector(yapDatabaseModifiedExternally:) selector:@selector(yapDatabaseModifiedExternally:)
name:YapDatabaseModifiedExternallyNotification name:YapDatabaseModifiedExternallyNotification
object:nil]; object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deregistrationStateDidChange:)
name:DeregistrationStateDidChangeNotification
object:nil];
} }
- (void)dealloc - (void)dealloc
@ -184,6 +191,13 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
[self reloadTableViewData]; [self reloadTableViewData];
} }
- (void)deregistrationStateDidChange:(id)notification
{
OWSAssertIsOnMainThread();
[self updateReminderViews];
}
#pragma mark - View Life Cycle #pragma mark - View Life Cycle
- (void)loadView - (void)loadView
@ -197,12 +211,32 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
[SignalApp.sharedApp setHomeViewController:self]; [SignalApp.sharedApp setHomeViewController:self];
} }
UIStackView *reminderStackView = [UIStackView new];
reminderStackView.axis = UILayoutConstraintAxisVertical;
reminderStackView.spacing = 0;
[self.view addSubview:reminderStackView];
[reminderStackView autoPinWidthToSuperview];
[reminderStackView autoPinToTopLayoutGuideOfViewController:self withInset:0];
__weak HomeViewController *weakSelf = self;
ReminderView *deregisteredView =
[ReminderView nagWithText:NSLocalizedString(@"DEREGISTRATION_WARNING",
@"Label warning the user that they have been de-registered.")
tapAction:^{
HomeViewController *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[RegistrationUtils showReregistrationUIFromViewController:strongSelf];
}];
[reminderStackView addArrangedSubview:deregisteredView];
self.hideDeregisteredViewConstraint = [deregisteredView autoSetDimension:ALDimensionHeight toSize:0];
self.hideDeregisteredViewConstraint.priority = UILayoutPriorityRequired;
ReminderView *archiveReminderView = ReminderView *archiveReminderView =
[ReminderView explanationWithText:NSLocalizedString(@"INBOX_VIEW_ARCHIVE_MODE_REMINDER", [ReminderView explanationWithText:NSLocalizedString(@"INBOX_VIEW_ARCHIVE_MODE_REMINDER",
@"Label reminding the user that they are in archive mode.")]; @"Label reminding the user that they are in archive mode.")];
[self.view addSubview:archiveReminderView]; [reminderStackView addArrangedSubview:archiveReminderView];
[archiveReminderView autoPinWidthToSuperview];
[archiveReminderView autoPinToTopLayoutGuideOfViewController:self withInset:0];
self.hideArchiveReminderViewConstraint = [archiveReminderView autoSetDimension:ALDimensionHeight toSize:0]; self.hideArchiveReminderViewConstraint = [archiveReminderView autoSetDimension:ALDimensionHeight toSize:0];
self.hideArchiveReminderViewConstraint.priority = UILayoutPriorityRequired; self.hideArchiveReminderViewConstraint.priority = UILayoutPriorityRequired;
@ -212,9 +246,7 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
tapAction:^{ tapAction:^{
[[UIApplication sharedApplication] openSystemSettings]; [[UIApplication sharedApplication] openSystemSettings];
}]; }];
[self.view addSubview:missingContactsPermissionView]; [reminderStackView addArrangedSubview:missingContactsPermissionView];
[missingContactsPermissionView autoPinWidthToSuperview];
[missingContactsPermissionView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:archiveReminderView];
self.hideMissingContactsPermissionViewConstraint = self.hideMissingContactsPermissionViewConstraint =
[missingContactsPermissionView autoSetDimension:ALDimensionHeight toSize:0]; [missingContactsPermissionView autoSetDimension:ALDimensionHeight toSize:0];
self.hideMissingContactsPermissionViewConstraint.priority = UILayoutPriorityRequired; self.hideMissingContactsPermissionViewConstraint.priority = UILayoutPriorityRequired;
@ -228,7 +260,7 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
[self.view addSubview:self.tableView]; [self.view addSubview:self.tableView];
[self.tableView autoPinWidthToSuperview]; [self.tableView autoPinWidthToSuperview];
[self.tableView autoPinEdgeToSuperviewEdge:ALEdgeBottom]; [self.tableView autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[self.tableView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:missingContactsPermissionView]; [self.tableView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:reminderStackView];
self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 60; self.tableView.estimatedRowHeight = 60;
@ -258,12 +290,18 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
{ {
BOOL shouldHideArchiveReminderView = self.homeViewMode != HomeViewMode_Archive; BOOL shouldHideArchiveReminderView = self.homeViewMode != HomeViewMode_Archive;
BOOL shouldHideMissingContactsPermissionView = !self.shouldShowMissingContactsPermissionView; BOOL shouldHideMissingContactsPermissionView = !self.shouldShowMissingContactsPermissionView;
BOOL shouldHideDeregisteredView = !TSAccountManager.sharedInstance.isDeregistered;
if (self.hideArchiveReminderViewConstraint.active == shouldHideArchiveReminderView if (self.hideArchiveReminderViewConstraint.active == shouldHideArchiveReminderView
&& self.hideMissingContactsPermissionViewConstraint.active == shouldHideMissingContactsPermissionView) { && self.hideMissingContactsPermissionViewConstraint.active == shouldHideMissingContactsPermissionView
&& self.hideDeregisteredViewConstraint.active == shouldHideDeregisteredView) {
return; return;
} }
self.hideArchiveReminderViewConstraint.active = shouldHideArchiveReminderView; self.hideArchiveReminderViewConstraint.active = shouldHideArchiveReminderView;
self.hideMissingContactsPermissionViewConstraint.active = shouldHideMissingContactsPermissionView; self.hideMissingContactsPermissionViewConstraint.active = shouldHideMissingContactsPermissionView;
self.hideDeregisteredViewConstraint.active = shouldHideDeregisteredView;
[self.view setNeedsLayout]; [self.view setNeedsLayout];
[self.view layoutSubviews]; [self.view layoutSubviews];
} }
@ -788,11 +826,8 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
// Constrain to cell margins. // Constrain to cell margins.
[stackView autoPinEdgeToSuperviewMargin:ALEdgeLeading relation:NSLayoutRelationGreaterThanOrEqual]; [stackView autoPinEdgeToSuperviewMargin:ALEdgeLeading relation:NSLayoutRelationGreaterThanOrEqual];
[stackView autoPinEdgeToSuperviewMargin:ALEdgeTrailing relation:NSLayoutRelationGreaterThanOrEqual]; [stackView autoPinEdgeToSuperviewMargin:ALEdgeTrailing relation:NSLayoutRelationGreaterThanOrEqual];
// Ensure that the cell's contents never overflow the cell bounds. [stackView autoPinEdgeToSuperviewMargin:ALEdgeTop];
// We pin to the superview _edge_ and not _margin_ for the purposes [stackView autoPinEdgeToSuperviewMargin:ALEdgeBottom];
// of overflow, so that changes to the margins do not trip these safe guards.
[stackView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:0 relation:NSLayoutRelationGreaterThanOrEqual];
[stackView autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:0 relation:NSLayoutRelationGreaterThanOrEqual];
return cell; return cell;
} }

@ -112,16 +112,25 @@ NS_ASSUME_NONNULL_BEGIN
[titleLabel autoSetDimension:ALDimensionHeight toSize:40]; [titleLabel autoSetDimension:ALDimensionHeight toSize:40];
[titleLabel autoHCenterInSuperview]; [titleLabel autoHCenterInSuperview];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; // This view is used in more than one context.
[backButton //
setTitle:NSLocalizedString(@"VERIFICATION_BACK_BUTTON", @"button text for back button on verification view") // * Usually, it is pushed atop RegistrationViewController in which
forState:UIControlStateNormal]; // case we want a "back" button.
[backButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // * It can also be used to re-register from the app's "de-registration"
backButton.titleLabel.font = [UIFont ows_mediumFontWithSize:14.f]; // views, in which case RegistrationViewController is not used and we
[header addSubview:backButton]; // do _not_ want a "back" button.
[backButton autoPinLeadingToSuperviewMarginWithInset:10.f]; if (self.navigationController.viewControllers.count > 1) {
[backButton autoAlignAxis:ALAxisHorizontal toSameAxisOfView:titleLabel]; UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton addTarget:self action:@selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [backButton
setTitle:NSLocalizedString(@"VERIFICATION_BACK_BUTTON", @"button text for back button on verification view")
forState:UIControlStateNormal];
[backButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
backButton.titleLabel.font = [UIFont ows_mediumFontWithSize:14.f];
[header addSubview:backButton];
[backButton autoPinLeadingToSuperviewMarginWithInset:10.f];
[backButton autoAlignAxis:ALAxisHorizontal toSameAxisOfView:titleLabel];
[backButton addTarget:self action:@selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
}
_phoneNumberLabel = [UILabel new]; _phoneNumberLabel = [UILabel new];
_phoneNumberLabel.textColor = [UIColor ows_darkGrayColor]; _phoneNumberLabel.textColor = [UIColor ows_darkGrayColor];

@ -278,6 +278,61 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
[self.activateButton setEnabled:YES]; [self.activateButton setEnabled:YES];
[self.spinnerView stopAnimating]; [self.spinnerView stopAnimating];
[self.phoneNumberTextField becomeFirstResponder]; [self.phoneNumberTextField becomeFirstResponder];
if ([TSAccountManager sharedInstance].isReregistering) {
// If re-registering, pre-populate the country (country code, calling code, country name)
// and phone number state.
NSString *_Nullable phoneNumberE164 = [TSAccountManager sharedInstance].reregisterationPhoneNumber;
if (!phoneNumberE164) {
OWSFail(@"%@ Could not resume re-registration; missing phone number.", self.logTag);
} else if ([self tryToApplyPhoneNumberE164:phoneNumberE164]) {
// Don't let user edit their phone number while re-registering.
self.phoneNumberTextField.enabled = NO;
}
}
}
- (BOOL)tryToApplyPhoneNumberE164:(NSString *)phoneNumberE164
{
OWSAssert(phoneNumberE164);
if (phoneNumberE164.length < 1) {
OWSFail(@"%@ Could not resume re-registration; invalid phoneNumberE164.", self.logTag);
return NO;
}
PhoneNumber *_Nullable parsedPhoneNumber = [PhoneNumber phoneNumberFromE164:phoneNumberE164];
if (!parsedPhoneNumber) {
OWSFail(@"%@ Could not resume re-registration; couldn't parse phoneNumberE164.", self.logTag);
return NO;
}
NSNumber *_Nullable callingCode = parsedPhoneNumber.getCountryCode;
if (!callingCode) {
OWSFail(@"%@ Could not resume re-registration; missing callingCode.", self.logTag);
return NO;
}
NSString *callingCodeText = [NSString stringWithFormat:@"+%d", callingCode.intValue];
NSArray<NSString *> *_Nullable countryCodes =
[PhoneNumberUtil.sharedThreadLocal countryCodesFromCallingCode:callingCodeText];
if (countryCodes.count < 1) {
OWSFail(@"%@ Could not resume re-registration; unknown countryCode.", self.logTag);
return NO;
}
NSString *countryCode = countryCodes.firstObject;
NSString *_Nullable countryName = [PhoneNumberUtil countryNameFromCountryCode:countryCode];
if (!countryName) {
OWSFail(@"%@ Could not resume re-registration; unknown countryName.", self.logTag);
return NO;
}
if (![phoneNumberE164 hasPrefix:callingCodeText]) {
OWSFail(@"%@ Could not resume re-registration; non-matching calling code.", self.logTag);
return NO;
}
NSString *phoneNumberWithoutCallingCode = [phoneNumberE164 substringFromIndex:callingCodeText.length];
[self updateCountryWithName:countryName callingCode:callingCodeText countryCode:countryCode];
self.phoneNumberTextField.text = phoneNumberWithoutCallingCode;
return YES;
} }
#pragma mark - Country #pragma mark - Country
@ -385,6 +440,11 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi
- (void)countryCodeRowWasTapped:(UIGestureRecognizer *)sender - (void)countryCodeRowWasTapped:(UIGestureRecognizer *)sender
{ {
if (TSAccountManager.sharedInstance.isReregistering) {
// Don't let user edit their phone number while re-registering.
return;
}
if (sender.state == UIGestureRecognizerStateRecognized) { if (sender.state == UIGestureRecognizerStateRecognized) {
[self changeCountryCodeTapped]; [self changeCountryCodeTapped];
} }

@ -0,0 +1,15 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface RegistrationUtils : NSObject
- (instancetype)init NS_UNAVAILABLE;
+ (void)showReregistrationUIFromViewController:(UIViewController *)fromViewController;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,91 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "RegistrationUtils.h"
#import "CodeVerificationViewController.h"
#import "OWSNavigationController.h"
#import <SignalMessaging/Environment.h>
#import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/TSAccountManager.h>
NS_ASSUME_NONNULL_BEGIN
@implementation RegistrationUtils
+ (void)showReregistrationUIFromViewController:(UIViewController *)fromViewController
{
UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheetController
addAction:[UIAlertAction
actionWithTitle:NSLocalizedString(@"DEREGISTRATION_REREGISTER_WITH_SAME_PHONE_NUMBER",
@"Label for button that lets users re-register using the same phone number.")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
[RegistrationUtils reregisterWithFromViewController:fromViewController];
}]];
[actionSheetController addAction:[OWSAlerts cancelAction]];
[fromViewController presentViewController:actionSheetController animated:YES completion:nil];
}
+ (void)reregisterWithFromViewController:(UIViewController *)fromViewController
{
DDLogInfo(@"%@ reregisterWithSamePhoneNumber.", self.logTag);
if (![[TSAccountManager sharedInstance] resetForReregistration]) {
OWSFail(@"%@ could not reset for re-registration.", self.logTag);
return;
}
[[Environment current].preferences unsetRecordedAPNSTokens];
[ModalActivityIndicatorViewController
presentFromViewController:fromViewController
canCancel:NO
backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
[TSAccountManager
registerWithPhoneNumber:[TSAccountManager sharedInstance].reregisterationPhoneNumber
success:^{
DDLogInfo(@"%@ re-registering: send verification code succeeded.", self.logTag);
dispatch_async(dispatch_get_main_queue(), ^{
[modalActivityIndicator dismissWithCompletion:^{
CodeVerificationViewController *viewController =
[CodeVerificationViewController new];
OWSNavigationController *navigationController =
[[OWSNavigationController alloc] initWithRootViewController:viewController];
navigationController.navigationBarHidden = YES;
[UIApplication sharedApplication].delegate.window.rootViewController
= navigationController;
}];
});
}
failure:^(NSError *error) {
DDLogError(@"%@ re-registering: send verification code failed.", self.logTag);
dispatch_async(dispatch_get_main_queue(), ^{
[modalActivityIndicator dismissWithCompletion:^{
if (error.code == 400) {
[OWSAlerts showAlertWithTitle:NSLocalizedString(@"REGISTRATION_ERROR", nil)
message:NSLocalizedString(
@"REGISTRATION_NON_VALID_NUMBER", nil)];
} else {
[OWSAlerts showAlertWithTitle:error.localizedDescription
message:error.localizedRecoverySuggestion];
}
}];
});
}
smsVerification:YES];
}];
}
@end
NS_ASSUME_NONNULL_END

@ -89,12 +89,7 @@ class ReminderView: UIView {
// Margin: top and bottom 12 left and right 16. // Margin: top and bottom 12 left and right 16.
// Label // Label
switch (mode) { label.font = UIFont.ows_dynamicTypeSubheadline
case .nag:
label.font = UIFont.ows_regularFont(withSize: 14)
case .explanation:
label.font = UIFont.ows_dynamicTypeSubheadline
}
container.addSubview(label) container.addSubview(label)
label.textColor = UIColor.black.withAlphaComponent(0.9) label.textColor = UIColor.black.withAlphaComponent(0.9)
label.numberOfLines = 0 label.numberOfLines = 0

@ -647,6 +647,12 @@
/* Title of the alert before redirecting to GitHub Issues. */ /* Title of the alert before redirecting to GitHub Issues. */
"DEBUG_LOG_GITHUB_ISSUE_ALERT_TITLE" = "GitHub Redirection"; "DEBUG_LOG_GITHUB_ISSUE_ALERT_TITLE" = "GitHub Redirection";
/* Label for button that lets users re-register using the same phone number. */
"DEREGISTRATION_REREGISTER_WITH_SAME_PHONE_NUMBER" = "Re-register this phone number";
/* Label warning the user that they have been de-registered. */
"DEREGISTRATION_WARNING" = "Device no longer registered! This is likely because you registered your phone number with Signal on a different device. Tap to re-register.";
/* {{Short Date}} when device last communicated with Signal Server. */ /* {{Short Date}} when device last communicated with Signal Server. */
"DEVICE_LAST_ACTIVE_AT_LABEL" = "Last active: %@"; "DEVICE_LAST_ACTIVE_AT_LABEL" = "Last active: %@";
@ -659,7 +665,7 @@
/* table cell label in conversation settings */ /* table cell label in conversation settings */
"DISAPPEARING_MESSAGES" = "Disappearing Messages"; "DISAPPEARING_MESSAGES" = "Disappearing Messages";
/* Info Message when added to {{group name}} which has enabled message expiration after {{time amount}}, see the *_TIME_AMOUNT strings for context. */ /* Info Message when added to a group which has enabled disappearing messages. Embeds {{time amount}} before messages disappear, see the *_TIME_AMOUNT strings for context. */
"DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT" = "Messages in this conversation will disappear after %@."; "DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT" = "Messages in this conversation will disappear after %@.";
/* subheading in conversation settings */ /* subheading in conversation settings */
@ -1309,6 +1315,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"NETWORK_STATUS_CONNECTING" = "Connecting"; "NETWORK_STATUS_CONNECTING" = "Connecting";
/* Error indicating that this device is no longer registered. */
"NETWORK_STATUS_DEREGISTERED" = "No Longer Registered";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"NETWORK_STATUS_HEADER" = "Network Status"; "NETWORK_STATUS_HEADER" = "Network Status";
@ -1972,6 +1981,9 @@
/* An explanation of the 'read receipts' setting. */ /* An explanation of the 'read receipts' setting. */
"SETTINGS_READ_RECEIPTS_SECTION_FOOTER" = "See and share when messages have been read. This setting is optional and applies to all conversations."; "SETTINGS_READ_RECEIPTS_SECTION_FOOTER" = "See and share when messages have been read. This setting is optional and applies to all conversations.";
/* Label for re-registration button. */
"SETTINGS_REREGISTER_BUTTON" = "Re-register";
/* Label for the 'screen lock activity timeout' setting of the privacy settings. */ /* Label for the 'screen lock activity timeout' setting of the privacy settings. */
"SETTINGS_SCREEN_LOCK_ACTIVITY_TIMEOUT" = "Screen Lock Timeout"; "SETTINGS_SCREEN_LOCK_ACTIVITY_TIMEOUT" = "Screen Lock Timeout";

@ -9,6 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
extern NSString *const TSRegistrationErrorDomain; extern NSString *const TSRegistrationErrorDomain;
extern NSString *const TSRegistrationErrorUserInfoHTTPStatus; extern NSString *const TSRegistrationErrorUserInfoHTTPStatus;
extern NSString *const RegistrationStateDidChangeNotification; extern NSString *const RegistrationStateDidChangeNotification;
extern NSString *const DeregistrationStateDidChangeNotification;
extern NSString *const kNSNotificationName_LocalNumberDidChange; extern NSString *const kNSNotificationName_LocalNumberDidChange;
@class OWSPrimaryStorage; @class OWSPrimaryStorage;
@ -116,6 +117,26 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange;
+ (void)unregisterTextSecureWithSuccess:(void (^)(void))success failure:(void (^)(NSError *error))failureBlock; + (void)unregisterTextSecureWithSuccess:(void (^)(void))success failure:(void (^)(NSError *error))failureBlock;
#pragma mark - De-Registration
// De-registration reflects whether or not the "last known contact"
// with the service was:
//
// * A 403 from the service, indicating de-registration.
// * A successful auth'd request _or_ websocket connection indicating
// valid registration.
- (BOOL)isDeregistered;
- (void)setIsDeregistered:(BOOL)isDeregistered;
#pragma mark - Re-registration
// Re-registration is the process of re-registering _with the same phone number_.
// Returns YES on success.
- (BOOL)resetForReregistration;
- (NSString *)reregisterationPhoneNumber;
- (BOOL)isReregistering;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -16,6 +16,7 @@
#import "TSPreKeyManager.h" #import "TSPreKeyManager.h"
#import "TSVerifyCodeRequest.h" #import "TSVerifyCodeRequest.h"
#import "YapDatabaseConnection+OWS.h" #import "YapDatabaseConnection+OWS.h"
#import "YapDatabaseTransaction+OWS.h"
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -23,9 +24,12 @@ NS_ASSUME_NONNULL_BEGIN
NSString *const TSRegistrationErrorDomain = @"TSRegistrationErrorDomain"; NSString *const TSRegistrationErrorDomain = @"TSRegistrationErrorDomain";
NSString *const TSRegistrationErrorUserInfoHTTPStatus = @"TSHTTPStatus"; NSString *const TSRegistrationErrorUserInfoHTTPStatus = @"TSHTTPStatus";
NSString *const RegistrationStateDidChangeNotification = @"RegistrationStateDidChangeNotification"; NSString *const RegistrationStateDidChangeNotification = @"RegistrationStateDidChangeNotification";
NSString *const DeregistrationStateDidChangeNotification = @"DeregistrationStateDidChangeNotification";
NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName_LocalNumberDidChange"; NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName_LocalNumberDidChange";
NSString *const TSAccountManager_RegisteredNumberKey = @"TSStorageRegisteredNumberKey"; NSString *const TSAccountManager_RegisteredNumberKey = @"TSStorageRegisteredNumberKey";
NSString *const TSAccountManager_IsDeregisteredKey = @"TSAccountManager_IsDeregisteredKey";
NSString *const TSAccountManager_ReregisteringPhoneNumberKey = @"TSAccountManager_ReregisteringPhoneNumberKey";
NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegistrationId"; NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegistrationId";
NSString *const TSAccountManager_UserAccountCollection = @"TSStorageUserAccountCollection"; NSString *const TSAccountManager_UserAccountCollection = @"TSStorageUserAccountCollection";
@ -44,6 +48,8 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
@property (nonatomic, nullable) NSString *cachedLocalNumber; @property (nonatomic, nullable) NSString *cachedLocalNumber;
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@property (nonatomic, nullable) NSNumber *cachedIsDeregistered;
@end @end
#pragma mark - #pragma mark -
@ -101,21 +107,6 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
userInfo:nil]; userInfo:nil];
} }
- (void)resetForRegistration
{
@synchronized(self)
{
_isRegistered = NO;
_cachedLocalNumber = nil;
_phoneNumberAwaitingVerification = nil;
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[transaction removeAllObjectsInCollection:TSAccountManager_UserAccountCollection];
[[OWSPrimaryStorage sharedManager] resetSessionStore:transaction];
}];
}
}
+ (BOOL)isRegistered + (BOOL)isRegistered
{ {
return [[self sharedInstance] isRegistered]; return [[self sharedInstance] isRegistered];
@ -152,6 +143,7 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
// Warm these cached values. // Warm these cached values.
[self isRegistered]; [self isRegistered];
[self localNumber]; [self localNumber];
[self isDeregistered];
} }
+ (nullable NSString *)localNumber + (nullable NSString *)localNumber
@ -191,6 +183,13 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
[self.dbConnection setObject:localNumber [self.dbConnection setObject:localNumber
forKey:TSAccountManager_RegisteredNumberKey forKey:TSAccountManager_RegisteredNumberKey
inCollection:TSAccountManager_UserAccountCollection]; inCollection:TSAccountManager_UserAccountCollection];
[self.dbConnection removeObjectForKey:TSAccountManager_ReregisteringPhoneNumberKey
inCollection:TSAccountManager_UserAccountCollection];
self.phoneNumberAwaitingVerification = nil;
self.cachedLocalNumber = localNumber;
} }
} }
@ -524,6 +523,91 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
} }
} }
#pragma mark - De-Registration
- (BOOL)isDeregistered
{
// Cache this since we access this a lot, and once set it will not change.
@synchronized(self) {
if (self.cachedIsDeregistered == nil) {
self.cachedIsDeregistered = @([self.dbConnection boolForKey:TSAccountManager_IsDeregisteredKey
inCollection:TSAccountManager_UserAccountCollection
defaultValue:NO]);
}
OWSAssert(self.cachedIsDeregistered);
return self.cachedIsDeregistered.boolValue;
}
}
- (void)setIsDeregistered:(BOOL)isDeregistered
{
@synchronized(self) {
if (self.cachedIsDeregistered && self.cachedIsDeregistered.boolValue == isDeregistered) {
return;
}
DDLogWarn(@"%@ isDeregistered: %d", self.logTag, isDeregistered);
self.cachedIsDeregistered = @(isDeregistered);
}
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction setObject:@(isDeregistered)
forKey:TSAccountManager_IsDeregisteredKey
inCollection:TSAccountManager_UserAccountCollection];
}];
[[NSNotificationCenter defaultCenter] postNotificationNameAsync:DeregistrationStateDidChangeNotification
object:nil
userInfo:nil];
}
#pragma mark - Re-registration
- (BOOL)resetForReregistration
{
@synchronized(self) {
NSString *_Nullable localNumber = self.localNumber;
if (!localNumber) {
OWSFail(@"%@ can't re-register without valid local number.", self.logTag);
return NO;
}
_isRegistered = NO;
_cachedLocalNumber = nil;
_phoneNumberAwaitingVerification = nil;
_cachedIsDeregistered = nil;
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction removeAllObjectsInCollection:TSAccountManager_UserAccountCollection];
[[OWSPrimaryStorage sharedManager] resetSessionStore:transaction];
[transaction setObject:localNumber
forKey:TSAccountManager_ReregisteringPhoneNumberKey
inCollection:TSAccountManager_UserAccountCollection];
}];
return YES;
}
}
- (NSString *)reregisterationPhoneNumber
{
OWSAssert([self isReregistering]);
NSString *_Nullable result = [self.dbConnection stringForKey:TSAccountManager_ReregisteringPhoneNumberKey
inCollection:TSAccountManager_UserAccountCollection];
OWSAssert(result);
return result;
}
- (BOOL)isReregistering
{
return nil !=
[self.dbConnection stringForKey:TSAccountManager_ReregisteringPhoneNumberKey
inCollection:TSAccountManager_UserAccountCollection];
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -87,6 +87,11 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
// TODO: Remove this logging when the call connection issues have been resolved. // TODO: Remove this logging when the call connection issues have been resolved.
TSNetworkManagerSuccess success = ^(NSURLSessionDataTask *task, _Nullable id responseObject) { TSNetworkManagerSuccess success = ^(NSURLSessionDataTask *task, _Nullable id responseObject) {
DDLogInfo(@"%@ request succeeded : %@", self.logTag, request); DDLogInfo(@"%@ request succeeded : %@", self.logTag, request);
if (request.shouldHaveAuthorizationHeaders) {
[TSAccountManager.sharedInstance setIsDeregistered:NO];
}
successBlock(task, responseObject); successBlock(task, responseObject);
}; };
TSNetworkManagerFailure failure = [TSNetworkManager errorPrettifyingForFailureBlock:failureBlock request:request]; TSNetworkManagerFailure failure = [TSNetworkManager errorPrettifyingForFailureBlock:failureBlock request:request];
@ -166,6 +171,9 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
} }
case 400: { case 400: {
DDLogError(@"The request contains an invalid parameter : %@, %@", networkError.debugDescription, request); DDLogError(@"The request contains an invalid parameter : %@, %@", networkError.debugDescription, request);
[TSAccountManager.sharedInstance setIsDeregistered:YES];
failureBlock(task, error); failureBlock(task, error);
break; break;
} }

@ -612,8 +612,16 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
BOOL hasSuccessStatus = 200 <= responseStatus && responseStatus <= 299; BOOL hasSuccessStatus = 200 <= responseStatus && responseStatus <= 299;
BOOL didSucceed = hasSuccessStatus && hasValidResponse; BOOL didSucceed = hasSuccessStatus && hasValidResponse;
if (didSucceed) { if (didSucceed) {
[TSAccountManager.sharedInstance setIsDeregistered:NO];
[socketMessage didSucceedWithResponseObject:responseObject]; [socketMessage didSucceedWithResponseObject:responseObject];
} else { } else {
if (responseStatus == 403) {
// This should be redundant with our check for the socket
// failing due to 403, but let's be thorough.
[TSAccountManager.sharedInstance setIsDeregistered:YES];
}
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeMessageResponseFailed, NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeMessageResponseFailed,
NSLocalizedString( NSLocalizedString(
@"ERROR_DESCRIPTION_RESPONSE_FAILED", @"Error indicating that a socket response failed.")); @"ERROR_DESCRIPTION_RESPONSE_FAILED", @"Error indicating that a socket response failed."));
@ -666,6 +674,9 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
} }
self.state = SocketManagerStateOpen; self.state = SocketManagerStateOpen;
// If socket opens, we know we're not de-registered.
[TSAccountManager.sharedInstance setIsDeregistered:NO];
} }
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error { - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
@ -678,6 +689,13 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
DDLogError(@"Websocket did fail with error: %@", error); DDLogError(@"Websocket did fail with error: %@", error);
if ([error.domain isEqualToString:SRWebSocketErrorDomain] && error.code == 2132) {
NSNumber *_Nullable statusCode = error.userInfo[SRHTTPResponseErrorKey];
if (statusCode.unsignedIntegerValue == 403) {
[TSAccountManager.sharedInstance setIsDeregistered:YES];
}
}
[self handleSocketFailure]; [self handleSocketFailure];
} }
@ -690,6 +708,9 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
return; return;
} }
// If we receive a response, we know we're not de-registered.
[TSAccountManager.sharedInstance setIsDeregistered:NO];
WebSocketResourcesWebSocketMessage *wsMessage; WebSocketResourcesWebSocketMessage *wsMessage;
@try { @try {
wsMessage = [WebSocketResourcesWebSocketMessage parseFromData:data]; wsMessage = [WebSocketResourcesWebSocketMessage parseFromData:data];

Loading…
Cancel
Save