From 0257003797ad9edbbbfa49e6a6cc0270174eab4d Mon Sep 17 00:00:00 2001 From: Brad Slayter Date: Wed, 7 Aug 2024 12:37:33 -0500 Subject: [PATCH] DBP waitlist removal (#3074) Task/Issue URL: https://app.asana.com/0/1203581873609357/1206988388191940 Tech Design URL: CC: **Description**: This PR removes all DBP waitlist references and pixels **Steps to test this PR**: 1. Smoke test DBP feature **Definition of Done**: * [ ] Does this PR satisfy our [Definition of Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)? --- ###### Internal references: [Pull Request Review Checklist](https://app.asana.com/0/1202500774821704/1203764234894239/f) [Software Engineering Expectations](https://app.asana.com/0/59792373528535/199064865822552) [Technical Design Template](https://app.asana.com/0/59792373528535/184709971311943) [Pull Request Documentation](https://app.asana.com/0/1202500774821704/1204012835277482/f) --- .../App/DBP/DuckDuckGoDBPAgent.xcconfig | 2 +- .../DBP/DuckDuckGoDBPAgentAppStore.xcconfig | 2 +- Configuration/App/DuckDuckGo.xcconfig | 2 +- Configuration/Common.xcconfig | 2 +- Configuration/Tests/IntegrationTests.xcconfig | 2 +- Configuration/Tests/UnitTests.xcconfig | 2 +- .../Tests/UnitTestsAppStore.xcconfig | 2 +- DuckDuckGo.xcodeproj/project.pbxproj | 12 -- DuckDuckGo/Application/AppDelegate.swift | 10 -- DuckDuckGo/Application/URLEventHandler.swift | 7 - .../Common/Extensions/BundleExtension.swift | 4 - .../Common/Localizables/UserText+DBP.swift | 55 ------- DuckDuckGo/DBP/DBPHomeViewController.swift | 30 ---- .../DBP/DataBrokerProtectionAppEvents.swift | 38 ----- .../DBP/DataBrokerProtectionDebugMenu.swift | 46 ------ ...okerProtectionExternalWaitlistPixels.swift | 46 ------ .../DataBrokerProtectionFeatureDisabler.swift | 23 +-- ...ataBrokerProtectionFeatureGatekeeper.swift | 76 +-------- ...taBrokerProtectionLoginItemInterface.swift | 4 - .../DBP/DataBrokerProtectionManager.swift | 8 - ...erProtectionSubscriptionEventHandler.swift | 3 - .../DBP/LoginItem+DataBrokerProtection.swift | 4 - DuckDuckGo/Menus/MainMenu.swift | 3 - DuckDuckGo/Menus/MainMenuActions.swift | 8 - .../NavigationBar/View/MoreOptionsMenu.swift | 6 - .../View/NavigationBarViewController.swift | 2 - .../Tab/View/BrowserTabViewController.swift | 18 --- .../Storage/WaitlistActivationDateStore.swift | 5 - .../Waitlist/Views/WaitlistRootView.swift | 56 ------- .../WaitlistSteps/InvitedToWaitlistView.swift | 14 -- .../WaitlistSteps/JoinWaitlistView.swift | 14 -- .../WaitlistSteps/JoinedWaitlistView.swift | 15 -- .../WaitlistTermsAndConditionsView.swift | 131 --------------- .../WaitlistThankYouPromptPresenter.swift | 36 +---- .../Waitlist/Views/WaitlistThankYouView.swift | 7 - .../WaitlistViewControllerPresenter.swift | 47 ------ DuckDuckGo/Waitlist/Waitlist.swift | 84 ---------- .../WaitlistFeatureSetupHandler.swift | 12 -- ...tlistTermsAndConditionsActionHandler.swift | 21 --- .../View/WindowControllersManager.swift | 2 - .../DataBrokerProtectionPixelTests.swift | 149 ------------------ ...okerProtectionFeatureGatekeeperTests.swift | 89 ----------- 42 files changed, 18 insertions(+), 1081 deletions(-) delete mode 100644 DuckDuckGo/DBP/DataBrokerProtectionExternalWaitlistPixels.swift delete mode 100644 DuckDuckGo/Waitlist/Views/WaitlistRootView.swift delete mode 100644 LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionPixelTests.swift diff --git a/Configuration/App/DBP/DuckDuckGoDBPAgent.xcconfig b/Configuration/App/DBP/DuckDuckGoDBPAgent.xcconfig index edfa557220..5a43ef574c 100644 --- a/Configuration/App/DBP/DuckDuckGoDBPAgent.xcconfig +++ b/Configuration/App/DBP/DuckDuckGoDBPAgent.xcconfig @@ -47,7 +47,7 @@ PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = macOS DBP Agent - Review PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = macOS DBP Agent - Release -FEATURE_FLAGS = FEEDBACK DBP +FEATURE_FLAGS = FEEDBACK GCC_PREPROCESSOR_DEFINITIONS[arch=*][sdk=*] = DBP=1 NETP_SYSTEM_EXTENSION=1 GCC_PREPROCESSOR_DEFINITIONS[config=CI][arch=*][sdk=*] = DBP=1 NETP_SYSTEM_EXTENSION=1 DEBUG=1 CI=1 $(inherited) diff --git a/Configuration/App/DBP/DuckDuckGoDBPAgentAppStore.xcconfig b/Configuration/App/DBP/DuckDuckGoDBPAgentAppStore.xcconfig index e19a23209a..a38ea9f43e 100644 --- a/Configuration/App/DBP/DuckDuckGoDBPAgentAppStore.xcconfig +++ b/Configuration/App/DBP/DuckDuckGoDBPAgentAppStore.xcconfig @@ -49,7 +49,7 @@ PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = match AppStore com.duckduckgo.mobile.ios.DBP.backgroundAgent.review macos PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = match AppStore com.duckduckgo.mobile.ios.DBP.backgroundAgent macos -FEATURE_FLAGS = FEEDBACK DBP +FEATURE_FLAGS = FEEDBACK GCC_PREPROCESSOR_DEFINITIONS[arch=*][sdk=*] = DBP=1 NETP_SYSTEM_EXTENSION=1 GCC_PREPROCESSOR_DEFINITIONS[config=CI][arch=*][sdk=*] = DBP=1 NETP_SYSTEM_EXTENSION=1 DEBUG=1 CI=1 $(inherited) diff --git a/Configuration/App/DuckDuckGo.xcconfig b/Configuration/App/DuckDuckGo.xcconfig index 8a851a43b1..9747795f35 100644 --- a/Configuration/App/DuckDuckGo.xcconfig +++ b/Configuration/App/DuckDuckGo.xcconfig @@ -26,7 +26,7 @@ CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development CODE_SIGN_IDENTITY[config=CI][sdk=macosx*] = -FEATURE_FLAGS = FEEDBACK SPARKLE DBP STRIPE +FEATURE_FLAGS = FEEDBACK SPARKLE STRIPE PRODUCT_NAME_PREFIX = DuckDuckGo diff --git a/Configuration/Common.xcconfig b/Configuration/Common.xcconfig index 04c51ab42e..e83abad09c 100644 --- a/Configuration/Common.xcconfig +++ b/Configuration/Common.xcconfig @@ -21,7 +21,7 @@ COMBINE_HIDPI_IMAGES = YES DEVELOPMENT_TEAM = HKE973VLUW DEVELOPMENT_TEAM[config=CI][sdk=*] = -FEATURE_FLAGS = FEEDBACK DBP +FEATURE_FLAGS = FEEDBACK GCC_PREPROCESSOR_DEFINITIONS[config=CI][arch=*][sdk=*] = DEBUG=1 CI=1 $(inherited) GCC_PREPROCESSOR_DEFINITIONS[config=Debug][arch=*][sdk=*] = DEBUG=1 $(inherited) diff --git a/Configuration/Tests/IntegrationTests.xcconfig b/Configuration/Tests/IntegrationTests.xcconfig index 5d6620f67b..128cc39a61 100644 --- a/Configuration/Tests/IntegrationTests.xcconfig +++ b/Configuration/Tests/IntegrationTests.xcconfig @@ -17,7 +17,7 @@ MACOSX_DEPLOYMENT_TARGET = 11.4 -FEATURE_FLAGS = FEEDBACK DBP +FEATURE_FLAGS = FEEDBACK INFOPLIST_FILE = IntegrationTests/Info.plist PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.Integration-Tests diff --git a/Configuration/Tests/UnitTests.xcconfig b/Configuration/Tests/UnitTests.xcconfig index 7f15939313..24d10b6755 100644 --- a/Configuration/Tests/UnitTests.xcconfig +++ b/Configuration/Tests/UnitTests.xcconfig @@ -17,7 +17,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -FEATURE_FLAGS = FEEDBACK DBP +FEATURE_FLAGS = FEEDBACK INFOPLIST_FILE = UnitTests/Info.plist PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.macos.browser.DuckDuckGoTests diff --git a/Configuration/Tests/UnitTestsAppStore.xcconfig b/Configuration/Tests/UnitTestsAppStore.xcconfig index e187624399..fb90843360 100644 --- a/Configuration/Tests/UnitTestsAppStore.xcconfig +++ b/Configuration/Tests/UnitTestsAppStore.xcconfig @@ -16,7 +16,7 @@ #include "UnitTests.xcconfig" #include "../AppStore.xcconfig" -FEATURE_FLAGS = FEEDBACK DBP +FEATURE_FLAGS = FEEDBACK PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.mobile.ios.DuckDuckGoTests diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index a7d9a41cba..69668943f2 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1322,8 +1322,6 @@ 4B9DB0422A983B24000927DB /* WaitlistDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0182A983B24000927DB /* WaitlistDialogView.swift */; }; 4B9DB0442A983B24000927DB /* WaitlistModalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0192A983B24000927DB /* WaitlistModalViewController.swift */; }; 4B9DB0452A983B24000927DB /* WaitlistModalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0192A983B24000927DB /* WaitlistModalViewController.swift */; }; - 4B9DB0472A983B24000927DB /* WaitlistRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB01A2A983B24000927DB /* WaitlistRootView.swift */; }; - 4B9DB0482A983B24000927DB /* WaitlistRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB01A2A983B24000927DB /* WaitlistRootView.swift */; }; 4B9DB04A2A983B24000927DB /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB01C2A983B24000927DB /* NotificationService.swift */; }; 4B9DB04B2A983B24000927DB /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB01C2A983B24000927DB /* NotificationService.swift */; }; 4B9DB0542A983B55000927DB /* MockWaitlistStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB04F2A983B55000927DB /* MockWaitlistStorage.swift */; }; @@ -2542,8 +2540,6 @@ BBB881892C4029BA001247C6 /* BookmarkListTreeControllerSearchDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB881872C4029BA001247C6 /* BookmarkListTreeControllerSearchDataSource.swift */; }; BBBEE1BF2C4FF63600035ABA /* SortBookmarksViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBEE1BE2C4FF63600035ABA /* SortBookmarksViewModelTests.swift */; }; BBBEE1C02C4FF63600035ABA /* SortBookmarksViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBEE1BE2C4FF63600035ABA /* SortBookmarksViewModelTests.swift */; }; - BBDFDC5A2B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */; }; - BBDFDC5D2B2B8E2100F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */; }; BBFB727F2C48047C0088884C /* SortBookmarksViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFB727E2C48047C0088884C /* SortBookmarksViewModel.swift */; }; BBFB72802C48047C0088884C /* SortBookmarksViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFB727E2C48047C0088884C /* SortBookmarksViewModel.swift */; }; BBFF355D2C4AF26200DA3289 /* BookmarksSortModeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFF355C2C4AF26200DA3289 /* BookmarksSortModeTests.swift */; }; @@ -3382,7 +3378,6 @@ 4B9DB0172A983B24000927DB /* JoinWaitlistView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JoinWaitlistView.swift; sourceTree = ""; }; 4B9DB0182A983B24000927DB /* WaitlistDialogView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WaitlistDialogView.swift; sourceTree = ""; }; 4B9DB0192A983B24000927DB /* WaitlistModalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WaitlistModalViewController.swift; sourceTree = ""; }; - 4B9DB01A2A983B24000927DB /* WaitlistRootView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WaitlistRootView.swift; sourceTree = ""; }; 4B9DB01C2A983B24000927DB /* NotificationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; 4B9DB04F2A983B55000927DB /* MockWaitlistStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockWaitlistStorage.swift; sourceTree = ""; }; 4B9DB0502A983B55000927DB /* MockNotificationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockNotificationService.swift; sourceTree = ""; }; @@ -4229,7 +4224,6 @@ BB7B5F972C4ED73800BA4AF8 /* BookmarksSearchAndSortMetrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksSearchAndSortMetrics.swift; sourceTree = ""; }; BBB881872C4029BA001247C6 /* BookmarkListTreeControllerSearchDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkListTreeControllerSearchDataSource.swift; sourceTree = ""; }; BBBEE1BE2C4FF63600035ABA /* SortBookmarksViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortBookmarksViewModelTests.swift; sourceTree = ""; }; - BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionExternalWaitlistPixels.swift; sourceTree = ""; }; BBFB727E2C48047C0088884C /* SortBookmarksViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortBookmarksViewModel.swift; sourceTree = ""; }; BBFF355C2C4AF26200DA3289 /* BookmarksSortModeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksSortModeTests.swift; sourceTree = ""; }; BD384AC72BBC821100EF3735 /* vpn-light-mode.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "vpn-light-mode.json"; sourceTree = ""; }; @@ -4830,7 +4824,6 @@ 316913252BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift */, 3199C6FC2AF97367002A7BA1 /* DataBrokerProtectionAppEvents.swift */, 316850712AF3AD58009A2828 /* DataBrokerProtectionDebugMenu.swift */, - BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */, 3199C6F82AF94F5B002A7BA1 /* DataBrokerProtectionFeatureDisabler.swift */, 31C5FFB82AF64D120008A79F /* DataBrokerProtectionFeatureGatekeeper.swift */, F1C70D782BFF50A400599292 /* DataBrokerProtectionLoginItemInterface.swift */, @@ -5771,7 +5764,6 @@ 4B9DB0182A983B24000927DB /* WaitlistDialogView.swift */, 4B9DB0192A983B24000927DB /* WaitlistModalViewController.swift */, 3168506C2AF3AD1C009A2828 /* WaitlistViewControllerPresenter.swift */, - 4B9DB01A2A983B24000927DB /* WaitlistRootView.swift */, 4B520F622BA5573A006405C7 /* WaitlistThankYouView.swift */, 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */, ); @@ -10046,10 +10038,8 @@ 3706FAFD293F65D500E42796 /* DownloadsPopover.swift in Sources */, 3706FAFE293F65D500E42796 /* SpacerNode.swift in Sources */, 3706FB00293F65D500E42796 /* PasswordManagementCreditCardModel.swift in Sources */, - BBDFDC5D2B2B8E2100F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift in Sources */, 3706FB01293F65D500E42796 /* NSEventExtension.swift in Sources */, 3706FB02293F65D500E42796 /* Onboarding.swift in Sources */, - 4B9DB0482A983B24000927DB /* WaitlistRootView.swift in Sources */, 3706FEB8293F6EFB00E42796 /* ConnectBitwardenView.swift in Sources */, 1DFAB51E2A8982A600A0F7F6 /* SetExtension.swift in Sources */, B60C6F8E29B200AB007BFAA8 /* SavePanelAccessoryView.swift in Sources */, @@ -11511,7 +11501,6 @@ 9F6434612BEC82B700D2D8A0 /* AttributionPixelHandler.swift in Sources */, B684592225C93BE000DC17B6 /* Publisher.asVoid.swift in Sources */, 4B9DB01D2A983B24000927DB /* Waitlist.swift in Sources */, - BBDFDC5A2B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift in Sources */, AAA0CC33252F181A0079BC96 /* NavigationButtonMenuDelegate.swift in Sources */, 1DA84D2F2C11989D0011C80F /* Update.swift in Sources */, AAC30A2A268E239100D2D9CD /* CrashReport.swift in Sources */, @@ -11910,7 +11899,6 @@ AA7EB6E527E7D6DC00036718 /* AnimationView.swift in Sources */, 8562599A269CA0A600EE44BC /* NSRectExtension.swift in Sources */, 4B37EE5F2B4CFC3C00A89A61 /* HomePageRemoteMessagingStorage.swift in Sources */, - 4B9DB0472A983B24000927DB /* WaitlistRootView.swift in Sources */, 31F28C5128C8EEC500119F70 /* YoutubeOverlayUserScript.swift in Sources */, B6ABD0CA2BC03F610000EB69 /* SecurityScopedFileURLController.swift in Sources */, B6040856274B830F00680351 /* DictionaryExtension.swift in Sources */, diff --git a/DuckDuckGo/Application/AppDelegate.swift b/DuckDuckGo/Application/AppDelegate.swift index 45cc31c17a..0978ae7504 100644 --- a/DuckDuckGo/Application/AppDelegate.swift +++ b/DuckDuckGo/Application/AppDelegate.swift @@ -106,7 +106,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate { // MARK: - DBP -#if DBP private lazy var dataBrokerProtectionSubscriptionEventHandler: DataBrokerProtectionSubscriptionEventHandler = { let authManager = DataBrokerAuthenticationManagerBuilder.buildAuthenticationManager(subscriptionManager: subscriptionManager) return DataBrokerProtectionSubscriptionEventHandler(featureDisabler: DataBrokerProtectionFeatureDisabler(), @@ -114,8 +113,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate { pixelHandler: DataBrokerProtectionPixelsHandler()) }() -#endif - private lazy var vpnRedditSessionWorkaround: VPNRedditSessionWorkaround = { let ipcClient = VPNControllerXPCClient.shared let statusReporter = DefaultNetworkProtectionStatusReporter( @@ -374,13 +371,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate { NetworkProtectionAppEvents(featureGatekeeper: DefaultVPNFeatureGatekeeper(subscriptionManager: subscriptionManager)).applicationDidFinishLaunching() UNUserNotificationCenter.current().delegate = self -#if DBP dataBrokerProtectionSubscriptionEventHandler.registerForSubscriptionAccountManagerEvents() -#endif - -#if DBP DataBrokerProtectionAppEvents(featureGatekeeper: DefaultDataBrokerProtectionFeatureGatekeeper(accountManager: subscriptionManager.accountManager)).applicationDidFinishLaunching() -#endif setUpAutoClearHandler() @@ -427,11 +419,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate { NetworkProtectionAppEvents(featureGatekeeper: DefaultVPNFeatureGatekeeper(subscriptionManager: subscriptionManager)).applicationDidBecomeActive() -#if DBP DataBrokerProtectionAppEvents(featureGatekeeper: DefaultDataBrokerProtectionFeatureGatekeeper(accountManager: subscriptionManager.accountManager)).applicationDidBecomeActive() -#endif subscriptionManager.refreshCachedSubscriptionAndEntitlements { isSubscriptionActive in if isSubscriptionActive { diff --git a/DuckDuckGo/Application/URLEventHandler.swift b/DuckDuckGo/Application/URLEventHandler.swift index 596737458a..8e79662a1c 100644 --- a/DuckDuckGo/Application/URLEventHandler.swift +++ b/DuckDuckGo/Application/URLEventHandler.swift @@ -23,10 +23,7 @@ import PixelKit import Subscription import NetworkProtectionUI import VPNAppLauncher - -#if DBP import DataBrokerProtection -#endif // @MainActor final class URLEventHandler { @@ -117,11 +114,9 @@ final class URLEventHandler { } } -#if DBP if url.scheme?.isDataBrokerProtectionScheme == true { handleDataBrokerProtectionURL(url) } -#endif DispatchQueue.main.async { if url.isFileURL && url.pathExtension == WebKitDownloadTask.downloadExtension { @@ -146,7 +141,6 @@ final class URLEventHandler { } } -#if DBP /// Handles DBP URLs /// private static func handleDataBrokerProtectionURL(_ url: URL) { @@ -160,7 +154,6 @@ final class URLEventHandler { return } } -#endif } private extension String { diff --git a/DuckDuckGo/Common/Extensions/BundleExtension.swift b/DuckDuckGo/Common/Extensions/BundleExtension.swift index 76fb870b32..3ac81f66f5 100644 --- a/DuckDuckGo/Common/Extensions/BundleExtension.swift +++ b/DuckDuckGo/Common/Extensions/BundleExtension.swift @@ -38,10 +38,8 @@ extension Bundle { static let ipcAppGroup = "IPC_APP_GROUP" -#if DBP static let dbpBackgroundAgentBundleId = "DBP_BACKGROUND_AGENT_BUNDLE_ID" static let dbpBackgroundAgentProductName = "DBP_BACKGROUND_AGENT_PRODUCT_NAME" -#endif } var buildNumber: String { @@ -87,7 +85,6 @@ extension Bundle { } #endif -#if DBP var dbpBackgroundAgentBundleId: String { guard let bundleID = object(forInfoDictionaryKey: Keys.dbpBackgroundAgentBundleId) as? String else { fatalError("Info.plist is missing \(Keys.dbpBackgroundAgentBundleId)") @@ -101,7 +98,6 @@ extension Bundle { } return loginItemsURL.appendingPathComponent(productName + ".app") } -#endif func appGroup(bundle: BundleGroup) -> String { let appGroupName = bundle.appGroupKey diff --git a/DuckDuckGo/Common/Localizables/UserText+DBP.swift b/DuckDuckGo/Common/Localizables/UserText+DBP.swift index 65590075e0..19ed7535b0 100644 --- a/DuckDuckGo/Common/Localizables/UserText+DBP.swift +++ b/DuckDuckGo/Common/Localizables/UserText+DBP.swift @@ -19,59 +19,6 @@ import Foundation import Common -#if DBP -// MARK: - Data Broker Protection Waitlist -extension UserText { - // "data-broker-protection.privacy-policy.title" - Privacy Policy title for Personal Information Removal - static let dataBrokerProtectionPrivacyPolicyTitle = "Privacy Policy" - // "data-broker-protection.waitlist.notification.title" - Title for Personal Information Removal waitlist notification - static let dataBrokerProtectionWaitlistNotificationTitle = "Personal Information Removal beta is ready!" - // "data-broker-protection.waitlist.notification.text" - Title for Personal Information Removal waitlist notification - static let dataBrokerProtectionWaitlistNotificationText = "Open your invite" - // "data-broker-protection.waitlist.join.title" - Title for Personal Information Removal join waitlist screen - static let dataBrokerProtectionWaitlistJoinTitle = "Personal Information Removal Beta" - // "data-broker-protection.waitlist.join.subtitle.1" - First subtitle for Personal Information Removal join waitlist screen - static let dataBrokerProtectionWaitlistJoinSubtitle1 = "Automatically scan and remove your data from 17+ sites that sell personal information with DuckDuckGo’s Personal Information Removal." - // "data-broker-protection.waitlist.joined.title" - Title for Personal Information Removal joined waitlist screen - static let dataBrokerProtectionWaitlistJoinedTitle = "You’re on the list!" - // "data-broker-protection.waitlist.joined.with-notifications.subtitle.1" - Subtitle 1 for Personal Information Removal joined waitlist screen when notifications are enabled - static let dataBrokerProtectionWaitlistJoinedWithNotificationsSubtitle1 = "New invites are sent every few days, on a first come, first served basis." - // "data-broker-protection.waitlist.joined.with-notifications.subtitle.2" - Subtitle 2 for Personal Information Removal joined waitlist screen when notifications are enabled - static let dataBrokerProtectionWaitlistJoinedWithNotificationsSubtitle2 = "We’ll notify you when your invite is ready." - // "data-broker-protection.waitlist.enable-notifications" - Enable notifications prompt for Personal Information Removal joined waitlist screen - static let dataBrokerProtectionWaitlistEnableNotifications = "Want to get a notification when your Personal Information Removal invite is ready?" - // "data-broker-protection.waitlist.invited.title" - Title for Personal Information Removal invited screen - static let dataBrokerProtectionWaitlistInvitedTitle = "You’re invited to try\nPersonal Information Removal beta!" - // "data-broker-protection.waitlist.invited.subtitle" - Subtitle for Personal Information Removal invited screen - static let dataBrokerProtectionWaitlistInvitedSubtitle = "Automatically find and remove your personal information – such as your name and address – from 17+ sites that store and sell it, reducing the risk of identity theft and spam." - // "data-broker-protection.waitlist.enable.title" - Title for Personal Information Removal enable screen - static let dataBrokerProtectionWaitlistEnableTitle = "Let’s get started" - // "data-broker-protection.waitlist.enable.subtitle" - Subtitle for Personal Information Removal enable screen - static let dataBrokerProtectionWaitlistEnableSubtitle = "We’ll need your name, address and the year you were born in order to find your personal information on data broker sites\n\nThis info is stored securely on your device, and is never sent to DuckDuckGo." - // "data-broker-protection.waitlist.availability-disclaimer" - Availability disclaimer for Personal Information Removal join waitlist screen - static let dataBrokerProtectionWaitlistAvailabilityDisclaimer = "Personal Information Removal is free during the beta.\nJoin the waitlist and we'll notify you when ready." - // "data-broker-protection.waitlist.button.close" - Close button for Personal Information Removal join waitlist screen - static let dataBrokerProtectionWaitlistButtonClose = "Close" - // "data-broker-protection.waitlist.button.done" - Close button for Personal Information Removal joined waitlist screen - static let dataBrokerProtectionWaitlistButtonDone = "Done" - // "data-broker-protection.waitlist.button.dismiss" - Dismiss button for Personal Information Removal join waitlist screen - static let dataBrokerProtectionWaitlistButtonDismiss = "Dismiss" - // "data-broker-protection.waitlist.button.cancel" - Cancel button for Personal Information Removal join waitlist screen - static let dataBrokerProtectionWaitlistButtonCancel = "Cancel" - // "data-broker-protection.waitlist.button.no-thanks" - No Thanks button for Personal Information Removal joined waitlist screen - static let dataBrokerProtectionWaitlistButtonNoThanks = "No Thanks" - // "data-broker-protection.waitlist.button.get-started" - Get Started button for Personal Information Removal joined waitlist screen - static let dataBrokerProtectionWaitlistButtonGetStarted = "Get Started" - // "data-broker-protection.waitlist.button.got-it" - Get started button for Personal Information Removal joined waitlist screen - static let dataBrokerProtectionWaitlistButtonGotIt = "Get started" - // "data-broker-protection.waitlist.button.enable-notifications" - Enable Notifications button for Personal Information Removal joined waitlist screen - static let dataBrokerProtectionWaitlistButtonEnableNotifications = "Enable Notifications" - // "data-broker-protection.waitlist.button.join-waitlist" - Join Waitlist button for Personal Information Removal join waitlist screen - static let dataBrokerProtectionWaitlistButtonJoinWaitlist = "Join the Waitlist" - // "data-broker-protection.waitlist.button.agree-and-continue" - Agree and Continue button for Personal Information Removal join waitlist screen - static let dataBrokerProtectionWaitlistButtonAgreeAndContinue = "Agree and Continue" -} - // MARK: - DBP Error pages extension UserText { static let dbpErrorPageBadPathTitle = NotLocalizedString("dbp.errorpage.bad.path.title", value: "Move DuckDuckGo App to Applications", comment: "Title for Personal Information Removal bad path error screen") @@ -82,5 +29,3 @@ extension UserText { static let dbpErrorPageNoPermissionMessage = NotLocalizedString("dbp.errorpage.no.permission.message", value: "Open System Settings and allow DuckDuckGo Personal Information Removal to run in the background.", comment: "Message for error screen when there is no permission") static let dbpErrorPageNoPermissionCTA = NotLocalizedString("dbp.errorpage.no.permission.cta", value: "Open System Settings...", comment: "Call to action for opening system settings") } - -#endif diff --git a/DuckDuckGo/DBP/DBPHomeViewController.swift b/DuckDuckGo/DBP/DBPHomeViewController.swift index 9f1848bcbe..6da4daef5e 100644 --- a/DuckDuckGo/DBP/DBPHomeViewController.swift +++ b/DuckDuckGo/DBP/DBPHomeViewController.swift @@ -16,8 +16,6 @@ // limitations under the License. // -#if DBP - import Foundation import DataBrokerProtection import AppKit @@ -90,16 +88,6 @@ final class DBPHomeViewController: NSViewController { setupUI() setupObserver() - - do { - if try dataBrokerProtectionManager.dataManager.fetchProfile() != nil { - let dbpDateStore = DefaultWaitlistActivationDateStore(source: .dbp) - dbpDateStore.updateLastActiveDate() - } - } catch { - os_log("DBPHomeViewController error: viewDidLoad, error: %{public}@", log: .error, error.localizedDescription) - pixelHandler.fire(.generalError(error: error, functionOccurredIn: "DBPHomeViewController.viewDidLoad")) - } } override func viewDidAppear() { @@ -128,22 +116,6 @@ final class DBPHomeViewController: NSViewController { } } - private func presentInviteCodeFlow() { - let viewModel = DataBrokerProtectionInviteDialogsViewModel(delegate: self) - - let view = DataBrokerProtectionInviteDialogsView(viewModel: viewModel) - let hostingVC = NSHostingController(rootView: view) - presentedWindowController = hostingVC.wrappedInWindowController() - - guard let newWindow = presentedWindowController?.window, - let parentWindowController = WindowControllersManager.shared.lastKeyMainWindowController - else { - assertionFailure("Failed to present \(hostingVC)") - return - } - parentWindowController.window?.beginSheet(newWindow) - } - private func setupUIWithCurrentStatus() { setupUIWithStatus(prerequisiteVerifier.checkStatus()) } @@ -252,5 +224,3 @@ extension DBPHomeViewController { } } } - -#endif diff --git a/DuckDuckGo/DBP/DataBrokerProtectionAppEvents.swift b/DuckDuckGo/DBP/DataBrokerProtectionAppEvents.swift index 4c98934cc4..4eeb776e44 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionAppEvents.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionAppEvents.swift @@ -16,8 +16,6 @@ // limitations under the License. // -#if DBP - import Foundation import LoginItems import Common @@ -46,15 +44,6 @@ struct DataBrokerProtectionAppEvents { } func applicationDidFinishLaunching() { - guard !featureGatekeeper.cleanUpDBPForPrivacyProIfNecessary() else { return } - - /// If the user is not in the waitlist and Privacy Pro flag is false, we want to remove the data for waitlist users - /// since the waitlist flag might have been turned off - if !featureGatekeeper.isFeatureVisible() && !featureGatekeeper.isPrivacyProEnabled() { - featureGatekeeper.disableAndDeleteForWaitlistUsers() - return - } - let loginItemsManager = LoginItemsManager() let loginItemInterface = DataBrokerProtectionManager.shared.loginItemInterface @@ -68,8 +57,6 @@ struct DataBrokerProtectionAppEvents { // Wait to make sure the agent has had time to restart before attempting to call a method on it try await Task.sleep(nanoseconds: 1_000_000_000) loginItemInterface.appLaunched() - } else { - featureGatekeeper.disableAndDeleteForWaitlistUsers() } } @@ -85,29 +72,6 @@ struct DataBrokerProtectionAppEvents { return } } - - guard !featureGatekeeper.cleanUpDBPForPrivacyProIfNecessary() else { return } - - /// If the user is not in the waitlist and Privacy Pro flag is false, we want to remove the data for waitlist users - /// since the waitlist flag might have been turned off - if !featureGatekeeper.isFeatureVisible() && !featureGatekeeper.isPrivacyProEnabled() { - featureGatekeeper.disableAndDeleteForWaitlistUsers() - return - } - } - - @MainActor - func handleWaitlistInvitedNotification(source: WaitlistNotificationSource) { - if DataBrokerProtectionWaitlist().readyToAcceptTermsAndConditions { - switch source { - case .cardUI: - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistCardUITapped, frequency: .dailyAndCount) - case .localPush: - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistNotificationTapped, frequency: .dailyAndCount) - } - - DataBrokerProtectionWaitlistViewControllerPresenter.show() - } } private func restartBackgroundAgent(loginItemsManager: LoginItemsManager) { @@ -118,5 +82,3 @@ struct DataBrokerProtectionAppEvents { // restartLoginItems doesn't work when we change the agent name } } - -#endif diff --git a/DuckDuckGo/DBP/DataBrokerProtectionDebugMenu.swift b/DuckDuckGo/DBP/DataBrokerProtectionDebugMenu.swift index a01fa5dc20..660cf055c5 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionDebugMenu.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionDebugMenu.swift @@ -16,8 +16,6 @@ // limitations under the License. // -#if DBP - import DataBrokerProtection import Foundation import AppKit @@ -56,25 +54,6 @@ final class DataBrokerProtectionDebugMenu: NSMenu { super.init(title: "Personal Information Removal") buildItems { - NSMenuItem(title: "Waitlist") { - NSMenuItem(title: "Reset Waitlist State", action: #selector(DataBrokerProtectionDebugMenu.resetWaitlistState)) - .targetting(self) - NSMenuItem(title: "Reset T&C Acceptance", action: #selector(DataBrokerProtectionDebugMenu.resetTermsAndConditionsAcceptance)) - .targetting(self) - - NSMenuItem(title: "Send Notification", action: #selector(DataBrokerProtectionDebugMenu.sendWaitlistAvailableNotification)) - .targetting(self) - - NSMenuItem.separator() - - NSMenuItem.separator() - - waitlistTokenItem - waitlistTimestampItem - waitlistInviteCodeItem - waitlistTermsAndConditionsAcceptedItem - } - NSMenuItem(title: "Environment") .submenu(environmentMenu) @@ -231,7 +210,6 @@ final class DataBrokerProtectionDebugMenu: NSMenu { @objc private func deleteAllDataAndStopAgent() { Task { @MainActor in guard case .alertFirstButtonReturn = await NSAlert.removeAllDBPStateAndDataAlert().runModal() else { return } - resetWaitlistState() DataBrokerProtectionFeatureDisabler().disableAndDelete() } } @@ -292,28 +270,6 @@ final class DataBrokerProtectionDebugMenu: NSMenu { } } - @objc private func resetWaitlistState() { - DataBrokerProtectionWaitlist().waitlistStorage.deleteWaitlistState() - KeychainAuthenticationData().reset() - - UserDefaults().removeObject(forKey: UserDefaultsWrapper.Key.shouldShowDBPWaitlistInvitedCardUI.rawValue) - UserDefaults().removeObject(forKey: UserDefaultsWrapper.Key.dataBrokerProtectionTermsAndConditionsAccepted.rawValue) - NotificationCenter.default.post(name: .dataBrokerProtectionWaitlistAccessChanged, object: nil) - os_log("DBP waitlist state cleaned", log: .dataBrokerProtection) - } - - @objc private func resetTermsAndConditionsAcceptance() { - UserDefaults().removeObject(forKey: UserDefaultsWrapper.Key.dataBrokerProtectionTermsAndConditionsAccepted.rawValue) - NotificationCenter.default.post(name: .dataBrokerProtectionWaitlistAccessChanged, object: nil) - os_log("DBP waitlist terms and conditions cleaned", log: .dataBrokerProtection) - } - - @objc private func sendWaitlistAvailableNotification() { - DataBrokerProtectionWaitlist().sendInviteCodeAvailableNotification(completion: nil) - - os_log("DBP waitlist notification sent", log: .dataBrokerProtection) - } - @objc private func toggleShowStatusMenuItem() { settings.showInMenuBar.toggle() } @@ -384,5 +340,3 @@ extension DataBrokerProtectionDebugMenu: NSWindowDelegate { dataBrokerForceOptOutWindowController = nil } } - -#endif diff --git a/DuckDuckGo/DBP/DataBrokerProtectionExternalWaitlistPixels.swift b/DuckDuckGo/DBP/DataBrokerProtectionExternalWaitlistPixels.swift deleted file mode 100644 index f23a4884a5..0000000000 --- a/DuckDuckGo/DBP/DataBrokerProtectionExternalWaitlistPixels.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// DataBrokerProtectionExternalWaitlistPixels.swift -// -// Copyright © 2023 DuckDuckGo. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -import PixelKit - -struct DataBrokerProtectionExternalWaitlistPixels { - - static var isUserLocaleAllowed: Bool { - var regionCode: String? - if #available(macOS 13, *) { - regionCode = Locale.current.region?.identifier - } else { - regionCode = Locale.current.regionCode - } - -#if DEBUG // Always assume US for debug builds - regionCode = "US" -#endif - - return (regionCode ?? "US") == "US" - } - - static func fire(pixel: PixelKitEventV2, frequency: PixelKit.Frequency) { - if Self.isUserLocaleAllowed { - let isInternalUser = NSApp.delegateTyped.internalUserDecider.isInternalUser - let parameters = ["isInternalUser": isInternalUser.description] - PixelKit.fire(pixel, frequency: frequency, withAdditionalParameters: parameters) - } - } -} diff --git a/DuckDuckGo/DBP/DataBrokerProtectionFeatureDisabler.swift b/DuckDuckGo/DBP/DataBrokerProtectionFeatureDisabler.swift index 1e81a281e8..66df557611 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionFeatureDisabler.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionFeatureDisabler.swift @@ -16,8 +16,6 @@ // limitations under the License. // -#if DBP - import Foundation import DataBrokerProtection import Common @@ -41,19 +39,14 @@ struct DataBrokerProtectionFeatureDisabler: DataBrokerProtectionFeatureDisabling } func disableAndDelete() { - if !DefaultDataBrokerProtectionFeatureGatekeeper.bypassWaitlist { - - do { - try dataManager.removeAllData() - // the dataManagers delegate handles login item disabling - } catch { - os_log("DataBrokerProtectionFeatureDisabler error: disableAndDelete, error: %{public}@", log: .error, error.localizedDescription) - } - - DataBrokerProtectionLoginItemPixels.fire(pixel: GeneralPixel.dataBrokerDisableAndDeleteDaily, frequency: .daily) - NotificationCenter.default.post(name: .dbpWasDisabled, object: nil) + do { + try dataManager.removeAllData() + // the dataManagers delegate handles login item disabling + } catch { + os_log("DataBrokerProtectionFeatureDisabler error: disableAndDelete, error: %{public}@", log: .error, error.localizedDescription) } + + DataBrokerProtectionLoginItemPixels.fire(pixel: GeneralPixel.dataBrokerDisableAndDeleteDaily, frequency: .daily) + NotificationCenter.default.post(name: .dbpWasDisabled, object: nil) } } - -#endif diff --git a/DuckDuckGo/DBP/DataBrokerProtectionFeatureGatekeeper.swift b/DuckDuckGo/DBP/DataBrokerProtectionFeatureGatekeeper.swift index 8437d6962c..491ca77a52 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionFeatureGatekeeper.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionFeatureGatekeeper.swift @@ -16,8 +16,6 @@ // limitations under the License. // -#if DBP - import Foundation import BrowserServicesKit import Common @@ -25,13 +23,9 @@ import DataBrokerProtection import Subscription protocol DataBrokerProtectionFeatureGatekeeper { - var waitlistIsOngoing: Bool { get } func isFeatureVisible() -> Bool func disableAndDeleteForAllUsers() - func disableAndDeleteForWaitlistUsers() func isPrivacyProEnabled() -> Bool - func isEligibleForThankYouMessage() -> Bool - func cleanUpDBPForPrivacyProIfNecessary() -> Bool func arePrerequisitesSatisfied() async -> Bool } @@ -40,35 +34,23 @@ struct DefaultDataBrokerProtectionFeatureGatekeeper: DataBrokerProtectionFeature private let featureDisabler: DataBrokerProtectionFeatureDisabling private let pixelHandler: EventMapping private let userDefaults: UserDefaults - private let waitlistStorage: WaitlistStorage private let subscriptionAvailability: SubscriptionFeatureAvailability private let accountManager: AccountManager - private let dataBrokerProtectionKey = "data-broker-protection.cleaned-up-from-waitlist-to-privacy-pro" - - /// Temporary code to use while we have both redeem flow for diary study users. Should be removed later - static var bypassWaitlist = false - init(privacyConfigurationManager: PrivacyConfigurationManaging = ContentBlocking.shared.privacyConfigurationManager, featureDisabler: DataBrokerProtectionFeatureDisabling = DataBrokerProtectionFeatureDisabler(), pixelHandler: EventMapping = DataBrokerProtectionPixelsHandler(), userDefaults: UserDefaults = .standard, - waitlistStorage: WaitlistStorage = DataBrokerProtectionWaitlist().waitlistStorage, subscriptionAvailability: SubscriptionFeatureAvailability = DefaultSubscriptionFeatureAvailability(), accountManager: AccountManager) { self.privacyConfigurationManager = privacyConfigurationManager self.featureDisabler = featureDisabler self.pixelHandler = pixelHandler self.userDefaults = userDefaults - self.waitlistStorage = waitlistStorage self.subscriptionAvailability = subscriptionAvailability self.accountManager = accountManager } - var waitlistIsOngoing: Bool { - isWaitlistEnabled && isWaitlistBetaActive - } - var isUserLocaleAllowed: Bool { var regionCode: String? if #available(macOS 13, *) { @@ -91,36 +73,12 @@ struct DefaultDataBrokerProtectionFeatureGatekeeper: DataBrokerProtectionFeature return subscriptionAvailability.isFeatureAvailable } - func isEligibleForThankYouMessage() -> Bool { - return wasWaitlistUser && isPrivacyProEnabled() - } - func disableAndDeleteForAllUsers() { featureDisabler.disableAndDelete() os_log("Disabling and removing DBP for all users", log: .dataBrokerProtection) } - func disableAndDeleteForWaitlistUsers() { - guard isWaitlistUser else { - return - } - - os_log("Disabling and removing DBP for waitlist users", log: .dataBrokerProtection) - featureDisabler.disableAndDelete() - } - - /// Returns true if a cleanup was performed, false otherwise - func cleanUpDBPForPrivacyProIfNecessary() -> Bool { - if isPrivacyProEnabled() && wasWaitlistUser && !dataBrokerProtectionCleanedUpFromWaitlistToPrivacyPro { - disableAndDeleteForWaitlistUsers() - dataBrokerProtectionCleanedUpFromWaitlistToPrivacyPro = true - return true - } else { - return false - } - } - /// If we want to prevent new users from joining the waitlist while still allowing waitlist users to continue using it, /// we should set isWaitlistEnabled to false and isWaitlistBetaActive to true. /// To remove it from everyone, isWaitlistBetaActive should be set to false @@ -129,13 +87,7 @@ struct DefaultDataBrokerProtectionFeatureGatekeeper: DataBrokerProtectionFeature guard isUserLocaleAllowed else { return false } // US internal users should have it available by default - guard !isInternalUser else { return true } - - if isWaitlistUser { - return isWaitlistBetaActive - } else { - return isWaitlistEnabled && isWaitlistBetaActive - } + return isInternalUser } func arePrerequisitesSatisfied() async -> Bool { @@ -159,35 +111,10 @@ struct DefaultDataBrokerProtectionFeatureGatekeeper: DataBrokerProtectionFeature private extension DefaultDataBrokerProtectionFeatureGatekeeper { - var dataBrokerProtectionCleanedUpFromWaitlistToPrivacyPro: Bool { - get { - return userDefaults.bool(forKey: dataBrokerProtectionKey) - } - nonmutating set { - userDefaults.set(newValue, forKey: dataBrokerProtectionKey) - } - } - var isInternalUser: Bool { NSApp.delegateTyped.internalUserDecider.isInternalUser } - var isWaitlistBetaActive: Bool { - return privacyConfigurationManager.privacyConfig.isSubfeatureEnabled(DBPSubfeature.waitlistBetaActive) - } - - var isWaitlistEnabled: Bool { - return privacyConfigurationManager.privacyConfig.isSubfeatureEnabled(DBPSubfeature.waitlist) - } - - var isWaitlistUser: Bool { - waitlistStorage.isWaitlistUser - } - - var wasWaitlistUser: Bool { - waitlistStorage.getWaitlistInviteCode() != nil - } - func firePrerequisitePixelsAndLogIfNecessary(hasEntitlements: Bool, isAuthenticatedResult: Bool) { if !hasEntitlements { pixelHandler.fire(.gatekeeperEntitlementsInvalid) @@ -200,4 +127,3 @@ private extension DefaultDataBrokerProtectionFeatureGatekeeper { } } } -#endif diff --git a/DuckDuckGo/DBP/DataBrokerProtectionLoginItemInterface.swift b/DuckDuckGo/DBP/DataBrokerProtectionLoginItemInterface.swift index c4e86483c9..881312dd17 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionLoginItemInterface.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionLoginItemInterface.swift @@ -16,8 +16,6 @@ // limitations under the License. // -#if DBP - import Foundation import DataBrokerProtection import Common @@ -115,5 +113,3 @@ extension DefaultDataBrokerProtectionLoginItemInterface: DataBrokerProtectionLog return await ipcClient.getDebugMetadata() } } - -#endif diff --git a/DuckDuckGo/DBP/DataBrokerProtectionManager.swift b/DuckDuckGo/DBP/DataBrokerProtectionManager.swift index 3a181f4594..d1ba4d7367 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionManager.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionManager.swift @@ -16,8 +16,6 @@ // limitations under the License. // -#if DBP - import Foundation import BrowserServicesKit import DataBrokerProtection @@ -31,7 +29,6 @@ public final class DataBrokerProtectionManager { private let pixelHandler: EventMapping = DataBrokerProtectionPixelsHandler() private let authenticationManager: DataBrokerProtectionAuthenticationManaging private let fakeBrokerFlag: DataBrokerDebugFlag = DataBrokerDebugFlagFakeBroker() - private let dataBrokerProtectionWaitlistDataSource: WaitlistActivationDateStore = DefaultWaitlistActivationDateStore(source: .dbp) lazy var dataManager: DataBrokerProtectionDataManager = { let dataManager = DataBrokerProtectionDataManager(pixelHandler: pixelHandler, fakeBrokerFlag: fakeBrokerFlag) @@ -68,14 +65,9 @@ public final class DataBrokerProtectionManager { extension DataBrokerProtectionManager: DataBrokerProtectionDataManagerDelegate { public func dataBrokerProtectionDataManagerDidUpdateData() { loginItemInterface.profileSaved() - - let dbpDateStore = DefaultWaitlistActivationDateStore(source: .dbp) - dbpDateStore.setActivationDateIfNecessary() } public func dataBrokerProtectionDataManagerDidDeleteData() { loginItemInterface.dataDeleted() } } - -#endif diff --git a/DuckDuckGo/DBP/DataBrokerProtectionSubscriptionEventHandler.swift b/DuckDuckGo/DBP/DataBrokerProtectionSubscriptionEventHandler.swift index 494319fa0c..a4ed56afc8 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionSubscriptionEventHandler.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionSubscriptionEventHandler.swift @@ -15,7 +15,6 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#if DBP import Combine import Foundation @@ -84,5 +83,3 @@ final class DataBrokerProtectionSubscriptionEventHandler { } } } - -#endif diff --git a/DuckDuckGo/DBP/LoginItem+DataBrokerProtection.swift b/DuckDuckGo/DBP/LoginItem+DataBrokerProtection.swift index d6fbfa761f..3411cf1dc6 100644 --- a/DuckDuckGo/DBP/LoginItem+DataBrokerProtection.swift +++ b/DuckDuckGo/DBP/LoginItem+DataBrokerProtection.swift @@ -20,8 +20,6 @@ import Foundation import LoginItems import DataBrokerProtection -#if DBP - extension LoginItem { static let dbpBackgroundAgent = LoginItem(bundleId: Bundle.main.dbpBackgroundAgentBundleId, defaults: .dbp, log: .dbp) @@ -51,5 +49,3 @@ extension LoginItem: DBPLoginItemStatusChecker { return false } } - -#endif diff --git a/DuckDuckGo/Menus/MainMenu.swift b/DuckDuckGo/Menus/MainMenu.swift index ef5b69c09c..4115217fad 100644 --- a/DuckDuckGo/Menus/MainMenu.swift +++ b/DuckDuckGo/Menus/MainMenu.swift @@ -602,7 +602,6 @@ final class MainMenu: NSMenu { NSMenuItem(title: "Show Credentials Saved Popover", action: #selector(MainViewController.showCredentialsSavedPopover)) NSMenuItem(title: "Show Pop Up Window", action: #selector(MainViewController.showPopUpWindow)) NSMenuItem(title: "Show VPN Thank You Modal", action: #selector(MainViewController.showVPNThankYouModal)) - NSMenuItem(title: "Show PIR Thank You Modal", action: #selector(MainViewController.showPIRThankYouModal)) NSMenuItem(title: "Reset Thank You Modal Checks", action: #selector(MainViewController.resetThankYouModalChecks)) } NSMenuItem(title: "Remote Configuration") { @@ -622,10 +621,8 @@ final class MainMenu: NSMenu { .submenu(SyncDebugMenu()) .withAccessibilityIdentifier("MainMenu.syncAndBackup") -#if DBP NSMenuItem(title: "Personal Information Removal") .submenu(DataBrokerProtectionDebugMenu()) -#endif if case .normal = NSApp.runType { NSMenuItem(title: "VPN") diff --git a/DuckDuckGo/Menus/MainMenuActions.swift b/DuckDuckGo/Menus/MainMenuActions.swift index 11ad9ce9af..3cbe45bcdc 100644 --- a/DuckDuckGo/Menus/MainMenuActions.swift +++ b/DuckDuckGo/Menus/MainMenuActions.swift @@ -911,14 +911,6 @@ extension MainViewController { } } - @objc func showPIRThankYouModal(_ sender: Any?) { - let thankYouModalView = WaitlistBetaThankYouDialogViewController(copy: .dbp) - let thankYouWindowController = thankYouModalView.wrappedInWindowController() - if let thankYouWindow = thankYouWindowController.window { - WindowsManager.windows.first?.beginSheet(thankYouWindow) - } - } - @objc func resetEmailProtectionInContextPrompt(_ sender: Any?) { EmailManager().resetEmailProtectionInContextPrompt() } diff --git a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift index d5bea3cc01..085e84e1fa 100644 --- a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift +++ b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift @@ -40,9 +40,7 @@ protocol OptionsButtonMenuDelegate: AnyObject { func optionsButtonMenuRequestedPreferences(_ menu: NSMenu) func optionsButtonMenuRequestedAppearancePreferences(_ menu: NSMenu) func optionsButtonMenuRequestedAccessibilityPreferences(_ menu: NSMenu) -#if DBP func optionsButtonMenuRequestedDataBrokerProtection(_ menu: NSMenu) -#endif func optionsButtonMenuRequestedSubscriptionPurchasePage(_ menu: NSMenu) func optionsButtonMenuRequestedSubscriptionPreferences(_ menu: NSMenu) func optionsButtonMenuRequestedIdentityTheftRestoration(_ menu: NSMenu) @@ -146,11 +144,9 @@ final class MoreOptionsMenu: NSMenu { addItem(preferencesItem) } -#if DBP @objc func openDataBrokerProtection(_ sender: NSMenuItem) { actionDelegate?.optionsButtonMenuRequestedDataBrokerProtection(self) } -#endif // DBP @objc func showNetworkProtectionStatus(_ sender: NSMenuItem) { actionDelegate?.optionsButtonMenuRequestedNetworkProtectionPopover(self) @@ -835,8 +831,6 @@ final class SubscriptionSubMenu: NSMenu, NSMenuDelegate { self.networkProtectionItem.isEnabled = isNetworkProtectionItemEnabled self.dataBrokerProtectionItem.isEnabled = isDataBrokerProtectionItemEnabled self.identityTheftRestorationItem.isEnabled = isIdentityTheftRestorationItemEnabled - - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistEntryPointMenuItemDisplayed, frequency: .dailyAndCount) } } } diff --git a/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift b/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift index 7f1b74a7df..a8eee48ad4 100644 --- a/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift +++ b/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift @@ -1012,11 +1012,9 @@ extension NavigationBarViewController: NSMenuDelegate { extension NavigationBarViewController: OptionsButtonMenuDelegate { -#if DBP func optionsButtonMenuRequestedDataBrokerProtection(_ menu: NSMenu) { WindowControllersManager.shared.showDataBrokerProtectionTab() } -#endif func optionsButtonMenuRequestedOpenExternalPasswordManager(_ menu: NSMenu) { BWManager.shared.openBitwarden() diff --git a/DuckDuckGo/Tab/View/BrowserTabViewController.swift b/DuckDuckGo/Tab/View/BrowserTabViewController.swift index 779e35dc47..3649438405 100644 --- a/DuckDuckGo/Tab/View/BrowserTabViewController.swift +++ b/DuckDuckGo/Tab/View/BrowserTabViewController.swift @@ -138,7 +138,6 @@ final class BrowserTabViewController: NSViewController { name: .emailDidCloseEmailProtection, object: nil) -#if DBP NotificationCenter.default.addObserver(self, selector: #selector(onDBPFeatureDisabled), name: .dbpWasDisabled, @@ -147,12 +146,6 @@ final class BrowserTabViewController: NSViewController { selector: #selector(onCloseDataBrokerProtection), name: .dbpDidClose, object: nil) - NotificationCenter.default.addObserver(self, - selector: #selector(onDataBrokerWaitlistGetStartedPressedByUser), - name: .dataBrokerProtectionUserPressedOnGetStartedOnWaitlist, - object: nil) - -#endif NotificationCenter.default.addObserver(self, selector: #selector(onCloseSubscriptionPage), @@ -195,7 +188,6 @@ final class BrowserTabViewController: NSViewController { self.previouslySelectedTab = nil } -#if DBP @objc private func onDBPFeatureDisabled(_ notification: Notification) { Task { @MainActor in @@ -221,8 +213,6 @@ final class BrowserTabViewController: NSViewController { WindowControllersManager.shared.showDataBrokerProtectionTab() } -#endif - @objc private func onCloseSubscriptionPage(_ notification: Notification) { guard let activeTab = tabViewModel?.tab else { return } @@ -288,13 +278,11 @@ final class BrowserTabViewController: NSViewController { private func removeDataBrokerViewIfNecessary() -> ([Tab]) -> Void { { [weak self] (tabs: [Tab]) in guard let self else { return } -#if DBP if let dataBrokerProtectionHomeViewController, !tabs.contains(where: { $0.content == .dataBrokerProtection }) { dataBrokerProtectionHomeViewController.removeCompletely() self.dataBrokerProtectionHomeViewController = nil } -#endif } } @@ -557,9 +545,7 @@ final class BrowserTabViewController: NSViewController { preferencesViewController?.removeCompletely() bookmarksViewController?.removeCompletely() homePageViewController?.removeCompletely() -#if DBP dataBrokerProtectionHomeViewController?.removeCompletely() -#endif if includingWebView { self.removeWebViewFromHierarchy() } @@ -611,13 +597,11 @@ final class BrowserTabViewController: NSViewController { removeAllTabContent() addAndLayoutChild(homePageViewControllerCreatingIfNeeded()) -#if DBP case .dataBrokerProtection: removeAllTabContent() let dataBrokerProtectionViewController = dataBrokerProtectionHomeViewControllerCreatingIfNeeded() self.previouslySelectedTab = tabCollectionViewModel.selectedTab addAndLayoutChild(dataBrokerProtectionViewController) -#endif default: removeAllTabContent() } @@ -695,7 +679,6 @@ final class BrowserTabViewController: NSViewController { }() } -#if DBP // MARK: - DataBrokerProtection var dataBrokerProtectionHomeViewController: DBPHomeViewController? @@ -706,7 +689,6 @@ final class BrowserTabViewController: NSViewController { return dataBrokerProtectionHomeViewController }() } -#endif // MARK: - Preferences diff --git a/DuckDuckGo/Waitlist/Storage/WaitlistActivationDateStore.swift b/DuckDuckGo/Waitlist/Storage/WaitlistActivationDateStore.swift index c355e196df..1b6d123767 100644 --- a/DuckDuckGo/Waitlist/Storage/WaitlistActivationDateStore.swift +++ b/DuckDuckGo/Waitlist/Storage/WaitlistActivationDateStore.swift @@ -20,19 +20,16 @@ import Foundation enum WaitlistActivationDateStoreSource { case netP - case dbp var activationDateKey: String { switch self { case .netP: return "com.duckduckgo.network-protection.activation-date" - case .dbp: return "com.duckduckgo.dbp.activation-date" } } var lastActiveDateKey: String { switch self { case .netP: return "com.duckduckgo.network-protection.last-active-date" - case .dbp: return "com.duckduckgo.dbp.last-active-date" } } } @@ -54,8 +51,6 @@ struct DefaultWaitlistActivationDateStore: WaitlistActivationDateStore { switch source { case.netP: self.userDefaults = .netP - case .dbp: - self.userDefaults = .dbp } } diff --git a/DuckDuckGo/Waitlist/Views/WaitlistRootView.swift b/DuckDuckGo/Waitlist/Views/WaitlistRootView.swift deleted file mode 100644 index b9a029d4c6..0000000000 --- a/DuckDuckGo/Waitlist/Views/WaitlistRootView.swift +++ /dev/null @@ -1,56 +0,0 @@ -// -// WaitlistRootView.swift -// -// Copyright © 2023 DuckDuckGo. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import SwiftUI - -#if DBP - -import SwiftUI - -struct DataBrokerProtectionWaitlistRootView: View { - @EnvironmentObject var model: WaitlistViewModel - - var body: some View { - Group { - switch model.viewState { - case .notOnWaitlist, .joiningWaitlist: - JoinWaitlistView(viewData: DataBrokerProtectionJoinWaitlistViewData()) - case .joinedWaitlist(let state): - JoinedWaitlistView(viewData: DataBrokerProtectionJoinedWaitlistViewData(), - notificationsAllowed: state == .notificationAllowed) - case .invited: - InvitedToWaitlistView(viewData: DataBrokerProtectionInvitedToWaitlistViewData()) - case .termsAndConditions: - WaitlistTermsAndConditionsView(viewData: DataBrokerProtectionWaitlistTermsAndConditionsViewData()) { - DataBrokerProtectionTermsAndConditionsContentView() - } - case .readyToEnable: - // Hack to skip the readyToEnable step and close the modal - Text("") - .onAppear { - Task { - await model.perform(action: .closeAndConfirmFeature) - } - } - } - } - .environmentObject(model) - } -} - -#endif diff --git a/DuckDuckGo/Waitlist/Views/WaitlistSteps/InvitedToWaitlistView.swift b/DuckDuckGo/Waitlist/Views/WaitlistSteps/InvitedToWaitlistView.swift index ca30a44deb..52c1219a1a 100644 --- a/DuckDuckGo/Waitlist/Views/WaitlistSteps/InvitedToWaitlistView.swift +++ b/DuckDuckGo/Waitlist/Views/WaitlistSteps/InvitedToWaitlistView.swift @@ -116,17 +116,3 @@ struct WaitlistEntryViewItemViewData: Identifiable { let title: String let subtitle: String } - -#if DBP - -struct DataBrokerProtectionInvitedToWaitlistViewData: InvitedToWaitlistViewData { - let headerImageName = "Gift-96" - let title = UserText.dataBrokerProtectionWaitlistInvitedTitle - let subtitle = UserText.dataBrokerProtectionWaitlistInvitedSubtitle - let buttonDismissLabel = UserText.dataBrokerProtectionWaitlistButtonDismiss - let buttonGetStartedLabel = UserText.dataBrokerProtectionWaitlistButtonGetStarted - let availabilityDisclaimer = UserText.dataBrokerProtectionWaitlistAvailabilityDisclaimer - let entryViewViewDataList = [WaitlistEntryViewItemViewData]() -} - -#endif diff --git a/DuckDuckGo/Waitlist/Views/WaitlistSteps/JoinWaitlistView.swift b/DuckDuckGo/Waitlist/Views/WaitlistSteps/JoinWaitlistView.swift index 6c0e4deb2a..e1b4741d65 100644 --- a/DuckDuckGo/Waitlist/Views/WaitlistSteps/JoinWaitlistView.swift +++ b/DuckDuckGo/Waitlist/Views/WaitlistSteps/JoinWaitlistView.swift @@ -72,17 +72,3 @@ struct JoinWaitlistView: View { .environmentObject(model) } } - -#if DBP - -struct DataBrokerProtectionJoinWaitlistViewData: JoinWaitlistViewViewData { - let headerImageName = "DBP-Information-Remover" - let title = UserText.dataBrokerProtectionWaitlistJoinTitle - let subtitle1 = UserText.dataBrokerProtectionWaitlistInvitedSubtitle - let subtitle2 = "" - let availabilityDisclaimer = UserText.dataBrokerProtectionWaitlistAvailabilityDisclaimer - let buttonCloseLabel = UserText.dataBrokerProtectionWaitlistButtonClose - let buttonJoinWaitlistLabel = UserText.dataBrokerProtectionWaitlistButtonJoinWaitlist -} - -#endif diff --git a/DuckDuckGo/Waitlist/Views/WaitlistSteps/JoinedWaitlistView.swift b/DuckDuckGo/Waitlist/Views/WaitlistSteps/JoinedWaitlistView.swift index 553d3e6562..0ca30ddd35 100644 --- a/DuckDuckGo/Waitlist/Views/WaitlistSteps/JoinedWaitlistView.swift +++ b/DuckDuckGo/Waitlist/Views/WaitlistSteps/JoinedWaitlistView.swift @@ -84,18 +84,3 @@ struct JoinedWaitlistView: View { .environmentObject(model) } } - -#if DBP - -struct DataBrokerProtectionJoinedWaitlistViewData: JoinedWaitlistViewData { - let headerImageName = "JoinedWaitlistHeader" - var title = UserText.dataBrokerProtectionWaitlistJoinedTitle - var joinedWithNoNotificationSubtitle1 = UserText.dataBrokerProtectionWaitlistJoinedWithNotificationsSubtitle1 - var joinedWithNoNotificationSubtitle2 = UserText.dataBrokerProtectionWaitlistJoinedWithNotificationsSubtitle2 - var enableNotificationSubtitle = UserText.dataBrokerProtectionWaitlistEnableNotifications - var buttonConfirmLabel = UserText.dataBrokerProtectionWaitlistButtonDone - var buttonCancelLabel = UserText.dataBrokerProtectionWaitlistButtonNoThanks - var buttonEnableNotificationLabel = UserText.dataBrokerProtectionWaitlistButtonEnableNotifications -} - -#endif diff --git a/DuckDuckGo/Waitlist/Views/WaitlistSteps/WaitlistTermsAndConditionsView.swift b/DuckDuckGo/Waitlist/Views/WaitlistSteps/WaitlistTermsAndConditionsView.swift index 7495ae9e0b..38b01473ff 100644 --- a/DuckDuckGo/Waitlist/Views/WaitlistSteps/WaitlistTermsAndConditionsView.swift +++ b/DuckDuckGo/Waitlist/Views/WaitlistSteps/WaitlistTermsAndConditionsView.swift @@ -81,134 +81,3 @@ private extension Text { } } - -#if DBP - -struct DataBrokerProtectionTermsAndConditionsContentView: View { - private let groupLeadingPadding: CGFloat = 15.0 - private let sectionBottomPadding: CGFloat = 10.0 - - var body: some View { - VStack(alignment: .leading, spacing: 5) { - - Text(verbatim: UserText.dataBrokerProtectionPrivacyPolicyTitle) - .font(.system(size: 15, weight: .bold)) - .multilineTextAlignment(.leading) - - Text(verbatim: "\nWe don’t save your personal information for this service to function.") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• This Privacy Policy is for our waitlist beta service.") - HStack(spacing: 0) { - Text(verbatim: "• Our main ") - Text(verbatim: "Privacy Policy ") - .foregroundColor(Color.blue) - .underline(color: .blue) - .onTapGesture { - let url = URL(string: "https://duckduckgo.com/privacy")! - WindowsManager.openNewWindow(with: url, source: .ui, isBurner: false) - } - Text(verbatim: "also applies here.") - } - Text(verbatim: "• This beta product may collect more diagnostic data than our typical products. Examples of such data include: alerts of low memory, application restarts, and user engagement with product features.") - } - .padding(.leading, groupLeadingPadding) - - Text(verbatim: "\nYour personal information is stored locally on your device.") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• The information you provide when you sign-up to use this service, for example your name, age, address, and phone number is stored on your device.") - Text(verbatim: "• We then scan data brokers from your device to check if any sites contain your personal information.") - Text(verbatim: "• We may find additional information on data broker sites through this scanning process, like alternative names or phone numbers, or the names of your relatives. This information is also stored locally on your device.") - } - .padding(.leading, groupLeadingPadding) - - Text(verbatim: "\nWe submit removal requests to data broker sites on your behalf.") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• We submit removal requests to the data broker sites directly from your device, unlike other services where the removal process is initiated on remote servers.") - Text(verbatim: "• The only personal information we may receive is a confirmation email from data broker sites which is deleted within 72 hours.") - Text(verbatim: "• We regularly re-scan data broker sites to check on the removal status of your information. If it has reappeared, we resubmit the removal request.") - } - .padding(.leading, groupLeadingPadding) - - Text(verbatim: "\nTerms of Service") - .fontWeight(.bold) - - Text(verbatim: "You must be eligible to use this service.") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• To use this service, you must be 18 or older.") - } - .padding(.leading, groupLeadingPadding) - - Text(verbatim: "\nThe service is for limited and personal use only.") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• The service is available for your personal use only. You represent and warrant that you will only initiate removal of your own personal information.") - Text(verbatim: "• This service is available on one device only.") - } - .padding(.leading, groupLeadingPadding) - - Text(verbatim: "\nYou give DuckDuckGo authority to act on your Here's an updated version with the remaining content:") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• You hereby authorize DuckDuckGo to act on your behalf to request removal of your personal information from data broker sites.") - Text(verbatim: "• Because data broker sites often have multi-step processes required to have information removed, and because they regularly update their databases with new personal information, this authorization includes ongoing action on your behalf solely to perform the service.") - } - .padding(.leading, groupLeadingPadding) - - Text(verbatim: "\nThe service cannot remove all of your information from the Internet.") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• This service requests removal from a limited number of data broker sites only. You understand that we cannot guarantee that the third-party sites will honor the requests, or that your personal information will not reappear in the future.") - Text(verbatim: "• You understand that we will only be able to request the removal of information based upon the information you provide to us.") - } - .padding(.leading, groupLeadingPadding) - - Text(verbatim: "\nWe provide this beta service as-is, and without warranty.") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• This service is provided as-is and without warranties or guarantees of any kind.") - Text(verbatim: "• To the extent possible under applicable law, DuckDuckGo will not be liable for any damage or loss arising from your use of the service. In any event, the total aggregate liability of DuckDuckGo shall not exceed $25 or the equivalent in your local currency.") - Text(verbatim: "• We may in the future transfer responsibility for the service to a subsidiary of DuckDuckGo. If that happens, you agree that references to “DuckDuckGo” will refer to our subsidiary, which will then become responsible for providing the service and for any liabilities relating to it.") - } - .padding(.leading, groupLeadingPadding) - - Text(verbatim: "\nWe may terminate access at any time.") - .fontWeight(.bold) - .padding(.bottom, sectionBottomPadding) - - Group { - Text(verbatim: "• This service is in beta, and your access to it is temporary.") - Text(verbatim: "• We reserve the right to terminate access at any time in our sole discretion, including for violation of these terms or our DuckDuckGo Terms of Service, which are incorporated by reference.") - } - .padding(.leading, groupLeadingPadding) - - }.padding(.all, 20) - } -} - -struct DataBrokerProtectionWaitlistTermsAndConditionsViewData: WaitlistTermsAndConditionsViewData { - let title = "Personal Information Removal Beta\nService Terms and Privacy Policy" - let buttonCancelLabel = UserText.dataBrokerProtectionWaitlistButtonCancel - let buttonAgreeAndContinueLabel = UserText.dataBrokerProtectionWaitlistButtonAgreeAndContinue -} - -#endif diff --git a/DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift b/DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift index fe79b7cc96..67cc8eaf59 100644 --- a/DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift +++ b/DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift @@ -25,20 +25,11 @@ final class WaitlistThankYouPromptPresenter { private enum Constants { static let didShowThankYouPromptKey = "duckduckgo.macos.browser.did-show-thank-you-prompt" - static let didDismissPIRCardKey = "duckduckgo.macos.browser.did-dismiss-pir-card" } - private let isPIRBetaTester: () -> Bool private let userDefaults: UserDefaults - convenience init() { - self.init(isPIRBetaTester: { - false - }) - } - - init(isPIRBetaTester: @escaping () -> Bool, userDefaults: UserDefaults = .standard) { - self.isPIRBetaTester = isPIRBetaTester + init(userDefaults: UserDefaults = .standard) { self.userDefaults = userDefaults } @@ -51,30 +42,12 @@ final class WaitlistThankYouPromptPresenter { guard canShowPromptCheck() else { return } - - if isPIRBetaTester() { - saveDidShowPromptCheck() - presentPIRThankYouPrompt(in: window) - } - } - - @MainActor - func presentPIRThankYouPrompt(in window: NSWindow) { - let thankYouModalView = WaitlistBetaThankYouDialogViewController(copy: .dbp) - let thankYouWindowController = thankYouModalView.wrappedInWindowController() - if let thankYouWindow = thankYouWindowController.window { - window.beginSheet(thankYouWindow) - } } // MARK: - Eligibility var canShowPIRCard: Bool { - guard !self.userDefaults.bool(forKey: Constants.didDismissPIRCardKey) else { - return false - } - - return isPIRBetaTester() + return false } func canShowPromptCheck() -> Bool { @@ -83,10 +56,6 @@ final class WaitlistThankYouPromptPresenter { // MARK: - Dismissal - func didDismissPIRThankYouCard() { - self.userDefaults.setValue(true, forKey: Constants.didDismissPIRCardKey) - } - private func saveDidShowPromptCheck() { self.userDefaults.setValue(true, forKey: Constants.didShowThankYouPromptKey) } @@ -95,7 +64,6 @@ final class WaitlistThankYouPromptPresenter { func resetPromptCheck() { self.userDefaults.removeObject(forKey: Constants.didShowThankYouPromptKey) - self.userDefaults.removeObject(forKey: Constants.didDismissPIRCardKey) } } diff --git a/DuckDuckGo/Waitlist/Views/WaitlistThankYouView.swift b/DuckDuckGo/Waitlist/Views/WaitlistThankYouView.swift index b94d1846d2..541f94ff73 100644 --- a/DuckDuckGo/Waitlist/Views/WaitlistThankYouView.swift +++ b/DuckDuckGo/Waitlist/Views/WaitlistThankYouView.swift @@ -23,13 +23,6 @@ import SwiftUI // MARK: - Model struct WaitlistBetaThankYouCopy { - static let dbp = WaitlistBetaThankYouCopy( - title: UserText.dbpThankYouTitle, - subtitle: UserText.dbpThankYouSubtitle, - body1: UserText.dbpThankYouBody1, - body2: UserText.dbpThankYouBody2 - ) - static let vpn = WaitlistBetaThankYouCopy( title: UserText.vpnThankYouTitle, subtitle: UserText.vpnThankYouSubtitle, diff --git a/DuckDuckGo/Waitlist/Views/WaitlistViewControllerPresenter.swift b/DuckDuckGo/Waitlist/Views/WaitlistViewControllerPresenter.swift index 55ee0e6584..360dfda449 100644 --- a/DuckDuckGo/Waitlist/Views/WaitlistViewControllerPresenter.swift +++ b/DuckDuckGo/Waitlist/Views/WaitlistViewControllerPresenter.swift @@ -29,50 +29,3 @@ extension WaitlistViewControllerPresenter { Self.show(completion: nil) } } - -#if DBP - -struct DataBrokerProtectionWaitlistViewControllerPresenter: WaitlistViewControllerPresenter { - - static func shouldPresentWaitlist() -> Bool { - if DefaultSubscriptionFeatureAvailability().isFeatureAvailable { - return false - } - - let waitlist = DataBrokerProtectionWaitlist() - - let accepted = UserDefaults().bool(forKey: UserDefaultsWrapper.Key.dataBrokerProtectionTermsAndConditionsAccepted.rawValue) - - return !(waitlist.waitlistStorage.isInvited && accepted) - } - - @MainActor - static func show(completion: (() -> Void)? = nil) { - guard let windowController = WindowControllersManager.shared.lastKeyMainWindowController else { - return - } - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistIntroDisplayed, frequency: .dailyAndCount) - - // This is a hack to get around an issue with the waitlist notification screen showing the wrong state while it animates in, and then - // jumping to the correct state as soon as the animation is complete. This works around that problem by providing the correct state up front, - // preventing any state changing from occurring. - UNUserNotificationCenter.current().getNotificationSettings { settings in - let status = settings.authorizationStatus - let state = WaitlistViewModel.NotificationPermissionState.from(status) - DispatchQueue.main.async { - let viewModel = WaitlistViewModel(waitlist: DataBrokerProtectionWaitlist(), - notificationPermissionState: state, - showNotificationSuccessState: false, - termsAndConditionActionHandler: DataBrokerProtectionWaitlistTermsAndConditionsActionHandler(), - featureSetupHandler: DataBrokerProtectionWaitlistFeatureSetupHandler()) - - let viewController = WaitlistModalViewController(viewModel: viewModel, contentView: DataBrokerProtectionWaitlistRootView()) - windowController.mainViewController.beginSheet(viewController) { _ in - completion?() - } - } - } - } -} - -#endif diff --git a/DuckDuckGo/Waitlist/Waitlist.swift b/DuckDuckGo/Waitlist/Waitlist.swift index 4ed31b5b08..27ac30ced1 100644 --- a/DuckDuckGo/Waitlist/Waitlist.swift +++ b/DuckDuckGo/Waitlist/Waitlist.swift @@ -64,8 +64,6 @@ enum WaitlistInviteCodeFetchError: Error, Equatable { extension Notification.Name { static let networkProtectionWaitlistAccessChanged = Notification.Name(rawValue: "networkProtectionWaitlistAccessChanged") - static let dataBrokerProtectionWaitlistAccessChanged = Notification.Name(rawValue: "dataBrokerProtectionWaitlistAccessChanged") - static let dataBrokerProtectionUserPressedOnGetStartedOnWaitlist = Notification.Name(rawValue: "dataBrokerProtectionUserPressedOnGetStartedOnWaitlist") } @@ -153,85 +151,3 @@ extension ProductWaitlistRequest { self.init(productName: productName, makeHTTPRequest: makeHTTPRequest) } } - -#if DBP - -// MARK: - DataBroker Protection Waitlist - -import DataBrokerProtection - -struct DataBrokerProtectionWaitlist: Waitlist { - - static let identifier: String = "databrokerprotection" - static let apiProductName: String = "dbp" - static let keychainAppGroup: String = Bundle.main.appGroup(bundle: .dbp) - - static let notificationIdentifier = "com.duckduckgo.macos.browser.data-broker-protection.invite-code-available" - static let inviteAvailableNotificationTitle = UserText.dataBrokerProtectionWaitlistNotificationTitle - static let inviteAvailableNotificationBody = UserText.dataBrokerProtectionWaitlistNotificationText - - let waitlistStorage: WaitlistStorage - let waitlistRequest: WaitlistRequest - - private let redeemUseCase: DataBrokerProtectionRedeemUseCase - private let redeemAuthenticationRepository: AuthenticationRepository - - var readyToAcceptTermsAndConditions: Bool { - let accepted = UserDefaults().bool(forKey: UserDefaultsWrapper.Key.dataBrokerProtectionTermsAndConditionsAccepted.rawValue) - return waitlistStorage.isInvited && !accepted - } - - init() { - self.init( - store: WaitlistKeychainStore(waitlistIdentifier: Self.identifier, keychainAppGroup: Self.keychainAppGroup), - request: ProductWaitlistRequest(productName: Self.apiProductName), - redeemUseCase: RedeemUseCase(), - redeemAuthenticationRepository: KeychainAuthenticationData() - ) - } - - init(store: WaitlistStorage, request: WaitlistRequest, - redeemUseCase: DataBrokerProtectionRedeemUseCase, - redeemAuthenticationRepository: AuthenticationRepository) { - self.waitlistStorage = store - self.waitlistRequest = request - self.redeemUseCase = redeemUseCase - self.redeemAuthenticationRepository = redeemAuthenticationRepository - } - - private func fetchInviteCode() async throws -> String { - - // First check if we have it stored locally - if let inviteCode = waitlistStorage.getWaitlistInviteCode() { - return inviteCode - } - - // If not, then try to fetch it remotely - _ = await fetchInviteCodeIfAvailable() - - // Try to fetch it from storage again - if let inviteCode = waitlistStorage.getWaitlistInviteCode() { - return inviteCode - } else { - throw WaitlistInviteCodeFetchError.noCodeAvailable - } - } - - private func redeemInviteCode(_ inviteCode: String) async throws { - os_log("Redeeming DBP invite code...", log: .dataBrokerProtection) - - try await redeemUseCase.redeem(inviteCode: inviteCode) - NotificationCenter.default.post(name: .dataBrokerProtectionWaitlistAccessChanged, object: nil) - - os_log("DBP invite code redeemed", log: .dataBrokerProtection) - UserDefaults().setValue(true, forKey: UserDefaultsWrapper.Key.shouldShowDBPWaitlistInvitedCardUI.rawValue) - - sendInviteCodeAvailableNotification { - DispatchQueue.main.async { - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistNotificationShown, frequency: .dailyAndCount) - } - } - } -} - -#endif diff --git a/DuckDuckGo/Waitlist/WaitlistFeatureSetupHandler.swift b/DuckDuckGo/Waitlist/WaitlistFeatureSetupHandler.swift index 6c2c63b563..a849b9b62a 100644 --- a/DuckDuckGo/Waitlist/WaitlistFeatureSetupHandler.swift +++ b/DuckDuckGo/Waitlist/WaitlistFeatureSetupHandler.swift @@ -28,15 +28,3 @@ struct NetworkProtectionWaitlistFeatureSetupHandler: WaitlistFeatureSetupHandler NotificationCenter.default.post(name: .networkProtectionWaitlistAccessChanged, object: nil) } } - -#if DBP - -struct DataBrokerProtectionWaitlistFeatureSetupHandler: WaitlistFeatureSetupHandler { - func confirmFeature() { - NotificationCenter.default.post(name: .dataBrokerProtectionWaitlistAccessChanged, object: nil) - NotificationCenter.default.post(name: .dataBrokerProtectionUserPressedOnGetStartedOnWaitlist, object: nil) - UserDefaults().setValue(false, forKey: UserDefaultsWrapper.Key.shouldShowDBPWaitlistInvitedCardUI.rawValue) - } -} - -#endif diff --git a/DuckDuckGo/Waitlist/WaitlistTermsAndConditionsActionHandler.swift b/DuckDuckGo/Waitlist/WaitlistTermsAndConditionsActionHandler.swift index 3f6f456ea0..8e0e4d3dfb 100644 --- a/DuckDuckGo/Waitlist/WaitlistTermsAndConditionsActionHandler.swift +++ b/DuckDuckGo/Waitlist/WaitlistTermsAndConditionsActionHandler.swift @@ -25,24 +25,3 @@ protocol WaitlistTermsAndConditionsActionHandler { func didShow() mutating func didAccept() } - -#if DBP - -struct DataBrokerProtectionWaitlistTermsAndConditionsActionHandler: WaitlistTermsAndConditionsActionHandler { - @UserDefaultsWrapper(key: .dataBrokerProtectionTermsAndConditionsAccepted, defaultValue: false) - var acceptedTermsAndConditions: Bool - - func didShow() { - PixelKit.fire(GeneralPixel.dataBrokerProtectionWaitlistTermsAndConditionsDisplayed, frequency: .dailyAndCount) - } - - mutating func didAccept() { - acceptedTermsAndConditions = true - // Remove delivered NetP notifications in case the user didn't click them. - UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [DataBrokerProtectionWaitlist.notificationIdentifier]) - - PixelKit.fire(GeneralPixel.dataBrokerProtectionWaitlistTermsAndConditionsAccepted, frequency: .dailyAndCount) - } -} - -#endif diff --git a/DuckDuckGo/Windows/View/WindowControllersManager.swift b/DuckDuckGo/Windows/View/WindowControllersManager.swift index e21c96bc99..3cbb3630d8 100644 --- a/DuckDuckGo/Windows/View/WindowControllersManager.swift +++ b/DuckDuckGo/Windows/View/WindowControllersManager.swift @@ -115,11 +115,9 @@ final class WindowControllersManager: WindowControllersManagerProtocol { extension WindowControllersManager { -#if DBP func showDataBrokerProtectionTab() { showTab(with: .dataBrokerProtection) } -#endif func showBookmarksTab() { showTab(with: .bookmarks) diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionPixelTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionPixelTests.swift deleted file mode 100644 index 1d32a2e762..0000000000 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionPixelTests.swift +++ /dev/null @@ -1,149 +0,0 @@ -// -// DataBrokerProtectionPixelTests.swift -// -// Copyright © 2023 DuckDuckGo. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#if DBP - -import DataBrokerProtection -import Networking -import Foundation -import PixelKit -import PixelKitTestingUtilities -import XCTest -@testable import DuckDuckGo_Privacy_Browser - -/// Tests to ensure that DBP pixels sent from the main app work well -/// -final class DataBrokerProtectionPixelTests: XCTestCase { - - struct PixelDataStoreMock: PixelDataStore { - func set(_ value: Int, forKey: String, completionHandler: ((Error?) -> Void)?) { - completionHandler?(nil) - } - - func set(_ value: String, forKey: String, completionHandler: ((Error?) -> Void)?) { - completionHandler?(nil) - } - - func set(_ value: Double, forKey: String, completionHandler: ((Error?) -> Void)?) { - completionHandler?(nil) - } - - func value(forKey key: String) -> Double? { - nil - } - - func value(forKey key: String) -> Int? { - nil - } - - func value(forKey key: String) -> String? { - nil - } - - func removeValue(forKey key: String, completionHandler: ((Error?) -> Void)?) { - completionHandler?(nil) - } - } - - func mapToPixelEvent(_ dbpPixel: DataBrokerProtectionPixels) -> Pixel.Event { - switch dbpPixel { - case .error(let error, _): - return .debug(event: .pixelKitEvent(dbpPixel), error: error) - default: - return .pixelKitEvent(dbpPixel) - } - } - - /// This method implements validation logic that can be used to test several events. - /// - func validatePixel(for dbpEvent: DataBrokerProtectionPixels) { - let inAppVersion = "1.0.1" - let inUserAgent = "ddg_mac/\(inAppVersion) (com.duckduckgo.macos.browser.dbp.debug; macOS Version 14.0 (Build 23A344))" - - // We want to make sure the callback is executed exactly once to validate - // all of the fire parameters - let callbackExecuted = expectation(description: "We expect the callback to be executed once") - callbackExecuted.expectedFulfillmentCount = 1 - callbackExecuted.assertForOverFulfill = true - - // This is annoyingly necessary to test the user agent right now - APIRequest.Headers.setUserAgent(inUserAgent) - - let storeMock = PixelDataStoreMock() - - let inEvent = mapToPixelEvent(dbpEvent) - - let pixel = Pixel(appVersion: inAppVersion, store: storeMock) { (event, parameters, _, headers, onComplete) in - - // Validate that the event is the one we expect - XCTAssertEqual(event, inEvent) - - // Validate that the basic params are present - let pixelRequestValidator = PixelRequestValidator() - pixelRequestValidator.validateBasicPixelParams(expectedAppVersion: inAppVersion, expectedUserAgent: inUserAgent, requestParameters: parameters, requestHeaders: headers.httpHeaders) - - // Validate that the debug params are present - if case .debug(let wrappedEvent, let error) = inEvent { - XCTAssertEqual("m_mac_debug_\(wrappedEvent.name)", inEvent.name) - - pixelRequestValidator.validateDebugPixelParams(expectedError: error, requestParameters: parameters) - } - - // Validate that the dbp-specific params are present in the fire event parameters - XCTAssertTrue( - dbpEvent.params?.allSatisfy({ key, value in - parameters[key] == value - }) ?? false) - - callbackExecuted.fulfill() - onComplete(nil) - } - - pixel.fire(inEvent, withAdditionalParameters: dbpEvent.params) - - waitForExpectations(timeout: 0.1) - } - - func testBasicPixelValidation() { - let inDataBroker = "inDataBroker" - - let eventsToTest: [DataBrokerProtectionPixels] = [ - .error(error: DataBrokerProtectionError.cancelled, dataBroker: inDataBroker), - .parentChildMatches(parent: "a", child: "b", value: 5), - .optOutStart(dataBroker: "a", attemptId: UUID()), - .optOutEmailGenerate(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutCaptchaParse(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutCaptchaSend(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutCaptchaSolve(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutSubmit(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutEmailReceive(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutEmailConfirm(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutValidate(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutFinish(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutSubmitSuccess(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutSuccess(dataBroker: "a", attemptId: UUID(), duration: 5), - .optOutFailure(dataBroker: "a", attemptId: UUID(), duration: 5, stage: "some") - ] - - for event in eventsToTest { - validatePixel(for: event) - } - } -} - -#endif diff --git a/UnitTests/DBP/Tests/DataBrokerProtectionFeatureGatekeeperTests.swift b/UnitTests/DBP/Tests/DataBrokerProtectionFeatureGatekeeperTests.swift index 7f70a0e805..f85d03a145 100644 --- a/UnitTests/DBP/Tests/DataBrokerProtectionFeatureGatekeeperTests.swift +++ b/UnitTests/DBP/Tests/DataBrokerProtectionFeatureGatekeeperTests.swift @@ -27,7 +27,6 @@ final class DataBrokerProtectionFeatureGatekeeperTests: XCTestCase { private var sut: DefaultDataBrokerProtectionFeatureGatekeeper! private var mockFeatureDisabler: MockFeatureDisabler! private var mockFeatureAvailability: MockFeatureAvailability! - private var waitlistStorage: MockWaitlistStorage! private var mockAccountManager: MockAccountManager! private func userDefaults() -> UserDefaults { @@ -37,100 +36,15 @@ final class DataBrokerProtectionFeatureGatekeeperTests: XCTestCase { override func setUpWithError() throws { mockFeatureDisabler = MockFeatureDisabler() mockFeatureAvailability = MockFeatureAvailability() - waitlistStorage = MockWaitlistStorage() mockAccountManager = MockAccountManager() } - /// Waitlist is OFF, Not redeemed - /// PP flag is OF - func testWhenWaitlistHasNoInviteCodeAndFeatureDisabled_thenCleanUpIsNotCalled() throws { - sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, - userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, - subscriptionAvailability: mockFeatureAvailability, - accountManager: mockAccountManager) - - XCTAssertFalse(sut.cleanUpDBPForPrivacyProIfNecessary()) - XCTAssertFalse(mockFeatureDisabler.disableAndDeleteWasCalled) - } - - /// Waitlist is OFF, Not redeemed - /// PP flag is ON - func testWhenWaitlistHasNoInviteCodeAndFeatureEnabled_thenCleanUpIsNotCalled() throws { - mockFeatureAvailability.mockFeatureAvailable = true - - sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, - userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, - subscriptionAvailability: mockFeatureAvailability, - accountManager: mockAccountManager) - - XCTAssertFalse(sut.cleanUpDBPForPrivacyProIfNecessary()) - XCTAssertFalse(mockFeatureDisabler.disableAndDeleteWasCalled) - } - - /// Waitlist is ON, redeemed - /// PP flag is OFF - func testWhenWaitlistHasInviteCodeAndFeatureDisabled_thenCleanUpIsNotCalled() throws { - waitlistStorage.store(waitlistToken: "potato") - waitlistStorage.store(inviteCode: "banana") - waitlistStorage.store(waitlistTimestamp: 123) - - sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, - userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, - subscriptionAvailability: mockFeatureAvailability, - accountManager: mockAccountManager) - - XCTAssertFalse(sut.cleanUpDBPForPrivacyProIfNecessary()) - XCTAssertFalse(mockFeatureDisabler.disableAndDeleteWasCalled) - } - - /// Waitlist is ON, redeemed - /// PP flag is ON - func testWhenWaitlistHasInviteCodeAndFeatureEnabled_thenCleanUpIsCalled() throws { - waitlistStorage.store(waitlistToken: "potato") - waitlistStorage.store(inviteCode: "banana") - waitlistStorage.store(waitlistTimestamp: 123) - mockFeatureAvailability.mockFeatureAvailable = true - - sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, - userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, - subscriptionAvailability: mockFeatureAvailability, - accountManager: mockAccountManager) - - XCTAssertTrue(sut.cleanUpDBPForPrivacyProIfNecessary()) - XCTAssertTrue(mockFeatureDisabler.disableAndDeleteWasCalled) - } - - /// Waitlist is ON, redeemed - /// PP flag is ON - func testWhenWaitlistHasInviteCodeAndFeatureEnabled_thenCleanUpIsCalledTwice() throws { - waitlistStorage.store(waitlistToken: "potato") - waitlistStorage.store(inviteCode: "banana") - waitlistStorage.store(waitlistTimestamp: 123) - mockFeatureAvailability.mockFeatureAvailable = true - - sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, - userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, - subscriptionAvailability: mockFeatureAvailability, - accountManager: mockAccountManager) - - XCTAssertTrue(sut.cleanUpDBPForPrivacyProIfNecessary()) - XCTAssertTrue(mockFeatureDisabler.disableAndDeleteWasCalled) - - XCTAssertFalse(sut.cleanUpDBPForPrivacyProIfNecessary()) - } - func testWhenNoAccessTokenIsFound_butEntitlementIs_thenFeatureIsDisabled() async { // Given mockAccountManager.accessToken = nil mockAccountManager.hasEntitlementResult = .success(true) sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, subscriptionAvailability: mockFeatureAvailability, accountManager: mockAccountManager) @@ -147,7 +61,6 @@ final class DataBrokerProtectionFeatureGatekeeperTests: XCTestCase { mockAccountManager.hasEntitlementResult = .failure(MockError.someError) sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, subscriptionAvailability: mockFeatureAvailability, accountManager: mockAccountManager) @@ -164,7 +77,6 @@ final class DataBrokerProtectionFeatureGatekeeperTests: XCTestCase { mockAccountManager.hasEntitlementResult = .failure(MockError.someError) sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, subscriptionAvailability: mockFeatureAvailability, accountManager: mockAccountManager) @@ -181,7 +93,6 @@ final class DataBrokerProtectionFeatureGatekeeperTests: XCTestCase { mockAccountManager.hasEntitlementResult = .success(true) sut = DefaultDataBrokerProtectionFeatureGatekeeper(featureDisabler: mockFeatureDisabler, userDefaults: userDefaults(), - waitlistStorage: waitlistStorage, subscriptionAvailability: mockFeatureAvailability, accountManager: mockAccountManager)