From fc9a6781817bcaf1ff6990a9f170e50e90835fd6 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 17 Apr 2020 13:55:24 +1000 Subject: [PATCH] Fix APNs token updating bug --- Signal/src/AppDelegate.m | 4 ++-- Signal/src/Jobs/SyncPushTokensJob.swift | 2 +- .../Loki/View Controllers/PNModeSheet.swift | 4 +++- .../src/Loki/View Controllers/PNModeVC.swift | 4 +++- Signal/src/Models/AccountManager.swift | 7 ++++--- .../NotificationSettingsViewController.m | 4 +++- .../src/Account/TSAccountManager.h | 3 ++- .../src/Account/TSAccountManager.m | 9 ++++++--- .../Loki/API/LokiPushNotificationManager.swift | 18 +++++++++--------- 9 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index eb2bfe7c6..72379bd5f 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -590,9 +590,9 @@ static BOOL isInternalTestVersion = NO; OWSLogInfo(@"Registering for push notifications with token: %@.", deviceToken); BOOL isUsingFullAPNs = [NSUserDefaults.standardUserDefaults boolForKey:@"isUsingFullAPNs"]; if (isUsingFullAPNs) { - __unused AnyPromise *promise = [LKPushNotificationManager registerWithToken:deviceToken hexEncodedPublicKey:self.tsAccountManager.localNumber]; + __unused AnyPromise *promise = [LKPushNotificationManager registerWithToken:deviceToken hexEncodedPublicKey:self.tsAccountManager.localNumber isForcedUpdate:NO]; } else { - __unused AnyPromise *promise = [LKPushNotificationManager registerWithToken:deviceToken]; + __unused AnyPromise *promise = [LKPushNotificationManager registerWithToken:deviceToken isForcedUpdate:NO]; } } diff --git a/Signal/src/Jobs/SyncPushTokensJob.swift b/Signal/src/Jobs/SyncPushTokensJob.swift index 08132ec80..14c457abf 100644 --- a/Signal/src/Jobs/SyncPushTokensJob.swift +++ b/Signal/src/Jobs/SyncPushTokensJob.swift @@ -59,7 +59,7 @@ class SyncPushTokensJob: NSObject { Logger.warn("uploading tokens to account servers. pushToken: \(redact(pushToken)), voipToken: \(redact(voipToken))") return firstly { - self.accountManager.updatePushTokens(pushToken: pushToken, voipToken: voipToken) + self.accountManager.updatePushTokens(pushToken: pushToken, voipToken: voipToken, isForcedUpdate: shouldUploadTokens) }.done { _ in self.recordPushTokensLocally(pushToken: pushToken, voipToken: voipToken) } diff --git a/Signal/src/Loki/View Controllers/PNModeSheet.swift b/Signal/src/Loki/View Controllers/PNModeSheet.swift index 242a9ec30..5263fe734 100644 --- a/Signal/src/Loki/View Controllers/PNModeSheet.swift +++ b/Signal/src/Loki/View Controllers/PNModeSheet.swift @@ -76,7 +76,9 @@ final class PNModeSheet : Sheet, OptionViewDelegate { return present(alert, animated: true, completion: nil) } UserDefaults.standard[.isUsingFullAPNs] = (selectedOptionView == apnsOptionView) - let _: Promise = SyncPushTokensJob.run(accountManager: AppEnvironment.shared.accountManager, preferences: Environment.shared.preferences) + let syncTokensJob = SyncPushTokensJob(accountManager: AppEnvironment.shared.accountManager, preferences: Environment.shared.preferences) + syncTokensJob.uploadOnlyIfStale = false + let _: Promise = syncTokensJob.run() close() } diff --git a/Signal/src/Loki/View Controllers/PNModeVC.swift b/Signal/src/Loki/View Controllers/PNModeVC.swift index 09f739d2e..d0e22f22a 100644 --- a/Signal/src/Loki/View Controllers/PNModeVC.swift +++ b/Signal/src/Loki/View Controllers/PNModeVC.swift @@ -98,6 +98,8 @@ final class PNModeVC : BaseVC, OptionViewDelegate { TSAccountManager.sharedInstance().didRegister() let homeVC = HomeVC() navigationController!.setViewControllers([ homeVC ], animated: true) - let _: Promise = SyncPushTokensJob.run(accountManager: AppEnvironment.shared.accountManager, preferences: Environment.shared.preferences) + let syncTokensJob = SyncPushTokensJob(accountManager: AppEnvironment.shared.accountManager, preferences: Environment.shared.preferences) + syncTokensJob.uploadOnlyIfStale = false + let _: Promise = syncTokensJob.run() } } diff --git a/Signal/src/Models/AccountManager.swift b/Signal/src/Models/AccountManager.swift index bb825b7c3..99d0f611b 100644 --- a/Signal/src/Models/AccountManager.swift +++ b/Signal/src/Models/AccountManager.swift @@ -105,12 +105,13 @@ public class AccountManager: NSObject { // MARK: Message Delivery - func updatePushTokens(pushToken: String, voipToken: String) -> Promise { + func updatePushTokens(pushToken: String, voipToken: String, isForcedUpdate: Bool) -> Promise { return Promise { resolver in tsAccountManager.registerForPushNotifications(pushToken: pushToken, voipToken: voipToken, - success: { resolver.fulfill(()) }, - failure: resolver.reject) + isForcedUpdate: isForcedUpdate, + success: { resolver.fulfill(()) }, + failure: resolver.reject) } } diff --git a/Signal/src/ViewControllers/AppSettings/NotificationSettingsViewController.m b/Signal/src/ViewControllers/AppSettings/NotificationSettingsViewController.m index c930e91a6..dcc236ed4 100644 --- a/Signal/src/ViewControllers/AppSettings/NotificationSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettings/NotificationSettingsViewController.m @@ -137,7 +137,9 @@ - (void)didToggleAPNsSwitch:(UISwitch *)sender { [NSUserDefaults.standardUserDefaults setBool:sender.on forKey:@"isUsingFullAPNs"]; - __unused AnyPromise *promise = [OWSSyncPushTokensJob runWithAccountManager:AppEnvironment.shared.accountManager preferences:Environment.shared.preferences]; + OWSSyncPushTokensJob *syncTokensJob = [[OWSSyncPushTokensJob alloc] initWithAccountManager:AppEnvironment.shared.accountManager preferences:Environment.shared.preferences]; + syncTokensJob.uploadOnlyIfStale = NO; + __unused AnyPromise *promise = [syncTokensJob run]; } @end diff --git a/SignalServiceKit/src/Account/TSAccountManager.h b/SignalServiceKit/src/Account/TSAccountManager.h index 6cced2d2c..c8dd602cc 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.h +++ b/SignalServiceKit/src/Account/TSAccountManager.h @@ -120,9 +120,10 @@ typedef NS_ENUM(NSUInteger, OWSRegistrationState) { */ - (void)registerForPushNotificationsWithPushToken:(NSString *)pushToken voipToken:(NSString *)voipToken + isForcedUpdate:(BOOL)isForcedUpdate success:(void (^)(void))successHandler failure:(void (^)(NSError *error))failureHandler - NS_SWIFT_NAME(registerForPushNotifications(pushToken:voipToken:success:failure:)); + NS_SWIFT_NAME(registerForPushNotifications(pushToken:voipToken:isForcedUpdate:success:failure:)); #endif diff --git a/SignalServiceKit/src/Account/TSAccountManager.m b/SignalServiceKit/src/Account/TSAccountManager.m index ebcbad8f8..7820467cf 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.m +++ b/SignalServiceKit/src/Account/TSAccountManager.m @@ -280,11 +280,13 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa - (void)registerForPushNotificationsWithPushToken:(NSString *)pushToken voipToken:(NSString *)voipToken + isForcedUpdate:(BOOL)isForcedUpdate success:(void (^)(void))successHandler failure:(void (^)(NSError *))failureHandler { [self registerForPushNotificationsWithPushToken:pushToken voipToken:voipToken + isForcedUpdate:isForcedUpdate success:successHandler failure:failureHandler remainingRetries:3]; @@ -292,20 +294,21 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa - (void)registerForPushNotificationsWithPushToken:(NSString *)pushToken voipToken:(NSString *)voipToken + isForcedUpdate:(BOOL)isForcedUpdate success:(void (^)(void))successHandler failure:(void (^)(NSError *))failureHandler remainingRetries:(int)remainingRetries { BOOL isUsingFullAPNs = [NSUserDefaults.standardUserDefaults boolForKey:@"isUsingFullAPNs"]; - AnyPromise *promise = isUsingFullAPNs ? [LKPushNotificationManager registerWithToken:pushToken hexEncodedPublicKey:self.localNumber] - : [LKPushNotificationManager registerWithToken:pushToken]; + AnyPromise *promise = isUsingFullAPNs ? [LKPushNotificationManager registerWithToken:pushToken hexEncodedPublicKey:self.localNumber isForcedUpdate:isForcedUpdate] + : [LKPushNotificationManager registerWithToken:pushToken isForcedUpdate:isForcedUpdate]; promise .then(^() { successHandler(); }) .catch(^(NSError *error) { if (remainingRetries > 0) { - [self registerForPushNotificationsWithPushToken:pushToken voipToken:voipToken success:successHandler failure:failureHandler + [self registerForPushNotificationsWithPushToken:pushToken voipToken:voipToken isForcedUpdate:isForcedUpdate success:successHandler failure:failureHandler remainingRetries:remainingRetries - 1]; } else { if (!IsNSErrorNetworkFailure(error)) { diff --git a/SignalServiceKit/src/Loki/API/LokiPushNotificationManager.swift b/SignalServiceKit/src/Loki/API/LokiPushNotificationManager.swift index 75a64630a..6c3dc0e97 100644 --- a/SignalServiceKit/src/Loki/API/LokiPushNotificationManager.swift +++ b/SignalServiceKit/src/Loki/API/LokiPushNotificationManager.swift @@ -17,14 +17,14 @@ public final class LokiPushNotificationManager : NSObject { // MARK: Registration /// Registers the user for silent push notifications (that then trigger the app /// into fetching messages). Only the user's device token is needed for this. - static func register(with token: Data) -> Promise { + static func register(with token: Data, isForcedUpdate: Bool) -> Promise { let hexEncodedToken = token.toHexString() let userDefaults = UserDefaults.standard let oldToken = userDefaults[.deviceToken] let lastUploadTime = userDefaults[.lastDeviceTokenUpload] let isUsingFullAPNs = userDefaults[.isUsingFullAPNs] let now = Date().timeIntervalSince1970 - guard hexEncodedToken != oldToken || now - lastUploadTime < tokenExpirationInterval else { + guard isForcedUpdate || hexEncodedToken != oldToken || now - lastUploadTime < tokenExpirationInterval else { print("[Loki] Device token hasn't changed; no need to re-upload.") return Promise { $0.fulfill(()) } } @@ -56,14 +56,14 @@ public final class LokiPushNotificationManager : NSObject { /// Registers the user for silent push notifications (that then trigger the app /// into fetching messages). Only the user's device token is needed for this. - @objc(registerWithToken:) - static func objc_register(with token: Data) -> AnyPromise { - return AnyPromise.from(register(with: token)) + @objc(registerWithToken:isForcedUpdate:) + static func objc_register(with token: Data, isForcedUpdate: Bool) -> AnyPromise { + return AnyPromise.from(register(with: token, isForcedUpdate: isForcedUpdate)) } /// Registers the user for normal push notifications. Requires the user's device /// token and their Session ID. - static func register(with token: Data, hexEncodedPublicKey: String) -> Promise { + static func register(with token: Data, hexEncodedPublicKey: String, isForcedUpdate: Bool) -> Promise { let hexEncodedToken = token.toHexString() let userDefaults = UserDefaults.standard let now = Date().timeIntervalSince1970 @@ -91,9 +91,9 @@ public final class LokiPushNotificationManager : NSObject { /// Registers the user for normal push notifications. Requires the user's device /// token and their Session ID. - @objc(registerWithToken:hexEncodedPublicKey:) - static func objc_register(with token: Data, hexEncodedPublicKey: String) -> AnyPromise { - return AnyPromise.from(register(with: token, hexEncodedPublicKey: hexEncodedPublicKey)) + @objc(registerWithToken:hexEncodedPublicKey:isForcedUpdate:) + static func objc_register(with token: Data, hexEncodedPublicKey: String, isForcedUpdate: Bool) -> AnyPromise { + return AnyPromise.from(register(with: token, hexEncodedPublicKey: hexEncodedPublicKey, isForcedUpdate: isForcedUpdate)) } @objc(acknowledgeDeliveryForMessageWithHash:expiration:hexEncodedPublicKey:)