Skip to content

Commit

Permalink
Remove Privacy Pro from device once expired account is deleted (#870)
Browse files Browse the repository at this point in the history
* On failed request return response status code

* When updating subscription sign out on 401 error

* Rename function to better reflect intent

* Remove old unused function

* Swiftlint fix
  • Loading branch information
miasma13 authored Jun 30, 2024
1 parent 39e10c8 commit be669f8
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 37 deletions.
19 changes: 11 additions & 8 deletions Sources/Subscription/API/APIService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Common
public enum APIServiceError: Swift.Error {
case decodingError
case encodingError
case serverError(description: String)
case serverError(statusCode: Int, error: String?)
case unknownServerError
case connectionError
}
Expand Down Expand Up @@ -59,22 +59,25 @@ public struct DefaultAPIService: APIService {

printDebugInfo(method: method, endpoint: endpoint, data: data, response: urlResponse)

if let httpResponse = urlResponse as? HTTPURLResponse, (200..<300).contains(httpResponse.statusCode) {
guard let httpResponse = urlResponse as? HTTPURLResponse else { return .failure(.unknownServerError) }

if (200..<300).contains(httpResponse.statusCode) {
if let decodedResponse = decode(T.self, from: data) {
return .success(decodedResponse)
} else {
os_log(.error, log: .subscription, "Service error: APIServiceError.decodingError")
return .failure(.decodingError)
}
} else {
var errorString: String?

if let decodedResponse = decode(ErrorResponse.self, from: data) {
let errorDescription = "[\(endpoint)] \(urlResponse.httpStatusCodeAsString ?? ""): \(decodedResponse.error)"
os_log(.error, log: .subscription, "Service error: %{public}@", errorDescription)
return .failure(.serverError(description: errorDescription))
} else {
os_log(.error, log: .subscription, "Service error: APIServiceError.unknownServerError")
return .failure(.unknownServerError)
errorString = decodedResponse.error
}

let errorLogMessage = "/\(endpoint) \(httpResponse.statusCode): \(errorString ?? "")"
os_log(.error, log: .subscription, "Service error: %{public}@", errorLogMessage)
return .failure(.serverError(statusCode: httpResponse.statusCode, error: errorString))
}
} catch {
os_log(.error, log: .subscription, "Service error: %{public}@", error.localizedDescription)
Expand Down
20 changes: 1 addition & 19 deletions Sources/Subscription/Managers/AccountManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public protocol AccountManager {

typealias AccountDetails = (email: String?, externalID: String)
func fetchAccountDetails(with accessToken: String) async -> Result<AccountDetails, Error>
func refreshSubscriptionAndEntitlements() async

@discardableResult func checkForEntitlements(wait waitTime: Double, retry retryCount: Int) async -> Bool
}

Expand Down Expand Up @@ -331,24 +331,6 @@ public final class DefaultAccountManager: AccountManager {
}
}

public func refreshSubscriptionAndEntitlements() async {
os_log(.info, log: .subscription, "[AccountManager] refreshSubscriptionAndEntitlements")

guard let token = accessToken else {
subscriptionEndpointService.signOut()
entitlementsCache.reset()
return
}

if case .success(let subscription) = await subscriptionEndpointService.getSubscription(accessToken: token, cachePolicy: .reloadIgnoringLocalCacheData) {
if !subscription.isActive {
signOut()
}
}

await fetchEntitlements(cachePolicy: .reloadIgnoringLocalCacheData)
}

@discardableResult
public func checkForEntitlements(wait waitTime: Double, retry retryCount: Int) async -> Bool {
var count = 0
Expand Down
27 changes: 22 additions & 5 deletions Sources/Subscription/Managers/SubscriptionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public protocol SubscriptionManager {
var canPurchase: Bool { get }
@available(macOS 12.0, iOS 15.0, *) func storePurchaseManager() -> StorePurchaseManager
func loadInitialData()
func updateSubscriptionStatus(completion: @escaping (_ isActive: Bool) -> Void)
func refreshCachedSubscriptionAndEntitlements(completion: @escaping (_ isSubscriptionActive: Bool) -> Void)
func url(for type: SubscriptionURL) -> URL
}

Expand Down Expand Up @@ -118,14 +118,31 @@ public final class DefaultSubscriptionManager: SubscriptionManager {
}
}

public func updateSubscriptionStatus(completion: @escaping (_ isActive: Bool) -> Void) {
public func refreshCachedSubscriptionAndEntitlements(completion: @escaping (_ isSubscriptionActive: Bool) -> Void) {
Task {
guard let token = accountManager.accessToken else { return }
guard let token = accountManager.accessToken else { return }

if case .success(let subscription) = await subscriptionEndpointService.getSubscription(accessToken: token, cachePolicy: .reloadIgnoringLocalCacheData) {
completion(subscription.isActive)
var isSubscriptionActive = false

defer {
completion(isSubscriptionActive)
}

// Refetch and cache subscription
switch await subscriptionEndpointService.getSubscription(accessToken: token, cachePolicy: .reloadIgnoringLocalCacheData) {
case .success(let subscription):
isSubscriptionActive = subscription.isActive
case .failure(let error):
if case let .apiError(serviceError) = error, case let .serverError(statusCode, error) = serviceError {

Check warning on line 136 in Sources/Subscription/Managers/SubscriptionManager.swift

View workflow job for this annotation

GitHub Actions / Run unit tests (iOS)

immutable value 'error' was never used; consider replacing with '_' or removing it
if statusCode == 401 {
// Token is no longer valid
accountManager.signOut()
return
}
}
}

// Refetch and cache entitlements
_ = await accountManager.fetchEntitlements(cachePolicy: .reloadIgnoringLocalCacheData)
}
}
Expand Down
4 changes: 0 additions & 4 deletions Sources/SubscriptionTestingUtilities/AccountManagerMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,6 @@ public final class AccountManagerMock: AccountManager {
}
}

public func refreshSubscriptionAndEntitlements() async {

}

public func checkForEntitlements(wait waitTime: Double, retry retryCount: Int) async -> Bool {
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public final class SubscriptionManagerMock: SubscriptionManager {

}

public func updateSubscriptionStatus(completion: @escaping (Bool) -> Void) {
public func refreshCachedSubscriptionAndEntitlements(completion: @escaping (Bool) -> Void) {
completion(true)
}

Expand Down

0 comments on commit be669f8

Please sign in to comment.