From 495e714737d152eb60b0dd65d0432ac4ec15e275 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sat, 9 Nov 2019 12:40:48 +0100 Subject: [PATCH] Revert refunded features on launch --- Passepartout-iOS/AppDelegate.swift | 4 ++ Passepartout-iOS/Global/ProductManager.swift | 60 +++++++++++++++++++- Submodules/Core | 2 +- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/Passepartout-iOS/AppDelegate.swift b/Passepartout-iOS/AppDelegate.swift index 1f5d0731..2cfd786f 100644 --- a/Passepartout-iOS/AppDelegate.swift +++ b/Passepartout-iOS/AppDelegate.swift @@ -27,6 +27,9 @@ import UIKit import TunnelKit import PassepartoutCore import Convenience +import SwiftyBeaver + +private let log = SwiftyBeaver.self @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate { @@ -79,6 +82,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + ProductManager.shared.reviewPurchases() } func applicationWillTerminate(_ application: UIApplication) { diff --git a/Passepartout-iOS/Global/ProductManager.swift b/Passepartout-iOS/Global/ProductManager.swift index 39039409..84afba98 100644 --- a/Passepartout-iOS/Global/ProductManager.swift +++ b/Passepartout-iOS/Global/ProductManager.swift @@ -96,7 +96,7 @@ class ProductManager: NSObject { // MARK: In-app eligibility - private func reloadReceipt() { + private func reloadReceipt(andNotify: Bool = true) { guard let url = Bundle.main.appStoreReceiptURL else { log.warning("No App Store receipt found!") return @@ -140,7 +140,9 @@ class ProductManager: NSObject { } log.info("Purchased features: \(purchasedFeatures)") - NotificationCenter.default.post(name: ProductManager.didReloadReceipt, object: nil) + if andNotify { + NotificationCenter.default.post(name: ProductManager.didReloadReceipt, object: nil) + } } func isFullVersion() -> Bool { @@ -169,6 +171,60 @@ class ProductManager: NSObject { func isEligibleForFeedback() -> Bool { return AppConstants.Flags.isBeta || !purchasedFeatures.isEmpty } + + // MARK: Review + + func reviewPurchases() { + let service = TransientStore.shared.service + reloadReceipt(andNotify: false) + var shouldReinstall = false + + // review features and potentially revert them if they were used (Siri is handled in AppDelegate) + + log.debug("Checking 'Trusted networks'") + if !isEligible(forFeature: .trustedNetworks) { + if service.preferences.trustsMobileNetwork || !service.preferences.trustedWifis.isEmpty { + service.preferences.trustsMobileNetwork = false + service.preferences.trustedWifis.removeAll() + log.debug("\tRefunded") + shouldReinstall = true + } + } + + log.debug("Checking 'Unlimited hosts'") + if !isEligible(forFeature: .unlimitedHosts) { + let ids = service.ids(forContext: .host) + if ids.count > AppConstants.InApp.limitedNumberOfHosts { + for id in ids { + service.removeProfile(ProfileKey(.host, id)) + } + log.debug("\tRefunded") + shouldReinstall = true + } + } + + log.debug("Checking providers") + for name in service.currentProviderNames() { + if !isEligible(forProvider: name) { + service.removeProfile(ProfileKey(name)) + log.debug("\tRefunded provider: \(name)") + shouldReinstall = true + } + } + + // no refunds + guard shouldReinstall else { + return + } + + // + + // save reverts and remove fraud VPN profile + TransientStore.shared.serialize(withProfiles: true) + VPN.shared.uninstall(completionHandler: nil) + + NotificationCenter.default.post(name: ProductManager.didReloadReceipt, object: nil) + } } extension ConnectionService { diff --git a/Submodules/Core b/Submodules/Core index 7476e075..dad47f35 160000 --- a/Submodules/Core +++ b/Submodules/Core @@ -1 +1 @@ -Subproject commit 7476e0751d1a64efca0180a1e31f0e24f04fce84 +Subproject commit dad47f3581ab25d966d204de93634d82b9fe808b