From 63260ee94d80e879efcc35748f767ba9a7f35bf1 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 8 Jan 2019 15:10:32 -0500 Subject: [PATCH] Fix registration. --- Signal/src/Models/AccountManager.swift | 44 +++++++++++-------- .../DebugUI/DebugUIProfile.swift | 6 +-- .../src/Account/TSAccountManager.m | 28 +++++++++++- .../src/Account/TSPreKeyManager.m | 19 +++++--- .../src/Messages/OWSMessageSender.m | 9 ++-- .../src/Messages/UD/OWSUDManager.swift | 6 ++- .../src/Network/API/TSNetworkManager.m | 22 ++++++++-- .../src/Network/WebSockets/OWSWebSocket.m | 16 +++++-- 8 files changed, 108 insertions(+), 42 deletions(-) diff --git a/Signal/src/Models/AccountManager.swift b/Signal/src/Models/AccountManager.swift index 79ca9c47c..3a393de3f 100644 --- a/Signal/src/Models/AccountManager.swift +++ b/Signal/src/Models/AccountManager.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -13,11 +13,19 @@ import SignalServiceKit @objc public class AccountManager: NSObject { + // MARK: - Dependencies + var pushManager: PushManager { // dependency injection hack since PushManager has *alot* of dependencies, and would induce a cycle. return PushManager.shared() } + var profileManager: OWSProfileManager { + return OWSProfileManager.shared() + } + + // MARK: - + @objc public override init() { super.init() @@ -58,22 +66,20 @@ public class AccountManager: NSObject { Logger.debug("registering with signal server") let registrationPromise: Promise = firstly { return self.registerForTextSecure(verificationCode: verificationCode, pin: pin) - }.then { - return self.syncPushTokens() - }.recover { (error) -> Promise in - switch error { - case PushRegistrationError.pushNotSupported(let description): - // This can happen with: - // - simulators, none of which support receiving push notifications - // - on iOS11 devices which have disabled "Allow Notifications" and disabled "Enable Background Refresh" in the system settings. - Logger.info("Recovered push registration error. Registering for manual message fetcher because push not supported: \(description)") - return self.enableManualMessageFetching() - default: - throw error + }.then { _ -> Promise in + return self.syncPushTokens().recover { (error) -> Promise in + switch error { + case PushRegistrationError.pushNotSupported(let description): + // This can happen with: + // - simulators, none of which support receiving push notifications + // - on iOS11 devices which have disabled "Allow Notifications" and disabled "Enable Background Refresh" in the system settings. + Logger.info("Recovered push registration error. Registering for manual message fetcher because push not supported: \(description)") + return self.enableManualMessageFetching() + default: + throw error + } } - }.then { (_) in - self.tsAccountManager.performUpdateAccountAttributes() - }.done { (_) in + }.done { (_) -> Void in self.completeRegistration() } @@ -86,9 +92,9 @@ public class AccountManager: NSObject { pin: String?) -> Promise { return Promise { resolver in tsAccountManager.verifyAccount(withCode: verificationCode, - pin: pin, - success: resolver.fulfill, - failure: resolver.reject) + pin: pin, + success: resolver.fulfill, + failure: resolver.reject) } } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift b/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift index 126d54d0c..7fb9a30a3 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -8,7 +8,7 @@ import SignalMessaging class DebugUIProfile: DebugUIPage { - // MARK: Dependencies + // MARK: - Dependencies var messageSender: MessageSender { return SSKEnvironment.shared.messageSender @@ -17,7 +17,7 @@ class DebugUIProfile: DebugUIPage { return OWSProfileManager.shared() } - // MARK: Overrides + // MARK: - Overrides override func name() -> String { return "Profile" diff --git a/SignalServiceKit/src/Account/TSAccountManager.m b/SignalServiceKit/src/Account/TSAccountManager.m index 9d9a671b0..75261d303 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.m +++ b/SignalServiceKit/src/Account/TSAccountManager.m @@ -398,8 +398,32 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa case 200: case 204: { OWSLogInfo(@"Verification code accepted."); - [TSPreKeyManager createPreKeysWithSuccess:successBlock failure:failureBlock]; - [self.profileManager fetchLocalUsersProfile]; + + [self storeServerAuthToken:authToken]; + + [[[SignalServiceRestClient new] updateAccountAttributesObjC] + .thenInBackground(^{ + return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { + [TSPreKeyManager + createPreKeysWithSuccess:^{ + resolve(@(1)); + } + failure:^(NSError *error) { + resolve(error); + }]; + }]; + }) + .then(^{ + [self.profileManager fetchLocalUsersProfile]; + }) + .then(^{ + successBlock(); + }) + .catchInBackground(^(NSError *error) { + OWSLogError(@"Error: %@", error); + failureBlock(error); + }) retainUntilComplete]; + break; } default: { diff --git a/SignalServiceKit/src/Account/TSPreKeyManager.m b/SignalServiceKit/src/Account/TSPreKeyManager.m index c90a4b6af..1e058e783 100644 --- a/SignalServiceKit/src/Account/TSPreKeyManager.m +++ b/SignalServiceKit/src/Account/TSPreKeyManager.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "TSPreKeyManager.h" @@ -13,6 +13,8 @@ #import #import +NS_ASSUME_NONNULL_BEGIN + // Time before deletion of signed prekeys (measured in seconds) #define kSignedPreKeysDeletionTime (7 * kDayInterval) @@ -107,12 +109,10 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5; + (void)checkPreKeysIfNecessary { - if (!CurrentAppContext().isMainApp) { + if (!CurrentAppContext().isMainAppAndActive) { return; } - OWSAssertDebug(CurrentAppContext().isMainAppAndActive); - - if (!self.tsAccountManager.isRegistered) { + if (!self.tsAccountManager.isRegisteredAndReady) { return; } @@ -156,6 +156,8 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5; + (void)createPreKeysWithSuccess:(void (^)(void))successHandler failure:(void (^)(NSError *error))failureHandler { + OWSAssertDebug(!self.tsAccountManager.isRegisteredAndReady); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ SSKCreatePreKeysOperation *operation = [SSKCreatePreKeysOperation new]; [self.operationQueue addOperations:@[ operation ] waitUntilFinished:YES]; @@ -175,6 +177,8 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5; + (void)rotateSignedPreKeyWithSuccess:(void (^)(void))successHandler failure:(void (^)(NSError *error))failureHandler { + OWSAssertDebug(!self.tsAccountManager.isRegisteredAndReady); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ SSKRotateSignedPreKeyOperation *operation = [SSKRotateSignedPreKeyOperation new]; [self.operationQueue addOperations:@[ operation ] waitUntilFinished:YES]; @@ -197,6 +201,9 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5; if (!CurrentAppContext().isMainApp) { return; } + if (!self.tsAccountManager.isRegisteredAndReady) { + return; + } SSKRefreshPreKeysOperation *operation = [SSKRefreshPreKeysOperation new]; [self.operationQueue addOperation:operation]; @@ -292,3 +299,5 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5; } @end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 59a581552..977f1cc4c 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1252,11 +1252,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; void (^handle404)(void) = ^{ OWSLogWarn(@"Unregistered recipient: %@", recipient.uniqueId); - TSThread *_Nullable thread = messageSend.thread; - OWSAssertDebug(thread); - dispatch_async([OWSDispatch sendingQueue], ^{ - [self unregisteredRecipient:recipient message:message thread:thread]; + if (![messageSend.message isKindOfClass:[OWSOutgoingSyncMessage class]]) { + TSThread *_Nullable thread = messageSend.thread; + OWSAssertDebug(thread); + [self unregisteredRecipient:recipient message:message thread:thread]; + } NSError *error = OWSErrorMakeNoSuchSignalRecipientError(); // No need to retry if the recipient is not registered. diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index fa60dc0bf..f0c4005de 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -155,6 +155,10 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { func registrationStateDidChange() { AssertIsOnMainThread() + guard tsAccountManager.isRegisteredAndReady() else { + return + } + // Any error is silently ignored ensureSenderCertificate(certificateExpirationPolicy: .strict).retainUntilComplete() } diff --git a/SignalServiceKit/src/Network/API/TSNetworkManager.m b/SignalServiceKit/src/Network/API/TSNetworkManager.m index 9af915388..660f478d1 100644 --- a/SignalServiceKit/src/Network/API/TSNetworkManager.m +++ b/SignalServiceKit/src/Network/API/TSNetworkManager.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "TSNetworkManager.h" @@ -37,10 +37,19 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); @implementation TSNetworkManager +#pragma mark - Dependencies + ++ (TSAccountManager *)tsAccountManager +{ + return TSAccountManager.sharedInstance; +} + +#pragma mark - + @synthesize udSessionManager = _udSessionManager; @synthesize udSerialQueue = _udSerialQueue; -#pragma mark Singleton implementation +#pragma mark - Singleton + (instancetype)sharedManager { @@ -108,7 +117,7 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); OWSLogInfo(@"Non-UD request succeeded : %@", request); if (request.shouldHaveAuthorizationHeaders) { - [TSAccountManager.sharedInstance setIsDeregistered:NO]; + [TSNetworkManager.tsAccountManager setIsDeregistered:NO]; } successBlock(task, responseObject); @@ -406,7 +415,12 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); // * etc. if ([task.originalRequest.URL.absoluteString hasPrefix:textSecureServerURL] && request.shouldHaveAuthorizationHeaders) { - [TSAccountManager.sharedInstance setIsDeregistered:YES]; + if (self.tsAccountManager.isRegisteredAndReady) { + [self.tsAccountManager setIsDeregistered:YES]; + } else { + OWSFailDebug( + @"Ignoring auth failure; not registered and ready: %@.", task.originalRequest.URL.absoluteString); + } } else { OWSLogWarn(@"Ignoring %d for URL: %@", (int)statusCode, task.originalRequest.URL.absoluteString); } diff --git a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m index c3e55a469..334a98455 100644 --- a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m +++ b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "OWSWebSocket.h" @@ -639,7 +639,11 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O if (responseStatus == 403) { // This should be redundant with our check for the socket // failing due to 403, but let's be thorough. - [self.tsAccountManager setIsDeregistered:YES]; + if (self.tsAccountManager.isRegisteredAndReady) { + [self.tsAccountManager setIsDeregistered:YES]; + } else { + OWSFailDebug(@"Ignoring auth failure; not registered and ready."); + } } NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeMessageResponseFailed, @@ -705,7 +709,11 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O if ([error.domain isEqualToString:SRWebSocketErrorDomain] && error.code == 2132) { NSNumber *_Nullable statusCode = error.userInfo[SRHTTPResponseErrorKey]; if (statusCode.unsignedIntegerValue == 403) { - [self.tsAccountManager setIsDeregistered:YES]; + if (self.tsAccountManager.isRegisteredAndReady) { + [self.tsAccountManager setIsDeregistered:YES]; + } else { + OWSFailDebug(@"Ignoring auth failure; not registered and ready."); + } } } @@ -932,7 +940,7 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O return NO; } - if (![self.tsAccountManager isRegistered]) { + if (![self.tsAccountManager isRegisteredAndReady]) { return NO; }