Skip to content

Commit

Permalink
Push subscription expired handling (#6851)
Browse files Browse the repository at this point in the history
* Use .afterFirstUnlock on all apnsToken instances

* Re-register push on subscriptionExpired
  • Loading branch information
eoger committed Jun 24, 2020
1 parent b1af71b commit 3c5c224
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Account/FxAPushMessageHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extension FxAPushMessageHandler {

guard let string = plaintext else {
// The app will detect this missing, and re-register. see AppDelegate+PushNotifications.swift.
keychain.removeObject(forKey: KeychainKey.apnsToken)
keychain.removeObject(forKey: KeychainKey.apnsToken, withAccessibility: .afterFirstUnlock)
return deferMaybe(PushMessageError.notDecrypted)
}

Expand Down
12 changes: 11 additions & 1 deletion Client/Application/AppDelegate+PushNotifications.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,21 @@ extension AppDelegate {
}
}

// If we see our local device with a pushEndpointExpired flag, clear the APNS token and re-register.
NotificationCenter.default.addObserver(forName: .constellationStateUpdate, object: nil, queue: nil) { notification in
if let newState = notification.userInfo?["newState"] as? ConstellationState {
if newState.localDevice?.subscriptionExpired ?? false {
KeychainWrapper.sharedAppContainerKeychain.removeObject(forKey: KeychainKey.apnsToken, withAccessibility: .afterFirstUnlock)
NotificationCenter.default.post(name: .RegisterForPushNotifications, object: nil)
}
}
}

// Use sync event as a periodic check for the apnsToken.
// The notification service extension can clear this token if there is an error, and the main app can detect this and re-register.
NotificationCenter.default.addObserver(forName: .ProfileDidStartSyncing, object: nil, queue: .main) { _ in
let kc = KeychainWrapper.sharedAppContainerKeychain
if kc.object(forKey: KeychainKey.apnsToken) == nil {
if kc.object(forKey: KeychainKey.apnsToken, withAccessibility: .afterFirstUnlock) == nil {
NotificationCenter.default.post(name: .RegisterForPushNotifications, object: nil)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Push/PushClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public extension PushClient {
mutableURLRequest.httpBody = JSON(parameters).stringify()?.utf8EncodedData

return send(request: mutableURLRequest) >>== { json in
KeychainStore.shared.setString(apnsToken, forKey: KeychainKey.apnsToken)
KeychainStore.shared.setString(apnsToken, forKey: KeychainKey.apnsToken, withAccessibility: .afterFirstUnlock)
return deferMaybe(creds)
}
}
Expand Down
2 changes: 1 addition & 1 deletion RustFxA/PushNotificationSetup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ open class PushNotificationSetup {
// If we've already registered this push subscription, we don't need to do it again.
let apnsToken = deviceToken.hexEncodedString
let keychain = KeychainWrapper.sharedAppContainerKeychain
guard keychain.string(forKey: KeychainKey.apnsToken) != apnsToken else {
guard keychain.string(forKey: KeychainKey.apnsToken, withAccessibility: .afterFirstUnlock) != apnsToken else {
return
}

Expand Down

0 comments on commit 3c5c224

Please sign in to comment.