From c6f4a8574d9a1de2d81d7274800add3bc4528e9c Mon Sep 17 00:00:00 2001 From: Michal Smaga Date: Mon, 22 Jul 2024 11:02:44 +0200 Subject: [PATCH 1/6] Add 'I have a subscription' debug menu item --- DuckDuckGo/MainViewController+Segues.swift | 8 ++++ DuckDuckGo/SettingsRootView.swift | 11 +++++ DuckDuckGo/SettingsViewModel.swift | 2 + .../SubscriptionDebugViewController.swift | 40 +++++++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/DuckDuckGo/MainViewController+Segues.swift b/DuckDuckGo/MainViewController+Segues.swift index b7f515cbc1..4856566f99 100644 --- a/DuckDuckGo/MainViewController+Segues.swift +++ b/DuckDuckGo/MainViewController+Segues.swift @@ -246,6 +246,14 @@ extension MainViewController { } } + func segueToSubscriptionRestoreFlow() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + launchSettings { + $0.triggerDeepLinkNavigation(to: .restoreFlow) + } + } + func segueToDebugSettings() { os_log(#function, log: .generalLog, type: .debug) hideAllHighlightsIfNeeded() diff --git a/DuckDuckGo/SettingsRootView.swift b/DuckDuckGo/SettingsRootView.swift index 32d4599313..0a6520ae4e 100644 --- a/DuckDuckGo/SettingsRootView.swift +++ b/DuckDuckGo/SettingsRootView.swift @@ -102,6 +102,13 @@ struct SettingsRootView: View { } } }) + + .onReceive(subscriptionNavigationCoordinator.$shouldPopToAppSettings) { shouldDismiss in + if shouldDismiss { + shouldDisplayDeepLinkSheet = false + shouldDisplayDeepLinkPush = false + } + } } // MARK: DeepLink Views @@ -117,6 +124,10 @@ struct SettingsRootView: View { SubscriptionContainerViewFactory.makeSubscribeFlow(origin: origin, navigationCoordinator: subscriptionNavigationCoordinator, subscriptionManager: AppDependencyProvider.shared.subscriptionManager) + case .restoreFlow: + SubscriptionContainerViewFactory.makeEmailFlow(navigationCoordinator: subscriptionNavigationCoordinator, + subscriptionManager: AppDependencyProvider.shared.subscriptionManager, + onDisappear: {}) default: EmptyView() } diff --git a/DuckDuckGo/SettingsViewModel.swift b/DuckDuckGo/SettingsViewModel.swift index f437dd7d4f..6db70f12f8 100644 --- a/DuckDuckGo/SettingsViewModel.swift +++ b/DuckDuckGo/SettingsViewModel.swift @@ -634,6 +634,7 @@ extension SettingsViewModel { case dbp case itr case subscriptionFlow(origin: String? = nil) + case restoreFlow // Add other cases as needed var id: String { @@ -642,6 +643,7 @@ extension SettingsViewModel { case .dbp: return "dbp" case .itr: return "itr" case .subscriptionFlow: return "subscriptionFlow" + case .restoreFlow: return "restoreFlow" // Ensure all cases are covered } } diff --git a/DuckDuckGo/SubscriptionDebugViewController.swift b/DuckDuckGo/SubscriptionDebugViewController.swift index 9a2dba8630..0fe21b6958 100644 --- a/DuckDuckGo/SubscriptionDebugViewController.swift +++ b/DuckDuckGo/SubscriptionDebugViewController.swift @@ -48,6 +48,7 @@ import NetworkProtection } enum AuthorizationRows: Int, CaseIterable { + case restoreSubscription case showAccountDetails case clearAuthData case injectCredentials @@ -87,6 +88,8 @@ import NetworkProtection case .authorization: switch AuthorizationRows(rawValue: indexPath.row) { + case .restoreSubscription: + cell.textLabel?.text = "I Have a Subscription" case .clearAuthData: cell.textLabel?.text = "Clear Authorization Data (Sign out)" case .showAccountDetails: @@ -151,6 +154,7 @@ import NetworkProtection switch Sections(rawValue: indexPath.section) { case .authorization: switch AuthorizationRows(rawValue: indexPath.row) { + case .restoreSubscription: openSubscriptionRestoreFlow() case .clearAuthData: clearAuthData() case .showAccountDetails: showAccountDetails() case .injectCredentials: injectCredentials() @@ -221,6 +225,17 @@ import NetworkProtection // func showAlert(title: String, message: String, alternativeAction) // MARK: Account Status Actions + + private func openSubscriptionRestoreFlow() { + guard let mainVC = view.window?.rootViewController as? MainViewController else { return } + + if let navigationController = mainVC.presentedViewController as? UINavigationController { + navigationController.popToRootViewController { + mainVC.segueToSubscriptionRestoreFlow() + } + } + } + private func clearAuthData() { subscriptionManager.accountManager.signOut() showAlert(title: "Data cleared!") @@ -332,3 +347,28 @@ import NetworkProtection } } } + +extension UINavigationController { + + func popToRootViewController(animated: Bool = true, completion: @escaping ()->()) { + CATransaction.begin() + CATransaction.setCompletionBlock(completion) + self.popToRootViewController(animated: animated) + CATransaction.commit() + } + + func popViewControllerWithHandler(animated: Bool = true, completion: @escaping ()->()) { + CATransaction.begin() + CATransaction.setCompletionBlock(completion) + self.popViewController(animated: animated) + CATransaction.commit() + } + + func pushViewController(viewController: UIViewController, animated: Bool = true, completion: @escaping ()->()) { + CATransaction.begin() + CATransaction.setCompletionBlock(completion) + self.pushViewController(viewController, animated: animated) + CATransaction.commit() + } + +} From f5c361573be908510d45e2113dd1791179759cfd Mon Sep 17 00:00:00 2001 From: Michal Smaga Date: Mon, 22 Jul 2024 11:03:37 +0200 Subject: [PATCH 2/6] Remove obsolete menu item --- DuckDuckGo/SubscriptionDebugViewController.swift | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/DuckDuckGo/SubscriptionDebugViewController.swift b/DuckDuckGo/SubscriptionDebugViewController.swift index 0fe21b6958..a105468563 100644 --- a/DuckDuckGo/SubscriptionDebugViewController.swift +++ b/DuckDuckGo/SubscriptionDebugViewController.swift @@ -51,7 +51,6 @@ import NetworkProtection case restoreSubscription case showAccountDetails case clearAuthData - case injectCredentials } enum SubscriptionRows: Int, CaseIterable { @@ -94,8 +93,6 @@ import NetworkProtection cell.textLabel?.text = "Clear Authorization Data (Sign out)" case .showAccountDetails: cell.textLabel?.text = "Show Account Details" - case .injectCredentials: - cell.textLabel?.text = "Simulate Authentication (Inject Fake token)" case .none: break } @@ -157,7 +154,6 @@ import NetworkProtection case .restoreSubscription: openSubscriptionRestoreFlow() case .clearAuthData: clearAuthData() case .showAccountDetails: showAccountDetails() - case .injectCredentials: injectCredentials() default: break } case .appstore: @@ -241,13 +237,6 @@ import NetworkProtection showAlert(title: "Data cleared!") } - private func injectCredentials() { - subscriptionManager.accountManager.storeAccount(token: "a-fake-token", - email: "a.fake@email.com", - externalID: "666") - showAccountDetails() - } - private func showAccountDetails() { let title = subscriptionManager.accountManager.isUserAuthenticated ? "Authenticated" : "Not Authenticated" let message = subscriptionManager.accountManager.isUserAuthenticated ? From 16f905337fcae330dbeac77a68a0259ad47b0361 Mon Sep 17 00:00:00 2001 From: Michal Smaga Date: Mon, 22 Jul 2024 11:15:08 +0200 Subject: [PATCH 3/6] Clean up debug menu --- .../SubscriptionDebugViewController.swift | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/DuckDuckGo/SubscriptionDebugViewController.swift b/DuckDuckGo/SubscriptionDebugViewController.swift index a105468563..0a2730c25d 100644 --- a/DuckDuckGo/SubscriptionDebugViewController.swift +++ b/DuckDuckGo/SubscriptionDebugViewController.swift @@ -35,27 +35,27 @@ import NetworkProtection private let titles = [ Sections.authorization: "Authentication", - Sections.subscription: "Subscription", + Sections.api: "Make API Call", Sections.appstore: "App Store", Sections.environment: "Environment", ] enum Sections: Int, CaseIterable { case authorization - case subscription + case api case appstore case environment } enum AuthorizationRows: Int, CaseIterable { case restoreSubscription - case showAccountDetails case clearAuthData + case showAccountDetails } enum SubscriptionRows: Int, CaseIterable { case validateToken - case getEntitlements + case checkEntitlements case getSubscription } @@ -90,15 +90,26 @@ import NetworkProtection case .restoreSubscription: cell.textLabel?.text = "I Have a Subscription" case .clearAuthData: - cell.textLabel?.text = "Clear Authorization Data (Sign out)" + cell.textLabel?.text = "Remove Subscription From This Device" case .showAccountDetails: cell.textLabel?.text = "Show Account Details" case .none: break } - case.none: - break + case .api: + switch SubscriptionRows(rawValue: indexPath.row) { + case .validateToken: + cell.textLabel?.text = "Validate Token" + case .checkEntitlements: + cell.textLabel?.text = "Check Entitlements" + case .getSubscription: + cell.textLabel?.text = "Get Subscription Details" + + case .none: + break + } + case .appstore: switch AppStoreRows(rawValue: indexPath.row) { @@ -107,18 +118,6 @@ import NetworkProtection case .none: break } - - case .subscription: - switch SubscriptionRows(rawValue: indexPath.row) { - case .validateToken: - cell.textLabel?.text = "Validate Token" - case .getSubscription: - cell.textLabel?.text = "Get subscription details" - case .getEntitlements: - cell.textLabel?.text = "Get Entitlements" - case .none: - break - } case .environment: let currentEnv = subscriptionManager.currentEnvironment.serviceEnvironment @@ -132,14 +131,18 @@ import NetworkProtection case .none: break } + + case.none: + break } + return cell } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch Sections(rawValue: section) { case .authorization: return AuthorizationRows.allCases.count - case .subscription: return SubscriptionRows.allCases.count + case .api: return SubscriptionRows.allCases.count case .appstore: return AppStoreRows.allCases.count case .environment: return EnvironmentRows.allCases.count case .none: return 0 @@ -161,11 +164,11 @@ import NetworkProtection case .syncAppStoreAccount: syncAppleIDAccount() default: break } - case .subscription: + case .api: switch SubscriptionRows(rawValue: indexPath.row) { case .validateToken: validateToken() - case .getSubscription: getSubscription() - case .getEntitlements: getEntitlements() + case .checkEntitlements: checkEntitlements() + case .getSubscription: getSubscriptionDetails() default: break } case .environment: @@ -275,7 +278,7 @@ import NetworkProtection } } - private func getSubscription() { + private func getSubscriptionDetails() { Task { guard let token = subscriptionManager.accountManager.accessToken else { showAlert(title: "Not authenticated", message: "No authenticated user found! - Subscription not available") @@ -291,7 +294,7 @@ import NetworkProtection } } - private func getEntitlements() { + private func checkEntitlements() { Task { var results: [String] = [] guard subscriptionManager.accountManager.accessToken != nil else { From 5b30f486d0d1f5779c528208fdeca0327f0262b1 Mon Sep 17 00:00:00 2001 From: Michal Smaga Date: Mon, 22 Jul 2024 11:24:21 +0200 Subject: [PATCH 4/6] Accomodate for debug menu shown from long press --- DuckDuckGo/SubscriptionDebugViewController.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/DuckDuckGo/SubscriptionDebugViewController.swift b/DuckDuckGo/SubscriptionDebugViewController.swift index 0a2730c25d..73cc6481b9 100644 --- a/DuckDuckGo/SubscriptionDebugViewController.swift +++ b/DuckDuckGo/SubscriptionDebugViewController.swift @@ -228,9 +228,17 @@ import NetworkProtection private func openSubscriptionRestoreFlow() { guard let mainVC = view.window?.rootViewController as? MainViewController else { return } + if let navigationController = mainVC.presentedViewController as? UINavigationController { + navigationController.popToRootViewController { - mainVC.segueToSubscriptionRestoreFlow() + if navigationController.viewControllers.first is SettingsHostingController { + mainVC.segueToSubscriptionRestoreFlow() + } else { + navigationController.dismiss(animated: true, completion: { + mainVC.segueToSubscriptionRestoreFlow() + }) + } } } } From d2b317220036f18a74b436e8b6c69210d1a8aeb0 Mon Sep 17 00:00:00 2001 From: Michal Smaga Date: Mon, 22 Jul 2024 11:27:49 +0200 Subject: [PATCH 5/6] Rename debug menu entry --- DuckDuckGo/Debug.storyboard | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo/Debug.storyboard b/DuckDuckGo/Debug.storyboard index 2ae12b72f9..c23d8be91a 100644 --- a/DuckDuckGo/Debug.storyboard +++ b/DuckDuckGo/Debug.storyboard @@ -220,7 +220,7 @@ -