From 5e8d6b0a57e593cae3a205fee1963ff5266017e2 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Fri, 19 Jan 2024 00:10:28 -0500 Subject: [PATCH 01/25] Exchange access token for auth token --- DuckDuckGo/MainViewController.swift | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index b5cb5f8083..6774332e37 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -31,6 +31,10 @@ import Persistence import PrivacyDashboard import Networking +#if NETWORK_PROTECTION +import NetworkProtection +#endif + // swiftlint:disable file_length // swiftlint:disable type_body_length class MainViewController: UIViewController { @@ -98,6 +102,10 @@ class MainViewController: UIViewController { private var syncFeatureFlagsCancellable: AnyCancellable? private var favoritesDisplayModeCancellable: AnyCancellable? private var emailCancellables = Set() + +#if NETWORK_PROTECTION + private var netpCancellables = Set() +#endif private lazy var featureFlagger = AppDependencyProvider.shared.featureFlagger @@ -244,6 +252,10 @@ class MainViewController: UIViewController { addLaunchTabNotificationObserver() subscribeToEmailProtectionStatusNotifications() +#if NETWORK_PROTECTION + subscribeToNetworkProtectionSubscriptionEvents() +#endif + findInPageView.delegate = self findInPageBottomLayoutConstraint.constant = 0 registerForKeyboardNotifications() @@ -1229,6 +1241,50 @@ class MainViewController: UIViewController { .store(in: &emailCancellables) } +#if NETWORK_PROTECTION + private func subscribeToNetworkProtectionSubscriptionEvents() { + NotificationCenter.default.publisher(for: .accountDidSignIn) + .receive(on: DispatchQueue.main) + .sink { [weak self] notification in + self?.onNetworkProtectionAccountSignIn(notification) + } + .store(in: &netpCancellables) + NotificationCenter.default.publisher(for: .accountDidSignOut) + .receive(on: DispatchQueue.main) + .sink { [weak self] notification in + self?.onNetworkProtectionAccountSignOut(notification) + } + .store(in: &netpCancellables) + } + + @objc + private func onNetworkProtectionAccountSignIn(_ notification: Notification) { + guard let token = AccountManager().accessToken else { + assertionFailure("[NetP Subscription] AccountManager signed in but token could not be retrieved") + return + } + + Task { + do { + try await NetworkProtectionCodeRedemptionCoordinator().exchange(accessToken: token) + print("[NetP Subscription] Exchanged access token for auth token successfully") + } catch { + print("[NetP Subscription] Failed to exchange access token for auth token: \(error)") + } + } + } + + @objc + private func onNetworkProtectionAccountSignOut(_ notification: Notification) { + do { + try NetworkProtectionKeychainTokenStore().deleteToken() + print("[NetP Subscription] Deleted NetP auth token after signing out from Privacy Pro") + } catch { + print("[NetP Subscription] Failed to delete NetP auth token after signing out from Privacy Pro: \(error)") + } + } +#endif + @objc private func onDuckDuckGoEmailSignIn(_ notification: Notification) { fireEmailPixel(.emailEnabled, notification: notification) From 9254447ebe8432a3d16d78450b6112cdd3188e73 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Fri, 19 Jan 2024 11:23:08 -0500 Subject: [PATCH 02/25] Fix typos --- DuckDuckGo/Subscription/Views/SubscriptionFlowView.swift | 2 +- DuckDuckGo/UserText.swift | 2 +- DuckDuckGo/en.lproj/Localizable.strings | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DuckDuckGo/Subscription/Views/SubscriptionFlowView.swift b/DuckDuckGo/Subscription/Views/SubscriptionFlowView.swift index 07d7571e0a..f730d19d4c 100644 --- a/DuckDuckGo/Subscription/Views/SubscriptionFlowView.swift +++ b/DuckDuckGo/Subscription/Views/SubscriptionFlowView.swift @@ -74,7 +74,7 @@ struct SubscriptionFlowView: View { message: Text(UserText.subscriptionFoundText), primaryButton: .cancel(Text(UserText.subscriptionFoundCancel)) { }, - secondaryButton: .default(Text(UserText.subscriptionFoundCancel)) { + secondaryButton: .default(Text(UserText.subscriptionFoundRestore)) { viewModel.restoreAppstoreTransaction() } ) diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index dc0705d9e9..92480e89e4 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -1023,7 +1023,7 @@ But if you *do* want a peek under the hood, you can find more information about public static let subscriptionRemoveFromDeviceConfirmText = NSLocalizedString("subscription.remove.from.device.text", value: "You will no longer be able to access your Privacy Pro subscription on this device. This will not cancel your subscription, and it will remain active on your other devices.", comment: "Remove from device confirmation dialog text") public static let subscriptionRemove = NSLocalizedString("subscription.remove.subscription", value: "Remove Subscription", comment: "Remove subscription button text") public static let subscriptionRemoveCancel = NSLocalizedString("subscription.remove.subscription.cancel", value: "Cancel", comment: "Remove subscription cancel button text") - public static let subscriptionFoundTitle = NSLocalizedString("subscription.subscription.found.tite", value: "Subscription Found", comment: "Title for the existing subscription dialog") + public static let subscriptionFoundTitle = NSLocalizedString("subscription.subscription.found.title", value: "Subscription Found", comment: "Title for the existing subscription dialog") public static let subscriptionFoundText = NSLocalizedString("subscription.subscription.found.text", value: "We found a subscription associated with this Apple ID.", comment: "Message for the existing subscription dialog") public static let subscriptionFoundCancel = NSLocalizedString("subscription.subscription.found.cancel", value: "Cancel", comment: "Cancel action for the existing subscription dialog") public static let subscriptionFoundRestore = NSLocalizedString("subscription.subscription.found.restore", value: "Restore", comment: "Restore action for the existing subscription dialog") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index 34845d2775..ba876a5c6c 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -1972,7 +1972,7 @@ But if you *do* want a peek under the hood, you can find more information about "subscription.subscription.found.text" = "We found a subscription associated with this Apple ID."; /* Title for the existing subscription dialog */ -"subscription.subscription.found.tite" = "Subscription Found"; +"subscription.subscription.found.title" = "Subscription Found"; /* Message confirming that recovery code was copied to clipboard */ "sync.code.copied" = "Recovery code copied to clipboard"; From 647f6eff54207d191c375898348d1448b81720e1 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Mon, 22 Jan 2024 22:41:36 -0500 Subject: [PATCH 03/25] Just enough for AccountManager check --- DuckDuckGo.xcodeproj/project.pbxproj | 16 ++++++++++++++++ .../xcshareddata/swiftpm/Package.resolved | 4 ++-- .../EventMapping+NetworkProtectionError.swift | 2 ++ DuckDuckGo/en.lproj/Localizable.strings | 12 ------------ .../NetworkProtectionPacketTunnelProvider.swift | 5 ++++- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index fd01290cb8..7d877923d9 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -697,6 +697,13 @@ B6BA95C528894A28004ABA20 /* BrowsingMenuViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6BA95C428894A28004ABA20 /* BrowsingMenuViewController.storyboard */; }; B6BA95E828924730004ABA20 /* JSAlertController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6BA95E728924730004ABA20 /* JSAlertController.storyboard */; }; B6CB93E5286445AB0090FEB4 /* Base64DownloadSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */; }; + BD7B379F2B5F6A3F0040F991 /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C8E2B291CA90054390C /* AccountManager.swift */; }; + BD7B37A02B5F6A4D0040F991 /* AccountKeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C902B291CA90054390C /* AccountKeychainStorage.swift */; }; + BD7B37A12B5F6A6A0040F991 /* AccountStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C912B291CA90054390C /* AccountStorage.swift */; }; + BD7B37A22B5F6A770040F991 /* AuthService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C9D2B291CA90054390C /* AuthService.swift */; }; + BD7B37A32B5F6A830040F991 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C9C2B291CA90054390C /* APIService.swift */; }; + BD7B37A42B5F6A9C0040F991 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C8D2B291CA90054390C /* Logging.swift */; }; + BD7B37A52B5F6AAA0040F991 /* SubscriptionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C9B2B291CA90054390C /* SubscriptionService.swift */; }; BD862E032B30DA170073E2EE /* VPNFeedbackFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E022B30DA170073E2EE /* VPNFeedbackFormViewModel.swift */; }; BD862E052B30DB250073E2EE /* VPNFeedbackCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E042B30DB250073E2EE /* VPNFeedbackCategory.swift */; }; BD862E072B30F5E30073E2EE /* VPNFeedbackSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E062B30F5E30073E2EE /* VPNFeedbackSender.swift */; }; @@ -2329,6 +2336,7 @@ B6BA95C428894A28004ABA20 /* BrowsingMenuViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = BrowsingMenuViewController.storyboard; sourceTree = ""; }; B6BA95E728924730004ABA20 /* JSAlertController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = JSAlertController.storyboard; sourceTree = ""; }; B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64DownloadSession.swift; sourceTree = ""; }; + BD7B37A72B5F6B8D0040F991 /* BrowserServicesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = BrowserServicesKit; path = ../../BrowserServicesKit; sourceTree = ""; }; BD862E022B30DA170073E2EE /* VPNFeedbackFormViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackFormViewModel.swift; sourceTree = ""; }; BD862E042B30DB250073E2EE /* VPNFeedbackCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackCategory.swift; sourceTree = ""; }; BD862E062B30F5E30073E2EE /* VPNFeedbackSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackSender.swift; sourceTree = ""; }; @@ -3451,6 +3459,7 @@ 31E69A60280F4BAD00478327 /* LocalPackages */ = { isa = PBXGroup; children = ( + BD7B37A72B5F6B8D0040F991 /* BrowserServicesKit */, 85875B5F29912A2D00115F05 /* SyncUI */, 37FCAACB2993149A000E420A /* Waitlist */, 31794BFF2821DFB600F18633 /* DuckUI */, @@ -6409,6 +6418,7 @@ buildActionMask = 2147483647; files = ( 02025B0D29884D2C00E694E7 /* AppTrackerData.swift in Sources */, + BD7B37A42B5F6A9C0040F991 /* Logging.swift in Sources */, 4BEF656C2989C2FC00B650CB /* TunnelEvent.swift in Sources */, 02025A9A2988229800E694E7 /* TUNInterface.swift in Sources */, 02025A9B2988229800E694E7 /* IPStackProtocol.swift in Sources */, @@ -6421,6 +6431,7 @@ 4BEF656D2989C2FC00B650CB /* EventType.swift in Sources */, 02025AAC2988229800E694E7 /* GCDHTTPProxyServer.swift in Sources */, 02025AAD2988229800E694E7 /* NWUDPSocket.swift in Sources */, + BD7B37A52B5F6AAA0040F991 /* SubscriptionService.swift in Sources */, EE3766DE2AC5945500AAB575 /* NetworkProtectionUNNotificationPresenter.swift in Sources */, 02025AAE2988229800E694E7 /* RawTCPSocketProtocol.swift in Sources */, 02025AAF2988229800E694E7 /* NWTCPSocket.swift in Sources */, @@ -6430,6 +6441,7 @@ 02025AB72988229800E694E7 /* AllRule.swift in Sources */, 02025AB82988229800E694E7 /* DNSSessionMatchResult.swift in Sources */, 02025AB92988229800E694E7 /* Rule.swift in Sources */, + BD7B37A32B5F6A830040F991 /* APIService.swift in Sources */, 02025ABA2988229800E694E7 /* DirectRule.swift in Sources */, 02025ABB2988229800E694E7 /* RuleManager.swift in Sources */, 02025ABC2988229800E694E7 /* IPRangeListRule.swift in Sources */, @@ -6443,16 +6455,20 @@ 02025AD82988229800E694E7 /* Tunnel.swift in Sources */, 02025ADA2988229800E694E7 /* Port.swift in Sources */, 02025ADB2988229800E694E7 /* HTTPStreamScanner.swift in Sources */, + BD7B37A02B5F6A4D0040F991 /* AccountKeychainStorage.swift in Sources */, + BD7B379F2B5F6A3F0040F991 /* AccountManager.swift in Sources */, 02025ADC2988229800E694E7 /* UInt128.swift in Sources */, 02025ADD2988229800E694E7 /* IPInterval.swift in Sources */, 02025ADE2988229800E694E7 /* IPPool.swift in Sources */, 4BEF65692989C2FC00B650CB /* AdapterSocketEvent.swift in Sources */, 02025ADF2988229800E694E7 /* IPMask.swift in Sources */, 4BEF656A2989C2FC00B650CB /* ProxyServerEvent.swift in Sources */, + BD7B37A12B5F6A6A0040F991 /* AccountStorage.swift in Sources */, 4BEF656B2989C2FC00B650CB /* RuleMatchEvent.swift in Sources */, 02025AE02988229800E694E7 /* IPRange.swift in Sources */, 02025AE12988229800E694E7 /* IPAddress.swift in Sources */, 02025B1529884EA500E694E7 /* DDGObserverFactory.swift in Sources */, + BD7B37A22B5F6A770040F991 /* AuthService.swift in Sources */, 02025AE32988229800E694E7 /* BinaryDataScanner.swift in Sources */, 021D30752989C04200918636 /* Observer.swift in Sources */, 02025AE42988229800E694E7 /* Checksum.swift in Sources */, diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index abda3a95e5..5f1852e31c 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/content-scope-scripts", "state" : { - "revision" : "0b68b0d404d8d4f32296cd84fa160b18b0aeaf44", - "version" : "4.59.1" + "revision" : "bb027f14bec7fbb1a85d308139e7a66686da160e", + "version" : "4.59.0" } }, { diff --git a/DuckDuckGo/EventMapping+NetworkProtectionError.swift b/DuckDuckGo/EventMapping+NetworkProtectionError.swift index a139b4c9a2..79e76c7890 100644 --- a/DuckDuckGo/EventMapping+NetworkProtectionError.swift +++ b/DuckDuckGo/EventMapping+NetworkProtectionError.swift @@ -66,6 +66,8 @@ extension EventMapping where Event == NetworkProtectionError { params[PixelParameters.keychainErrorCode] = String(status) case .noAuthTokenFound: pixelEvent = .networkProtectionNoAuthTokenFoundError + case .vpnAccessRevoked: + return case .noServerRegistrationInfo, .couldNotSelectClosestServer, diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index 13fb938aff..3f4fec34a1 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -2017,18 +2017,6 @@ But if you *do* want a peek under the hood, you can find more information about /* Subscription Expiration Data */ "subscription.subscription.active.caption" = "Your Privacy Pro subscription renews on %@"; -/* Cancel action for the existing subscription dialog */ -"subscription.subscription.found.cancel" = "Cancel"; - -/* Restore action for the existing subscription dialog */ -"subscription.subscription.found.restore" = "Restore"; - -/* Message for the existing subscription dialog */ -"subscription.subscription.found.text" = "We found a subscription associated with this Apple ID."; - -/* Title for the existing subscription dialog */ -"subscription.subscription.found.title" = "Subscription Found"; - /* Message confirming that recovery code was copied to clipboard */ "sync.code.copied" = "Recovery code copied to clipboard"; diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index 180342ab9c..06df285d9e 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -158,6 +158,8 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { params[PixelParameters.wireguardErrorCode] = String(code) case .noAuthTokenFound: pixelEvent = .networkProtectionNoAuthTokenFoundError + case .vpnAccessRevoked: + return case .unhandledError(function: let function, line: let line, error: let error): pixelEvent = .networkProtectionUnhandledError params[PixelParameters.function] = function @@ -214,7 +216,8 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { tokenStore: tokenStore, debugEvents: Self.networkProtectionDebugEvents(controllerErrorStore: errorStore), providerEvents: Self.packetTunnelProviderEvents, - settings: settings) + settings: settings, + isEntitlementValid: { await AccountManager().hasEntitlement(for: "dummy1") }) startMonitoringMemoryPressureEvents() observeServerChanges() observeStatusChanges() From 9dc98f1a04911a0682a629e2c188656f571844ed Mon Sep 17 00:00:00 2001 From: Anh Do Date: Wed, 24 Jan 2024 13:39:34 -0500 Subject: [PATCH 04/25] Fix Alpha build not installing NetP --- DuckDuckGo.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 7d877923d9..062930c679 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -6408,7 +6408,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Conditionally embeds PacketTunnelProvider extension for Debug and Alpha builds.\n\n# Conditionally embeds the PacketTunnelProvider extension for debug builds.\\n# To be moved to the Embed App Extensions phase on release.\n\nif [ \"${CONFIGURATION}\" = \"Debug\" ] || [ \"${CONFIGURATION}\" = \"Release\" ] || [ \"${CONFIGURATION}\" = \"Alpha\" ]; then\n# Copy the extension \n rsync -r --copy-links \"${CONFIGURATION_BUILD_DIR}/PacketTunnelProvider.appex\" \"${CONFIGURATION_BUILD_DIR}/${PLUGINS_FOLDER_PATH}\"\nfi\n"; + shellScript = "# Conditionally embeds PacketTunnelProvider extension for Debug and Alpha builds.\n\n# Conditionally embeds the PacketTunnelProvider extension for debug builds.\\n# To be moved to the Embed App Extensions phase on release.\n\nif [ \"${CONFIGURATION}\" = \"Debug\" ] || [ \"${CONFIGURATION}\" = \"Release\" ] || [ \"${CONFIGURATION}\" = \"Alpha\" || [ \"${CONFIGURATION}\" = \"Alpha Debug\" ]; then\n# Copy the extension \n rsync -r --copy-links \"${CONFIGURATION_BUILD_DIR}/PacketTunnelProvider.appex\" \"${CONFIGURATION_BUILD_DIR}/${PLUGINS_FOLDER_PATH}\"\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -9129,7 +9129,7 @@ MTL_FAST_MATH = YES; OTHER_CFLAGS = ""; OTHER_SWIFT_FLAGS = "-D NETWORK_EXTENSION"; - PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.mobile.ios.NetworkExtension; + PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.mobile.ios.alpha.NetworkExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; From f837faefc87981a288bc45fef0ee7573230256f0 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 25 Jan 2024 12:54:24 -0500 Subject: [PATCH 05/25] Show last disconnect error in Debug view --- .../Feedback/VPNMetadataCollector.swift | 2 +- ...NetworkProtectionDebugViewController.swift | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/DuckDuckGo/Feedback/VPNMetadataCollector.swift b/DuckDuckGo/Feedback/VPNMetadataCollector.swift index 3ab9f25421..d1daf056bb 100644 --- a/DuckDuckGo/Feedback/VPNMetadataCollector.swift +++ b/DuckDuckGo/Feedback/VPNMetadataCollector.swift @@ -195,7 +195,7 @@ final class DefaultVPNMetadataCollector: VPNMetadataCollector { connectedServerIP: connectedServerIP) } - private func lastDisconnectError() async -> String { + public func lastDisconnectError() async -> String { if #available(iOS 16, *) { guard let tunnelManager = try? await NETunnelProviderManager.loadAllFromPreferences().first else { return "none" diff --git a/DuckDuckGo/NetworkProtectionDebugViewController.swift b/DuckDuckGo/NetworkProtectionDebugViewController.swift index e50c45e17f..55c4445f64 100644 --- a/DuckDuckGo/NetworkProtectionDebugViewController.swift +++ b/DuckDuckGo/NetworkProtectionDebugViewController.swift @@ -43,6 +43,7 @@ final class NetworkProtectionDebugViewController: UITableViewController { Sections.registrationKey: "Registration Key", Sections.notifications: "Notifications", Sections.networkPath: "Network Path", + Sections.lastDisconnectError: "Last Disconnect Error", Sections.connectionTest: "Connection Test", Sections.vpnConfiguration: "VPN Configuration" @@ -56,6 +57,7 @@ final class NetworkProtectionDebugViewController: UITableViewController { case notifications case connectionTest case networkPath + case lastDisconnectError case vpnConfiguration } @@ -90,6 +92,10 @@ final class NetworkProtectionDebugViewController: UITableViewController { case networkPath } + enum LastDisconnectErrorRows: Int, CaseIterable { + case lastDisconnectError + } + enum ConnectionTestRows: Int, CaseIterable { case runConnectionTest } @@ -106,6 +112,7 @@ final class NetworkProtectionDebugViewController: UITableViewController { private let pathMonitor = NWPathMonitor() private var currentNetworkPath: String? + private var lastDisconnectError: String? private var baseConfigurationData: String? private var fullProtocolConfigurationData: String? @@ -138,6 +145,7 @@ final class NetworkProtectionDebugViewController: UITableViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + loadLastDisconnectError() loadConfigurationData() startPathMonitor() } @@ -188,6 +196,9 @@ final class NetworkProtectionDebugViewController: UITableViewController { case .networkPath: configure(cell, forNetworkPathRow: indexPath.row) + case .lastDisconnectError: + configure(cell, forLastDisconnectErrorRow: indexPath.row) + case .connectionTest: configure(cell, forConnectionTestRow: indexPath.row) @@ -209,6 +220,7 @@ final class NetworkProtectionDebugViewController: UITableViewController { case .registrationKey: return RegistrationKeyRows.allCases.count case .notifications: return NotificationsRows.allCases.count case .networkPath: return NetworkPathRows.allCases.count + case .lastDisconnectError: return LastDisconnectErrorRows.allCases.count case .connectionTest: return ConnectionTestRows.allCases.count + connectionTestResults.count case .vpnConfiguration: return ConfigurationRows.allCases.count case .none: return 0 @@ -235,6 +247,8 @@ final class NetworkProtectionDebugViewController: UITableViewController { didSelectTestNotificationAction(at: indexPath) case .networkPath: break + case .lastDisconnectError: + break case .connectionTest: if indexPath.row == connectionTestResults.count { Task { @@ -394,6 +408,20 @@ final class NetworkProtectionDebugViewController: UITableViewController { pathMonitor.start(queue: .main) } + // MARK: Last disconnect error + + private func configure(_ cell: UITableViewCell, forLastDisconnectErrorRow row: Int) { + cell.textLabel?.font = .monospacedSystemFont(ofSize: 13.0, weight: .regular) + cell.textLabel?.text = lastDisconnectError ?? "Loading Last Disconnect Error..." + } + + private func loadLastDisconnectError() { + Task { @MainActor in + lastDisconnectError = await DefaultVPNMetadataCollector().lastDisconnectError() + tableView.reloadData() + } + } + // MARK: Connection Test private func configure(_ cell: UITableViewCell, forConnectionTestRow row: Int) { From 770c0b88cafdc158a06a60c39d8564e5470e0a53 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 25 Jan 2024 20:09:18 -0500 Subject: [PATCH 06/25] Minor refactoring --- .../NetworkProtectionPacketTunnelProvider.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index 06df285d9e..71d65aa5ad 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -217,7 +217,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { debugEvents: Self.networkProtectionDebugEvents(controllerErrorStore: errorStore), providerEvents: Self.packetTunnelProviderEvents, settings: settings, - isEntitlementValid: { await AccountManager().hasEntitlement(for: "dummy1") }) + isEntitlementValid: Self.isEntitlementValid) startMonitoringMemoryPressureEvents() observeServerChanges() observeStatusChanges() @@ -268,6 +268,13 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { .store(in: &cancellables) } + public static func isEntitlementValid() async -> Bool { +#if ALPHA + await AccountManager().hasEntitlement(for: "dummy1") +#else + true +#endif + } } #endif From eb64fe3435e2de2e7cdb08c9ef61826b4388c1dd Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 25 Jan 2024 20:34:13 -0500 Subject: [PATCH 07/25] To be dropped --- DuckDuckGo.xcodeproj/project.pbxproj | 2 -- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index f21c5ecb92..7a3c15c5f0 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -2340,7 +2340,6 @@ B6BA95C428894A28004ABA20 /* BrowsingMenuViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = BrowsingMenuViewController.storyboard; sourceTree = ""; }; B6BA95E728924730004ABA20 /* JSAlertController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = JSAlertController.storyboard; sourceTree = ""; }; B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64DownloadSession.swift; sourceTree = ""; }; - BD7B37A72B5F6B8D0040F991 /* BrowserServicesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = BrowserServicesKit; path = ../../BrowserServicesKit; sourceTree = ""; }; BD862E022B30DA170073E2EE /* VPNFeedbackFormViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackFormViewModel.swift; sourceTree = ""; }; BD862E042B30DB250073E2EE /* VPNFeedbackCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackCategory.swift; sourceTree = ""; }; BD862E062B30F5E30073E2EE /* VPNFeedbackSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackSender.swift; sourceTree = ""; }; @@ -3465,7 +3464,6 @@ 31E69A60280F4BAD00478327 /* LocalPackages */ = { isa = PBXGroup; children = ( - BD7B37A72B5F6B8D0040F991 /* BrowserServicesKit */, 85875B5F29912A2D00115F05 /* SyncUI */, 37FCAACB2993149A000E420A /* Waitlist */, 31794BFF2821DFB600F18633 /* DuckUI */, diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index e3e23a2663..d85be58c3b 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/content-scope-scripts", "state" : { - "revision" : "bb027f14bec7fbb1a85d308139e7a66686da160e", - "version" : "4.59.0" + "revision" : "0b68b0d404d8d4f32296cd84fa160b18b0aeaf44", + "version" : "4.59.1" } }, { From f91093d0e255e35177c8c919763deeacfc90f2dd Mon Sep 17 00:00:00 2001 From: Anh Do Date: Mon, 29 Jan 2024 20:55:35 -0500 Subject: [PATCH 08/25] Show notification --- ...tworkProtectionNotificationIdentifier.swift | 1 + DuckDuckGo/UserText.swift | 18 ++++++++++++++++-- DuckDuckGo/en.lproj/Localizable.strings | 18 ++++++++++++++++++ ...workProtectionUNNotificationPresenter.swift | 7 ++++++- PacketTunnelProvider/UserText.swift | 2 ++ .../en.lproj/Localizable.strings | 3 +++ 6 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Core/NetworkProtectionNotificationIdentifier.swift b/Core/NetworkProtectionNotificationIdentifier.swift index 20e1a7631a..5ac235621c 100644 --- a/Core/NetworkProtectionNotificationIdentifier.swift +++ b/Core/NetworkProtectionNotificationIdentifier.swift @@ -23,4 +23,5 @@ public enum NetworkProtectionNotificationIdentifier: String { case connection = "network-protection.notification.connection" case superseded = "network-protection.notification.superseded" case test = "network-protection.notification.test" + case entitlement = "network-protection.notification.entitlement" } diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index 531900ac59..2f8e121aa1 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -962,10 +962,24 @@ But if you *do* want a peek under the hood, you can find more information about static let networkProtectionNotificationPromptTitle = NSLocalizedString("network-protection.waitlist.notification-prompt-title", value: "Know the instant you're invited", comment: "Title for the alert to confirm enabling notifications") static let networkProtectionNotificationPromptDescription = NSLocalizedString("network-protection.waitlist.notification-prompt-description", value: "Get a notification when your copy of Network Protection early access is ready.", comment: "Subtitle for the alert to confirm enabling notifications") - + + static let networkProtectionNotificationsTitle = NSLocalizedString("network.protection.notification.title", value: "DuckDuckGo", comment: "The title of the notifications shown from Network Protection") + static let networkProtectionConnectionSuccessNotificationBody = NSLocalizedString("network.protection.success.notification.body", value: "Network Protection is On. Your location and online activity are protected.", comment: "The body of the notification shown when Network Protection reconnects successfully") + static func networkProtectionConnectionSuccessNotificationBody(serverLocation: String) -> String { + let localized = NSLocalizedString( + "network.protection.success.notification.subtitle.including.serverLocation", + value: "Routing device traffic through %@.", + comment: "The body of the notification shown when Network Protection connects successfully with the city + state/country as formatted parameter" + ) + return String(format: localized, serverLocation) + } + static let networkProtectionConnectionInterruptedNotificationBody = NSLocalizedString("network.protection.interrupted.notification.body", value: "Network Protection was interrupted. Attempting to reconnect now...", comment: "The body of the notification shown when Network Protection's connection is interrupted") + static let networkProtectionConnectionFailureNotificationBody = NSLocalizedString("network.protection.failure.notification.body", value: "Network Protection failed to connect. Please try again later.", comment: "The body of the notification shown when Network Protection fails to reconnect") + static let networkProtectionEntitlementExpiredNotificationBody = NSLocalizedString("network.protection.entitlement.expired.notification.body", value: "VPN disconnected due to expired subscription. Subscribe to Privacy Pro to reconnect DuckDuckGo VPN.", comment: "The body of the notification when Privacy Pro subscription expired") + // MARK: Settings Screeen public static let settingsTitle = NSLocalizedString("settings.title", value: "Settings", comment: "Title for the Settings View") - + // General Section public static let settingsSetDefault = NSLocalizedString("settings.default.browser", value: "Set as Default Browser", comment: "Settings screen cell text for setting the app as default browser") public static let settingsAddToDock = NSLocalizedString("settings.add.to.dock", value: "Add App to Your Dock", comment: "Settings screen cell text for adding the app to the dock") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index 815afd61b6..9d4956336f 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -1519,6 +1519,15 @@ https://duckduckgo.com/mac"; /* Subtitle text for the Network Protection settings row */ "network-protection.waitlist.settings-subtitle.waitlist-not-joined" = "Join the private waitlist"; +/* The body of the notification when Privacy Pro subscription expired */ +"network.protection.entitlement.expired.notification.body" = "VPN disconnected due to expired subscription. Subscribe to Privacy Pro to reconnect DuckDuckGo VPN."; + +/* The body of the notification shown when Network Protection fails to reconnect */ +"network.protection.failure.notification.body" = "Network Protection failed to connect. Please try again later."; + +/* The body of the notification shown when Network Protection's connection is interrupted */ +"network.protection.interrupted.notification.body" = "Network Protection was interrupted. Attempting to reconnect now..."; + /* Message for the network protection invite dialog */ "network.protection.invite.dialog.message" = "Enter your invite code to get started."; @@ -1534,6 +1543,9 @@ https://duckduckgo.com/mac"; /* Title for the network protection invite success view */ "network.protection.invite.success.title" = "Success! You’re in."; +/* The title of the notifications shown from Network Protection */ +"network.protection.notification.title" = "DuckDuckGo"; + /* Title text for an iOS quick action that opens VPN settings */ "network.protection.quick-action.open-vpn" = "Open VPN"; @@ -1582,6 +1594,12 @@ https://duckduckgo.com/mac"; /* Title label text for the status view when netP is disconnected */ "network.protection.status.view.title" = "Network Protection"; +/* The body of the notification shown when Network Protection reconnects successfully */ +"network.protection.success.notification.body" = "Network Protection is On. Your location and online activity are protected."; + +/* The body of the notification shown when Network Protection connects successfully with the city + state/country as formatted parameter */ +"network.protection.success.notification.subtitle.including.serverLocation" = "Routing device traffic through %@."; + /* Title for the button to link to the iOS app settings and enable notifications app-wide. */ "network.protection.turn.on.notifications.button.title" = "Turn On Notifications"; diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionUNNotificationPresenter.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionUNNotificationPresenter.swift index 28358d72c8..92222d4b80 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionUNNotificationPresenter.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionUNNotificationPresenter.swift @@ -62,7 +62,7 @@ final class NetworkProtectionUNNotificationPresenter: NSObject, NetworkProtectio content.title = UserText.networkProtectionNotificationsTitle content.body = body - if #available(iOSApplicationExtension 15.0, *) { + if #available(iOS 15.0, *) { content.interruptionLevel = .timeSensitive content.relevanceScore = 0 } @@ -105,6 +105,11 @@ final class NetworkProtectionUNNotificationPresenter: NSObject, NetworkProtectio func showSupersededNotification() { } + func showExpiredEntitlementNotification() { + let content = notificationContent(body: UserText.networkProtectionEntitlementExpiredNotificationBody) + showNotification(.entitlement, content) + } + private func showNotification(_ identifier: NetworkProtectionNotificationIdentifier, _ content: UNNotificationContent) { let request = UNNotificationRequest(identifier: identifier.rawValue, content: content, trigger: .none) diff --git a/PacketTunnelProvider/UserText.swift b/PacketTunnelProvider/UserText.swift index 820a4a6ebf..7243db5e2b 100644 --- a/PacketTunnelProvider/UserText.swift +++ b/PacketTunnelProvider/UserText.swift @@ -40,5 +40,7 @@ final class UserText { static let networkProtectionConnectionInterruptedNotificationBody = NSLocalizedString("network.protection.interrupted.notification.body", value: "Network Protection was interrupted. Attempting to reconnect now...", comment: "The body of the notification shown when Network Protection's connection is interrupted") static let networkProtectionConnectionFailureNotificationBody = NSLocalizedString("network.protection.failure.notification.body", value: "Network Protection failed to connect. Please try again later.", comment: "The body of the notification shown when Network Protection fails to reconnect") + + static let networkProtectionEntitlementExpiredNotificationBody = NSLocalizedString("network.protection.entitlement.expired.notification.body", value: "VPN disconnected due to expired subscription. Subscribe to Privacy Pro to reconnect DuckDuckGo VPN.", comment: "The body of the notification when Privacy Pro subscription expired") } // swiftlint:enable line_length diff --git a/PacketTunnelProvider/en.lproj/Localizable.strings b/PacketTunnelProvider/en.lproj/Localizable.strings index 1a6d5fe4de..3ceec0f887 100644 --- a/PacketTunnelProvider/en.lproj/Localizable.strings +++ b/PacketTunnelProvider/en.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* The body of the notification when Privacy Pro subscription expired */ +"network.protection.entitlement.expired.notification.body" = "VPN disconnected due to expired subscription. Subscribe to Privacy Pro to reconnect DuckDuckGo VPN."; + /* The body of the notification shown when Network Protection fails to reconnect */ "network.protection.failure.notification.body" = "Network Protection failed to connect. Please try again later."; From d1ec9580b69bdcc77d9169c3ba9dba009c6d259c Mon Sep 17 00:00:00 2001 From: Anh Do Date: Wed, 31 Jan 2024 20:49:50 -0500 Subject: [PATCH 09/25] Add ALPHA to Alpha Debug build --- DuckDuckGo.xcodeproj/project.pbxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index d03c5710b3..1f621e2b34 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -2341,6 +2341,7 @@ B6BA95C428894A28004ABA20 /* BrowsingMenuViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = BrowsingMenuViewController.storyboard; sourceTree = ""; }; B6BA95E728924730004ABA20 /* JSAlertController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = JSAlertController.storyboard; sourceTree = ""; }; B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64DownloadSession.swift; sourceTree = ""; }; + BD25422E2B6A8F10002FA3CC /* BrowserServicesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = BrowserServicesKit; path = ../../BrowserServicesKit; sourceTree = ""; }; BD862E022B30DA170073E2EE /* VPNFeedbackFormViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackFormViewModel.swift; sourceTree = ""; }; BD862E042B30DB250073E2EE /* VPNFeedbackCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackCategory.swift; sourceTree = ""; }; BD862E062B30F5E30073E2EE /* VPNFeedbackSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackSender.swift; sourceTree = ""; }; @@ -3466,6 +3467,7 @@ 31E69A60280F4BAD00478327 /* LocalPackages */ = { isa = PBXGroup; children = ( + BD25422E2B6A8F10002FA3CC /* BrowserServicesKit */, 85875B5F29912A2D00115F05 /* SyncUI */, 37FCAACB2993149A000E420A /* Waitlist */, 31794BFF2821DFB600F18633 /* DuckUI */, @@ -8986,7 +8988,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG APP_TRACKING_PROTECTION NETWORK_PROTECTION SUBSCRIPTION"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG APP_TRACKING_PROTECTION NETWORK_PROTECTION SUBSCRIPTION ALPHA"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "$(ARCHS_STANDARD_64_BIT)"; From a0ee6c29e1d4469d4e3c5e5c6446f1d7f9274a19 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Wed, 31 Jan 2024 22:33:06 -0500 Subject: [PATCH 10/25] Populate isSubscriptionEnabled --- .../EventMapping+NetworkProtectionError.swift | 2 +- ...orkProtectionConvenienceInitialisers.swift | 3 ++- ...etworkProtectionPacketTunnelProvider.swift | 19 ++++++++++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/DuckDuckGo/EventMapping+NetworkProtectionError.swift b/DuckDuckGo/EventMapping+NetworkProtectionError.swift index 8aaa5c559a..b75add9346 100644 --- a/DuckDuckGo/EventMapping+NetworkProtectionError.swift +++ b/DuckDuckGo/EventMapping+NetworkProtectionError.swift @@ -70,7 +70,7 @@ extension EventMapping where Event == NetworkProtectionError { params[PixelParameters.keychainErrorCode] = String(status) case .noAuthTokenFound: pixelEvent = .networkProtectionNoAuthTokenFoundError - case .vpnAccessRevoked: + case .vpnAccessRevoked, .noSubscriptionAccessTokenFound: return case .noServerRegistrationInfo, diff --git a/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift b/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift index 8698a6df68..020845f6be 100644 --- a/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift +++ b/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift @@ -85,7 +85,8 @@ extension NetworkProtectionLocationListCompositeRepository { self.init( environment: settings.selectedEnvironment, tokenStore: NetworkProtectionKeychainTokenStore(), - errorEvents: .networkProtectionAppDebugEvents + errorEvents: .networkProtectionAppDebugEvents, + isSubscriptionEnabled: AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) ) } } diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index 57c2c9f8d1..f938b5fb96 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -162,7 +162,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { params[PixelParameters.wireguardErrorCode] = String(code) case .noAuthTokenFound: pixelEvent = .networkProtectionNoAuthTokenFoundError - case .vpnAccessRevoked: + case .vpnAccessRevoked, .noSubscriptionAccessTokenFound: return case .unhandledError(function: let function, line: let line, error: let error): pixelEvent = .networkProtectionUnhandledError @@ -221,6 +221,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { debugEvents: Self.networkProtectionDebugEvents(controllerErrorStore: errorStore), providerEvents: Self.packetTunnelProviderEvents, settings: settings, + isSubscriptionEnabled: Self.isSubscriptionEnabled(), isEntitlementValid: Self.isEntitlementValid) startMonitoringMemoryPressureEvents() observeServerChanges() @@ -272,13 +273,25 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { .store(in: &cancellables) } - public static func isEntitlementValid() async -> Bool { #if ALPHA + public static func isSubscriptionEnabled() -> Bool { + true + } + + public static func isEntitlementValid() async -> Bool { + // TODO: Replace this with proper entitlement check + // https://app.asana.com/0/0/1206470585910128/f await AccountManager().hasEntitlement(for: "dummy1") + } #else + public static func isSubscriptionEnabled() -> Bool { + false + } + + public static func isEntitlementValid() async -> Bool { true -#endif } +#endif } #endif From 7ece8fa1d4c238d1259081937af2cb810ae478c0 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Wed, 31 Jan 2024 23:36:34 -0500 Subject: [PATCH 11/25] Use SubscriptionConfig instead --- ...etworkProtectionPacketTunnelProvider.swift | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index f938b5fb96..42e2dee8b5 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -221,8 +221,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { debugEvents: Self.networkProtectionDebugEvents(controllerErrorStore: errorStore), providerEvents: Self.packetTunnelProviderEvents, settings: settings, - isSubscriptionEnabled: Self.isSubscriptionEnabled(), - isEntitlementValid: Self.isEntitlementValid) + subscriptionConfig: SubscriptionConfig.makeConfiguration()) startMonitoringMemoryPressureEvents() observeServerChanges() observeStatusChanges() @@ -272,26 +271,34 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { } .store(in: &cancellables) } +} + +#endif +extension PacketTunnelProvider.SubscriptionConfig { #if ALPHA - public static func isSubscriptionEnabled() -> Bool { - true + static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfig { + .init( + isEnabled: true, + isEntitlementValid: Self.isEntitlementValid, + getAccessToken: { + AccountManager().accessToken + } + ) } - public static func isEntitlementValid() async -> Bool { + static func isEntitlementValid() async -> Bool { // TODO: Replace this with proper entitlement check // https://app.asana.com/0/0/1206470585910128/f await AccountManager().hasEntitlement(for: "dummy1") } #else - public static func isSubscriptionEnabled() -> Bool { - false - } - - public static func isEntitlementValid() async -> Bool { - true + static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfig { + .init( + isEnabled: false, + isEntitlementValid: { true }, + getAccessToken: { nil } + ) } #endif } - -#endif From 56e11bfb0c8d65a31e1a05301bad644fe25c5e24 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 1 Feb 2024 09:22:04 -0500 Subject: [PATCH 12/25] Update entitlement for Alpha Debug --- DuckDuckGo.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 1f621e2b34..e417a8333d 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -9000,7 +9000,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = "DDG-AppIcon-Alpha"; - CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGo.entitlements; + CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGoAlpha.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 0; @@ -9125,7 +9125,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = PacketTunnelProvider/PacketTunnelProvider.entitlements; + CODE_SIGN_ENTITLEMENTS = PacketTunnelProvider/PacketTunnelProviderAlpha.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 0; From 6da158623e010ed3879015a58a9b82917ba5f353 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 1 Feb 2024 09:22:18 -0500 Subject: [PATCH 13/25] Use ddg:accessToken for NetP authentication --- DuckDuckGo/MainViewController.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index c9e0cafaaf..4ca4260e7b 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -1271,10 +1271,10 @@ class MainViewController: UIViewController { Task { do { - try await NetworkProtectionCodeRedemptionCoordinator().exchange(accessToken: token) - print("[NetP Subscription] Exchanged access token for auth token successfully") + try NetworkProtectionKeychainTokenStore().store("ddg:\(token)") + print("[NetP Subscription] Stored derived NetP auth token") } catch { - print("[NetP Subscription] Failed to exchange access token for auth token: \(error)") + print("[NetP Subscription] Failed to store derived NetP auth token: \(error)") } } } From 9fe8986e27dc1dfbfbbd93daba66fc56afb19f00 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 1 Feb 2024 09:36:38 -0500 Subject: [PATCH 14/25] Clean up --- .../EventMapping+NetworkProtectionError.swift | 2 +- DuckDuckGo/MainViewController.swift | 9 ++------- ...workProtectionConvenienceInitialisers.swift | 16 ++++++++++++++-- DuckDuckGo/UserText.swift | 14 -------------- DuckDuckGo/en.lproj/Localizable.strings | 18 ------------------ ...NetworkProtectionPacketTunnelProvider.swift | 16 +++++++--------- 6 files changed, 24 insertions(+), 51 deletions(-) diff --git a/DuckDuckGo/EventMapping+NetworkProtectionError.swift b/DuckDuckGo/EventMapping+NetworkProtectionError.swift index b75add9346..8aaa5c559a 100644 --- a/DuckDuckGo/EventMapping+NetworkProtectionError.swift +++ b/DuckDuckGo/EventMapping+NetworkProtectionError.swift @@ -70,7 +70,7 @@ extension EventMapping where Event == NetworkProtectionError { params[PixelParameters.keychainErrorCode] = String(status) case .noAuthTokenFound: pixelEvent = .networkProtectionNoAuthTokenFoundError - case .vpnAccessRevoked, .noSubscriptionAccessTokenFound: + case .vpnAccessRevoked: return case .noServerRegistrationInfo, diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index 4ca4260e7b..759f6d9a06 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -1271,7 +1271,7 @@ class MainViewController: UIViewController { Task { do { - try NetworkProtectionKeychainTokenStore().store("ddg:\(token)") + try NetworkProtectionKeychainTokenStore().store(NetworkProtectionKeychainTokenStore.makeToken(from: token)) print("[NetP Subscription] Stored derived NetP auth token") } catch { print("[NetP Subscription] Failed to store derived NetP auth token: \(error)") @@ -1281,12 +1281,7 @@ class MainViewController: UIViewController { @objc private func onNetworkProtectionAccountSignOut(_ notification: Notification) { - do { - try NetworkProtectionKeychainTokenStore().deleteToken() - print("[NetP Subscription] Deleted NetP auth token after signing out from Privacy Pro") - } catch { - print("[NetP Subscription] Failed to delete NetP auth token after signing out from Privacy Pro: \(error)") - } + // no-op } #endif diff --git a/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift b/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift index 020845f6be..1f1d63b40a 100644 --- a/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift +++ b/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift @@ -46,9 +46,15 @@ extension ConnectionServerInfoObserverThroughSession { extension NetworkProtectionKeychainTokenStore { convenience init() { +#if ALPHA + let isSubscriptionEnabled = true +#else + let isSubscriptionEnabled = AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) +#endif self.init(keychainType: .dataProtection(.unspecified), serviceName: "\(Bundle.main.bundleIdentifier!).authToken", - errorEvents: .networkProtectionAppDebugEvents) + errorEvents: .networkProtectionAppDebugEvents, + isSubscriptionEnabled: isSubscriptionEnabled) } } @@ -82,11 +88,17 @@ extension NetworkProtectionVPNSettingsViewModel { extension NetworkProtectionLocationListCompositeRepository { convenience init() { let settings = VPNSettings(defaults: .networkProtectionGroupDefaults) +#if ALPHA + let isSubscriptionEnabled = true +#else + let isSubscriptionEnabled = AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) +#endif + self.init( environment: settings.selectedEnvironment, tokenStore: NetworkProtectionKeychainTokenStore(), errorEvents: .networkProtectionAppDebugEvents, - isSubscriptionEnabled: AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) + isSubscriptionEnabled: isSubscriptionEnabled ) } } diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index 2f8e121aa1..e865ad0f28 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -963,20 +963,6 @@ But if you *do* want a peek under the hood, you can find more information about static let networkProtectionNotificationPromptTitle = NSLocalizedString("network-protection.waitlist.notification-prompt-title", value: "Know the instant you're invited", comment: "Title for the alert to confirm enabling notifications") static let networkProtectionNotificationPromptDescription = NSLocalizedString("network-protection.waitlist.notification-prompt-description", value: "Get a notification when your copy of Network Protection early access is ready.", comment: "Subtitle for the alert to confirm enabling notifications") - static let networkProtectionNotificationsTitle = NSLocalizedString("network.protection.notification.title", value: "DuckDuckGo", comment: "The title of the notifications shown from Network Protection") - static let networkProtectionConnectionSuccessNotificationBody = NSLocalizedString("network.protection.success.notification.body", value: "Network Protection is On. Your location and online activity are protected.", comment: "The body of the notification shown when Network Protection reconnects successfully") - static func networkProtectionConnectionSuccessNotificationBody(serverLocation: String) -> String { - let localized = NSLocalizedString( - "network.protection.success.notification.subtitle.including.serverLocation", - value: "Routing device traffic through %@.", - comment: "The body of the notification shown when Network Protection connects successfully with the city + state/country as formatted parameter" - ) - return String(format: localized, serverLocation) - } - static let networkProtectionConnectionInterruptedNotificationBody = NSLocalizedString("network.protection.interrupted.notification.body", value: "Network Protection was interrupted. Attempting to reconnect now...", comment: "The body of the notification shown when Network Protection's connection is interrupted") - static let networkProtectionConnectionFailureNotificationBody = NSLocalizedString("network.protection.failure.notification.body", value: "Network Protection failed to connect. Please try again later.", comment: "The body of the notification shown when Network Protection fails to reconnect") - static let networkProtectionEntitlementExpiredNotificationBody = NSLocalizedString("network.protection.entitlement.expired.notification.body", value: "VPN disconnected due to expired subscription. Subscribe to Privacy Pro to reconnect DuckDuckGo VPN.", comment: "The body of the notification when Privacy Pro subscription expired") - // MARK: Settings Screeen public static let settingsTitle = NSLocalizedString("settings.title", value: "Settings", comment: "Title for the Settings View") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index 9d4956336f..815afd61b6 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -1519,15 +1519,6 @@ https://duckduckgo.com/mac"; /* Subtitle text for the Network Protection settings row */ "network-protection.waitlist.settings-subtitle.waitlist-not-joined" = "Join the private waitlist"; -/* The body of the notification when Privacy Pro subscription expired */ -"network.protection.entitlement.expired.notification.body" = "VPN disconnected due to expired subscription. Subscribe to Privacy Pro to reconnect DuckDuckGo VPN."; - -/* The body of the notification shown when Network Protection fails to reconnect */ -"network.protection.failure.notification.body" = "Network Protection failed to connect. Please try again later."; - -/* The body of the notification shown when Network Protection's connection is interrupted */ -"network.protection.interrupted.notification.body" = "Network Protection was interrupted. Attempting to reconnect now..."; - /* Message for the network protection invite dialog */ "network.protection.invite.dialog.message" = "Enter your invite code to get started."; @@ -1543,9 +1534,6 @@ https://duckduckgo.com/mac"; /* Title for the network protection invite success view */ "network.protection.invite.success.title" = "Success! You’re in."; -/* The title of the notifications shown from Network Protection */ -"network.protection.notification.title" = "DuckDuckGo"; - /* Title text for an iOS quick action that opens VPN settings */ "network.protection.quick-action.open-vpn" = "Open VPN"; @@ -1594,12 +1582,6 @@ https://duckduckgo.com/mac"; /* Title label text for the status view when netP is disconnected */ "network.protection.status.view.title" = "Network Protection"; -/* The body of the notification shown when Network Protection reconnects successfully */ -"network.protection.success.notification.body" = "Network Protection is On. Your location and online activity are protected."; - -/* The body of the notification shown when Network Protection connects successfully with the city + state/country as formatted parameter */ -"network.protection.success.notification.subtitle.including.serverLocation" = "Routing device traffic through %@."; - /* Title for the button to link to the iOS app settings and enable notifications app-wide. */ "network.protection.turn.on.notifications.button.title" = "Turn On Notifications"; diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index 42e2dee8b5..ebeda53607 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -162,7 +162,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { params[PixelParameters.wireguardErrorCode] = String(code) case .noAuthTokenFound: pixelEvent = .networkProtectionNoAuthTokenFoundError - case .vpnAccessRevoked, .noSubscriptionAccessTokenFound: + case .vpnAccessRevoked: return case .unhandledError(function: let function, line: let line, error: let error): pixelEvent = .networkProtectionUnhandledError @@ -203,8 +203,10 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { } @objc init() { + let subscriptionConfig = SubscriptionConfig.makeConfiguration() let tokenStore = NetworkProtectionKeychainTokenStore(keychainType: .dataProtection(.unspecified), - errorEvents: nil) + errorEvents: nil, + isSubscriptionEnabled: subscriptionConfig.isEnabled) let errorStore = NetworkProtectionTunnelErrorStore() let notificationsPresenter = NetworkProtectionUNNotificationPresenter() let settings = VPNSettings(defaults: .networkProtectionGroupDefaults) @@ -221,7 +223,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { debugEvents: Self.networkProtectionDebugEvents(controllerErrorStore: errorStore), providerEvents: Self.packetTunnelProviderEvents, settings: settings, - subscriptionConfig: SubscriptionConfig.makeConfiguration()) + subscriptionConfig: subscriptionConfig) startMonitoringMemoryPressureEvents() observeServerChanges() observeStatusChanges() @@ -280,10 +282,7 @@ extension PacketTunnelProvider.SubscriptionConfig { static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfig { .init( isEnabled: true, - isEntitlementValid: Self.isEntitlementValid, - getAccessToken: { - AccountManager().accessToken - } + isEntitlementValid: Self.isEntitlementValid ) } @@ -296,8 +295,7 @@ extension PacketTunnelProvider.SubscriptionConfig { static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfig { .init( isEnabled: false, - isEntitlementValid: { true }, - getAccessToken: { nil } + isEntitlementValid: { true } ) } #endif From 11ba78f557bf19a46dc45a5bdd5fa2ef0f451ec5 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 1 Feb 2024 22:28:18 -0500 Subject: [PATCH 15/25] Update BSK --- DuckDuckGo.xcodeproj/project.pbxproj | 6 ++---- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index a46a29d7e5..718f98f5f5 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -2341,7 +2341,6 @@ B6BA95C428894A28004ABA20 /* BrowsingMenuViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = BrowsingMenuViewController.storyboard; sourceTree = ""; }; B6BA95E728924730004ABA20 /* JSAlertController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = JSAlertController.storyboard; sourceTree = ""; }; B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64DownloadSession.swift; sourceTree = ""; }; - BD25422E2B6A8F10002FA3CC /* BrowserServicesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = BrowserServicesKit; path = ../../BrowserServicesKit; sourceTree = ""; }; BD862E022B30DA170073E2EE /* VPNFeedbackFormViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackFormViewModel.swift; sourceTree = ""; }; BD862E042B30DB250073E2EE /* VPNFeedbackCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackCategory.swift; sourceTree = ""; }; BD862E062B30F5E30073E2EE /* VPNFeedbackSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackSender.swift; sourceTree = ""; }; @@ -3467,7 +3466,6 @@ 31E69A60280F4BAD00478327 /* LocalPackages */ = { isa = PBXGroup; children = ( - BD25422E2B6A8F10002FA3CC /* BrowserServicesKit */, 85875B5F29912A2D00115F05 /* SyncUI */, 37FCAACB2993149A000E420A /* Waitlist */, 31794BFF2821DFB600F18633 /* DuckUI */, @@ -9992,8 +9990,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit"; requirement = { - kind = exactVersion; - version = 104.1.0; + branch = "anh/netp-check-entitlement-while-rekeying"; + kind = branch; }; }; C14882EB27F211A000D59F0C /* XCRemoteSwiftPackageReference "SwiftSoup" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3c3d5054b6..998f8f103c 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { - "revision" : "537dc46b8aa45d9a177ab189fbc6705bc14dfd93", - "version" : "104.1.0" + "branch" : "anh/netp-check-entitlement-while-rekeying", + "revision" : "b39d3c737088fc9fd0f538b61dc88bfb68b7c3fd" } }, { From 9c261ab9f7d6c37b34d68c7fc13a66d567399f1a Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 1 Feb 2024 23:09:23 -0500 Subject: [PATCH 16/25] Update BSK --- .../xcshareddata/swiftpm/Package.resolved | 2 +- ...etworkProtectionPacketTunnelProvider.swift | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 998f8f103c..9203e31c11 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { "branch" : "anh/netp-check-entitlement-while-rekeying", - "revision" : "b39d3c737088fc9fd0f538b61dc88bfb68b7c3fd" + "revision" : "ef7b4288f87f401b0777ca6708f18b2ad5445511" } }, { diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index ebeda53607..5c530b09ba 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -203,10 +203,10 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { } @objc init() { - let subscriptionConfig = SubscriptionConfig.makeConfiguration() + let subscriptionConfiguration = SubscriptionConfiguration.makeConfiguration() let tokenStore = NetworkProtectionKeychainTokenStore(keychainType: .dataProtection(.unspecified), errorEvents: nil, - isSubscriptionEnabled: subscriptionConfig.isEnabled) + isSubscriptionEnabled: subscriptionConfiguration.isSubscriptionEnabled) let errorStore = NetworkProtectionTunnelErrorStore() let notificationsPresenter = NetworkProtectionUNNotificationPresenter() let settings = VPNSettings(defaults: .networkProtectionGroupDefaults) @@ -223,7 +223,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { debugEvents: Self.networkProtectionDebugEvents(controllerErrorStore: errorStore), providerEvents: Self.packetTunnelProviderEvents, settings: settings, - subscriptionConfig: subscriptionConfig) + subscriptionConfiguration: subscriptionConfiguration) startMonitoringMemoryPressureEvents() observeServerChanges() observeStatusChanges() @@ -277,24 +277,23 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { #endif -extension PacketTunnelProvider.SubscriptionConfig { +extension PacketTunnelProvider.SubscriptionConfiguration { #if ALPHA - static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfig { + static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfiguration { .init( - isEnabled: true, + isSubscriptionEnabled: true, isEntitlementValid: Self.isEntitlementValid ) } static func isEntitlementValid() async -> Bool { - // TODO: Replace this with proper entitlement check - // https://app.asana.com/0/0/1206470585910128/f + // todo - https://app.asana.com/0/0/1206470585910128/f await AccountManager().hasEntitlement(for: "dummy1") } #else - static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfig { + static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfiguration { .init( - isEnabled: false, + isSubscriptionEnabled: false, isEntitlementValid: { true } ) } From 844e6557f09a6fb083945f1cb8e1034ffadd0a89 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Thu, 1 Feb 2024 23:18:10 -0500 Subject: [PATCH 17/25] Update BSK --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- .../NetworkProtectionPacketTunnelProvider.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9203e31c11..69ea9b37b9 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { "branch" : "anh/netp-check-entitlement-while-rekeying", - "revision" : "ef7b4288f87f401b0777ca6708f18b2ad5445511" + "revision" : "23e7d39288dfbb333d5ee644fa4c2f3b09a4aed2" } }, { diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index 5c530b09ba..6391b47e9b 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -278,10 +278,10 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { #endif extension PacketTunnelProvider.SubscriptionConfiguration { -#if ALPHA +#if ALPHA && SUBSCRIPTION static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfiguration { .init( - isSubscriptionEnabled: true, + isSubscriptionEnabled: AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription), isEntitlementValid: Self.isEntitlementValid ) } From 695f857b76f47de68781da640a2452c5dc0f0d93 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Mon, 5 Feb 2024 13:02:22 -0500 Subject: [PATCH 18/25] Add missing file --- .../xcshareddata/swiftpm/Package.resolved | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000000..69ea9b37b9 --- /dev/null +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,185 @@ +{ + "pins" : [ + { + "identity" : "bloom_cpp", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/bloom_cpp.git", + "state" : { + "revision" : "8076199456290b61b4544bf2f4caf296759906a0", + "version" : "3.0.0" + } + }, + { + "identity" : "browserserviceskit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", + "state" : { + "branch" : "anh/netp-check-entitlement-while-rekeying", + "revision" : "23e7d39288dfbb333d5ee644fa4c2f3b09a4aed2" + } + }, + { + "identity" : "cocoaasyncsocket", + "kind" : "remoteSourceControl", + "location" : "https://github.com/robbiehanson/CocoaAsyncSocket", + "state" : { + "revision" : "dbdc00669c1ced63b27c3c5f052ee4d28f10150c", + "version" : "7.6.5" + } + }, + { + "identity" : "content-scope-scripts", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/content-scope-scripts", + "state" : { + "revision" : "38ee7284bac7fa12d822fcaf0677ea3969d15fb1", + "version" : "4.59.2" + } + }, + { + "identity" : "designresourceskit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/DesignResourcesKit", + "state" : { + "revision" : "d7ea2561ec7624c224f52e1c9b349075ddf1c782", + "version" : "2.0.0" + } + }, + { + "identity" : "duckduckgo-autofill", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/duckduckgo-autofill.git", + "state" : { + "revision" : "b972bc0ab6ee1d57a0a18a197dcc31e40ae6ac57", + "version" : "10.0.3" + } + }, + { + "identity" : "grdb.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/GRDB.swift.git", + "state" : { + "revision" : "9f049d7b97b1e68ffd86744b500660d34a9e79b8", + "version" : "2.3.0" + } + }, + { + "identity" : "ios-js-support", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/ios-js-support", + "state" : { + "revision" : "6a6789ac8104a587316c58af75539753853b50d9", + "version" : "2.0.0" + } + }, + { + "identity" : "kingfisher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/onevcat/Kingfisher.git", + "state" : { + "revision" : "af4be924ad984cf4d16f4ae4df424e79a443d435", + "version" : "7.6.2" + } + }, + { + "identity" : "lottie-ios", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/lottie-ios.git", + "state" : { + "revision" : "abf5510e261c85ffddd29de0bca9b72592ea2bdd", + "version" : "3.3.0" + } + }, + { + "identity" : "ohhttpstubs", + "kind" : "remoteSourceControl", + "location" : "https://github.com/AliSoftware/OHHTTPStubs.git", + "state" : { + "revision" : "12f19662426d0434d6c330c6974d53e2eb10ecd9", + "version" : "9.1.0" + } + }, + { + "identity" : "privacy-dashboard", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/privacy-dashboard", + "state" : { + "revision" : "c67d268bf234760f49034a0fe7a6137a1b216b05", + "version" : "3.2.0" + } + }, + { + "identity" : "punycodeswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/gumob/PunycodeSwift.git", + "state" : { + "revision" : "4356ec54e073741449640d3d50a1fd24fd1e1b8b", + "version" : "2.1.0" + } + }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser", + "state" : { + "revision" : "c8ed701b513cf5177118a175d85fbbbcd707ab41", + "version" : "1.3.0" + } + }, + { + "identity" : "swifter", + "kind" : "remoteSourceControl", + "location" : "https://github.com/httpswift/swifter.git", + "state" : { + "revision" : "9483a5d459b45c3ffd059f7b55f9638e268632fd", + "version" : "1.5.0" + } + }, + { + "identity" : "swiftsoup", + "kind" : "remoteSourceControl", + "location" : "https://github.com/scinfu/SwiftSoup", + "state" : { + "revision" : "41e7c263fb8c277e980ebcb9b0b5f6031d3d4886", + "version" : "2.4.2" + } + }, + { + "identity" : "sync_crypto", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/sync_crypto", + "state" : { + "revision" : "2ab6ab6f0f96b259c14c2de3fc948935fc16ac78", + "version" : "0.2.0" + } + }, + { + "identity" : "trackerradarkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/TrackerRadarKit", + "state" : { + "revision" : "a6b7ba151d9dc6684484f3785293875ec01cc1ff", + "version" : "1.2.2" + } + }, + { + "identity" : "wireguard-apple", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/wireguard-apple", + "state" : { + "revision" : "2d8172c11478ab11b0f5ad49bdb4f93f4b3d5e0d", + "version" : "1.1.1" + } + }, + { + "identity" : "zipfoundation", + "kind" : "remoteSourceControl", + "location" : "https://github.com/weichsel/ZIPFoundation.git", + "state" : { + "revision" : "a3f5c2bae0f04b0bce9ef3c4ba6bd1031a0564c4", + "version" : "0.9.17" + } + } + ], + "version" : 2 +} From e53ce3d4e513c30797dc281af324bd53a290fc90 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Mon, 5 Feb 2024 18:01:19 -0500 Subject: [PATCH 19/25] Clean up --- DuckDuckGo.xcodeproj/project.pbxproj | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 718f98f5f5..27c9678d52 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -105,17 +105,12 @@ 1CB7B82123CEA1F800AA24EA /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CB7B82023CEA1F800AA24EA /* DateExtension.swift */; }; 1CB7B82323CEA28300AA24EA /* DateExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CB7B82223CEA28300AA24EA /* DateExtensionTests.swift */; }; 1E016AB42949FEB500F21625 /* OmniBarNotificationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E016AB32949FEB500F21625 /* OmniBarNotificationViewModel.swift */; }; - 1E016AB6294A5EB100F21625 /* CustomDaxDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E016AB5294A5EB100F21625 /* CustomDaxDialog.swift */; }; 1E05D1D629C46EBB00BF9A1F /* DailyPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E05D1D529C46EBB00BF9A1F /* DailyPixel.swift */; }; 1E05D1D829C46EDA00BF9A1F /* TimedPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E05D1D729C46EDA00BF9A1F /* TimedPixel.swift */; }; 1E05D1DB29C47B3300BF9A1F /* DailyPixelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E05D1D929C47B2B00BF9A1F /* DailyPixelTests.swift */; }; 1E0A75EA27A2FBD000A2BFB6 /* Downloads.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1E0A75E927A2FBD000A2BFB6 /* Downloads.storyboard */; }; 1E162605296840D80004127F /* Triangle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E162604296840D80004127F /* Triangle.swift */; }; 1E1626072968413B0004127F /* ViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E1626062968413B0004127F /* ViewExtension.swift */; }; - 1E16260B296845120004127F /* cookie-banner-illustration-animated.json in Resources */ = {isa = PBXBuildFile; fileRef = 1E162609296845120004127F /* cookie-banner-illustration-animated.json */; }; - 1E16260C296845120004127F /* cookie-banner-illustration-animated-dark.json in Resources */ = {isa = PBXBuildFile; fileRef = 1E16260A296845120004127F /* cookie-banner-illustration-animated-dark.json */; }; - 1E162610296C5C630004127F /* CustomDaxDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E16260F296C5C630004127F /* CustomDaxDialogViewModel.swift */; }; - 1E162613296C62820004127F /* CookieConsentDaxDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E162612296C62820004127F /* CookieConsentDaxDialogViewModel.swift */; }; 1E162615296D910F0004127F /* cookie-icon-animated-40-dark.json in Resources */ = {isa = PBXBuildFile; fileRef = 1E162614296D910F0004127F /* cookie-icon-animated-40-dark.json */; }; 1E1D8B5D2994FFE100C96994 /* AutoconsentMessageProtocolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E1D8B5C2994FFE100C96994 /* AutoconsentMessageProtocolTests.swift */; }; 1E1D8B6129950FD200C96994 /* AutoconsentBackgroundTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E1D8B6029950FD200C96994 /* AutoconsentBackgroundTests.swift */; }; @@ -1217,17 +1212,12 @@ 1CB7B82023CEA1F800AA24EA /* DateExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateExtension.swift; sourceTree = ""; }; 1CB7B82223CEA28300AA24EA /* DateExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateExtensionTests.swift; sourceTree = ""; }; 1E016AB32949FEB500F21625 /* OmniBarNotificationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OmniBarNotificationViewModel.swift; sourceTree = ""; }; - 1E016AB5294A5EB100F21625 /* CustomDaxDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDaxDialog.swift; sourceTree = ""; }; 1E05D1D529C46EBB00BF9A1F /* DailyPixel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyPixel.swift; sourceTree = ""; }; 1E05D1D729C46EDA00BF9A1F /* TimedPixel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimedPixel.swift; sourceTree = ""; }; 1E05D1D929C47B2B00BF9A1F /* DailyPixelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyPixelTests.swift; sourceTree = ""; }; 1E0A75E927A2FBD000A2BFB6 /* Downloads.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Downloads.storyboard; sourceTree = ""; }; 1E162604296840D80004127F /* Triangle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Triangle.swift; sourceTree = ""; }; 1E1626062968413B0004127F /* ViewExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewExtension.swift; sourceTree = ""; }; - 1E162609296845120004127F /* cookie-banner-illustration-animated.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "cookie-banner-illustration-animated.json"; sourceTree = ""; }; - 1E16260A296845120004127F /* cookie-banner-illustration-animated-dark.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "cookie-banner-illustration-animated-dark.json"; sourceTree = ""; }; - 1E16260F296C5C630004127F /* CustomDaxDialogViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDaxDialogViewModel.swift; sourceTree = ""; }; - 1E162612296C62820004127F /* CookieConsentDaxDialogViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CookieConsentDaxDialogViewModel.swift; sourceTree = ""; }; 1E162614296D910F0004127F /* cookie-icon-animated-40-dark.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "cookie-icon-animated-40-dark.json"; sourceTree = ""; }; 1E1D8B5C2994FFE100C96994 /* AutoconsentMessageProtocolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoconsentMessageProtocolTests.swift; sourceTree = ""; }; 1E1D8B6029950FD200C96994 /* AutoconsentBackgroundTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoconsentBackgroundTests.swift; sourceTree = ""; }; @@ -3107,7 +3097,6 @@ children = ( 1E1626082968418F0004127F /* Animations */, 1E162611296C62350004127F /* Model */, - 1E016AB5294A5EB100F21625 /* CustomDaxDialog.swift */, ); name = CustomDaxDialog; sourceTree = ""; @@ -3126,8 +3115,6 @@ 1E1626082968418F0004127F /* Animations */ = { isa = PBXGroup; children = ( - 1E16260A296845120004127F /* cookie-banner-illustration-animated-dark.json */, - 1E162609296845120004127F /* cookie-banner-illustration-animated.json */, ); name = Animations; sourceTree = ""; @@ -3135,8 +3122,6 @@ 1E162611296C62350004127F /* Model */ = { isa = PBXGroup; children = ( - 1E16260F296C5C630004127F /* CustomDaxDialogViewModel.swift */, - 1E162612296C62820004127F /* CookieConsentDaxDialogViewModel.swift */, ); name = Model; sourceTree = ""; @@ -6092,7 +6077,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1E16260C296845120004127F /* cookie-banner-illustration-animated-dark.json in Resources */, AA4D6A8D23DE49A5007E8790 /* AppIconBlack40x40@3x.png in Resources */, F47E53DB250A9A1C0037C686 /* Onboarding.xcassets in Resources */, AA4D6ACC23DE4D27007E8790 /* AppIconPurple60x60@2x.png in Resources */, @@ -6155,7 +6139,6 @@ 85A313972028E78A00327D00 /* release_notes.txt in Resources */, 9865DFFD22A84CF300D27829 /* FavoriteHomeCell.xib in Resources */, 1EE411FE2858B9300003FE64 /* dark-shield.json in Resources */, - 1E16260B296845120004127F /* cookie-banner-illustration-animated.json in Resources */, AA4D6AD323DE4D27007E8790 /* AppIconPurple29x29@2x.png in Resources */, AA4D6AA123DE4CC4007E8790 /* AppIconBlue60x60@3x.png in Resources */, 984147A824F0259000362052 /* Onboarding.storyboard in Resources */, @@ -6545,7 +6528,6 @@ D664C7C72B289AA200CBFA76 /* PurchaseInProgressView.swift in Sources */, D6E83C122B1E6AB3006C8AFB /* SettingsView.swift in Sources */, F1668BCE1E798081008CBA04 /* BookmarksViewController.swift in Sources */, - 1E162610296C5C630004127F /* CustomDaxDialogViewModel.swift in Sources */, 8590CB69268A4E190089F6BF /* DebugEtagStorage.swift in Sources */, D6D12CA62B291CAA0054390C /* AppStoreRestoreFlow.swift in Sources */, C1CDA3162AFB9C7F006D1476 /* AutofillNeverPromptWebsitesManager.swift in Sources */, @@ -6783,7 +6765,6 @@ 98DA6ECA2181E41F00E65433 /* ThemeManager.swift in Sources */, C159DF072A430B60007834BB /* EmailSignupViewController.swift in Sources */, 37A6A8FE2AFD0208008580A3 /* FaviconsFetcherOnboarding.swift in Sources */, - 1E016AB6294A5EB100F21625 /* CustomDaxDialog.swift in Sources */, 02341FA42A437999008A1531 /* OnboardingStepView.swift in Sources */, F1CA3C3B1F045B65005FADB3 /* Authenticator.swift in Sources */, CBD4F13D279EBFA000B20FD7 /* HomeMessageCollectionViewCell.swift in Sources */, @@ -6972,7 +6953,6 @@ 3132FA2827A0788400DD7A12 /* PassKitPreviewHelper.swift in Sources */, 8505836C219F424500ED4EDB /* TextFieldWithInsets.swift in Sources */, CBD4F13F279EBFAF00B20FD7 /* HomeMessageViewModel.swift in Sources */, - 1E162613296C62820004127F /* CookieConsentDaxDialogViewModel.swift in Sources */, 1E4DCF4A27B6A38000961E25 /* DownloadListRepresentable.swift in Sources */, 2DC3FC65C6D9DA634426672D /* AutofillNoAuthAvailableView.swift in Sources */, ); From c67390cbc51b44170b3bb73f7294b13418965fd9 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Mon, 5 Feb 2024 19:16:26 -0500 Subject: [PATCH 20/25] Update BSK --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 69ea9b37b9..e83d82c074 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { "branch" : "anh/netp-check-entitlement-while-rekeying", - "revision" : "23e7d39288dfbb333d5ee644fa4c2f3b09a4aed2" + "revision" : "92950875a9855546de79e7e25c3b031710b8927c" } }, { From e76255260d6d861e0606ab0d872060a8dd0b0341 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Tue, 6 Feb 2024 23:28:14 -0500 Subject: [PATCH 21/25] Update BSK --- .../xcshareddata/swiftpm/Package.resolved | 2 +- .../NetworkProtectionConvenienceInitialisers.swift | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index e83d82c074..99e7fb919c 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { "branch" : "anh/netp-check-entitlement-while-rekeying", - "revision" : "92950875a9855546de79e7e25c3b031710b8927c" + "revision" : "c0eb8700eea4180b12c3a968411a6d292f1bc992" } }, { diff --git a/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift b/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift index 1f1d63b40a..dbc2636c3a 100644 --- a/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift +++ b/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift @@ -60,12 +60,19 @@ extension NetworkProtectionKeychainTokenStore { extension NetworkProtectionCodeRedemptionCoordinator { convenience init(isManualCodeRedemptionFlow: Bool = false) { +#if ALPHA + let isSubscriptionEnabled = true +#else + let isSubscriptionEnabled = AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) +#endif + let settings = VPNSettings(defaults: .networkProtectionGroupDefaults) self.init( environment: settings.selectedEnvironment, tokenStore: NetworkProtectionKeychainTokenStore(), isManualCodeRedemptionFlow: isManualCodeRedemptionFlow, - errorEvents: .networkProtectionAppDebugEvents + errorEvents: .networkProtectionAppDebugEvents, + isSubscriptionEnabled: isSubscriptionEnabled ) } } From bba1c7980790bc9947a61417e62b354fb9951153 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Tue, 20 Feb 2024 11:14:57 -0500 Subject: [PATCH 22/25] Update BSK --- DuckDuckGo.xcodeproj/project.pbxproj | 14 -------------- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 7eb6ea9122..79dad3916a 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -688,13 +688,6 @@ B6BA95C528894A28004ABA20 /* BrowsingMenuViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6BA95C428894A28004ABA20 /* BrowsingMenuViewController.storyboard */; }; B6BA95E828924730004ABA20 /* JSAlertController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6BA95E728924730004ABA20 /* JSAlertController.storyboard */; }; B6CB93E5286445AB0090FEB4 /* Base64DownloadSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */; }; - BD7B379F2B5F6A3F0040F991 /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C8E2B291CA90054390C /* AccountManager.swift */; }; - BD7B37A02B5F6A4D0040F991 /* AccountKeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C902B291CA90054390C /* AccountKeychainStorage.swift */; }; - BD7B37A12B5F6A6A0040F991 /* AccountStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C912B291CA90054390C /* AccountStorage.swift */; }; - BD7B37A22B5F6A770040F991 /* AuthService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C9D2B291CA90054390C /* AuthService.swift */; }; - BD7B37A32B5F6A830040F991 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C9C2B291CA90054390C /* APIService.swift */; }; - BD7B37A42B5F6A9C0040F991 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C8D2B291CA90054390C /* Logging.swift */; }; - BD7B37A52B5F6AAA0040F991 /* SubscriptionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12C9B2B291CA90054390C /* SubscriptionService.swift */; }; BD862E032B30DA170073E2EE /* VPNFeedbackFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E022B30DA170073E2EE /* VPNFeedbackFormViewModel.swift */; }; BD862E052B30DB250073E2EE /* VPNFeedbackCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E042B30DB250073E2EE /* VPNFeedbackCategory.swift */; }; BD862E072B30F5E30073E2EE /* VPNFeedbackSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E062B30F5E30073E2EE /* VPNFeedbackSender.swift */; }; @@ -6384,7 +6377,6 @@ buildActionMask = 2147483647; files = ( 02025B0D29884D2C00E694E7 /* AppTrackerData.swift in Sources */, - BD7B37A42B5F6A9C0040F991 /* Logging.swift in Sources */, 4BEF656C2989C2FC00B650CB /* TunnelEvent.swift in Sources */, 02025A9A2988229800E694E7 /* TUNInterface.swift in Sources */, 02025A9B2988229800E694E7 /* IPStackProtocol.swift in Sources */, @@ -6397,7 +6389,6 @@ 4BEF656D2989C2FC00B650CB /* EventType.swift in Sources */, 02025AAC2988229800E694E7 /* GCDHTTPProxyServer.swift in Sources */, 02025AAD2988229800E694E7 /* NWUDPSocket.swift in Sources */, - BD7B37A52B5F6AAA0040F991 /* SubscriptionService.swift in Sources */, EE3766DE2AC5945500AAB575 /* NetworkProtectionUNNotificationPresenter.swift in Sources */, 02025AAE2988229800E694E7 /* RawTCPSocketProtocol.swift in Sources */, 02025AAF2988229800E694E7 /* NWTCPSocket.swift in Sources */, @@ -6407,7 +6398,6 @@ 02025AB72988229800E694E7 /* AllRule.swift in Sources */, 02025AB82988229800E694E7 /* DNSSessionMatchResult.swift in Sources */, 02025AB92988229800E694E7 /* Rule.swift in Sources */, - BD7B37A32B5F6A830040F991 /* APIService.swift in Sources */, 02025ABA2988229800E694E7 /* DirectRule.swift in Sources */, 02025ABB2988229800E694E7 /* RuleManager.swift in Sources */, 02025ABC2988229800E694E7 /* IPRangeListRule.swift in Sources */, @@ -6421,20 +6411,16 @@ 02025AD82988229800E694E7 /* Tunnel.swift in Sources */, 02025ADA2988229800E694E7 /* Port.swift in Sources */, 02025ADB2988229800E694E7 /* HTTPStreamScanner.swift in Sources */, - BD7B37A02B5F6A4D0040F991 /* AccountKeychainStorage.swift in Sources */, - BD7B379F2B5F6A3F0040F991 /* AccountManager.swift in Sources */, 02025ADC2988229800E694E7 /* UInt128.swift in Sources */, 02025ADD2988229800E694E7 /* IPInterval.swift in Sources */, 02025ADE2988229800E694E7 /* IPPool.swift in Sources */, 4BEF65692989C2FC00B650CB /* AdapterSocketEvent.swift in Sources */, 02025ADF2988229800E694E7 /* IPMask.swift in Sources */, 4BEF656A2989C2FC00B650CB /* ProxyServerEvent.swift in Sources */, - BD7B37A12B5F6A6A0040F991 /* AccountStorage.swift in Sources */, 4BEF656B2989C2FC00B650CB /* RuleMatchEvent.swift in Sources */, 02025AE02988229800E694E7 /* IPRange.swift in Sources */, 02025AE12988229800E694E7 /* IPAddress.swift in Sources */, 02025B1529884EA500E694E7 /* DDGObserverFactory.swift in Sources */, - BD7B37A22B5F6A770040F991 /* AuthService.swift in Sources */, 02025AE32988229800E694E7 /* BinaryDataScanner.swift in Sources */, 021D30752989C04200918636 /* Observer.swift in Sources */, 02025AE42988229800E694E7 /* Checksum.swift in Sources */, diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 7b37d3e8ab..fdc8ddd560 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -12,10 +12,10 @@ { "identity" : "browserserviceskit", "kind" : "remoteSourceControl", - "location" : "https://github.com/duckduckgo/BrowserServicesKit", + "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { "branch" : "anh/netp-check-entitlement-while-rekeying", - "revision" : "c0eb8700eea4180b12c3a968411a6d292f1bc992" + "revision" : "cf48f671035c16d672bfb0c09a7c0a8aa8c66c3a" } }, { From e5577d7b3e0903454fa1a3dd34547db66608827f Mon Sep 17 00:00:00 2001 From: Anh Do Date: Tue, 20 Feb 2024 12:26:22 -0500 Subject: [PATCH 23/25] Address PR comments --- DuckDuckGo.xcodeproj/project.pbxproj | 24 ------------------- DuckDuckGo/MainViewController.swift | 12 +--------- ...orkProtectionConvenienceInitialisers.swift | 23 +++--------------- 3 files changed, 4 insertions(+), 55 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 79dad3916a..878eedc2c3 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -3093,15 +3093,6 @@ name = AppTPBreakageForm; sourceTree = ""; }; - 1E16260029683B4D0004127F /* CustomDaxDialog */ = { - isa = PBXGroup; - children = ( - 1E1626082968418F0004127F /* Animations */, - 1E162611296C62350004127F /* Model */, - ); - name = CustomDaxDialog; - sourceTree = ""; - }; 1E162603296840790004127F /* SwiftUI */ = { isa = PBXGroup; children = ( @@ -3113,20 +3104,6 @@ name = SwiftUI; sourceTree = ""; }; - 1E1626082968418F0004127F /* Animations */ = { - isa = PBXGroup; - children = ( - ); - name = Animations; - sourceTree = ""; - }; - 1E162611296C62350004127F /* Model */ = { - isa = PBXGroup; - children = ( - ); - name = Model; - sourceTree = ""; - }; 1E162616296D962A0004127F /* Model */ = { isa = PBXGroup; children = ( @@ -4892,7 +4869,6 @@ F11CEF581EBB66C80088E4D7 /* Tutorials */ = { isa = PBXGroup; children = ( - 1E16260029683B4D0004127F /* CustomDaxDialog */, 858650CF2469BCC100C36F8A /* DaxOnboarding */, 85EE7F53224667C3000FE757 /* WebContainer */, 85C11E4A209084DE00BFFEB4 /* HomeRow */, diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index 25811755be..8b0ec3a6cf 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -1334,12 +1334,6 @@ class MainViewController: UIViewController { self?.onNetworkProtectionAccountSignIn(notification) } .store(in: &netpCancellables) - NotificationCenter.default.publisher(for: .accountDidSignOut) - .receive(on: DispatchQueue.main) - .sink { [weak self] notification in - self?.onNetworkProtectionAccountSignOut(notification) - } - .store(in: &netpCancellables) } @objc @@ -1351,6 +1345,7 @@ class MainViewController: UIViewController { Task { do { + // todo - https://app.asana.com/0/0/1206541966681608/f try NetworkProtectionKeychainTokenStore().store(NetworkProtectionKeychainTokenStore.makeToken(from: token)) print("[NetP Subscription] Stored derived NetP auth token") } catch { @@ -1358,11 +1353,6 @@ class MainViewController: UIViewController { } } } - - @objc - private func onNetworkProtectionAccountSignOut(_ notification: Notification) { - // no-op - } #endif @objc diff --git a/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift b/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift index 70856de7c0..922220f2a8 100644 --- a/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift +++ b/DuckDuckGo/NetworkProtectionConvenienceInitialisers.swift @@ -56,33 +56,22 @@ extension ConnectionServerInfoObserverThroughSession { extension NetworkProtectionKeychainTokenStore { convenience init() { -#if ALPHA - let isSubscriptionEnabled = true -#else - let isSubscriptionEnabled = AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) -#endif self.init(keychainType: .dataProtection(.unspecified), serviceName: "\(Bundle.main.bundleIdentifier!).authToken", errorEvents: .networkProtectionAppDebugEvents, - isSubscriptionEnabled: isSubscriptionEnabled) + isSubscriptionEnabled: AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription)) } } extension NetworkProtectionCodeRedemptionCoordinator { convenience init(isManualCodeRedemptionFlow: Bool = false) { -#if ALPHA - let isSubscriptionEnabled = true -#else - let isSubscriptionEnabled = AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) -#endif - let settings = VPNSettings(defaults: .networkProtectionGroupDefaults) self.init( environment: settings.selectedEnvironment, tokenStore: NetworkProtectionKeychainTokenStore(), isManualCodeRedemptionFlow: isManualCodeRedemptionFlow, errorEvents: .networkProtectionAppDebugEvents, - isSubscriptionEnabled: isSubscriptionEnabled + isSubscriptionEnabled: AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) ) } } @@ -105,17 +94,11 @@ extension NetworkProtectionVPNSettingsViewModel { extension NetworkProtectionLocationListCompositeRepository { convenience init() { let settings = VPNSettings(defaults: .networkProtectionGroupDefaults) -#if ALPHA - let isSubscriptionEnabled = true -#else - let isSubscriptionEnabled = AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) -#endif - self.init( environment: settings.selectedEnvironment, tokenStore: NetworkProtectionKeychainTokenStore(), errorEvents: .networkProtectionAppDebugEvents, - isSubscriptionEnabled: isSubscriptionEnabled + isSubscriptionEnabled: AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription) ) } } From 67bebd020031e87cce31275b7abb3f7c2205a015 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Tue, 20 Feb 2024 13:16:28 -0500 Subject: [PATCH 24/25] Simplify subscription config --- ...etworkProtectionPacketTunnelProvider.swift | 37 +++++-------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index 6391b47e9b..a25daf6fe2 100644 --- a/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -203,19 +203,23 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { } @objc init() { - let subscriptionConfiguration = SubscriptionConfiguration.makeConfiguration() +#if ALPHA + let isSubscriptionEnabled = true +#else + let isSubscriptionEnabled = false +#endif let tokenStore = NetworkProtectionKeychainTokenStore(keychainType: .dataProtection(.unspecified), errorEvents: nil, - isSubscriptionEnabled: subscriptionConfiguration.isSubscriptionEnabled) + isSubscriptionEnabled: isSubscriptionEnabled) let errorStore = NetworkProtectionTunnelErrorStore() let notificationsPresenter = NetworkProtectionUNNotificationPresenter() let settings = VPNSettings(defaults: .networkProtectionGroupDefaults) - let nofificationsPresenterDecorator = NetworkProtectionNotificationsPresenterTogglableDecorator( + let notificationsPresenterDecorator = NetworkProtectionNotificationsPresenterTogglableDecorator( settings: settings, wrappee: notificationsPresenter ) notificationsPresenter.requestAuthorization() - super.init(notificationsPresenter: nofificationsPresenterDecorator, + super.init(notificationsPresenter: notificationsPresenterDecorator, tunnelHealthStore: NetworkProtectionTunnelHealthStore(), controllerErrorStore: errorStore, keychainType: .dataProtection(.unspecified), @@ -223,7 +227,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { debugEvents: Self.networkProtectionDebugEvents(controllerErrorStore: errorStore), providerEvents: Self.packetTunnelProviderEvents, settings: settings, - subscriptionConfiguration: subscriptionConfiguration) + isSubscriptionEnabled: isSubscriptionEnabled) startMonitoringMemoryPressureEvents() observeServerChanges() observeStatusChanges() @@ -276,26 +280,3 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { } #endif - -extension PacketTunnelProvider.SubscriptionConfiguration { -#if ALPHA && SUBSCRIPTION - static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfiguration { - .init( - isSubscriptionEnabled: AppDependencyProvider.shared.featureFlagger.isFeatureOn(.subscription), - isEntitlementValid: Self.isEntitlementValid - ) - } - - static func isEntitlementValid() async -> Bool { - // todo - https://app.asana.com/0/0/1206470585910128/f - await AccountManager().hasEntitlement(for: "dummy1") - } -#else - static func makeConfiguration() -> PacketTunnelProvider.SubscriptionConfiguration { - .init( - isSubscriptionEnabled: false, - isEntitlementValid: { true } - ) - } -#endif -} From c0ff06cf6d9908246791cf69016c4afeee7adcb6 Mon Sep 17 00:00:00 2001 From: Anh Do Date: Tue, 20 Feb 2024 13:38:16 -0500 Subject: [PATCH 25/25] Update BSK --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index fdc8ddd560..dffec4b993 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { "branch" : "anh/netp-check-entitlement-while-rekeying", - "revision" : "cf48f671035c16d672bfb0c09a7c0a8aa8c66c3a" + "revision" : "edb3fc3b8fa61f98345185e775804dbfcefdedce" } }, {