From 1f6cbd399e9dbae3f7c80e5e044fcd3d7f0b904d Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Feb 2018 09:58:54 -0500 Subject: [PATCH 1/9] Sketch out 2FA feature. --- .../NotificationSettingsViewController.m | 50 +++------ .../PrivacySettingsTableViewController.m | 37 +++++- .../ViewControllers/OWSTableViewController.h | 9 +- .../ViewControllers/OWSTableViewController.m | 33 ++++-- .../Requests/OWSDeviceProvisioningRequest.m | 9 +- .../Network/API/Requests/OWSRequestFactory.h | 19 ++++ .../Network/API/Requests/OWSRequestFactory.m | 31 ++++++ .../Requests/TSContactsIntersectionRequest.m | 17 +-- .../API/Requests/TSRecipientPrekeyRequest.m | 20 ++-- .../API/Requests/TSRegisterForPushRequest.m | 19 ++-- .../API/Requests/TSRegisterPrekeysRequest.m | 11 +- .../Requests/TSRegisterSignedPrekeyRequest.m | 9 +- .../src/Network/API/Requests/TSRequest.h | 8 +- .../src/Network/API/Requests/TSRequest.m | 19 +++- .../TSRequestVerificationCodeRequest.m | 6 +- .../API/Requests/TSSubmitMessageRequest.m | 23 ++-- .../API/Requests/TSUpdateAttributesRequest.m | 6 +- .../API/Requests/TSVerifyCodeRequest.m | 11 +- .../src/Network/API/TSNetworkManager.m | 5 +- SignalServiceKit/src/TSConstants.h | 23 ++-- SignalServiceKit/src/Util/OWS2FAManager.h | 25 +++++ SignalServiceKit/src/Util/OWS2FAManager.m | 105 ++++++++++++++++++ 22 files changed, 363 insertions(+), 132 deletions(-) create mode 100644 SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.h create mode 100644 SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m create mode 100644 SignalServiceKit/src/Util/OWS2FAManager.h create mode 100644 SignalServiceKit/src/Util/OWS2FAManager.m diff --git a/Signal/src/ViewControllers/NotificationSettingsViewController.m b/Signal/src/ViewControllers/NotificationSettingsViewController.m index f299fce923..430c2ebb95 100644 --- a/Signal/src/ViewControllers/NotificationSettingsViewController.m +++ b/Signal/src/ViewControllers/NotificationSettingsViewController.m @@ -38,21 +38,15 @@ OWSTableSection *soundsSection = [OWSTableSection new]; soundsSection.headerTitle = NSLocalizedString(@"SETTINGS_SECTION_SOUNDS", @"Header Label for the sounds section of settings views."); - - [soundsSection addItem:[OWSTableItem itemWithCustomCellBlock:^{ - UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 - reuseIdentifier:@"UITableViewCellStyleValue1"]; - cell.textLabel.text = NSLocalizedString(@"SETTINGS_ITEM_NOTIFICATION_SOUND", - @"Label for settings view that allows user to change the notification sound."); - OWSSound sound = [OWSSounds globalNotificationSound]; - cell.detailTextLabel.text = [OWSSounds displayNameForSound:sound]; - [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; - return cell; - } - actionBlock:^{ - OWSSoundSettingsViewController *vc = [OWSSoundSettingsViewController new]; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]]; + [soundsSection + addItem:[OWSTableItem disclosureItemWithText: + NSLocalizedString(@"SETTINGS_ITEM_NOTIFICATION_SOUND", + @"Label for settings view that allows user to change the notification sound.") + detailText:[OWSSounds displayNameForSound:[OWSSounds globalNotificationSound]] + actionBlock:^{ + OWSSoundSettingsViewController *vc = [OWSSoundSettingsViewController new]; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]]; NSString *inAppSoundsLabelText = NSLocalizedString(@"NOTIFICATIONS_SECTION_INAPP", @"Table cell switch label. When disabled, Signal will not play notification sounds while the app is in the " @@ -65,23 +59,15 @@ OWSTableSection *backgroundSection = [OWSTableSection new]; backgroundSection.headerTitle = NSLocalizedString(@"SETTINGS_NOTIFICATION_CONTENT_TITLE", @"table section header"); - [backgroundSection addItem:[OWSTableItem itemWithCustomCellBlock:^{ - UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 - reuseIdentifier:@"UITableViewCellStyleValue1"]; - - NotificationType notifType = [prefs notificationPreviewType]; - NSString *detailString = [prefs nameForNotificationPreviewType:notifType]; - cell.textLabel.text = NSLocalizedString(@"NOTIFICATIONS_SHOW", nil); - cell.detailTextLabel.text = detailString; - [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; - - return cell; - } - actionBlock:^{ - NotificationSettingsOptionsViewController *vc = - [NotificationSettingsOptionsViewController new]; - [weakSelf.navigationController pushViewController:vc animated:YES]; - }]]; + [backgroundSection + addItem:[OWSTableItem + disclosureItemWithText:NSLocalizedString(@"NOTIFICATIONS_SHOW", nil) + detailText:[prefs nameForNotificationPreviewType:[prefs notificationPreviewType]] + actionBlock:^{ + NotificationSettingsOptionsViewController *vc = + [NotificationSettingsOptionsViewController new]; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]]; backgroundSection.footerTitle = NSLocalizedString(@"SETTINGS_NOTIFICATION_CONTENT_DESCRIPTION", @"table section footer"); [contents addSection:backgroundSection]; diff --git a/Signal/src/ViewControllers/PrivacySettingsTableViewController.m b/Signal/src/ViewControllers/PrivacySettingsTableViewController.m index f66ff97453..4bf43c4f95 100644 --- a/Signal/src/ViewControllers/PrivacySettingsTableViewController.m +++ b/Signal/src/ViewControllers/PrivacySettingsTableViewController.m @@ -7,6 +7,7 @@ #import "Signal-Swift.h" #import #import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -120,7 +121,31 @@ NS_ASSUME_NONNULL_BEGIN }]]; [contents addSection:historyLogsSection]; - self.contents = contents; + OWSTableSection *twoFactorAuthSection = [OWSTableSection new]; + twoFactorAuthSection.headerTitle = NSLocalizedString( + @"SETTINGS_TWO_FACTOR_AUTH_TITLE", @"Title for the 'two factor auth' section of the privacy settings."); + BOOL is2FAEnabled = [OWS2FAManager.sharedManager is2FAEnabled]; + [twoFactorAuthSection + addItem:[OWSTableItem + disclosureItemWithText: + (is2FAEnabled ? NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_ENABLE", + @"Label for the 'enable two factor auth' item of the privacy settings.") + : NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_DISABLE", + @"Label for the 'disable two factor auth' item of the privacy settings.")) + actionBlock:^{ + if (is2FAEnabled) { + [weakSelf disable2FA]; + } else { + [weakSelf enable2FA]; + } + }]]; + [contents addSection:twoFactorAuthSection]; + + OWS2FAManager + .h + + self.contents + = contents; } #pragma mark - Events @@ -214,6 +239,16 @@ NS_ASSUME_NONNULL_BEGIN [SignalApp.sharedApp.callService createCallUIAdapter]; } +- (void)enable2FA +{ + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); +} + +- (void)disable2FA +{ + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); +} + #pragma mark - Log util + (NSString *)tag diff --git a/SignalMessaging/ViewControllers/OWSTableViewController.h b/SignalMessaging/ViewControllers/OWSTableViewController.h index 12a390a90d..e086cd2bdf 100644 --- a/SignalMessaging/ViewControllers/OWSTableViewController.h +++ b/SignalMessaging/ViewControllers/OWSTableViewController.h @@ -44,11 +44,6 @@ extern const CGFloat kOWSTable_DefaultCellHeight; #pragma mark - -typedef NS_ENUM(NSInteger, OWSTableItemType) { - OWSTableItemTypeDefault, - OWSTableItemTypeAction, -}; - typedef void (^OWSTableActionBlock)(void); typedef void (^OWSTableSubPageBlock)(UIViewController *viewController); typedef UITableViewCell *_Nonnull (^OWSTableCustomCellBlock)(void); @@ -72,6 +67,10 @@ typedef UITableViewCell *_Nonnull (^OWSTableCustomCellBlock)(void); + (OWSTableItem *)disclosureItemWithText:(NSString *)text actionBlock:(nullable OWSTableActionBlock)actionBlock; ++ (OWSTableItem *)disclosureItemWithText:(NSString *)text + detailText:(NSString *)detailText + actionBlock:(nullable OWSTableActionBlock)actionBlock; + + (OWSTableItem *)disclosureItemWithText:(NSString *)text customRowHeight:(CGFloat)customRowHeight actionBlock:(nullable OWSTableActionBlock)actionBlock; diff --git a/SignalMessaging/ViewControllers/OWSTableViewController.m b/SignalMessaging/ViewControllers/OWSTableViewController.m index 7f75932f96..f556d92849 100644 --- a/SignalMessaging/ViewControllers/OWSTableViewController.m +++ b/SignalMessaging/ViewControllers/OWSTableViewController.m @@ -83,7 +83,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; @interface OWSTableItem () -@property (nonatomic) OWSTableItemType itemType; @property (nonatomic, nullable) NSString *title; @property (nonatomic, nullable) OWSTableActionBlock actionBlock; @@ -102,7 +101,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(title.length > 0); OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; item.actionBlock = actionBlock; item.title = title; return item; @@ -116,7 +114,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(customRowHeight > 0); OWSTableItem *item = [OWSTableItem new]; - item.itemType = (actionBlock != nil ? OWSTableItemTypeAction : OWSTableItemTypeDefault); item.actionBlock = actionBlock; item.customCell = customCell; item.customRowHeight = @(customRowHeight); @@ -140,7 +137,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(customCellBlock); OWSTableItem *item = [OWSTableItem new]; - item.itemType = (actionBlock != nil ? OWSTableItemTypeAction : OWSTableItemTypeDefault); item.actionBlock = actionBlock; item.customCellBlock = customCellBlock; return item; @@ -164,7 +160,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(actionBlock); OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; item.actionBlock = actionBlock; item.customCellBlock = ^{ UITableViewCell *cell = [UITableViewCell new]; @@ -188,13 +183,34 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; return item; } ++ (OWSTableItem *)disclosureItemWithText:(NSString *)text + detailText:(NSString *)detailText + actionBlock:(nullable OWSTableActionBlock)actionBlock +{ + OWSAssert(text.length > 0); + OWSAssert(actionBlock); + + OWSTableItem *item = [OWSTableItem new]; + item.actionBlock = actionBlock; + item.customCellBlock = ^{ + UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 + reuseIdentifier:@"UITableViewCellStyleValue1"]; + cell.textLabel.text = text; + cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f]; + cell.textLabel.textColor = [UIColor blackColor]; + cell.detailTextLabel.text = detailText; + [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + return cell; + }; + return item; +} + + (OWSTableItem *)subPageItemWithText:(NSString *)text actionBlock:(nullable OWSTableSubPageBlock)actionBlock { OWSAssert(text.length > 0); OWSAssert(actionBlock); OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; __weak OWSTableItem *weakItem = item; item.actionBlock = ^{ OWSTableItem *strongItem = weakItem; @@ -233,7 +249,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(actionBlock); OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; item.actionBlock = actionBlock; item.customCellBlock = ^{ UITableViewCell *cell = [UITableViewCell new]; @@ -250,7 +265,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(text.length > 0); OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; item.customCellBlock = ^{ UITableViewCell *cell = [UITableViewCell new]; cell.textLabel.text = text; @@ -282,7 +296,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(text.length > 0); OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; item.customCellBlock = ^{ UITableViewCell *cell = [UITableViewCell new]; cell.textLabel.text = text; @@ -300,7 +313,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(accessoryText.length > 0); OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; item.customCellBlock = ^{ UITableViewCell *cell = [UITableViewCell new]; cell.textLabel.text = text; @@ -337,7 +349,6 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; OWSAssert(selector); OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; __weak id weakTarget = target; item.customCellBlock = ^{ UITableViewCell *cell = [UITableViewCell new]; diff --git a/SignalServiceKit/src/Network/API/Requests/OWSDeviceProvisioningRequest.m b/SignalServiceKit/src/Network/API/Requests/OWSDeviceProvisioningRequest.m index 21f6271835..915e511af7 100644 --- a/SignalServiceKit/src/Network/API/Requests/OWSDeviceProvisioningRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/OWSDeviceProvisioningRequest.m @@ -1,4 +1,6 @@ -// Copyright (c) 2016 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// #import "OWSDeviceProvisioningRequest.h" #import "TSConstants.h" @@ -17,7 +19,10 @@ NS_ASSUME_NONNULL_BEGIN } self.HTTPMethod = @"PUT"; - [self.parameters addEntriesFromDictionary:@{ @"body" : [messageBody base64EncodedString] }]; + + self.parameters = @{ + @"body" : [messageBody base64EncodedString], + }; return self; } diff --git a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.h b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.h new file mode 100644 index 0000000000..0322b184ad --- /dev/null +++ b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.h @@ -0,0 +1,19 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +NS_ASSUME_NONNULL_BEGIN + +@class TSRequest; + +@interface OWSRequestFactory : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (TSRequest *)enable2FARequestWithPin:(NSString *)pin; + ++ (TSRequest *)disable2FARequest; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m new file mode 100644 index 0000000000..f6ec848b41 --- /dev/null +++ b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m @@ -0,0 +1,31 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "OWSRequestFactory.h" +#import "TSConstants.h" +#import "TSRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation OWSRequestFactory + ++ (TSRequest *)enable2FARequestWithPin:(NSString *)pin; +{ + OWSAssert(pin.length > 0); + + return [TSRequest requestWithUrl:[NSURL URLWithString:textSecure2FAAPI] + method:@"PUT" + parameters:@{ + @"pin" : pin, + }]; +} + ++ (TSRequest *)disable2FARequest +{ + return [TSRequest requestWithUrl:[NSURL URLWithString:textSecure2FAAPI] method:@"DELETE" parameters:@{}]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Network/API/Requests/TSContactsIntersectionRequest.m b/SignalServiceKit/src/Network/API/Requests/TSContactsIntersectionRequest.m index 9d0ac456ec..13c728238a 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSContactsIntersectionRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSContactsIntersectionRequest.m @@ -1,14 +1,9 @@ // -// TSContactsIntersection.m -// TextSecureiOS +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -// Created by Frederic Jacobs on 10/12/13. -// Copyright (c) 2013 Open Whisper Systems. All rights reserved. -// - -#import "TSConstants.h" #import "TSContactsIntersectionRequest.h" +#import "TSConstants.h" @implementation TSContactsIntersectionRequest @@ -16,9 +11,15 @@ self = [self initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", textSecureDirectoryAPI, @"tokens"]]]; + if (!self) { + return nil; + } + self.HTTPMethod = @"PUT"; - [self.parameters addEntriesFromDictionary:@{ @"contacts" : hashes }]; + self.parameters = @{ + @"contacts" : hashes, + }; return self; } diff --git a/SignalServiceKit/src/Network/API/Requests/TSRecipientPrekeyRequest.m b/SignalServiceKit/src/Network/API/Requests/TSRecipientPrekeyRequest.m index 0ac0184297..813956e146 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRecipientPrekeyRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSRecipientPrekeyRequest.m @@ -1,23 +1,21 @@ // -// TSGetRecipientPrekey.m -// TextSecureiOS -// -// Created by Christine Corbett Moran on 11/30/13. -// Copyright (c) 2013 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "TSConstants.h" #import "TSRecipientPrekeyRequest.h" +#import "TSConstants.h" @implementation TSRecipientPrekeyRequest - (TSRequest *)initWithRecipient:(NSString *)recipientNumber deviceId:(NSString *)deviceId { - NSString *recipientInformation = recipientNumber; + self = [super + initWithURL:[NSURL + URLWithString:[NSString + stringWithFormat:@"%@/%@/%@", textSecureKeysAPI, recipientNumber, deviceId]]]; - self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%@", - textSecureKeysAPI, - recipientInformation, - deviceId]]]; + if (!self) { + return nil; + } self.HTTPMethod = @"GET"; self.parameters = nil; diff --git a/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.m b/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.m index 4f390d4e97..a158f680b6 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.m @@ -1,14 +1,9 @@ // -// TSRegisterForPushRequest.m -// TextSecureiOS +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -// Created by Frederic Jacobs on 10/13/13. -// Copyright (c) 2013 Open Whisper Systems. All rights reserved. -// - -#import "TSConstants.h" #import "TSRegisterForPushRequest.h" +#import "TSConstants.h" @implementation TSRegisterForPushRequest @@ -16,14 +11,20 @@ self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", textSecureAccountsAPI, @"apn"]]]; + if (!self) { + return nil; + } + self.HTTPMethod = @"PUT"; - self.parameters = [@{ @"apnRegistrationId" : identifier } mutableCopy]; + NSMutableDictionary *parameters = [@{ @"apnRegistrationId" : identifier } mutableCopy]; if (voipId) { - [self.parameters setObject:voipId forKeyedSubscript:@"voipRegistrationId"]; + parameters[@"voipRegistrationId"] = voipId; } + self.parameters = parameters; + return self; } diff --git a/SignalServiceKit/src/Network/API/Requests/TSRegisterPrekeysRequest.m b/SignalServiceKit/src/Network/API/Requests/TSRegisterPrekeysRequest.m index 8bf641b723..fec0bb9371 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRegisterPrekeysRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSRegisterPrekeysRequest.m @@ -1,14 +1,13 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "TSConstants.h" #import "TSRegisterPrekeysRequest.h" - -#import +#import "TSConstants.h" #import #import #import +#import @implementation TSRegisterPrekeysRequest @@ -17,6 +16,10 @@ signedPreKeyRecord:(SignedPreKeyRecord *)signedRecord preKeyLastResort:(PreKeyRecord *)lastResort { self = [super initWithURL:[NSURL URLWithString:textSecureKeysAPI]]; + if (!self) { + return nil; + } + self.HTTPMethod = @"PUT"; NSString *publicIdentityKey = [[identityKeyPublic prependKeyType] base64EncodedStringWithOptions:0]; diff --git a/SignalServiceKit/src/Network/API/Requests/TSRegisterSignedPrekeyRequest.m b/SignalServiceKit/src/Network/API/Requests/TSRegisterSignedPrekeyRequest.m index 290aa8716a..caa41437ac 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRegisterSignedPrekeyRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSRegisterSignedPrekeyRequest.m @@ -1,20 +1,23 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "TSRegisterSignedPrekeyRequest.h" #import "TSConstants.h" - -#import #import #import #import +#import @implementation TSRegisterSignedPrekeyRequest - (id)initWithSignedPreKeyRecord:(SignedPreKeyRecord *)signedRecord { self = [super initWithURL:[NSURL URLWithString:textSecureSignedKeysAPI]]; + if (!self) { + return nil; + } + self.HTTPMethod = @"PUT"; NSDictionary *serializedKeyRegistrationParameters = [self dictionaryFromSignedPreKey:signedRecord]; diff --git a/SignalServiceKit/src/Network/API/Requests/TSRequest.h b/SignalServiceKit/src/Network/API/Requests/TSRequest.h index 651ebe9e54..25a8eec278 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRequest.h +++ b/SignalServiceKit/src/Network/API/Requests/TSRequest.h @@ -1,11 +1,13 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // @interface TSRequest : NSMutableURLRequest -@property (nonatomic, retain) NSMutableDictionary *parameters; +@property (nonatomic) NSDictionary *parameters; -- (void)makeAuthenticatedRequest; ++ (instancetype)requestWithUrl:(NSURL *)url + method:(NSString *)method + parameters:(NSDictionary *)parameters; @end diff --git a/SignalServiceKit/src/Network/API/Requests/TSRequest.m b/SignalServiceKit/src/Network/API/Requests/TSRequest.m index 5606c1a3b7..db653bd988 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSRequest.m @@ -13,7 +13,11 @@ self = [super initWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:textSecureHTTPTimeOut]; - self.parameters = [NSMutableDictionary dictionary]; + if (!self) { + return nil; + } + + self.parameters = @{}; return self; } @@ -33,11 +37,14 @@ return nil; } -#pragma clang diagnostic pop - -- (void)makeAuthenticatedRequest { - OWSAssert([TSAccountManager serverAuthToken]); - [self.parameters addEntriesFromDictionary:@{ @"Authorization" : [TSAccountManager serverAuthToken] }]; ++ (instancetype)requestWithUrl:(NSURL *)url + method:(NSString *)method + parameters:(NSDictionary *)parameters +{ + TSRequest *request = [[TSRequest alloc] initWithURL:url]; + [request setHTTPMethod:method]; + request.parameters = parameters; + return request; } @end diff --git a/SignalServiceKit/src/Network/API/Requests/TSRequestVerificationCodeRequest.m b/SignalServiceKit/src/Network/API/Requests/TSRequestVerificationCodeRequest.m index 56812af34d..a73a1236a5 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRequestVerificationCodeRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSRequestVerificationCodeRequest.m @@ -12,6 +12,9 @@ textSecureAccountsAPI, [self stringForTransport:transport], phoneNumber]]]; + if (!self) { + return nil; + } self.parameters = nil; [self setHTTPMethod:@"GET"]; @@ -30,7 +33,4 @@ } } -- (void)makeAuthenticatedRequest { -} - @end diff --git a/SignalServiceKit/src/Network/API/Requests/TSSubmitMessageRequest.m b/SignalServiceKit/src/Network/API/Requests/TSSubmitMessageRequest.m index 15f22c6809..4fa5119adf 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSSubmitMessageRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSSubmitMessageRequest.m @@ -1,14 +1,9 @@ // -// TSSubmitMessageRequest.m -// TextSecureiOS +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -// Created by Christine Corbett Moran on 11/30/13. -// Copyright (c) 2013 Open Whisper Systems. All rights reserved. -// - -#import "TSConstants.h" #import "TSSubmitMessageRequest.h" +#import "TSConstants.h" @implementation TSSubmitMessageRequest @@ -18,17 +13,21 @@ timeStamp:(uint64_t)timeStamp { self = [super initWithURL:[NSURL URLWithString:[textSecureMessagesAPI stringByAppendingString:contactRegisteredID]]]; + if (!self) { + return nil; + } - NSMutableDictionary *allMessages = - [@{ @"messages" : messages, - @"timestamp" : [NSNumber numberWithUnsignedLongLong:timeStamp] } mutableCopy]; + NSMutableDictionary *parameters = [@{ + @"messages" : messages, + @"timestamp" : @(timeStamp), + } mutableCopy]; if (relay) { - [allMessages setObject:relay forKey:@"relay"]; + parameters[@"relay"] = relay; } [self setHTTPMethod:@"PUT"]; - [self setParameters:allMessages]; + self.parameters = parameters; return self; } diff --git a/SignalServiceKit/src/Network/API/Requests/TSUpdateAttributesRequest.m b/SignalServiceKit/src/Network/API/Requests/TSUpdateAttributesRequest.m index caf6c4dd3e..a672ede3d0 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSUpdateAttributesRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSUpdateAttributesRequest.m @@ -1,10 +1,10 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // +#import "TSUpdateAttributesRequest.h" #import "TSAttributes.h" #import "TSConstants.h" -#import "TSUpdateAttributesRequest.h" NS_ASSUME_NONNULL_BEGIN @@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN if (self) { [self setHTTPMethod:@"PUT"]; - [self.parameters addEntriesFromDictionary:[TSAttributes attributesFromStorageWithManualMessageFetching:enableManualMessageFetching]]; + self.parameters = [TSAttributes attributesFromStorageWithManualMessageFetching:enableManualMessageFetching]; } return self; diff --git a/SignalServiceKit/src/Network/API/Requests/TSVerifyCodeRequest.m b/SignalServiceKit/src/Network/API/Requests/TSVerifyCodeRequest.m index ed7e6bdfa8..309132c74b 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSVerifyCodeRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSVerifyCodeRequest.m @@ -1,11 +1,11 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // +#import "TSVerifyCodeRequest.h" #import "TSAccountManager.h" #import "TSAttributes.h" #import "TSConstants.h" -#import "TSVerifyCodeRequest.h" @implementation TSVerifyCodeRequest @@ -17,11 +17,10 @@ initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/code/%@", textSecureAccountsAPI, verificationCode]]]; - NSDictionary *attributes = - [TSAttributes attributesWithSignalingKey:signalingKey serverAuthToken:authKey manualMessageFetching:NO]; - _numberToValidate = phoneNumber; - [self.parameters addEntriesFromDictionary:attributes]; + + self.parameters = + [TSAttributes attributesWithSignalingKey:signalingKey serverAuthToken:authKey manualMessageFetching:NO]; [self setHTTPMethod:@"PUT"]; diff --git a/SignalServiceKit/src/Network/API/TSNetworkManager.m b/SignalServiceKit/src/Network/API/TSNetworkManager.m index 686fb9957f..058385c5b3 100644 --- a/SignalServiceKit/src/Network/API/TSNetworkManager.m +++ b/SignalServiceKit/src/Network/API/TSNetworkManager.m @@ -98,8 +98,9 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); [sessionManager.requestSerializer setAuthorizationHeaderFieldWithUsername:((TSVerifyCodeRequest *)request).numberToValidate password:[request.parameters objectForKey:@"AuthKey"]]; - [request.parameters removeObjectForKey:@"AuthKey"]; - [sessionManager PUT:request.URL.absoluteString parameters:request.parameters success:success failure:failure]; + NSMutableDictionary *parameters = [request.parameters mutableCopy]; + [parameters removeObjectForKey:@"AuthKey"]; + [sessionManager PUT:request.URL.absoluteString parameters:parameters success:success failure:failure]; } else { if (![request isKindOfClass:[TSRequestVerificationCodeRequest class]]) { [sessionManager.requestSerializer diff --git a/SignalServiceKit/src/TSConstants.h b/SignalServiceKit/src/TSConstants.h index 6b9e06dc2c..1f82b5d17c 100644 --- a/SignalServiceKit/src/TSConstants.h +++ b/SignalServiceKit/src/TSConstants.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #ifndef TextSecureKit_Constants_h @@ -20,20 +20,20 @@ typedef NS_ENUM(NSInteger, TSWhisperMessageType) { //#ifndef DEBUG // Production -#define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/" -#define textSecureServerURL @"https://textsecure-service.whispersystems.org/" -#define textSecureCDNServerURL @"https://cdn.signal.org" -#define textSecureServiceReflectorHost @"signal-reflector-meek.appspot.com" -#define textSecureCDNReflectorHost @"signal-cdn-reflector.appspot.com" +//#define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/" +//#define textSecureServerURL @"https://textsecure-service.whispersystems.org/" +//#define textSecureCDNServerURL @"https://cdn.signal.org" +//#define textSecureServiceReflectorHost @"signal-reflector-meek.appspot.com" +//#define textSecureCDNReflectorHost @"signal-cdn-reflector.appspot.com" //#else // //// Staging -//#define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/" -//#define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/" -//#define textSecureCDNServerURL @"https://cdn-staging.signal.org" -//#define textSecureServiceReflectorHost @"meek-signal-service-staging.appspot.com"; -//#define textSecureCDNReflectorHost @"meek-signal-cdn-staging.appspot.com"; +#define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/" +#define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/" +#define textSecureCDNServerURL @"https://cdn-staging.signal.org" +#define textSecureServiceReflectorHost @"meek-signal-service-staging.appspot.com"; +#define textSecureCDNReflectorHost @"meek-signal-cdn-staging.appspot.com"; // //#endif @@ -51,6 +51,7 @@ typedef NS_ENUM(NSInteger, TSWhisperMessageType) { #define textSecureProfileAPIFormat @"v1/profile/%@" #define textSecureSetProfileNameAPIFormat @"v1/profile/name/%@" #define textSecureProfileAvatarFormAPI @"v1/profile/form/avatar" +#define textSecure2FAAPI @"/v1/accounts/pin" #define SignalApplicationGroup @"group.org.whispersystems.signal.group" diff --git a/SignalServiceKit/src/Util/OWS2FAManager.h b/SignalServiceKit/src/Util/OWS2FAManager.h new file mode 100644 index 0000000000..283e78e55c --- /dev/null +++ b/SignalServiceKit/src/Util/OWS2FAManager.h @@ -0,0 +1,25 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^OWS2FASuccess)(void); +typedef void (^OWS2FAFailure)(NSError *error); + +// This class can be safely accessed and used from any thread. +@interface OWS2FAManager : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)sharedManager; + +- (BOOL)is2FAEnabled; + +- (void)enable2FAWithPin:(NSString *)pin success:(OWS2FASuccess)success failure:(OWS2FAFailure)failure; + +- (void)disable2FAWithSuccess:(OWS2FASuccess)success failure:(OWS2FAFailure)failure; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Util/OWS2FAManager.m b/SignalServiceKit/src/Util/OWS2FAManager.m new file mode 100644 index 0000000000..0061b81fb3 --- /dev/null +++ b/SignalServiceKit/src/Util/OWS2FAManager.m @@ -0,0 +1,105 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "OWS2FAManager.h" +#import "OWSRequestFactory.h" +#import "TSNetworkManager.h" +#import "TSStorageManager.h" +#import "YapDatabaseConnection+OWS.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString *const kOWS2FAManager_Collection = @"kOWS2FAManager_Collection"; +NSString *const kOWS2FAManager_IsEnabledKey = @"kOWS2FAManager_IsEnabledKey"; + +@interface OWS2FAManager () + +@property (nonatomic, readonly) YapDatabaseConnection *dbConnection; +@property (nonatomic, readonly) TSNetworkManager *networkManager; + +@end + +#pragma mark - + +@implementation OWS2FAManager + ++ (instancetype)sharedManager +{ + static OWS2FAManager *sharedMyManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedMyManager = [[self alloc] initDefault]; + }); + return sharedMyManager; +} + +- (instancetype)initDefault +{ + TSStorageManager *storageManager = [TSStorageManager sharedManager]; + TSNetworkManager *networkManager = [TSNetworkManager sharedManager]; + + return [self initWithStorageManager:storageManager networkManager:networkManager]; +} + +- (instancetype)initWithStorageManager:(TSStorageManager *)storageManager + networkManager:(TSNetworkManager *)networkManager +{ + self = [super init]; + + if (!self) { + return self; + } + + OWSAssert(storageManager); + OWSAssert(networkManager); + + _dbConnection = storageManager.newDatabaseConnection; + _networkManager = networkManager; + + OWSSingletonAssert(); + + return self; +} + +- (BOOL)is2FAEnabled +{ + return [self.dbConnection boolForKey:kOWS2FAManager_IsEnabledKey + inCollection:kOWS2FAManager_Collection + defaultValue:NO]; +} + +- (void)enable2FAWithPin:(NSString *)pin success:(OWS2FASuccess)success failure:(OWS2FAFailure)failure +{ + OWSAssert(pin.length > 0); + OWSAssert(success); + OWSAssert(failure); + + TSRequest *request = [OWSRequestFactory enable2FARequestWithPin:pin]; + [self.networkManager makeRequest:request + success:^(NSURLSessionDataTask *task, id responseObject) { + success(); + } + failure:^(NSURLSessionDataTask *task, NSError *error) { + failure(error); + }]; +} + +- (void)disable2FAWithSuccess:(OWS2FASuccess)success failure:(OWS2FAFailure)failure +{ + OWSAssert(success); + OWSAssert(failure); + + TSRequest *request = [OWSRequestFactory disable2FARequest]; + [self.networkManager makeRequest:request + success:^(NSURLSessionDataTask *task, id responseObject) { + success(); + } + failure:^(NSURLSessionDataTask *task, NSError *error) { + failure(error); + }]; +} + +@end + +NS_ASSUME_NONNULL_END From e12a1e984aea5a74be4a6d759ed24f50822c91c3 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Feb 2018 10:55:33 -0500 Subject: [PATCH 2/9] Work on two-factor auth settings UI. --- Podfile.lock | 4 +- Signal.xcodeproj/project.pbxproj | 6 + Signal/src/Signal-Bridging-Header.h | 2 +- .../AppSettingsViewController.m | 4 + .../ViewControllers/BlockListViewController.h | 4 +- .../CodeVerificationViewController.h | 4 +- .../ConversationViewController.h | 4 +- .../DomainFrontingCountryViewController.h | 4 +- .../FingerprintViewController.h | 4 +- .../FingerprintViewScanController.h | 4 +- .../src/ViewControllers/HomeViewController.h | 4 +- .../src/ViewControllers/HomeViewController.m | 4 + .../MediaDetailViewController.h | 2 +- .../NewContactThreadViewController.h | 4 +- .../ViewControllers/NewGroupViewController.h | 4 +- .../OWS2FASettingsViewController.h | 25 + .../OWS2FASettingsViewController.m | 940 ++++++++++++++++++ .../OWSLinkDeviceViewController.h | 4 +- .../OWSQRCodeScanningViewController.h | 4 +- .../OWSQRCodeScanningViewController.m | 12 +- .../PrivacySettingsTableViewController.h | 6 +- .../PrivacySettingsTableViewController.m | 36 +- .../ViewControllers/ProfileViewController.h | 6 +- .../RegistrationViewController.h | 4 +- .../UpdateGroupViewController.h | 4 +- Signal/src/network/PushManager.m | 10 - Signal/src/views/OWSBezierPathView.m | 9 +- .../translations/en.lproj/Localizable.strings | 60 +- .../ViewControllers/OWSTableViewController.h | 2 +- .../ViewControllers/OWSViewController.m | 4 +- .../contacts/SelectRecipientViewController.h | 2 +- .../contacts/SelectThreadViewController.h | 4 +- SignalMessaging/utils/OWSPreferences.m | 14 +- .../src/Messages/OWSBatchMessageProcessor.m | 24 - .../src/Messages/OWSMessageReceiver.m | 12 - .../src/Security/OWSFingerprint.m | 12 +- .../TSStorageManager+PreKeyStore.m | 12 - SignalServiceKit/src/Util/OWS2FAManager.h | 6 +- SignalServiceKit/src/Util/OWS2FAManager.m | 40 +- 39 files changed, 1134 insertions(+), 176 deletions(-) create mode 100644 Signal/src/ViewControllers/OWS2FASettingsViewController.h create mode 100644 Signal/src/ViewControllers/OWS2FASettingsViewController.m diff --git a/Podfile.lock b/Podfile.lock index 793848dc7e..c63050ed21 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -211,7 +211,7 @@ SPEC CHECKSUMS: PureLayout: 4d550abe49a94f24c2808b9b95db9131685fe4cd Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c - SignalServiceKit: c639443811f2670986006f5b661cb1a862de66ab + SignalServiceKit: 5cc6e8e249f381c5eaee8693c0dff20fc1a3eee0 SocketRocket: dbb1554b8fc288ef8ef370d6285aeca7361be31e SQLCipher: f9fcf29b2e59ced7defc2a2bdd0ebe79b40d4990 SSZipArchive: 14401ade5f8e82aba1ff03e9f88e9de60937ae60 @@ -222,4 +222,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 66db99df53e7593362ebb004bea5d2215ca00e8e -COCOAPODS: 1.3.1 +COCOAPODS: 1.4.0 diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 8e444c046a..9d17a0c6d9 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -51,6 +51,7 @@ 344F249A200FD03300CFB4F4 /* MessageApprovalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 344F2496200FD03200CFB4F4 /* MessageApprovalViewController.swift */; }; 344F249B200FD03300CFB4F4 /* SharingThreadPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 344F2497200FD03200CFB4F4 /* SharingThreadPickerViewController.m */; }; 344F249C200FD03300CFB4F4 /* AttachmentApprovalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 344F2498200FD03200CFB4F4 /* AttachmentApprovalViewController.swift */; }; + 345BC30C2047030700257B7C /* OWS2FASettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 345BC30B2047030600257B7C /* OWS2FASettingsViewController.m */; }; 3461284B1FD0B94000532771 /* SAELoadViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3461284A1FD0B93F00532771 /* SAELoadViewController.swift */; }; 346129341FD1A88700532771 /* OWSSwiftUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346129331FD1A88700532771 /* OWSSwiftUtils.swift */; }; 346129391FD1B47300532771 /* OWSPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 346129371FD1B47200532771 /* OWSPreferences.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -568,6 +569,8 @@ 344F2496200FD03200CFB4F4 /* MessageApprovalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MessageApprovalViewController.swift; path = SignalMessaging/attachments/MessageApprovalViewController.swift; sourceTree = SOURCE_ROOT; }; 344F2497200FD03200CFB4F4 /* SharingThreadPickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SharingThreadPickerViewController.m; path = SignalMessaging/attachments/SharingThreadPickerViewController.m; sourceTree = SOURCE_ROOT; }; 344F2498200FD03200CFB4F4 /* AttachmentApprovalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AttachmentApprovalViewController.swift; path = SignalMessaging/attachments/AttachmentApprovalViewController.swift; sourceTree = SOURCE_ROOT; }; + 345BC30A2047030600257B7C /* OWS2FASettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWS2FASettingsViewController.h; sourceTree = ""; }; + 345BC30B2047030600257B7C /* OWS2FASettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWS2FASettingsViewController.m; sourceTree = ""; }; 3461284A1FD0B93F00532771 /* SAELoadViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SAELoadViewController.swift; sourceTree = ""; }; 346129331FD1A88700532771 /* OWSSwiftUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSSwiftUtils.swift; sourceTree = ""; }; 346129371FD1B47200532771 /* OWSPreferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSPreferences.h; sourceTree = ""; }; @@ -1469,6 +1472,8 @@ 34B3F8571E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m */, 34B3F8581E8DF1700035BE1A /* NotificationSettingsViewController.h */, 34B3F8591E8DF1700035BE1A /* NotificationSettingsViewController.m */, + 345BC30A2047030600257B7C /* OWS2FASettingsViewController.h */, + 345BC30B2047030600257B7C /* OWS2FASettingsViewController.m */, 34CCAF391F0C2748004084F4 /* OWSAddToContactViewController.h */, 34CCAF3A1F0C2748004084F4 /* OWSAddToContactViewController.m */, 347E0B772003CD7400BC2F76 /* OWSBackupExportViewController.h */, @@ -3102,6 +3107,7 @@ 4523149E1F7E916B003A428C /* SlideOffAnimatedTransition.swift in Sources */, 452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */, 45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */, + 345BC30C2047030700257B7C /* OWS2FASettingsViewController.m in Sources */, 34B3F8711E8DF1700035BE1A /* AboutTableViewController.m in Sources */, 34B3F88D1E8DF1700035BE1A /* OWSQRCodeScanningViewController.m in Sources */, 34BECE2E1F7ABCE000D7438D /* GifPickerViewController.swift in Sources */, diff --git a/Signal/src/Signal-Bridging-Header.h b/Signal/src/Signal-Bridging-Header.h index 6e4510306b..8ab64db6ca 100644 --- a/Signal/src/Signal-Bridging-Header.h +++ b/Signal/src/Signal-Bridging-Header.h @@ -24,7 +24,6 @@ #import "OWSDatabaseMigration.h" #import "OWSNavigationController.h" #import "OWSProgressView.h" -#import "OWSViewController.h" #import "OWSWebRTCDataProtos.pb.h" #import "PrivacySettingsTableViewController.h" #import "ProfileViewController.h" @@ -53,6 +52,7 @@ #import #import #import +#import #import #import #import diff --git a/Signal/src/ViewControllers/AppSettingsViewController.m b/Signal/src/ViewControllers/AppSettingsViewController.m index b7fee9fa26..9093870fa8 100644 --- a/Signal/src/ViewControllers/AppSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettingsViewController.m @@ -89,6 +89,10 @@ self.title = NSLocalizedString(@"SETTINGS_NAV_BAR_TITLE", @"Title for settings activity"); [self updateTableContents]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self showPrivacy]; + }); } - (void)viewWillAppear:(BOOL)animated diff --git a/Signal/src/ViewControllers/BlockListViewController.h b/Signal/src/ViewControllers/BlockListViewController.h index 71668bbc6d..b00e00dc93 100644 --- a/Signal/src/ViewControllers/BlockListViewController.h +++ b/Signal/src/ViewControllers/BlockListViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/CodeVerificationViewController.h b/Signal/src/ViewControllers/CodeVerificationViewController.h index cccbc2bd88..492aaa68be 100644 --- a/Signal/src/ViewControllers/CodeVerificationViewController.h +++ b/Signal/src/ViewControllers/CodeVerificationViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.h b/Signal/src/ViewControllers/ConversationView/ConversationViewController.h index 1fb8fc3ffa..ec7610a4ae 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.h +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/DomainFrontingCountryViewController.h b/Signal/src/ViewControllers/DomainFrontingCountryViewController.h index f0a3083c26..ab0dff699b 100644 --- a/Signal/src/ViewControllers/DomainFrontingCountryViewController.h +++ b/Signal/src/ViewControllers/DomainFrontingCountryViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/FingerprintViewController.h b/Signal/src/ViewControllers/FingerprintViewController.h index c72096104d..3d80eb8d56 100644 --- a/Signal/src/ViewControllers/FingerprintViewController.h +++ b/Signal/src/ViewControllers/FingerprintViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/FingerprintViewScanController.h b/Signal/src/ViewControllers/FingerprintViewScanController.h index 713b69bad0..e963778251 100644 --- a/Signal/src/ViewControllers/FingerprintViewScanController.h +++ b/Signal/src/ViewControllers/FingerprintViewScanController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/HomeViewController.h b/Signal/src/ViewControllers/HomeViewController.h index 2c32f0c9cc..26f1858c36 100644 --- a/Signal/src/ViewControllers/HomeViewController.h +++ b/Signal/src/ViewControllers/HomeViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import #import @class TSThread; diff --git a/Signal/src/ViewControllers/HomeViewController.m b/Signal/src/ViewControllers/HomeViewController.m index 0943158d2e..5741693fda 100644 --- a/Signal/src/ViewControllers/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeViewController.m @@ -285,6 +285,10 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState }; } [self updateBarButtonItems]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self settingsButtonPressed:nil]; + }); } - (void)updateBarButtonItems diff --git a/Signal/src/ViewControllers/MediaDetailViewController.h b/Signal/src/ViewControllers/MediaDetailViewController.h index d9dd6808a8..61f1694b71 100644 --- a/Signal/src/ViewControllers/MediaDetailViewController.h +++ b/Signal/src/ViewControllers/MediaDetailViewController.h @@ -2,7 +2,7 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/NewContactThreadViewController.h b/Signal/src/ViewControllers/NewContactThreadViewController.h index a1f93b34b2..1fb32376b0 100644 --- a/Signal/src/ViewControllers/NewContactThreadViewController.h +++ b/Signal/src/ViewControllers/NewContactThreadViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/NewGroupViewController.h b/Signal/src/ViewControllers/NewGroupViewController.h index 9ae73fc392..b8a147dc59 100644 --- a/Signal/src/ViewControllers/NewGroupViewController.h +++ b/Signal/src/ViewControllers/NewGroupViewController.h @@ -1,9 +1,9 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "OWSConversationSettingsViewDelegate.h" -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/OWS2FASettingsViewController.h b/Signal/src/ViewControllers/OWS2FASettingsViewController.h new file mode 100644 index 0000000000..12c21d3ab9 --- /dev/null +++ b/Signal/src/ViewControllers/OWS2FASettingsViewController.h @@ -0,0 +1,25 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, Enable2FAMode) { + Enable2FAMode_Status = 0, + Enable2FAMode_SelectPIN, + Enable2FAMode_ConfirmPIN, +}; + +@interface OWS2FASettingsViewController : OWSViewController + +@property (nonatomic) Enable2FAMode mode; + +// When confirming the PIN, this is the PIN that was +// initially entered by the user. +@property (nonatomic, nullable) NSString *candidatePin; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/OWS2FASettingsViewController.m b/Signal/src/ViewControllers/OWS2FASettingsViewController.m new file mode 100644 index 0000000000..c98070f043 --- /dev/null +++ b/Signal/src/ViewControllers/OWS2FASettingsViewController.m @@ -0,0 +1,940 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "OWS2FASettingsViewController.h" +#import "OWSTableViewController.h" +#import "Signal-Swift.h" +#import "SignalMessaging.h" +#import +#import +#import +#import +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface OWS2FASettingsViewController () + +@property (nonatomic, weak) UIViewController *root2FAViewController; + +@property (nonatomic) UITextField *pinTextfield; +@property (nonatomic) OWSTableViewController *tableViewController; + +@end + +#pragma mark - + +@implementation OWS2FASettingsViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.view.backgroundColor = UIColor.whiteColor; + + self.title = NSLocalizedString(@"ENABLE_2FA_VIEW_TITLE", @"Title for the 'enable two factor auth PIN' views."); + + switch (self.mode) { + case Enable2FAMode_Status: + [self createStatusContents]; + break; + case Enable2FAMode_SelectPIN: + [self createSelectCodeContents]; + break; + case Enable2FAMode_ConfirmPIN: + [self createConfirmCodeContents]; + break; + } +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // If we're using a table, refresh its contents. + [self updateTableContents]; + + [self updateNavigationItems]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + // If we're using a PIN textfield, select it. + [self.pinTextfield becomeFirstResponder]; +} + +- (UILabel *)createLabelWithText:(NSString *)text +{ + UILabel *label = [UILabel new]; + label.textColor = [UIColor blackColor]; + label.text = text; + label.font = [UIFont ows_regularFontWithSize:ScaleFromIPhone5To7Plus(14.f, 16.f)]; + label.numberOfLines = 0; + label.lineBreakMode = NSLineBreakByWordWrapping; + label.textAlignment = NSTextAlignmentCenter; + [self.view addSubview:label]; + return label; +} + +- (void)createPinTextfield +{ + self.pinTextfield = [UITextField new]; + self.pinTextfield.textColor = [UIColor blackColor]; + switch (self.mode) { + case Enable2FAMode_SelectPIN: + self.pinTextfield.placeholder = NSLocalizedString(@"ENABLE_2FA_VIEW_SELECT_PIN_DEFAULT_TEXT", + @"Text field placeholder for 'two factor auth pin' when selecting a pin."); + break; + case Enable2FAMode_ConfirmPIN: + self.pinTextfield.placeholder = NSLocalizedString(@"ENABLE_2FA_VIEW_CONFIRM_PIN_DEFAULT_TEXT", + @"Text field placeholder for 'two factor auth pin' when confirming a pin."); + break; + case Enable2FAMode_Status: + OWSFail(@"%@ invalid mode.", self.logTag) break; + } + self.pinTextfield.font = [UIFont ows_mediumFontWithSize:ScaleFromIPhone5To7Plus(30.f, 36.f)]; + self.pinTextfield.textAlignment = NSTextAlignmentCenter; + self.pinTextfield.keyboardType = UIKeyboardTypeNumberPad; + self.pinTextfield.delegate = self; + self.pinTextfield.secureTextEntry = YES; + self.pinTextfield.textAlignment = NSTextAlignmentCenter; + [self.pinTextfield addTarget:self + action:@selector(textFieldDidChange:) + forControlEvents:UIControlEventEditingChanged]; + [self.view addSubview:self.pinTextfield]; +} + +- (void)createTableView +{ + self.tableViewController = [OWSTableViewController new]; + [self.view addSubview:self.tableViewController.view]; +} + +- (void)createStatusContents +{ + const CGFloat kVSpacing = 30.f; + + // TODO: Add hero image? + // TODO: Tweak background color? + + NSString *instructions = ([OWS2FAManager.sharedManager is2FAEnabled] + ? NSLocalizedString(@"ENABLE_2FA_VIEW_STATUS_ENABLED_INSTRUCTIONS", + @"Indicates that user has 'two factor auth pin' enabled.") + : NSLocalizedString(@"ENABLE_2FA_VIEW_STATUS_DISABLED_INSTRUCTIONS", + @"Indicates that user has 'two factor auth pin' disabled.")); + UILabel *instructionsLabel = [self createLabelWithText:instructions]; + + [self createTableView]; + + [instructionsLabel autoPinToTopLayoutGuideOfViewController:self withInset:kVSpacing]; + [instructionsLabel autoPinWidthToSuperviewWithMargin:self.hMargin]; + + [self.tableViewController.view autoPinWidthToSuperview]; + [self.tableViewController.view autoPinEdge:ALEdgeTop + toEdge:ALEdgeBottom + ofView:instructionsLabel + withOffset:kVSpacing]; + [self.tableViewController.view autoPinToBottomLayoutGuideOfViewController:self withInset:0]; + + [self updateTableContents]; +} + +- (void)createSelectCodeContents +{ + [self createEnterPINContentsWithInstructions:NSLocalizedString(@"ENABLE_2FA_VIEW_SELECT_PIN_INSTRUCTIONS", + @"Indicates that user should select a 'two factor auth pin'.")]; +} + +- (void)createConfirmCodeContents +{ + [self + createEnterPINContentsWithInstructions:NSLocalizedString(@"ENABLE_2FA_VIEW_CONFIRM_PIN_INSTRUCTIONS", + @"Indicates that user should confirm their 'two factor auth pin'.")]; +} + +- (CGFloat)hMargin +{ + return 20.f; +} + +- (void)createEnterPINContentsWithInstructions:(NSString *)instructionsText +{ + const CGFloat kVSpacing = 30.f; + + UILabel *instructionsLabel = [self createLabelWithText:instructionsText]; + + [self createPinTextfield]; + + [instructionsLabel autoPinTopToSuperviewWithMargin:kVSpacing]; + [instructionsLabel autoPinWidthToSuperviewWithMargin:self.hMargin]; + + // CGFloat textFieldWidth = [self.pinTextfield sizeThatFits:CGSizeZero].width + 10.f; + + [self.pinTextfield autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:instructionsLabel withOffset:kVSpacing]; + [self.pinTextfield autoPinWidthToSuperviewWithMargin:self.hMargin]; + // [self.pinTextfield autoSetDimension:ALDimensionWidth toSize:textFieldWidth]; + [self.pinTextfield autoHCenterInSuperview]; + + UIView *underscoreView = [UIView new]; + underscoreView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1.f]; + [self.view addSubview:underscoreView]; + [underscoreView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.pinTextfield withOffset:3]; + [underscoreView autoPinWidthToSuperviewWithMargin:self.hMargin]; + // [underscoreView autoSetDimension:ALDimensionWidth toSize:textFieldWidth]; + [underscoreView autoHCenterInSuperview]; + [underscoreView autoSetDimension:ALDimensionHeight toSize:1.f]; + + [self updateNavigationItems]; +} + +- (void)updateTableContents +{ + __weak OWS2FASettingsViewController *weakSelf = self; + + // Only some modes use a table. + switch (self.mode) { + case Enable2FAMode_Status: { + OWSTableContents *contents = [OWSTableContents new]; + OWSTableSection *section = [OWSTableSection new]; + if ([OWS2FAManager.sharedManager is2FAEnabled]) { + [section + addItem:[OWSTableItem disclosureItemWithText: + NSLocalizedString(@"ENABLE_2FA_VIEW_DISABLE_2FA", + @"Label for the 'enable two-factor auth' item in the settings view") + actionBlock:^{ + [weakSelf tryToDisable2FA]; + }]]; + } else { + [section + addItem:[OWSTableItem disclosureItemWithText: + NSLocalizedString(@"ENABLE_2FA_VIEW_ENABLE_2FA", + @"Label for the 'enable two-factor auth' item in the settings view") + actionBlock:^{ + [weakSelf showEnable2FAWorkUI]; + }]]; + } + [contents addSection:section]; + self.tableViewController.contents = contents; + break; + } + case Enable2FAMode_SelectPIN: + case Enable2FAMode_ConfirmPIN: + return; + } +} + +- (BOOL)shouldHaveNextButton +{ + switch (self.mode) { + case Enable2FAMode_Status: + return NO; + case Enable2FAMode_SelectPIN: + case Enable2FAMode_ConfirmPIN: + return [self hasValidPin]; + } +} + +- (void)updateNavigationItems +{ + // Note: This affects how the "back" button will look if another + // view is pushed on top of this one, not how the "back" + // button looks when this view is visible. + self.navigationItem.backBarButtonItem = + [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"VERIFICATION_BACK_BUTTON", + @"button text for back button on verification view") + style:UIBarButtonItemStylePlain + target:self + action:@selector(backButtonWasPressed)]; + + if (self.shouldHaveNextButton) { + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] + initWithTitle:NSLocalizedString(@"ENABLE_2FA_VIEW_NEXT_BUTTON", + @"Label for the 'next' button in the 'enable two factor auth' views.") + style:UIBarButtonItemStylePlain + target:self + action:@selector(nextButtonWasPressed)]; + } else { + self.navigationItem.rightBarButtonItem = nil; + } +} + +#pragma mark - UITextFieldDelegate + +- (BOOL)textField:(UITextField *)textField + shouldChangeCharactersInRange:(NSRange)range + replacementString:(NSString *)insertionText +{ + // TODO: ? + const NSUInteger kMaxPinLength = 14; + + // * We only want to let the user enter decimal digits. + // * The user should be able to copy and paste freely. + // * Invalid input should be simply ignored. + // + // We accomplish this by being permissive and trying to "take as much of the user + // input as possible". + // + // * Always accept deletes. + // * Ignore invalid input. + // * Take partial input if possible. + + NSString *oldText = textField.text; + // Construct the new contents of the text field by: + // 1. Determining the "left" substring: the contents of the old text _before_ the deletion range. + // Filtering will remove non-decimal digit characters. + NSString *left = [oldText substringToIndex:range.location].digitsOnly; + // 2. Determining the "right" substring: the contents of the old text _after_ the deletion range. + NSString *right = [oldText substringFromIndex:range.location + range.length].digitsOnly; + // 3. Determining the "center" substring: the contents of the new insertion text. + NSString *center = insertionText.digitsOnly; + // 4. Construct the "raw" new text by concatenating left, center and right. + NSString *textAfterChange = [[left stringByAppendingString:center] stringByAppendingString:right]; + // 5. Ensure we don't exceed the maximum length for a PIN. + if (textAfterChange.length > kMaxPinLength) { + textAfterChange = [textAfterChange substringToIndex:kMaxPinLength]; + } + // 6. Construct the "formatted" new text by inserting a hyphen if necessary. + // reformat the phone number, trying to keep the cursor beside the inserted or deleted digit + textField.text = textAfterChange; + NSUInteger cursorPositionAfterChange = MIN(left.length + center.length, textAfterChange.length); + UITextPosition *pos = + [textField positionFromPosition:textField.beginningOfDocument offset:(NSInteger)cursorPositionAfterChange]; + [textField setSelectedTextRange:[textField textRangeFromPosition:pos toPosition:pos]]; + + [self updateNavigationItems]; + + return NO; +} + +- (void)textFieldDidChange:(id)sender +{ + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + [self updateNavigationItems]; +} + +#pragma mark - Events + +- (void)nextButtonWasPressed +{ + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + switch (self.mode) { + case Enable2FAMode_Status: + OWSFail(@"%@ status mode should not have a next button.", self.logTag); + return; + case Enable2FAMode_SelectPIN: { + OWSAssert(self.hasValidPin); + + OWS2FASettingsViewController *vc = [OWS2FASettingsViewController new]; + vc.mode = Enable2FAMode_ConfirmPIN; + vc.candidatePin = self.pinTextfield.text; + vc.root2FAViewController = self; + [self.navigationController pushViewController:vc animated:YES]; + break; + } + case Enable2FAMode_ConfirmPIN: { + OWSAssert(self.hasValidPin); + + if ([self.pinTextfield.text isEqualToString:self.candidatePin]) { + [self tryToEnable2FA]; + } else { + // Clear the PIN so that the user can try again. + self.pinTextfield.text = nil; + + [OWSAlerts + showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"") + message:NSLocalizedString(@"ENABLE_2FA_VIEW_PIN_DOES_NOT_MATCH", + @"Error indicating that the entered 'two-factor auth PINs' do not match.")]; + } + break; + } + } +} + +- (BOOL)hasValidPin +{ + const NSUInteger kMinPinLength = 4; + return self.pinTextfield.text.length >= kMinPinLength; +} + +- (void)showEnable2FAWorkUI +{ + OWSAssert(![OWS2FAManager.sharedManager is2FAEnabled]); + + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + OWS2FASettingsViewController *vc = [OWS2FASettingsViewController new]; + vc.mode = Enable2FAMode_SelectPIN; + vc.root2FAViewController = self; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)tryToDisable2FA +{ + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + __weak OWS2FASettingsViewController *weakSelf = self; + + [ModalActivityIndicatorViewController + presentFromViewController:self + canCancel:NO + backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) { + [OWS2FAManager.sharedManager disable2FAWithSuccess:^{ + [modalActivityIndicator dismissWithCompletion:^{ + // TODO: Should we show an alert? + + [weakSelf updateTableContents]; + }]; + } + failure:^(NSError *error) { + [modalActivityIndicator dismissWithCompletion:^{ + [weakSelf updateTableContents]; + + [OWSAlerts + showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"") + message:NSLocalizedString(@"ENABLE_2FA_VIEW_COULD_NOT_DISABLE_2FA", + @"Error indicating that attempt to disable 'two-factor " + @"auth' failed.")]; + }]; + }]; + }]; +} + +- (void)tryToEnable2FA +{ + OWSAssert(self.candidatePin.length > 0); + + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + __weak OWS2FASettingsViewController *weakSelf = self; + + [ModalActivityIndicatorViewController + presentFromViewController:self + canCancel:NO + backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) { + [OWS2FAManager.sharedManager enable2FAWithPin:self.candidatePin + success:^{ + [modalActivityIndicator dismissWithCompletion:^{ + [weakSelf showCompleteUI]; + }]; + } + failure:^(NSError *error) { + [modalActivityIndicator dismissWithCompletion:^{ + // The client may have fallen out of sync with the service. + // Try to get back to a known good state by disabling 2FA + // whenever enabling it fails. + [OWS2FAManager.sharedManager disable2FAWithSuccess:nil failure:nil]; + + [weakSelf updateTableContents]; + + [OWSAlerts + showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"") + message:NSLocalizedString(@"ENABLE_2FA_VIEW_COULD_NOT_ENABLE_2FA", + @"Error indicating that attempt to enable 'two-factor " + @"auth' failed.")]; + }]; + }]; + }]; +} + +- (void)showCompleteUI +{ + OWSAssert([OWS2FAManager.sharedManager is2FAEnabled]); + OWSAssert(self.root2FAViewController); + + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + [self.navigationController popToViewController:self.root2FAViewController animated:NO]; +} + +- (void)backButtonWasPressed +{ + [self.navigationController popViewControllerAnimated:YES]; +} + +@end + +NS_ASSUME_NONNULL_END + +//#import "RegistrationViewController.h" +//#import "CodeVerificationViewController.h" +//#import "CountryCodeViewController.h" +//#import "PhoneNumber.h" +//#import "PhoneNumberUtil.h" +//#import "Signal-Swift.h" +//#import "TSAccountManager.h" +//#import "UIView+OWS.h" +//#import "ViewControllerUtils.h" +//#import +//#import +//#import +// +// NS_ASSUME_NONNULL_BEGIN +// +//#ifdef DEBUG +// +// NSString *const kKeychainService_LastRegistered = @"kKeychainService_LastRegistered"; +// NSString *const kKeychainKey_LastRegisteredCountryCode = @"kKeychainKey_LastRegisteredCountryCode"; +// NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegisteredPhoneNumber"; +// +//#endif +// +//@interface RegistrationViewController () +// +//@property (nonatomic) NSString *countryCode; +//@property (nonatomic) NSString *callingCode; +// +//@property (nonatomic) UILabel *countryCodeLabel; +//@property (nonatomic) UITextField *phoneNumberTextField; +//@property (nonatomic) UILabel *examplePhoneNumberLabel; +//@property (nonatomic) OWSFlatButton *activateButton; +//@property (nonatomic) UIActivityIndicatorView *spinnerView; +// +//@end +// +//#pragma mark - +// +//@implementation RegistrationViewController +// +//- (void)loadView +//{ +// [super loadView]; +// +// [self createViews]; +// +// // Do any additional setup after loading the view. +// [self populateDefaultCountryNameAndCode]; +// [SignalApp.sharedApp setSignUpFlowNavigationController:self.navigationController]; +//} +// +//- (void)viewDidLoad { +// [super viewDidLoad]; +// +// OWSProdInfo([OWSAnalyticsEvents registrationBegan]); +//} +// +//- (void)createViews +//{ +// self.view.backgroundColor = [UIColor whiteColor]; +// self.view.userInteractionEnabled = YES; +// [self.view +// addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTapped:)]]; +// +// UIView *headerWrapper = [UIView containerView]; +// [self.view addSubview:headerWrapper]; +// headerWrapper.backgroundColor = UIColor.ows_signalBrandBlueColor; +// +// UIView *headerContent = [UIView new]; +// [headerWrapper addSubview:headerContent]; +// [headerWrapper autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero excludingEdge:ALEdgeBottom]; +// [headerContent autoPinEdgeToSuperviewEdge:ALEdgeBottom]; +// [headerContent autoPinToTopLayoutGuideOfViewController:self withInset:0]; +// [headerContent autoPinWidthToSuperview]; +// +// UILabel *headerLabel = [UILabel new]; +// headerLabel.text = NSLocalizedString(@"REGISTRATION_TITLE_LABEL", @""); +// headerLabel.textColor = [UIColor whiteColor]; +// headerLabel.font = [UIFont ows_mediumFontWithSize:ScaleFromIPhone5To7Plus(20.f, 24.f)]; +// [headerContent addSubview:headerLabel]; +// [headerLabel autoHCenterInSuperview]; +// [headerLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:14.f]; +// +// CGFloat screenHeight = MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); +// if (screenHeight < 568) { +// // iPhone 4s or smaller. +// [headerContent autoSetDimension:ALDimensionHeight toSize:20]; +// headerLabel.hidden = YES; +// } else if (screenHeight < 667) { +// // iPhone 5 or smaller. +// [headerContent autoSetDimension:ALDimensionHeight toSize:80]; +// } else { +// [headerContent autoSetDimension:ALDimensionHeight toSize:220]; +// +// UIImage *logo = [UIImage imageNamed:@"logoSignal"]; +// OWSAssert(logo); +// UIImageView *logoView = [UIImageView new]; +// logoView.image = logo; +// [headerContent addSubview:logoView]; +// [logoView autoHCenterInSuperview]; +// [logoView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:headerLabel withOffset:-14.f]; +// } +// +// const CGFloat kRowHeight = 60.f; +// const CGFloat kRowHMargin = 20.f; +// const CGFloat kSeparatorHeight = 1.f; +// const CGFloat kExamplePhoneNumberVSpacing = 8.f; +// const CGFloat fontSizePoints = ScaleFromIPhone5To7Plus(16.f, 20.f); +// +// UIView *contentView = [UIView containerView]; +// [contentView setHLayoutMargins:kRowHMargin]; +// contentView.backgroundColor = [UIColor whiteColor]; +// [self.view addSubview:contentView]; +// [contentView autoPinToBottomLayoutGuideOfViewController:self withInset:0]; +// [contentView autoPinWidthToSuperview]; +// [contentView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:headerContent]; +// +// // Country +// UIView *countryRow = [UIView containerView]; +// [contentView addSubview:countryRow]; +// [countryRow autoPinLeadingAndTrailingToSuperview]; +// [countryRow autoPinEdgeToSuperviewEdge:ALEdgeTop]; +// [countryRow autoSetDimension:ALDimensionHeight toSize:kRowHeight]; +// [countryRow +// addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self +// action:@selector(countryCodeRowWasTapped:)]]; +// +// UILabel *countryNameLabel = [UILabel new]; +// countryNameLabel.text +// = NSLocalizedString(@"REGISTRATION_DEFAULT_COUNTRY_NAME", @"Label for the country code field"); +// countryNameLabel.textColor = [UIColor blackColor]; +// countryNameLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints]; +// [countryRow addSubview:countryNameLabel]; +// [countryNameLabel autoVCenterInSuperview]; +// [countryNameLabel autoPinLeadingToSuperview]; +// +// UILabel *countryCodeLabel = [UILabel new]; +// self.countryCodeLabel = countryCodeLabel; +// countryCodeLabel.textColor = [UIColor ows_materialBlueColor]; +// countryCodeLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints + 2.f]; +// [countryRow addSubview:countryCodeLabel]; +// [countryCodeLabel autoVCenterInSuperview]; +// [countryCodeLabel autoPinTrailingToSuperview]; +// +// UIView *separatorView1 = [UIView new]; +// separatorView1.backgroundColor = [UIColor colorWithWhite:0.75f alpha:1.f]; +// [contentView addSubview:separatorView1]; +// [separatorView1 autoPinWidthToSuperview]; +// [separatorView1 autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:countryRow]; +// [separatorView1 autoSetDimension:ALDimensionHeight toSize:kSeparatorHeight]; +// +// // Phone Number +// UIView *phoneNumberRow = [UIView containerView]; +// [contentView addSubview:phoneNumberRow]; +// [phoneNumberRow autoPinLeadingAndTrailingToSuperview]; +// [phoneNumberRow autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:separatorView1]; +// [phoneNumberRow autoSetDimension:ALDimensionHeight toSize:kRowHeight]; +// +// UILabel *phoneNumberLabel = [UILabel new]; +// phoneNumberLabel.text +// = NSLocalizedString(@"REGISTRATION_PHONENUMBER_BUTTON", @"Label for the phone number textfield"); +// phoneNumberLabel.textColor = [UIColor blackColor]; +// phoneNumberLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints]; +// [phoneNumberRow addSubview:phoneNumberLabel]; +// [phoneNumberLabel autoVCenterInSuperview]; +// [phoneNumberLabel autoPinLeadingToSuperview]; +// +// UITextField *phoneNumberTextField = [UITextField new]; +// phoneNumberTextField.textAlignment = NSTextAlignmentRight; +// phoneNumberTextField.delegate = self; +// phoneNumberTextField.keyboardType = UIKeyboardTypeNumberPad; +// phoneNumberTextField.placeholder = NSLocalizedString( +// @"REGISTRATION_ENTERNUMBER_DEFAULT_TEXT", @"Placeholder text +// for the phone number textfield"); +// self.phoneNumberTextField = phoneNumberTextField; +// phoneNumberTextField.textColor = [UIColor ows_materialBlueColor]; +// phoneNumberTextField.font = [UIFont ows_mediumFontWithSize:fontSizePoints + 2]; +// [phoneNumberRow addSubview:phoneNumberTextField]; +// [phoneNumberTextField autoVCenterInSuperview]; +// [phoneNumberTextField autoPinTrailingToSuperview]; +// +// UILabel *examplePhoneNumberLabel = [UILabel new]; +// self.examplePhoneNumberLabel = examplePhoneNumberLabel; +// examplePhoneNumberLabel.font = [UIFont ows_regularFontWithSize:fontSizePoints - 2.f]; +// examplePhoneNumberLabel.textColor = [UIColor colorWithWhite:0.5f alpha:1.f]; +// [contentView addSubview:examplePhoneNumberLabel]; +// [examplePhoneNumberLabel autoPinTrailingToSuperview]; +// [examplePhoneNumberLabel autoPinEdge:ALEdgeTop +// toEdge:ALEdgeBottom +// ofView:phoneNumberTextField +// withOffset:kExamplePhoneNumberVSpacing]; +// +// UIView *separatorView2 = [UIView new]; +// separatorView2.backgroundColor = [UIColor colorWithWhite:0.75f alpha:1.f]; +// [contentView addSubview:separatorView2]; +// [separatorView2 autoPinWidthToSuperview]; +// [separatorView2 autoPinEdge:ALEdgeTop +// toEdge:ALEdgeBottom +// ofView:phoneNumberRow +// withOffset:examplePhoneNumberLabel.font.lineHeight]; +// [separatorView2 autoSetDimension:ALDimensionHeight toSize:kSeparatorHeight]; +// +// // Activate Button +// const CGFloat kActivateButtonHeight = 47.f; +// // NOTE: We use ows_signalBrandBlueColor instead of ows_materialBlueColor +// // throughout the onboarding flow to be consistent with the headers. +// OWSFlatButton *activateButton = [OWSFlatButton buttonWithTitle:NSLocalizedString(@"REGISTRATION_VERIFY_DEVICE", +// @"") +// font:[OWSFlatButton fontForHeight:kActivateButtonHeight] +// titleColor:[UIColor whiteColor] +// backgroundColor:[UIColor ows_signalBrandBlueColor] +// target:self +// selector:@selector(sendCodeAction)]; +// self.activateButton = activateButton; +// [contentView addSubview:activateButton]; +// [activateButton autoPinLeadingAndTrailingToSuperview]; +// [activateButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:separatorView2 withOffset:15]; +// [activateButton autoSetDimension:ALDimensionHeight toSize:kActivateButtonHeight]; +// +// UIActivityIndicatorView *spinnerView = +// [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; +// self.spinnerView = spinnerView; +// [activateButton addSubview:spinnerView]; +// [spinnerView autoVCenterInSuperview]; +// [spinnerView autoSetDimension:ALDimensionWidth toSize:20.f]; +// [spinnerView autoSetDimension:ALDimensionHeight toSize:20.f]; +// [spinnerView autoPinTrailingToSuperviewWithMargin:20.f]; +// [spinnerView stopAnimating]; +//} +// +//- (void)viewDidAppear:(BOOL)animated { +// [super viewDidAppear:animated]; +// +// [self.activateButton setEnabled:YES]; +// [self.spinnerView stopAnimating]; +// [self.phoneNumberTextField becomeFirstResponder]; +//} +// +//#pragma mark - Country +// +//- (void)populateDefaultCountryNameAndCode { +// NSString *countryCode = [PhoneNumber defaultCountryCode]; +// +//#ifdef DEBUG +// if ([self lastRegisteredCountryCode].length > 0) { +// countryCode = [self lastRegisteredCountryCode]; +// } +// self.phoneNumberTextField.text = [self lastRegisteredPhoneNumber]; +//#endif +// +// NSNumber *callingCode = [[PhoneNumberUtil sharedUtil].nbPhoneNumberUtil getCountryCodeForRegion:countryCode]; +// NSString *countryName = [PhoneNumberUtil countryNameFromCountryCode:countryCode]; +// [self updateCountryWithName:countryName +// callingCode:[NSString stringWithFormat:@"%@%@", +// COUNTRY_CODE_PREFIX, +// callingCode] +// countryCode:countryCode]; +//} +// +//- (void)updateCountryWithName:(NSString *)countryName +// callingCode:(NSString *)callingCode +// countryCode:(NSString *)countryCode { +// OWSAssertIsOnMainThread(); +// OWSAssert(countryName.length > 0); +// OWSAssert(callingCode.length > 0); +// OWSAssert(countryCode.length > 0); +// +// _countryCode = countryCode; +// _callingCode = callingCode; +// +// NSString *title = [NSString stringWithFormat:@"%@ (%@)", +// callingCode, +// countryCode.uppercaseString]; +// self.countryCodeLabel.text = title; +// [self.countryCodeLabel setNeedsLayout]; +// +// self.examplePhoneNumberLabel.text = +// [ViewControllerUtils examplePhoneNumberForCountryCode:countryCode callingCode:callingCode]; +// [self.examplePhoneNumberLabel setNeedsLayout]; +//} +// +//#pragma mark - Actions +// +//- (void)sendCodeAction +//{ +// NSString *phoneNumberText = [_phoneNumberTextField.text ows_stripped]; +// if (phoneNumberText.length < 1) { +// [OWSAlerts +// showAlertWithTitle:NSLocalizedString(@"REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_TITLE", +// @"Title of alert indicating that users needs to enter a phone number to +// register.") +// message: +// NSLocalizedString(@"REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_MESSAGE", +// @"Message of alert indicating that users needs to enter a phone number to register.")]; +// return; +// } +// NSString *countryCode = self.countryCode; +// NSString *phoneNumber = [NSString stringWithFormat:@"%@%@", _callingCode, phoneNumberText]; +// PhoneNumber *localNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumber]; +// NSString *parsedPhoneNumber = localNumber.toE164; +// if (parsedPhoneNumber.length < 1) { +// [OWSAlerts showAlertWithTitle: +// NSLocalizedString(@"REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_TITLE", +// @"Title of alert indicating that users needs to enter a valid phone number to register.") +// message:NSLocalizedString(@"REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_MESSAGE", +// @"Message of alert indicating that users needs to enter a +// valid phone number " +// @"to register.")]; +// return; +// } +// +// [self.activateButton setEnabled:NO]; +// [self.spinnerView startAnimating]; +// [self.phoneNumberTextField resignFirstResponder]; +// +// __weak RegistrationViewController *weakSelf = self; +// [TSAccountManager registerWithPhoneNumber:parsedPhoneNumber +// success:^{ +// OWSProdInfo([OWSAnalyticsEvents registrationRegisteredPhoneNumber]); +// +// [weakSelf.spinnerView stopAnimating]; +// +// CodeVerificationViewController *vc = [CodeVerificationViewController new]; +// [weakSelf.navigationController pushViewController:vc animated:YES]; +// +//#ifdef DEBUG +// [weakSelf setLastRegisteredCountryCode:countryCode]; +// [weakSelf setLastRegisteredPhoneNumber:phoneNumberText]; +//#endif +// } +// failure:^(NSError *error) { +// 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]; +// } +// +// [weakSelf.activateButton setEnabled:YES]; +// [weakSelf.spinnerView stopAnimating]; +// [weakSelf.phoneNumberTextField becomeFirstResponder]; +// } +// smsVerification:YES]; +//} +// +//- (void)countryCodeRowWasTapped:(UIGestureRecognizer *)sender +//{ +// if (sender.state == UIGestureRecognizerStateRecognized) { +// [self changeCountryCodeTapped]; +// } +//} +// +//- (void)changeCountryCodeTapped +//{ +// CountryCodeViewController *countryCodeController = [CountryCodeViewController new]; +// countryCodeController.countryCodeDelegate = self; +// UINavigationController *navigationController = +// [[UINavigationController alloc] initWithRootViewController:countryCodeController]; +// [self presentViewController:navigationController animated:YES completion:[UIUtil modalCompletionBlock]]; +//} +// +//- (void)backgroundTapped:(UIGestureRecognizer *)sender +//{ +// if (sender.state == UIGestureRecognizerStateRecognized) { +// [self.phoneNumberTextField becomeFirstResponder]; +// } +//} +// +//#pragma mark - CountryCodeViewControllerDelegate +// +//- (void)countryCodeViewController:(CountryCodeViewController *)vc +// didSelectCountryCode:(NSString *)countryCode +// countryName:(NSString *)countryName +// callingCode:(NSString *)callingCode +//{ +// OWSAssert(countryCode.length > 0); +// OWSAssert(countryName.length > 0); +// OWSAssert(callingCode.length > 0); +// +// [self updateCountryWithName:countryName callingCode:callingCode countryCode:countryCode]; +// +// // Trigger the formatting logic with a no-op edit. +// [self textField:self.phoneNumberTextField shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""]; +//} +// +//#pragma mark - Keyboard notifications +// +//- (void)initializeKeyboardHandlers { +// UITapGestureRecognizer *outsideTabRecognizer = +// [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)]; +// [self.view addGestureRecognizer:outsideTabRecognizer]; +//} +// +//- (void)dismissKeyboardFromAppropriateSubView { +// [self.view endEditing:NO]; +//} +// +//#pragma mark - UITextFieldDelegate +// +//- (BOOL)textField:(UITextField *)textField +// shouldChangeCharactersInRange:(NSRange)range +// replacementString:(NSString *)insertionText { +// +// [ViewControllerUtils phoneNumberTextField:textField +// shouldChangeCharactersInRange:range +// replacementString:insertionText +// countryCode:_callingCode]; +// +// return NO; // inform our caller that we took care of performing the change +//} +// +//- (BOOL)textFieldShouldReturn:(UITextField *)textField { +// [self sendCodeAction]; +// [textField resignFirstResponder]; +// return NO; +//} +// +//#pragma mark - Debug +// +//#ifdef DEBUG +// +//- (NSString *_Nullable)debugValueForKey:(NSString *)key +//{ +// OWSCAssert([NSThread isMainThread]); +// OWSCAssert(key.length > 0); +// +// NSError *error; +// NSString *value = [SAMKeychain passwordForService:kKeychainService_LastRegistered account:key error:&error]; +// if (value && !error) { +// return value; +// } +// return nil; +//} +// +//- (void)setDebugValue:(NSString *)value forKey:(NSString *)key +//{ +// OWSCAssert([NSThread isMainThread]); +// OWSCAssert(key.length > 0); +// OWSCAssert(value.length > 0); +// +// NSError *error; +// [SAMKeychain setAccessibilityType:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]; +// BOOL success = [SAMKeychain setPassword:value forService:kKeychainService_LastRegistered account:key +// error:&error]; if (!success || error) { +// DDLogError(@"%@ Error persisting 'last registered' value in keychain: %@", self.logTag, error); +// } +//} +// +//- (NSString *_Nullable)lastRegisteredCountryCode +//{ +// return [self debugValueForKey:kKeychainKey_LastRegisteredCountryCode]; +//} +// +//- (void)setLastRegisteredCountryCode:(NSString *)value +//{ +// [self setDebugValue:value forKey:kKeychainKey_LastRegisteredCountryCode]; +//} +// +//- (NSString *_Nullable)lastRegisteredPhoneNumber +//{ +// return [self debugValueForKey:kKeychainKey_LastRegisteredPhoneNumber]; +//} +// +//- (void)setLastRegisteredPhoneNumber:(NSString *)value +//{ +// [self setDebugValue:value forKey:kKeychainKey_LastRegisteredPhoneNumber]; +//} +// +//#endif +// +//@end +// +// NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/OWSLinkDeviceViewController.h b/Signal/src/ViewControllers/OWSLinkDeviceViewController.h index 6529564b08..7cd3cfbf4e 100644 --- a/Signal/src/ViewControllers/OWSLinkDeviceViewController.h +++ b/Signal/src/ViewControllers/OWSLinkDeviceViewController.h @@ -1,9 +1,9 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "OWSQRCodeScanningViewController.h" -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/OWSQRCodeScanningViewController.h b/Signal/src/ViewControllers/OWSQRCodeScanningViewController.h index 33bfe3d498..2ca5919622 100644 --- a/Signal/src/ViewControllers/OWSQRCodeScanningViewController.h +++ b/Signal/src/ViewControllers/OWSQRCodeScanningViewController.h @@ -1,9 +1,9 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" #import +#import #import #import diff --git a/Signal/src/ViewControllers/OWSQRCodeScanningViewController.m b/Signal/src/ViewControllers/OWSQRCodeScanningViewController.m index d50cd8ebcf..4cd7ba3e9d 100644 --- a/Signal/src/ViewControllers/OWSQRCodeScanningViewController.m +++ b/Signal/src/ViewControllers/OWSQRCodeScanningViewController.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "OWSQRCodeScanningViewController.h" @@ -149,16 +149,6 @@ NS_ASSUME_NONNULL_BEGIN } } -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.logTag; -} - @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/PrivacySettingsTableViewController.h b/Signal/src/ViewControllers/PrivacySettingsTableViewController.h index 7912c0d892..fb04321864 100644 --- a/Signal/src/ViewControllers/PrivacySettingsTableViewController.h +++ b/Signal/src/ViewControllers/PrivacySettingsTableViewController.h @@ -1,9 +1,13 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "OWSTableViewController.h" +NS_ASSUME_NONNULL_BEGIN + @interface PrivacySettingsTableViewController : OWSTableViewController @end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/PrivacySettingsTableViewController.m b/Signal/src/ViewControllers/PrivacySettingsTableViewController.m index 4bf43c4f95..bca7f92b42 100644 --- a/Signal/src/ViewControllers/PrivacySettingsTableViewController.m +++ b/Signal/src/ViewControllers/PrivacySettingsTableViewController.m @@ -4,6 +4,7 @@ #import "PrivacySettingsTableViewController.h" #import "BlockListViewController.h" +#import "OWS2FASettingsViewController.h" #import "Signal-Swift.h" #import #import @@ -20,6 +21,10 @@ NS_ASSUME_NONNULL_BEGIN self.title = NSLocalizedString(@"SETTINGS_PRIVACY_TITLE", @""); [self updateTableContents]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self enable2FA]; + }); } - (void)viewDidAppear:(BOOL)animated @@ -128,10 +133,10 @@ NS_ASSUME_NONNULL_BEGIN [twoFactorAuthSection addItem:[OWSTableItem disclosureItemWithText: - (is2FAEnabled ? NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_ENABLE", - @"Label for the 'enable two factor auth' item of the privacy settings.") - : NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_DISABLE", - @"Label for the 'disable two factor auth' item of the privacy settings.")) + (is2FAEnabled ? NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_DISABLE", + @"Label for the 'disable two factor auth' item of the privacy settings.") + : NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_ENABLE", + @"Label for the 'enable two factor auth' item of the privacy settings.")) actionBlock:^{ if (is2FAEnabled) { [weakSelf disable2FA]; @@ -141,11 +146,7 @@ NS_ASSUME_NONNULL_BEGIN }]]; [contents addSection:twoFactorAuthSection]; - OWS2FAManager - .h - - self.contents - = contents; + self.contents = contents; } #pragma mark - Events @@ -156,7 +157,6 @@ NS_ASSUME_NONNULL_BEGIN [self.navigationController pushViewController:vc animated:YES]; } - - (void)clearHistoryLogs { UIAlertController *alertController = @@ -242,6 +242,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)enable2FA { DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + OWS2FASettingsViewController *vc = [OWS2FASettingsViewController new]; + vc.mode = Enable2FAMode_Status; + [self.navigationController pushViewController:vc animated:YES]; } - (void)disable2FA @@ -249,18 +253,6 @@ NS_ASSUME_NONNULL_BEGIN DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); } -#pragma mark - Log util - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.logTag; -} - @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/ProfileViewController.h b/Signal/src/ViewControllers/ProfileViewController.h index 506f654db6..eecb2bae31 100644 --- a/Signal/src/ViewControllers/ProfileViewController.h +++ b/Signal/src/ViewControllers/ProfileViewController.h @@ -1,12 +1,14 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // +#import + NS_ASSUME_NONNULL_BEGIN @class HomeViewController; -@interface ProfileViewController : UIViewController +@interface ProfileViewController : OWSViewController - (instancetype)init NS_UNAVAILABLE; diff --git a/Signal/src/ViewControllers/RegistrationViewController.h b/Signal/src/ViewControllers/RegistrationViewController.h index 0f2d68ddb5..32cbe803ce 100644 --- a/Signal/src/ViewControllers/RegistrationViewController.h +++ b/Signal/src/ViewControllers/RegistrationViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/UpdateGroupViewController.h b/Signal/src/ViewControllers/UpdateGroupViewController.h index 9a9e07f765..36583c805d 100644 --- a/Signal/src/ViewControllers/UpdateGroupViewController.h +++ b/Signal/src/ViewControllers/UpdateGroupViewController.h @@ -1,9 +1,9 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "OWSConversationSettingsViewDelegate.h" -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index 264b7859dd..1fb260f9e1 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -484,14 +484,4 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager }); } -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.logTag; -} - @end diff --git a/Signal/src/views/OWSBezierPathView.m b/Signal/src/views/OWSBezierPathView.m index 0155737069..323b0ed5f4 100644 --- a/Signal/src/views/OWSBezierPathView.m +++ b/Signal/src/views/OWSBezierPathView.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "OWSBezierPathView.h" @@ -93,13 +93,6 @@ NS_ASSUME_NONNULL_BEGIN [self setNeedsDisplay]; } -#pragma mark - Logging - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - @end NS_ASSUME_NONNULL_END diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 0d37bc14c9..4238636af5 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -643,6 +643,45 @@ /* No comment provided by engineer. */ "EMPTY_INBOX_TITLE" = "Squeaky Freaking Clean."; +/* Text field placeholder for 'two factor auth pin' when confirming a pin. */ +"ENABLE_2FA_VIEW_CONFIRM_PIN_DEFAULT_TEXT" = "••••••"; + +/* Indicates that user should confirm their 'two factor auth pin'. */ +"ENABLE_2FA_VIEW_CONFIRM_PIN_INSTRUCTIONS" = "Confirm your PIN."; + +/* Error indicating that attempt to disable 'two-factor auth' failed. */ +"ENABLE_2FA_VIEW_COULD_NOT_DISABLE_2FA" = "Could not disable two-step verification."; + +/* Error indicating that attempt to enable 'two-factor auth' failed. */ +"ENABLE_2FA_VIEW_COULD_NOT_ENABLE_2FA" = "Could not enable two-step verification."; + +/* Label for the 'enable two-factor auth' item in the settings view */ +"ENABLE_2FA_VIEW_DISABLE_2FA" = "Disable"; + +/* Label for the 'enable two-factor auth' item in the settings view */ +"ENABLE_2FA_VIEW_ENABLE_2FA" = "Enable"; + +/* Label for the 'next' button in the 'enable two factor auth' views. */ +"ENABLE_2FA_VIEW_NEXT_BUTTON" = "Next"; + +/* Error indicating that the entered 'two-factor auth PINs' do not match. */ +"ENABLE_2FA_VIEW_PIN_DOES_NOT_MATCH" = "Pin does not match."; + +/* Text field placeholder for 'two factor auth pin' when selecting a pin. */ +"ENABLE_2FA_VIEW_SELECT_PIN_DEFAULT_TEXT" = "******"; + +/* Indicates that user should select a 'two factor auth pin'. */ +"ENABLE_2FA_VIEW_SELECT_PIN_INSTRUCTIONS" = "Enter a PIN which you'll be asked for when you register your phone number with Signal. Your PIN must have at least 4 digits."; + +/* Indicates that user has 'two factor auth pin' disabled. */ +"ENABLE_2FA_VIEW_STATUS_DISABLED_INSTRUCTIONS" = "For added security, enable two-step verification, which will require a PIN when registering your phone number with Signal again."; + +/* Indicates that user has 'two factor auth pin' enabled. */ +"ENABLE_2FA_VIEW_STATUS_ENABLED_INSTRUCTIONS" = "Two-step verification is enabled. You'll need to enter your PIN when registering your phone number with Signal again."; + +/* Title for the 'enable two factor auth PIN' views. */ +"ENABLE_2FA_VIEW_TITLE" = "Two-Step Verification"; + /* Call setup status label */ "END_CALL_RESPONDER_IS_BUSY" = "Busy."; @@ -1359,7 +1398,9 @@ /* Label for the country code field */ "REGISTRATION_DEFAULT_COUNTRY_NAME" = "Country Code"; -/* Placeholder text for the phone number textfield */ +/* Placeholder text +// for the phone number textfield + Placeholder text for the phone number textfield */ "REGISTRATION_ENTERNUMBER_DEFAULT_TEXT" = "Enter Number"; /* No comment provided by engineer. */ @@ -1389,7 +1430,9 @@ /* No comment provided by engineer. */ "REGISTRATION_VERIFY_DEVICE" = "Activate This Device"; -/* Message of alert indicating that users needs to enter a valid phone number to register. */ +/* Message of alert indicating that users needs to enter a +// valid phone number to register. + Message of alert indicating that users needs to enter a valid phone number to register. */ "REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_MESSAGE" = "Please enter a valid phone number to register."; /* Title of alert indicating that users needs to enter a valid phone number to register. */ @@ -1398,7 +1441,9 @@ /* Message of alert indicating that users needs to enter a phone number to register. */ "REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_MESSAGE" = "Please enter a phone number to register."; -/* Title of alert indicating that users needs to enter a phone number to register. */ +/* Title of alert indicating that users needs to enter a phone number to +// register. + Title of alert indicating that users needs to enter a phone number to register. */ "REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_TITLE" = "No Phone Number"; /* No comment provided by engineer. */ @@ -1623,6 +1668,15 @@ /* No comment provided by engineer. */ "SETTINGS_SUPPORT" = "Support"; +/* Label for the 'disable two factor auth' item of the privacy settings. */ +"SETTINGS_TWO_FACTOR_AUTH_DISABLE" = "Disable Two-Step Verification"; + +/* Label for the 'enable two factor auth' item of the privacy settings. */ +"SETTINGS_TWO_FACTOR_AUTH_ENABLE" = "Enable Two-Step Verification"; + +/* Title for the 'two factor auth' section of the privacy settings. */ +"SETTINGS_TWO_FACTOR_AUTH_TITLE" = "Two-Step Verification"; + /* No comment provided by engineer. */ "SETTINGS_VERSION" = "Version"; diff --git a/SignalMessaging/ViewControllers/OWSTableViewController.h b/SignalMessaging/ViewControllers/OWSTableViewController.h index e086cd2bdf..85d8b31dc9 100644 --- a/SignalMessaging/ViewControllers/OWSTableViewController.h +++ b/SignalMessaging/ViewControllers/OWSTableViewController.h @@ -2,7 +2,7 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalMessaging/ViewControllers/OWSViewController.m b/SignalMessaging/ViewControllers/OWSViewController.m index 08686ff0e1..21074f6d6f 100644 --- a/SignalMessaging/ViewControllers/OWSViewController.m +++ b/SignalMessaging/ViewControllers/OWSViewController.m @@ -1,9 +1,9 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" #import "UIView+OWS.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalMessaging/contacts/SelectRecipientViewController.h b/SignalMessaging/contacts/SelectRecipientViewController.h index f6a69d8af1..7619cf38f8 100644 --- a/SignalMessaging/contacts/SelectRecipientViewController.h +++ b/SignalMessaging/contacts/SelectRecipientViewController.h @@ -2,7 +2,7 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalMessaging/contacts/SelectThreadViewController.h b/SignalMessaging/contacts/SelectThreadViewController.h index f2b11da7f7..cfa3da58dc 100644 --- a/SignalMessaging/contacts/SelectThreadViewController.h +++ b/SignalMessaging/contacts/SelectThreadViewController.h @@ -1,8 +1,8 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSViewController.h" +#import @class TSThread; diff --git a/SignalMessaging/utils/OWSPreferences.m b/SignalMessaging/utils/OWSPreferences.m index afdda83948..b31a95582e 100644 --- a/SignalMessaging/utils/OWSPreferences.m +++ b/SignalMessaging/utils/OWSPreferences.m @@ -381,23 +381,11 @@ NSString *const OWSPreferencesKeySystemCallLogEnabled = @"OWSPreferencesKeySyste - (void)unsetRecordedAPNSTokens { - DDLogWarn(@"%@ Forgetting recorded APNS tokens", self.tag); + DDLogWarn(@"%@ Forgetting recorded APNS tokens", self.logTag); [self setValueForKey:OWSPreferencesKeyLastRecordedPushToken toValue:nil]; [self setValueForKey:OWSPreferencesKeyLastRecordedVoipToken toValue:nil]; } -#pragma mark - Logging - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.tag; -} - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m index 0f167a5923..73f8d32418 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m @@ -215,18 +215,6 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo [storage asyncRegisterExtension:[self databaseExtension] withName:OWSMessageContentJobFinderExtensionName]; } -#pragma mark Logging - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.logTag; -} - @end #pragma mark - Queue Processing @@ -365,18 +353,6 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo }]; } -#pragma mark Logging - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.logTag; -} - @end #pragma mark - OWSBatchMessageProcessor diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver.m b/SignalServiceKit/src/Messages/OWSMessageReceiver.m index a5de760182..874e42043f 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.m +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.m @@ -339,18 +339,6 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin }]; } -#pragma mark Logging - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.logTag; -} - @end #pragma mark - OWSMessageReceiver diff --git a/SignalServiceKit/src/Security/OWSFingerprint.m b/SignalServiceKit/src/Security/OWSFingerprint.m index 25cffb6938..50e2c79c98 100644 --- a/SignalServiceKit/src/Security/OWSFingerprint.m +++ b/SignalServiceKit/src/Security/OWSFingerprint.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "OWSFingerprint.h" @@ -309,16 +309,6 @@ static uint32_t const OWSFingerprintDefaultHashIterations = 5200; return qrImage; } -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.logTag; -} - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Storage/AxolotlStore/TSStorageManager+PreKeyStore.m b/SignalServiceKit/src/Storage/AxolotlStore/TSStorageManager+PreKeyStore.m index dca61472bb..ba9a3e5ed8 100644 --- a/SignalServiceKit/src/Storage/AxolotlStore/TSStorageManager+PreKeyStore.m +++ b/SignalServiceKit/src/Storage/AxolotlStore/TSStorageManager+PreKeyStore.m @@ -101,16 +101,4 @@ return lastPreKeyId; } -#pragma mark - Logging - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@+PreKeyStore]", self.class]; -} - -- (NSString *)tag -{ - return self.class.logTag; -} - @end diff --git a/SignalServiceKit/src/Util/OWS2FAManager.h b/SignalServiceKit/src/Util/OWS2FAManager.h index 283e78e55c..71f15db86a 100644 --- a/SignalServiceKit/src/Util/OWS2FAManager.h +++ b/SignalServiceKit/src/Util/OWS2FAManager.h @@ -16,9 +16,11 @@ typedef void (^OWS2FAFailure)(NSError *error); - (BOOL)is2FAEnabled; -- (void)enable2FAWithPin:(NSString *)pin success:(OWS2FASuccess)success failure:(OWS2FAFailure)failure; +- (void)enable2FAWithPin:(NSString *)pin + success:(nullable OWS2FASuccess)success + failure:(nullable OWS2FAFailure)failure; -- (void)disable2FAWithSuccess:(OWS2FASuccess)success failure:(OWS2FAFailure)failure; +- (void)disable2FAWithSuccess:(nullable OWS2FASuccess)success failure:(nullable OWS2FAFailure)failure; @end diff --git a/SignalServiceKit/src/Util/OWS2FAManager.m b/SignalServiceKit/src/Util/OWS2FAManager.m index 0061b81fb3..1be41697cd 100644 --- a/SignalServiceKit/src/Util/OWS2FAManager.m +++ b/SignalServiceKit/src/Util/OWS2FAManager.m @@ -69,7 +69,12 @@ NSString *const kOWS2FAManager_IsEnabledKey = @"kOWS2FAManager_IsEnabledKey"; defaultValue:NO]; } -- (void)enable2FAWithPin:(NSString *)pin success:(OWS2FASuccess)success failure:(OWS2FAFailure)failure +- (void)setIs2FAEnabled:(BOOL)value +{ + [self.dbConnection setBool:value forKey:kOWS2FAManager_IsEnabledKey inCollection:kOWS2FAManager_Collection]; +} + +- (void)enable2FAWithPin:(NSString *)pin success:(nullable OWS2FASuccess)success failure:(nullable OWS2FAFailure)failure { OWSAssert(pin.length > 0); OWSAssert(success); @@ -78,25 +83,42 @@ NSString *const kOWS2FAManager_IsEnabledKey = @"kOWS2FAManager_IsEnabledKey"; TSRequest *request = [OWSRequestFactory enable2FARequestWithPin:pin]; [self.networkManager makeRequest:request success:^(NSURLSessionDataTask *task, id responseObject) { - success(); + OWSAssertIsOnMainThread(); + + [self setIs2FAEnabled:YES]; + + if (success) { + success(); + } } failure:^(NSURLSessionDataTask *task, NSError *error) { - failure(error); + OWSAssertIsOnMainThread(); + + if (failure) { + failure(error); + } }]; } -- (void)disable2FAWithSuccess:(OWS2FASuccess)success failure:(OWS2FAFailure)failure +- (void)disable2FAWithSuccess:(nullable OWS2FASuccess)success failure:(nullable OWS2FAFailure)failure { - OWSAssert(success); - OWSAssert(failure); - TSRequest *request = [OWSRequestFactory disable2FARequest]; [self.networkManager makeRequest:request success:^(NSURLSessionDataTask *task, id responseObject) { - success(); + OWSAssertIsOnMainThread(); + + [self setIs2FAEnabled:NO]; + + if (success) { + success(); + } } failure:^(NSURLSessionDataTask *task, NSError *error) { - failure(error); + OWSAssertIsOnMainThread(); + + if (failure) { + failure(error); + } }]; } From ea783a8ad5e04ff47d77a9995f7c8cd38c282d9b Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Feb 2018 22:26:52 -0500 Subject: [PATCH 3/9] Work on two-factor auth settings UI. --- .../OWS2FASettingsViewController.h | 6 +- .../OWS2FASettingsViewController.m | 68 +++++++++++++------ .../PrivacySettingsTableViewController.m | 38 +++++------ .../translations/en.lproj/Localizable.strings | 11 +-- 4 files changed, 73 insertions(+), 50 deletions(-) diff --git a/Signal/src/ViewControllers/OWS2FASettingsViewController.h b/Signal/src/ViewControllers/OWS2FASettingsViewController.h index 12c21d3ab9..c5afc92ee3 100644 --- a/Signal/src/ViewControllers/OWS2FASettingsViewController.h +++ b/Signal/src/ViewControllers/OWS2FASettingsViewController.h @@ -7,9 +7,9 @@ NS_ASSUME_NONNULL_BEGIN typedef NS_ENUM(NSUInteger, Enable2FAMode) { - Enable2FAMode_Status = 0, - Enable2FAMode_SelectPIN, - Enable2FAMode_ConfirmPIN, + OWS2FASettingsMode_Status = 0, + OWS2FASettingsMode_SelectPIN, + OWS2FASettingsMode_ConfirmPIN, }; @interface OWS2FASettingsViewController : OWSViewController diff --git a/Signal/src/ViewControllers/OWS2FASettingsViewController.m b/Signal/src/ViewControllers/OWS2FASettingsViewController.m index c98070f043..975afb7f71 100644 --- a/Signal/src/ViewControllers/OWS2FASettingsViewController.m +++ b/Signal/src/ViewControllers/OWS2FASettingsViewController.m @@ -37,14 +37,23 @@ NS_ASSUME_NONNULL_BEGIN self.title = NSLocalizedString(@"ENABLE_2FA_VIEW_TITLE", @"Title for the 'enable two factor auth PIN' views."); + [self createContents]; +} + +- (void)createContents +{ + for (UIView *subview in self.view.subviews) { + [subview removeFromSuperview]; + } + switch (self.mode) { - case Enable2FAMode_Status: + case OWS2FASettingsMode_Status: [self createStatusContents]; break; - case Enable2FAMode_SelectPIN: + case OWS2FASettingsMode_SelectPIN: [self createSelectCodeContents]; break; - case Enable2FAMode_ConfirmPIN: + case OWS2FASettingsMode_ConfirmPIN: [self createConfirmCodeContents]; break; } @@ -52,10 +61,26 @@ NS_ASSUME_NONNULL_BEGIN - (void)viewWillAppear:(BOOL)animated { + switch (self.mode) { + case OWS2FASettingsMode_Status: + break; + case OWS2FASettingsMode_SelectPIN: + case OWS2FASettingsMode_ConfirmPIN: + OWSAssert(![OWS2FAManager.sharedManager is2FAEnabled]); + break; + } + [super viewWillAppear:animated]; - // If we're using a table, refresh its contents. - [self updateTableContents]; + if (self.mode == OWS2FASettingsMode_Status) { + // Ever time we re-enter the "status" view, recreate its + // contents wholesale since we may have just enabled or + // disabled 2FA. + [self createContents]; + } else { + // If we're using a table, refresh its contents. + [self updateTableContents]; + } [self updateNavigationItems]; } @@ -86,15 +111,15 @@ NS_ASSUME_NONNULL_BEGIN self.pinTextfield = [UITextField new]; self.pinTextfield.textColor = [UIColor blackColor]; switch (self.mode) { - case Enable2FAMode_SelectPIN: + case OWS2FASettingsMode_SelectPIN: self.pinTextfield.placeholder = NSLocalizedString(@"ENABLE_2FA_VIEW_SELECT_PIN_DEFAULT_TEXT", @"Text field placeholder for 'two factor auth pin' when selecting a pin."); break; - case Enable2FAMode_ConfirmPIN: + case OWS2FASettingsMode_ConfirmPIN: self.pinTextfield.placeholder = NSLocalizedString(@"ENABLE_2FA_VIEW_CONFIRM_PIN_DEFAULT_TEXT", @"Text field placeholder for 'two factor auth pin' when confirming a pin."); break; - case Enable2FAMode_Status: + case OWS2FASettingsMode_Status: OWSFail(@"%@ invalid mode.", self.logTag) break; } self.pinTextfield.font = [UIFont ows_mediumFontWithSize:ScaleFromIPhone5To7Plus(30.f, 36.f)]; @@ -198,7 +223,7 @@ NS_ASSUME_NONNULL_BEGIN // Only some modes use a table. switch (self.mode) { - case Enable2FAMode_Status: { + case OWS2FASettingsMode_Status: { OWSTableContents *contents = [OWSTableContents new]; OWSTableSection *section = [OWSTableSection new]; if ([OWS2FAManager.sharedManager is2FAEnabled]) { @@ -222,8 +247,8 @@ NS_ASSUME_NONNULL_BEGIN self.tableViewController.contents = contents; break; } - case Enable2FAMode_SelectPIN: - case Enable2FAMode_ConfirmPIN: + case OWS2FASettingsMode_SelectPIN: + case OWS2FASettingsMode_ConfirmPIN: return; } } @@ -231,10 +256,10 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)shouldHaveNextButton { switch (self.mode) { - case Enable2FAMode_Status: + case OWS2FASettingsMode_Status: return NO; - case Enable2FAMode_SelectPIN: - case Enable2FAMode_ConfirmPIN: + case OWS2FASettingsMode_SelectPIN: + case OWS2FASettingsMode_ConfirmPIN: return [self hasValidPin]; } } @@ -325,20 +350,21 @@ NS_ASSUME_NONNULL_BEGIN DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); switch (self.mode) { - case Enable2FAMode_Status: + case OWS2FASettingsMode_Status: OWSFail(@"%@ status mode should not have a next button.", self.logTag); return; - case Enable2FAMode_SelectPIN: { + case OWS2FASettingsMode_SelectPIN: { OWSAssert(self.hasValidPin); OWS2FASettingsViewController *vc = [OWS2FASettingsViewController new]; - vc.mode = Enable2FAMode_ConfirmPIN; + vc.mode = OWS2FASettingsMode_ConfirmPIN; vc.candidatePin = self.pinTextfield.text; - vc.root2FAViewController = self; + OWSAssert(self.root2FAViewController); + vc.root2FAViewController = self.root2FAViewController; [self.navigationController pushViewController:vc animated:YES]; break; } - case Enable2FAMode_ConfirmPIN: { + case OWS2FASettingsMode_ConfirmPIN: { OWSAssert(self.hasValidPin); if ([self.pinTextfield.text isEqualToString:self.candidatePin]) { @@ -370,7 +396,7 @@ NS_ASSUME_NONNULL_BEGIN DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); OWS2FASettingsViewController *vc = [OWS2FASettingsViewController new]; - vc.mode = Enable2FAMode_SelectPIN; + vc.mode = OWS2FASettingsMode_SelectPIN; vc.root2FAViewController = self; [self.navigationController pushViewController:vc animated:YES]; } @@ -394,7 +420,7 @@ NS_ASSUME_NONNULL_BEGIN } failure:^(NSError *error) { [modalActivityIndicator dismissWithCompletion:^{ - [weakSelf updateTableContents]; + [weakSelf createContents]; [OWSAlerts showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"") diff --git a/Signal/src/ViewControllers/PrivacySettingsTableViewController.m b/Signal/src/ViewControllers/PrivacySettingsTableViewController.m index bca7f92b42..848bd6dcf6 100644 --- a/Signal/src/ViewControllers/PrivacySettingsTableViewController.m +++ b/Signal/src/ViewControllers/PrivacySettingsTableViewController.m @@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN [self updateTableContents]; dispatch_async(dispatch_get_main_queue(), ^{ - [self enable2FA]; + [self show2FASettings]; }); } @@ -129,21 +129,20 @@ NS_ASSUME_NONNULL_BEGIN OWSTableSection *twoFactorAuthSection = [OWSTableSection new]; twoFactorAuthSection.headerTitle = NSLocalizedString( @"SETTINGS_TWO_FACTOR_AUTH_TITLE", @"Title for the 'two factor auth' section of the privacy settings."); - BOOL is2FAEnabled = [OWS2FAManager.sharedManager is2FAEnabled]; [twoFactorAuthSection - addItem:[OWSTableItem - disclosureItemWithText: - (is2FAEnabled ? NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_DISABLE", - @"Label for the 'disable two factor auth' item of the privacy settings.") - : NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_ENABLE", - @"Label for the 'enable two factor auth' item of the privacy settings.")) - actionBlock:^{ - if (is2FAEnabled) { - [weakSelf disable2FA]; - } else { - [weakSelf enable2FA]; - } - }]]; + addItem: + [OWSTableItem + disclosureItemWithText:NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_ITEM", + @"Label for the 'two factor auth' item of the privacy settings.") + detailText: + ([OWS2FAManager.sharedManager is2FAEnabled] + ? NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_ENABLED", + @"Indicates that 'two factor auth' is enabled in the privacy settings.") + : NSLocalizedString(@"SETTINGS_TWO_FACTOR_AUTH_DISABLED", + @"Indicates that 'two factor auth' is disabled in the privacy settings.")) + actionBlock:^{ + [weakSelf show2FASettings]; + }]]; [contents addSection:twoFactorAuthSection]; self.contents = contents; @@ -239,20 +238,15 @@ NS_ASSUME_NONNULL_BEGIN [SignalApp.sharedApp.callService createCallUIAdapter]; } -- (void)enable2FA +- (void)show2FASettings { DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); OWS2FASettingsViewController *vc = [OWS2FASettingsViewController new]; - vc.mode = Enable2FAMode_Status; + vc.mode = OWS2FASettingsMode_Status; [self.navigationController pushViewController:vc animated:YES]; } -- (void)disable2FA -{ - DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); -} - @end NS_ASSUME_NONNULL_END diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 4238636af5..accbacd1c1 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1668,11 +1668,14 @@ /* No comment provided by engineer. */ "SETTINGS_SUPPORT" = "Support"; -/* Label for the 'disable two factor auth' item of the privacy settings. */ -"SETTINGS_TWO_FACTOR_AUTH_DISABLE" = "Disable Two-Step Verification"; +/* Indicates that 'two factor auth' is disabled in the privacy settings. */ +"SETTINGS_TWO_FACTOR_AUTH_DISABLED" = "Disabled"; -/* Label for the 'enable two factor auth' item of the privacy settings. */ -"SETTINGS_TWO_FACTOR_AUTH_ENABLE" = "Enable Two-Step Verification"; +/* Indicates that 'two factor auth' is enabled in the privacy settings. */ +"SETTINGS_TWO_FACTOR_AUTH_ENABLED" = "Enabled"; + +/* Label for the 'two factor auth' item of the privacy settings. */ +"SETTINGS_TWO_FACTOR_AUTH_ITEM" = "Two-Step Verification"; /* Title for the 'two factor auth' section of the privacy settings. */ "SETTINGS_TWO_FACTOR_AUTH_TITLE" = "Two-Step Verification"; From 4afedac68cd68857889c883f6e5126cd93f540fd Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Feb 2018 22:34:29 -0500 Subject: [PATCH 4/9] Clean up ahead of PR. --- .../AppSettingsViewController.m | 4 - .../src/ViewControllers/HomeViewController.m | 4 - .../OWS2FASettingsViewController.m | 484 ------------------ .../PrivacySettingsTableViewController.m | 4 - .../translations/en.lproj/Localizable.strings | 12 +- SignalServiceKit/src/TSConstants.h | 21 +- 6 files changed, 13 insertions(+), 516 deletions(-) diff --git a/Signal/src/ViewControllers/AppSettingsViewController.m b/Signal/src/ViewControllers/AppSettingsViewController.m index 9093870fa8..b7fee9fa26 100644 --- a/Signal/src/ViewControllers/AppSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettingsViewController.m @@ -89,10 +89,6 @@ self.title = NSLocalizedString(@"SETTINGS_NAV_BAR_TITLE", @"Title for settings activity"); [self updateTableContents]; - - dispatch_async(dispatch_get_main_queue(), ^{ - [self showPrivacy]; - }); } - (void)viewWillAppear:(BOOL)animated diff --git a/Signal/src/ViewControllers/HomeViewController.m b/Signal/src/ViewControllers/HomeViewController.m index 5741693fda..0943158d2e 100644 --- a/Signal/src/ViewControllers/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeViewController.m @@ -285,10 +285,6 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState }; } [self updateBarButtonItems]; - - dispatch_async(dispatch_get_main_queue(), ^{ - [self settingsButtonPressed:nil]; - }); } - (void)updateBarButtonItems diff --git a/Signal/src/ViewControllers/OWS2FASettingsViewController.m b/Signal/src/ViewControllers/OWS2FASettingsViewController.m index 975afb7f71..611d7d5af8 100644 --- a/Signal/src/ViewControllers/OWS2FASettingsViewController.m +++ b/Signal/src/ViewControllers/OWS2FASettingsViewController.m @@ -198,11 +198,8 @@ NS_ASSUME_NONNULL_BEGIN [instructionsLabel autoPinTopToSuperviewWithMargin:kVSpacing]; [instructionsLabel autoPinWidthToSuperviewWithMargin:self.hMargin]; - // CGFloat textFieldWidth = [self.pinTextfield sizeThatFits:CGSizeZero].width + 10.f; - [self.pinTextfield autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:instructionsLabel withOffset:kVSpacing]; [self.pinTextfield autoPinWidthToSuperviewWithMargin:self.hMargin]; - // [self.pinTextfield autoSetDimension:ALDimensionWidth toSize:textFieldWidth]; [self.pinTextfield autoHCenterInSuperview]; UIView *underscoreView = [UIView new]; @@ -338,8 +335,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)textFieldDidChange:(id)sender { - DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); - [self updateNavigationItems]; } @@ -347,8 +342,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)nextButtonWasPressed { - DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); - switch (self.mode) { case OWS2FASettingsMode_Status: OWSFail(@"%@ status mode should not have a next button.", self.logTag); @@ -487,480 +480,3 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END - -//#import "RegistrationViewController.h" -//#import "CodeVerificationViewController.h" -//#import "CountryCodeViewController.h" -//#import "PhoneNumber.h" -//#import "PhoneNumberUtil.h" -//#import "Signal-Swift.h" -//#import "TSAccountManager.h" -//#import "UIView+OWS.h" -//#import "ViewControllerUtils.h" -//#import -//#import -//#import -// -// NS_ASSUME_NONNULL_BEGIN -// -//#ifdef DEBUG -// -// NSString *const kKeychainService_LastRegistered = @"kKeychainService_LastRegistered"; -// NSString *const kKeychainKey_LastRegisteredCountryCode = @"kKeychainKey_LastRegisteredCountryCode"; -// NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegisteredPhoneNumber"; -// -//#endif -// -//@interface RegistrationViewController () -// -//@property (nonatomic) NSString *countryCode; -//@property (nonatomic) NSString *callingCode; -// -//@property (nonatomic) UILabel *countryCodeLabel; -//@property (nonatomic) UITextField *phoneNumberTextField; -//@property (nonatomic) UILabel *examplePhoneNumberLabel; -//@property (nonatomic) OWSFlatButton *activateButton; -//@property (nonatomic) UIActivityIndicatorView *spinnerView; -// -//@end -// -//#pragma mark - -// -//@implementation RegistrationViewController -// -//- (void)loadView -//{ -// [super loadView]; -// -// [self createViews]; -// -// // Do any additional setup after loading the view. -// [self populateDefaultCountryNameAndCode]; -// [SignalApp.sharedApp setSignUpFlowNavigationController:self.navigationController]; -//} -// -//- (void)viewDidLoad { -// [super viewDidLoad]; -// -// OWSProdInfo([OWSAnalyticsEvents registrationBegan]); -//} -// -//- (void)createViews -//{ -// self.view.backgroundColor = [UIColor whiteColor]; -// self.view.userInteractionEnabled = YES; -// [self.view -// addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTapped:)]]; -// -// UIView *headerWrapper = [UIView containerView]; -// [self.view addSubview:headerWrapper]; -// headerWrapper.backgroundColor = UIColor.ows_signalBrandBlueColor; -// -// UIView *headerContent = [UIView new]; -// [headerWrapper addSubview:headerContent]; -// [headerWrapper autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero excludingEdge:ALEdgeBottom]; -// [headerContent autoPinEdgeToSuperviewEdge:ALEdgeBottom]; -// [headerContent autoPinToTopLayoutGuideOfViewController:self withInset:0]; -// [headerContent autoPinWidthToSuperview]; -// -// UILabel *headerLabel = [UILabel new]; -// headerLabel.text = NSLocalizedString(@"REGISTRATION_TITLE_LABEL", @""); -// headerLabel.textColor = [UIColor whiteColor]; -// headerLabel.font = [UIFont ows_mediumFontWithSize:ScaleFromIPhone5To7Plus(20.f, 24.f)]; -// [headerContent addSubview:headerLabel]; -// [headerLabel autoHCenterInSuperview]; -// [headerLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:14.f]; -// -// CGFloat screenHeight = MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); -// if (screenHeight < 568) { -// // iPhone 4s or smaller. -// [headerContent autoSetDimension:ALDimensionHeight toSize:20]; -// headerLabel.hidden = YES; -// } else if (screenHeight < 667) { -// // iPhone 5 or smaller. -// [headerContent autoSetDimension:ALDimensionHeight toSize:80]; -// } else { -// [headerContent autoSetDimension:ALDimensionHeight toSize:220]; -// -// UIImage *logo = [UIImage imageNamed:@"logoSignal"]; -// OWSAssert(logo); -// UIImageView *logoView = [UIImageView new]; -// logoView.image = logo; -// [headerContent addSubview:logoView]; -// [logoView autoHCenterInSuperview]; -// [logoView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:headerLabel withOffset:-14.f]; -// } -// -// const CGFloat kRowHeight = 60.f; -// const CGFloat kRowHMargin = 20.f; -// const CGFloat kSeparatorHeight = 1.f; -// const CGFloat kExamplePhoneNumberVSpacing = 8.f; -// const CGFloat fontSizePoints = ScaleFromIPhone5To7Plus(16.f, 20.f); -// -// UIView *contentView = [UIView containerView]; -// [contentView setHLayoutMargins:kRowHMargin]; -// contentView.backgroundColor = [UIColor whiteColor]; -// [self.view addSubview:contentView]; -// [contentView autoPinToBottomLayoutGuideOfViewController:self withInset:0]; -// [contentView autoPinWidthToSuperview]; -// [contentView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:headerContent]; -// -// // Country -// UIView *countryRow = [UIView containerView]; -// [contentView addSubview:countryRow]; -// [countryRow autoPinLeadingAndTrailingToSuperview]; -// [countryRow autoPinEdgeToSuperviewEdge:ALEdgeTop]; -// [countryRow autoSetDimension:ALDimensionHeight toSize:kRowHeight]; -// [countryRow -// addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self -// action:@selector(countryCodeRowWasTapped:)]]; -// -// UILabel *countryNameLabel = [UILabel new]; -// countryNameLabel.text -// = NSLocalizedString(@"REGISTRATION_DEFAULT_COUNTRY_NAME", @"Label for the country code field"); -// countryNameLabel.textColor = [UIColor blackColor]; -// countryNameLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints]; -// [countryRow addSubview:countryNameLabel]; -// [countryNameLabel autoVCenterInSuperview]; -// [countryNameLabel autoPinLeadingToSuperview]; -// -// UILabel *countryCodeLabel = [UILabel new]; -// self.countryCodeLabel = countryCodeLabel; -// countryCodeLabel.textColor = [UIColor ows_materialBlueColor]; -// countryCodeLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints + 2.f]; -// [countryRow addSubview:countryCodeLabel]; -// [countryCodeLabel autoVCenterInSuperview]; -// [countryCodeLabel autoPinTrailingToSuperview]; -// -// UIView *separatorView1 = [UIView new]; -// separatorView1.backgroundColor = [UIColor colorWithWhite:0.75f alpha:1.f]; -// [contentView addSubview:separatorView1]; -// [separatorView1 autoPinWidthToSuperview]; -// [separatorView1 autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:countryRow]; -// [separatorView1 autoSetDimension:ALDimensionHeight toSize:kSeparatorHeight]; -// -// // Phone Number -// UIView *phoneNumberRow = [UIView containerView]; -// [contentView addSubview:phoneNumberRow]; -// [phoneNumberRow autoPinLeadingAndTrailingToSuperview]; -// [phoneNumberRow autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:separatorView1]; -// [phoneNumberRow autoSetDimension:ALDimensionHeight toSize:kRowHeight]; -// -// UILabel *phoneNumberLabel = [UILabel new]; -// phoneNumberLabel.text -// = NSLocalizedString(@"REGISTRATION_PHONENUMBER_BUTTON", @"Label for the phone number textfield"); -// phoneNumberLabel.textColor = [UIColor blackColor]; -// phoneNumberLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints]; -// [phoneNumberRow addSubview:phoneNumberLabel]; -// [phoneNumberLabel autoVCenterInSuperview]; -// [phoneNumberLabel autoPinLeadingToSuperview]; -// -// UITextField *phoneNumberTextField = [UITextField new]; -// phoneNumberTextField.textAlignment = NSTextAlignmentRight; -// phoneNumberTextField.delegate = self; -// phoneNumberTextField.keyboardType = UIKeyboardTypeNumberPad; -// phoneNumberTextField.placeholder = NSLocalizedString( -// @"REGISTRATION_ENTERNUMBER_DEFAULT_TEXT", @"Placeholder text -// for the phone number textfield"); -// self.phoneNumberTextField = phoneNumberTextField; -// phoneNumberTextField.textColor = [UIColor ows_materialBlueColor]; -// phoneNumberTextField.font = [UIFont ows_mediumFontWithSize:fontSizePoints + 2]; -// [phoneNumberRow addSubview:phoneNumberTextField]; -// [phoneNumberTextField autoVCenterInSuperview]; -// [phoneNumberTextField autoPinTrailingToSuperview]; -// -// UILabel *examplePhoneNumberLabel = [UILabel new]; -// self.examplePhoneNumberLabel = examplePhoneNumberLabel; -// examplePhoneNumberLabel.font = [UIFont ows_regularFontWithSize:fontSizePoints - 2.f]; -// examplePhoneNumberLabel.textColor = [UIColor colorWithWhite:0.5f alpha:1.f]; -// [contentView addSubview:examplePhoneNumberLabel]; -// [examplePhoneNumberLabel autoPinTrailingToSuperview]; -// [examplePhoneNumberLabel autoPinEdge:ALEdgeTop -// toEdge:ALEdgeBottom -// ofView:phoneNumberTextField -// withOffset:kExamplePhoneNumberVSpacing]; -// -// UIView *separatorView2 = [UIView new]; -// separatorView2.backgroundColor = [UIColor colorWithWhite:0.75f alpha:1.f]; -// [contentView addSubview:separatorView2]; -// [separatorView2 autoPinWidthToSuperview]; -// [separatorView2 autoPinEdge:ALEdgeTop -// toEdge:ALEdgeBottom -// ofView:phoneNumberRow -// withOffset:examplePhoneNumberLabel.font.lineHeight]; -// [separatorView2 autoSetDimension:ALDimensionHeight toSize:kSeparatorHeight]; -// -// // Activate Button -// const CGFloat kActivateButtonHeight = 47.f; -// // NOTE: We use ows_signalBrandBlueColor instead of ows_materialBlueColor -// // throughout the onboarding flow to be consistent with the headers. -// OWSFlatButton *activateButton = [OWSFlatButton buttonWithTitle:NSLocalizedString(@"REGISTRATION_VERIFY_DEVICE", -// @"") -// font:[OWSFlatButton fontForHeight:kActivateButtonHeight] -// titleColor:[UIColor whiteColor] -// backgroundColor:[UIColor ows_signalBrandBlueColor] -// target:self -// selector:@selector(sendCodeAction)]; -// self.activateButton = activateButton; -// [contentView addSubview:activateButton]; -// [activateButton autoPinLeadingAndTrailingToSuperview]; -// [activateButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:separatorView2 withOffset:15]; -// [activateButton autoSetDimension:ALDimensionHeight toSize:kActivateButtonHeight]; -// -// UIActivityIndicatorView *spinnerView = -// [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; -// self.spinnerView = spinnerView; -// [activateButton addSubview:spinnerView]; -// [spinnerView autoVCenterInSuperview]; -// [spinnerView autoSetDimension:ALDimensionWidth toSize:20.f]; -// [spinnerView autoSetDimension:ALDimensionHeight toSize:20.f]; -// [spinnerView autoPinTrailingToSuperviewWithMargin:20.f]; -// [spinnerView stopAnimating]; -//} -// -//- (void)viewDidAppear:(BOOL)animated { -// [super viewDidAppear:animated]; -// -// [self.activateButton setEnabled:YES]; -// [self.spinnerView stopAnimating]; -// [self.phoneNumberTextField becomeFirstResponder]; -//} -// -//#pragma mark - Country -// -//- (void)populateDefaultCountryNameAndCode { -// NSString *countryCode = [PhoneNumber defaultCountryCode]; -// -//#ifdef DEBUG -// if ([self lastRegisteredCountryCode].length > 0) { -// countryCode = [self lastRegisteredCountryCode]; -// } -// self.phoneNumberTextField.text = [self lastRegisteredPhoneNumber]; -//#endif -// -// NSNumber *callingCode = [[PhoneNumberUtil sharedUtil].nbPhoneNumberUtil getCountryCodeForRegion:countryCode]; -// NSString *countryName = [PhoneNumberUtil countryNameFromCountryCode:countryCode]; -// [self updateCountryWithName:countryName -// callingCode:[NSString stringWithFormat:@"%@%@", -// COUNTRY_CODE_PREFIX, -// callingCode] -// countryCode:countryCode]; -//} -// -//- (void)updateCountryWithName:(NSString *)countryName -// callingCode:(NSString *)callingCode -// countryCode:(NSString *)countryCode { -// OWSAssertIsOnMainThread(); -// OWSAssert(countryName.length > 0); -// OWSAssert(callingCode.length > 0); -// OWSAssert(countryCode.length > 0); -// -// _countryCode = countryCode; -// _callingCode = callingCode; -// -// NSString *title = [NSString stringWithFormat:@"%@ (%@)", -// callingCode, -// countryCode.uppercaseString]; -// self.countryCodeLabel.text = title; -// [self.countryCodeLabel setNeedsLayout]; -// -// self.examplePhoneNumberLabel.text = -// [ViewControllerUtils examplePhoneNumberForCountryCode:countryCode callingCode:callingCode]; -// [self.examplePhoneNumberLabel setNeedsLayout]; -//} -// -//#pragma mark - Actions -// -//- (void)sendCodeAction -//{ -// NSString *phoneNumberText = [_phoneNumberTextField.text ows_stripped]; -// if (phoneNumberText.length < 1) { -// [OWSAlerts -// showAlertWithTitle:NSLocalizedString(@"REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_TITLE", -// @"Title of alert indicating that users needs to enter a phone number to -// register.") -// message: -// NSLocalizedString(@"REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_MESSAGE", -// @"Message of alert indicating that users needs to enter a phone number to register.")]; -// return; -// } -// NSString *countryCode = self.countryCode; -// NSString *phoneNumber = [NSString stringWithFormat:@"%@%@", _callingCode, phoneNumberText]; -// PhoneNumber *localNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumber]; -// NSString *parsedPhoneNumber = localNumber.toE164; -// if (parsedPhoneNumber.length < 1) { -// [OWSAlerts showAlertWithTitle: -// NSLocalizedString(@"REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_TITLE", -// @"Title of alert indicating that users needs to enter a valid phone number to register.") -// message:NSLocalizedString(@"REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_MESSAGE", -// @"Message of alert indicating that users needs to enter a -// valid phone number " -// @"to register.")]; -// return; -// } -// -// [self.activateButton setEnabled:NO]; -// [self.spinnerView startAnimating]; -// [self.phoneNumberTextField resignFirstResponder]; -// -// __weak RegistrationViewController *weakSelf = self; -// [TSAccountManager registerWithPhoneNumber:parsedPhoneNumber -// success:^{ -// OWSProdInfo([OWSAnalyticsEvents registrationRegisteredPhoneNumber]); -// -// [weakSelf.spinnerView stopAnimating]; -// -// CodeVerificationViewController *vc = [CodeVerificationViewController new]; -// [weakSelf.navigationController pushViewController:vc animated:YES]; -// -//#ifdef DEBUG -// [weakSelf setLastRegisteredCountryCode:countryCode]; -// [weakSelf setLastRegisteredPhoneNumber:phoneNumberText]; -//#endif -// } -// failure:^(NSError *error) { -// 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]; -// } -// -// [weakSelf.activateButton setEnabled:YES]; -// [weakSelf.spinnerView stopAnimating]; -// [weakSelf.phoneNumberTextField becomeFirstResponder]; -// } -// smsVerification:YES]; -//} -// -//- (void)countryCodeRowWasTapped:(UIGestureRecognizer *)sender -//{ -// if (sender.state == UIGestureRecognizerStateRecognized) { -// [self changeCountryCodeTapped]; -// } -//} -// -//- (void)changeCountryCodeTapped -//{ -// CountryCodeViewController *countryCodeController = [CountryCodeViewController new]; -// countryCodeController.countryCodeDelegate = self; -// UINavigationController *navigationController = -// [[UINavigationController alloc] initWithRootViewController:countryCodeController]; -// [self presentViewController:navigationController animated:YES completion:[UIUtil modalCompletionBlock]]; -//} -// -//- (void)backgroundTapped:(UIGestureRecognizer *)sender -//{ -// if (sender.state == UIGestureRecognizerStateRecognized) { -// [self.phoneNumberTextField becomeFirstResponder]; -// } -//} -// -//#pragma mark - CountryCodeViewControllerDelegate -// -//- (void)countryCodeViewController:(CountryCodeViewController *)vc -// didSelectCountryCode:(NSString *)countryCode -// countryName:(NSString *)countryName -// callingCode:(NSString *)callingCode -//{ -// OWSAssert(countryCode.length > 0); -// OWSAssert(countryName.length > 0); -// OWSAssert(callingCode.length > 0); -// -// [self updateCountryWithName:countryName callingCode:callingCode countryCode:countryCode]; -// -// // Trigger the formatting logic with a no-op edit. -// [self textField:self.phoneNumberTextField shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""]; -//} -// -//#pragma mark - Keyboard notifications -// -//- (void)initializeKeyboardHandlers { -// UITapGestureRecognizer *outsideTabRecognizer = -// [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)]; -// [self.view addGestureRecognizer:outsideTabRecognizer]; -//} -// -//- (void)dismissKeyboardFromAppropriateSubView { -// [self.view endEditing:NO]; -//} -// -//#pragma mark - UITextFieldDelegate -// -//- (BOOL)textField:(UITextField *)textField -// shouldChangeCharactersInRange:(NSRange)range -// replacementString:(NSString *)insertionText { -// -// [ViewControllerUtils phoneNumberTextField:textField -// shouldChangeCharactersInRange:range -// replacementString:insertionText -// countryCode:_callingCode]; -// -// return NO; // inform our caller that we took care of performing the change -//} -// -//- (BOOL)textFieldShouldReturn:(UITextField *)textField { -// [self sendCodeAction]; -// [textField resignFirstResponder]; -// return NO; -//} -// -//#pragma mark - Debug -// -//#ifdef DEBUG -// -//- (NSString *_Nullable)debugValueForKey:(NSString *)key -//{ -// OWSCAssert([NSThread isMainThread]); -// OWSCAssert(key.length > 0); -// -// NSError *error; -// NSString *value = [SAMKeychain passwordForService:kKeychainService_LastRegistered account:key error:&error]; -// if (value && !error) { -// return value; -// } -// return nil; -//} -// -//- (void)setDebugValue:(NSString *)value forKey:(NSString *)key -//{ -// OWSCAssert([NSThread isMainThread]); -// OWSCAssert(key.length > 0); -// OWSCAssert(value.length > 0); -// -// NSError *error; -// [SAMKeychain setAccessibilityType:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]; -// BOOL success = [SAMKeychain setPassword:value forService:kKeychainService_LastRegistered account:key -// error:&error]; if (!success || error) { -// DDLogError(@"%@ Error persisting 'last registered' value in keychain: %@", self.logTag, error); -// } -//} -// -//- (NSString *_Nullable)lastRegisteredCountryCode -//{ -// return [self debugValueForKey:kKeychainKey_LastRegisteredCountryCode]; -//} -// -//- (void)setLastRegisteredCountryCode:(NSString *)value -//{ -// [self setDebugValue:value forKey:kKeychainKey_LastRegisteredCountryCode]; -//} -// -//- (NSString *_Nullable)lastRegisteredPhoneNumber -//{ -// return [self debugValueForKey:kKeychainKey_LastRegisteredPhoneNumber]; -//} -// -//- (void)setLastRegisteredPhoneNumber:(NSString *)value -//{ -// [self setDebugValue:value forKey:kKeychainKey_LastRegisteredPhoneNumber]; -//} -// -//#endif -// -//@end -// -// NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/PrivacySettingsTableViewController.m b/Signal/src/ViewControllers/PrivacySettingsTableViewController.m index 848bd6dcf6..db706ef3e0 100644 --- a/Signal/src/ViewControllers/PrivacySettingsTableViewController.m +++ b/Signal/src/ViewControllers/PrivacySettingsTableViewController.m @@ -21,10 +21,6 @@ NS_ASSUME_NONNULL_BEGIN self.title = NSLocalizedString(@"SETTINGS_PRIVACY_TITLE", @""); [self updateTableContents]; - - dispatch_async(dispatch_get_main_queue(), ^{ - [self show2FASettings]; - }); } - (void)viewDidAppear:(BOOL)animated diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index accbacd1c1..5299108f83 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1398,9 +1398,7 @@ /* Label for the country code field */ "REGISTRATION_DEFAULT_COUNTRY_NAME" = "Country Code"; -/* Placeholder text -// for the phone number textfield - Placeholder text for the phone number textfield */ +/* Placeholder text for the phone number textfield */ "REGISTRATION_ENTERNUMBER_DEFAULT_TEXT" = "Enter Number"; /* No comment provided by engineer. */ @@ -1430,9 +1428,7 @@ /* No comment provided by engineer. */ "REGISTRATION_VERIFY_DEVICE" = "Activate This Device"; -/* Message of alert indicating that users needs to enter a -// valid phone number to register. - Message of alert indicating that users needs to enter a valid phone number to register. */ +/* Message of alert indicating that users needs to enter a valid phone number to register. */ "REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_MESSAGE" = "Please enter a valid phone number to register."; /* Title of alert indicating that users needs to enter a valid phone number to register. */ @@ -1441,9 +1437,7 @@ /* Message of alert indicating that users needs to enter a phone number to register. */ "REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_MESSAGE" = "Please enter a phone number to register."; -/* Title of alert indicating that users needs to enter a phone number to -// register. - Title of alert indicating that users needs to enter a phone number to register. */ +/* Title of alert indicating that users needs to enter a phone number to register. */ "REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_TITLE" = "No Phone Number"; /* No comment provided by engineer. */ diff --git a/SignalServiceKit/src/TSConstants.h b/SignalServiceKit/src/TSConstants.h index 1f82b5d17c..78c395f961 100644 --- a/SignalServiceKit/src/TSConstants.h +++ b/SignalServiceKit/src/TSConstants.h @@ -20,20 +20,20 @@ typedef NS_ENUM(NSInteger, TSWhisperMessageType) { //#ifndef DEBUG // Production -//#define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/" -//#define textSecureServerURL @"https://textsecure-service.whispersystems.org/" -//#define textSecureCDNServerURL @"https://cdn.signal.org" -//#define textSecureServiceReflectorHost @"signal-reflector-meek.appspot.com" -//#define textSecureCDNReflectorHost @"signal-cdn-reflector.appspot.com" +#define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/" +#define textSecureServerURL @"https://textsecure-service.whispersystems.org/" +#define textSecureCDNServerURL @"https://cdn.signal.org" +#define textSecureServiceReflectorHost @"signal-reflector-meek.appspot.com" +#define textSecureCDNReflectorHost @"signal-cdn-reflector.appspot.com" //#else // //// Staging -#define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/" -#define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/" -#define textSecureCDNServerURL @"https://cdn-staging.signal.org" -#define textSecureServiceReflectorHost @"meek-signal-service-staging.appspot.com"; -#define textSecureCDNReflectorHost @"meek-signal-cdn-staging.appspot.com"; +//#define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/" +//#define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/" +//#define textSecureCDNServerURL @"https://cdn-staging.signal.org" +//#define textSecureServiceReflectorHost @"meek-signal-service-staging.appspot.com"; +//#define textSecureCDNReflectorHost @"meek-signal-cdn-staging.appspot.com"; // //#endif @@ -51,7 +51,6 @@ typedef NS_ENUM(NSInteger, TSWhisperMessageType) { #define textSecureProfileAPIFormat @"v1/profile/%@" #define textSecureSetProfileNameAPIFormat @"v1/profile/name/%@" #define textSecureProfileAvatarFormAPI @"v1/profile/form/avatar" -#define textSecure2FAAPI @"/v1/accounts/pin" #define SignalApplicationGroup @"group.org.whispersystems.signal.group" From 2ebea29114bb62b9fc5f265f850324be86cb7515 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Feb 2018 22:37:22 -0500 Subject: [PATCH 5/9] Sketch out 2FA settings views. --- Pods | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pods b/Pods index 29babe2150..267e347b1e 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 29babe215072d52688ea5b18592f308bfc190612 +Subproject commit 267e347b1eb97f8fd2e03a881b1a1c0c1de20e0f From 8c542979189ec6f721755ee339f5b2a7167ad3a5 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Feb 2018 22:38:22 -0500 Subject: [PATCH 6/9] Sketch out 2FA settings views. --- SignalServiceKit/src/TSConstants.h | 1 + 1 file changed, 1 insertion(+) diff --git a/SignalServiceKit/src/TSConstants.h b/SignalServiceKit/src/TSConstants.h index 78c395f961..d80ff8e2d7 100644 --- a/SignalServiceKit/src/TSConstants.h +++ b/SignalServiceKit/src/TSConstants.h @@ -51,6 +51,7 @@ typedef NS_ENUM(NSInteger, TSWhisperMessageType) { #define textSecureProfileAPIFormat @"v1/profile/%@" #define textSecureSetProfileNameAPIFormat @"v1/profile/name/%@" #define textSecureProfileAvatarFormAPI @"v1/profile/form/avatar" +#define textSecure2FAAPI @"/v1/accounts/pin" #define SignalApplicationGroup @"group.org.whispersystems.signal.group" From 055061ff5e34ed2df6203a83bb4d01a91aeb3a8f Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Feb 2018 22:50:02 -0500 Subject: [PATCH 7/9] Clean up ahead of PR. --- .../OWS2FASettingsViewController.m | 32 +++++++++++++------ SignalServiceKit/src/Util/OWS2FAManager.h | 2 ++ SignalServiceKit/src/Util/OWS2FAManager.m | 7 ++++ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Signal/src/ViewControllers/OWS2FASettingsViewController.m b/Signal/src/ViewControllers/OWS2FASettingsViewController.m index 611d7d5af8..b91066c330 100644 --- a/Signal/src/ViewControllers/OWS2FASettingsViewController.m +++ b/Signal/src/ViewControllers/OWS2FASettingsViewController.m @@ -38,6 +38,16 @@ NS_ASSUME_NONNULL_BEGIN self.title = NSLocalizedString(@"ENABLE_2FA_VIEW_TITLE", @"Title for the 'enable two factor auth PIN' views."); [self createContents]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(stateDidChange:) + name:NSNotificationName_2FAStateDidChange + object:nil]; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)createContents @@ -72,15 +82,8 @@ NS_ASSUME_NONNULL_BEGIN [super viewWillAppear:animated]; - if (self.mode == OWS2FASettingsMode_Status) { - // Ever time we re-enter the "status" view, recreate its - // contents wholesale since we may have just enabled or - // disabled 2FA. - [self createContents]; - } else { - // If we're using a table, refresh its contents. - [self updateTableContents]; - } + // If we're using a table, refresh its contents. + [self updateTableContents]; [self updateNavigationItems]; } @@ -413,7 +416,7 @@ NS_ASSUME_NONNULL_BEGIN } failure:^(NSError *error) { [modalActivityIndicator dismissWithCompletion:^{ - [weakSelf createContents]; + [weakSelf updateTableContents]; [OWSAlerts showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", @"") @@ -477,6 +480,15 @@ NS_ASSUME_NONNULL_BEGIN [self.navigationController popViewControllerAnimated:YES]; } +- (void)stateDidChange:(NSNotification *)notification +{ + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + if (self.mode == OWS2FASettingsMode_Status) { + [self createContents]; + } +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Util/OWS2FAManager.h b/SignalServiceKit/src/Util/OWS2FAManager.h index 71f15db86a..9a2828b647 100644 --- a/SignalServiceKit/src/Util/OWS2FAManager.h +++ b/SignalServiceKit/src/Util/OWS2FAManager.h @@ -4,6 +4,8 @@ NS_ASSUME_NONNULL_BEGIN +extern NSString *const NSNotificationName_2FAStateDidChange; + typedef void (^OWS2FASuccess)(void); typedef void (^OWS2FAFailure)(NSError *error); diff --git a/SignalServiceKit/src/Util/OWS2FAManager.m b/SignalServiceKit/src/Util/OWS2FAManager.m index 1be41697cd..a886f2f2a6 100644 --- a/SignalServiceKit/src/Util/OWS2FAManager.m +++ b/SignalServiceKit/src/Util/OWS2FAManager.m @@ -3,6 +3,7 @@ // #import "OWS2FAManager.h" +#import "NSNotificationCenter+OWS.h" #import "OWSRequestFactory.h" #import "TSNetworkManager.h" #import "TSStorageManager.h" @@ -10,6 +11,8 @@ NS_ASSUME_NONNULL_BEGIN +NSString *const NSNotificationName_2FAStateDidChange = @"NSNotificationName_2FAStateDidChange"; + NSString *const kOWS2FAManager_Collection = @"kOWS2FAManager_Collection"; NSString *const kOWS2FAManager_IsEnabledKey = @"kOWS2FAManager_IsEnabledKey"; @@ -72,6 +75,10 @@ NSString *const kOWS2FAManager_IsEnabledKey = @"kOWS2FAManager_IsEnabledKey"; - (void)setIs2FAEnabled:(BOOL)value { [self.dbConnection setBool:value forKey:kOWS2FAManager_IsEnabledKey inCollection:kOWS2FAManager_Collection]; + + [[NSNotificationCenter defaultCenter] postNotificationNameAsync:NSNotificationName_2FAStateDidChange + object:nil + userInfo:nil]; } - (void)enable2FAWithPin:(NSString *)pin success:(nullable OWS2FASuccess)success failure:(nullable OWS2FAFailure)failure From a5128273ba32fb115267420b5f3f206a736f6c9a Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Feb 2018 22:53:15 -0500 Subject: [PATCH 8/9] Clean up ahead of PR. --- Signal/src/ViewControllers/OWS2FASettingsViewController.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Signal/src/ViewControllers/OWS2FASettingsViewController.m b/Signal/src/ViewControllers/OWS2FASettingsViewController.m index b91066c330..fd8938577e 100644 --- a/Signal/src/ViewControllers/OWS2FASettingsViewController.m +++ b/Signal/src/ViewControllers/OWS2FASettingsViewController.m @@ -210,7 +210,6 @@ NS_ASSUME_NONNULL_BEGIN [self.view addSubview:underscoreView]; [underscoreView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.pinTextfield withOffset:3]; [underscoreView autoPinWidthToSuperviewWithMargin:self.hMargin]; - // [underscoreView autoSetDimension:ALDimensionWidth toSize:textFieldWidth]; [underscoreView autoHCenterInSuperview]; [underscoreView autoSetDimension:ALDimensionHeight toSize:1.f]; From caeb97b466676d5ece36a179e2aeb389c61e6eb9 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 1 Mar 2018 15:32:51 -0500 Subject: [PATCH 9/9] Respond to CR. --- Gemfile.lock | 36 ++++++++++--------- .../OWS2FASettingsViewController.m | 3 +- .../API/Requests/TSRegisterForPushRequest.h | 10 +++--- .../API/Requests/TSRegisterForPushRequest.m | 16 +++++---- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c58a26a6b2..d490c3783c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (2.3.5) + CFPropertyList (2.3.6) activesupport (4.2.10) i18n (~> 0.7) minitest (~> 5.1) @@ -9,32 +9,33 @@ GEM tzinfo (~> 1.1) addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) + atomos (0.1.2) babosa (1.0.2) claide (1.0.2) - cocoapods (1.3.1) + cocoapods (1.4.0) activesupport (>= 4.0.2, < 5) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.3.1) - cocoapods-deintegrate (>= 1.0.1, < 2.0) + cocoapods-core (= 1.4.0) + cocoapods-deintegrate (>= 1.0.2, < 2.0) cocoapods-downloader (>= 1.1.3, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.2.0, < 2.0) + cocoapods-trunk (>= 1.3.0, < 2.0) cocoapods-try (>= 1.1.0, < 2.0) colored2 (~> 3.1) escape (~> 0.0.4) fourflusher (~> 2.0.1) gh_inspector (~> 1.0) - molinillo (~> 0.5.7) + molinillo (~> 0.6.4) nap (~> 1.0) ruby-macho (~> 1.1) - xcodeproj (>= 1.5.1, < 2.0) - cocoapods-core (1.3.1) + xcodeproj (>= 1.5.4, < 2.0) + cocoapods-core (1.4.0) activesupport (>= 4.0.2, < 6) fuzzy_match (~> 2.0.4) nap (~> 1.0) - cocoapods-deintegrate (1.0.1) + cocoapods-deintegrate (1.0.2) cocoapods-downloader (1.1.3) cocoapods-plugins (1.0.0) nap @@ -48,6 +49,7 @@ GEM colored2 (3.1.2) commander-fastlane (4.4.5) highline (~> 1.7.2) + concurrent-ruby (1.0.5) declarative (0.0.10) declarative-option (0.1.0) domain_name (0.5.20170404) @@ -98,7 +100,7 @@ GEM xcpretty-travis-formatter (>= 0.0.3) fourflusher (2.0.1) fuzzy_match (2.0.4) - gh_inspector (1.0.3) + gh_inspector (1.1.2) google-api-client (0.13.6) addressable (~> 2.5, >= 2.5.1) googleauth (~> 0.5) @@ -118,7 +120,8 @@ GEM http-cookie (1.0.3) domain_name (~> 0.5) httpclient (2.8.3) - i18n (0.8.6) + i18n (0.9.5) + concurrent-ruby (~> 1.0) json (2.1.0) jwt (1.5.6) little-plugger (1.1.4) @@ -130,8 +133,8 @@ GEM mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mini_magick (4.5.1) - minitest (5.10.3) - molinillo (0.5.7) + minitest (5.11.3) + molinillo (0.6.4) multi_json (1.12.2) multi_xml (0.6.0) multipart-post (2.0.0) @@ -161,7 +164,7 @@ GEM unicode-display_width (~> 1.1, >= 1.1.1) thread_safe (0.3.6) tty-screen (0.5.0) - tzinfo (1.2.3) + tzinfo (1.2.5) thread_safe (~> 0.1) uber (0.1.0) unf (0.1.4) @@ -169,8 +172,9 @@ GEM unf_ext (0.0.7.4) unicode-display_width (1.3.0) word_wrap (1.0.0) - xcodeproj (1.5.2) + xcodeproj (1.5.6) CFPropertyList (~> 2.3.3) + atomos (~> 0.1.2) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) nanaimo (~> 0.2.3) @@ -187,4 +191,4 @@ DEPENDENCIES fastlane BUNDLED WITH - 1.14.6 + 1.16.1 diff --git a/Signal/src/ViewControllers/OWS2FASettingsViewController.m b/Signal/src/ViewControllers/OWS2FASettingsViewController.m index fd8938577e..5c9cd58730 100644 --- a/Signal/src/ViewControllers/OWS2FASettingsViewController.m +++ b/Signal/src/ViewControllers/OWS2FASettingsViewController.m @@ -322,8 +322,7 @@ NS_ASSUME_NONNULL_BEGIN if (textAfterChange.length > kMaxPinLength) { textAfterChange = [textAfterChange substringToIndex:kMaxPinLength]; } - // 6. Construct the "formatted" new text by inserting a hyphen if necessary. - // reformat the phone number, trying to keep the cursor beside the inserted or deleted digit + // 6. Construct the final text. textField.text = textAfterChange; NSUInteger cursorPositionAfterChange = MIN(left.length + center.length, textAfterChange.length); UITextPosition *pos = diff --git a/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.h b/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.h index 97025b4af5..5dff583b2e 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.h +++ b/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.h @@ -1,15 +1,15 @@ // -// TSRegisterForPushRequest.h -// TextSecureiOS -// -// Created by Frederic Jacobs on 10/13/13. -// Copyright (c) 2013 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "TSRequest.h" +NS_ASSUME_NONNULL_BEGIN + @interface TSRegisterForPushRequest : TSRequest - (id)initWithPushIdentifier:(NSString *)identifier voipIdentifier:(NSString *)voipId; @end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.m b/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.m index a158f680b6..14e937efbd 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSRegisterForPushRequest.m @@ -5,6 +5,8 @@ #import "TSRegisterForPushRequest.h" #import "TSConstants.h" +NS_ASSUME_NONNULL_BEGIN + @implementation TSRegisterForPushRequest - (id)initWithPushIdentifier:(NSString *)identifier voipIdentifier:(NSString *)voipId { @@ -17,15 +19,15 @@ self.HTTPMethod = @"PUT"; - NSMutableDictionary *parameters = [@{ @"apnRegistrationId" : identifier } mutableCopy]; - - if (voipId) { - parameters[@"voipRegistrationId"] = voipId; - } - - self.parameters = parameters; + OWSAssert(voipId); + self.parameters = @{ + @"apnRegistrationId" : identifier, + @"voipRegistrationId" : voipId ?: @"", + }; return self; } @end + +NS_ASSUME_NONNULL_END