From ce5fd6d5e1ce46f3b99afc7155b77d35f4c1724f Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Fri, 18 Aug 2023 12:49:26 +0200 Subject: [PATCH 01/13] Committing to save my WIP. Signed-off-by: Diego Rey Mendez --- DuckDuckGo.xcodeproj/project.pbxproj | 8 ++++ .../xcshareddata/swiftpm/Package.resolved | 13 +------ DuckDuckGo/AppDelegate/AppDelegate.swift | 37 ++++++++++++++++++- DuckDuckGo/DuckDuckGo.entitlements | 2 +- DuckDuckGo/DuckDuckGoAppStore.entitlements | 1 + DuckDuckGo/DuckDuckGoDebug.entitlements | 2 +- .../NetworkProtectionBundle.swift | 9 +++-- .../KeychainType+ClientDefault.swift | 30 +++++++++++++++ ...rkProtection+ConvenienceInitializers.swift | 4 +- .../MacPacketTunnelProvider.swift | 2 +- DuckDuckGoAgent/DuckDuckGoAgent.entitlements | 4 ++ .../DuckDuckGoAgentAppStore.entitlements | 4 ++ 12 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/KeychainType+ClientDefault.swift diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 5dcf332424..0f68c404c6 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1333,6 +1333,8 @@ 7BBD45B22A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */; }; 7BBD45B42A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B32A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift */; }; 7BBD45B52A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B32A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift */; }; + 7BD3AF5D2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; + 7BD3AF5E2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; 7BE146072A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */; }; 7BE146082A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */; }; 85012B0229133F9F003D0DCC /* NavigationBarPopovers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85012B0129133F9F003D0DCC /* NavigationBarPopovers.swift */; }; @@ -2593,6 +2595,8 @@ 7BB108582A43375D000AB95F /* PFMoveApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PFMoveApplication.m; sourceTree = ""; }; 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionDebugUtilities.swift; sourceTree = ""; }; 7BBD45B32A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionLoginItemsManager.swift; sourceTree = ""; }; + 7BD3AF5B2A8E77D8006F9F56 /* BrowserServicesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = BrowserServicesKit; path = ../../BrowserServicesKit; sourceTree = ""; }; + 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeychainType+ClientDefault.swift"; sourceTree = ""; }; 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionDebugMenu.swift; sourceTree = ""; }; 85012B0129133F9F003D0DCC /* NavigationBarPopovers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarPopovers.swift; sourceTree = ""; }; 850E8DFA2A6FEC5E00691187 /* BookmarksBarAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksBarAppearance.swift; sourceTree = ""; }; @@ -3664,6 +3668,7 @@ 378E279C2970217400FCADA2 /* LocalPackages */ = { isa = PBXGroup; children = ( + 7BD3AF5B2A8E77D8006F9F56 /* BrowserServicesKit */, 378E279D2970217400FCADA2 /* BuildToolPlugins */, 4BE15DB32A0B0DD500898243 /* NetworkProtectionUI */, 4BE15DB12A0B0DD500898243 /* PixelKit */, @@ -3994,6 +3999,7 @@ 4B4D60652A0B29FA00BCD287 /* NetworkProtectionNavBarButtonModel.swift */, 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */, 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */, + 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */, 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */, 4B4D606B2A0B29FA00BCD287 /* Invite */, 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */, @@ -7497,6 +7503,7 @@ 37197EAB2942443D00394917 /* WebViewContainerView.swift in Sources */, 3706FA88293F65D500E42796 /* Logging.swift in Sources */, 3706FA89293F65D500E42796 /* CrashReportPromptPresenter.swift in Sources */, + 7BD3AF5E2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift in Sources */, 3706FA8B293F65D500E42796 /* PreferencesRootView.swift in Sources */, 3706FA8C293F65D500E42796 /* AppStateChangedPublisher.swift in Sources */, 3706FA8D293F65D500E42796 /* BookmarkTableCellView.swift in Sources */, @@ -8827,6 +8834,7 @@ 4BE65478271FCD41008D1D63 /* PasswordManagementNoteItemView.swift in Sources */, AA5C8F632591021700748EB7 /* NSApplicationExtension.swift in Sources */, AA9E9A5625A3AE8400D1959D /* NSWindowExtension.swift in Sources */, + 7BD3AF5D2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift in Sources */, AAC5E4C725D6A6E8007F5990 /* BookmarkPopover.swift in Sources */, 37CC53F027E8D1440028713D /* PreferencesDownloadsView.swift in Sources */, B6F7127E29F6779000594A45 /* QRSharingService.swift in Sources */, diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index caa11bcaaa..91a2bfe995 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,22 +9,13 @@ "version" : "3.0.0" } }, - { - "identity" : "browserserviceskit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/duckduckgo/BrowserServicesKit", - "state" : { - "revision" : "da6b1eac1d4b4416eb82fb5648519aa5cb363a17", - "version" : "74.0.1" - } - }, { "identity" : "content-scope-scripts", "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/content-scope-scripts", "state" : { - "revision" : "a4f35ad23ac4a0eb9b36b94f1f2aa0f0ebf2855d", - "version" : "4.30.0" + "revision" : "8def15fe8a4c2fb76730f640507e9fd1d6c1f8a7", + "version" : "4.32.0" } }, { diff --git a/DuckDuckGo/AppDelegate/AppDelegate.swift b/DuckDuckGo/AppDelegate/AppDelegate.swift index 6ae7e3f113..041126560b 100644 --- a/DuckDuckGo/AppDelegate/AppDelegate.swift +++ b/DuckDuckGo/AppDelegate/AppDelegate.swift @@ -315,13 +315,46 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel #if NETWORK_PROTECTION + /// If necessary, this method migrates the auth token from an unspecified data protection keychain (our previous + /// storage location), to the new shared keychain, which is where apps in our app group will try to access the NetP + /// auth token. + /// + /// This method bails out on any error condition - the user will probably have to re-enter their auth token if we can't + /// migrate this, and that's ok. This migration only affects internal users so it's not worth pixeling, and it's not worth + /// alerting the user to an error since they'll see Network Protection disable and eventually re-enable it. + /// + private func migrateNetworkProtectionAuthTokenToSharedKeychainIfNecessary() { + let sharedKeychainStore = NetworkProtectionKeychainTokenStore() + + guard !sharedKeychainStore.isFeatureActivated else { + // We only migrate if the auth token is missing from our new shared keychain. + return + } + + let anyDataProtectionKeychainStore = NetworkProtectionKeychainTokenStore(keychainType: .dataProtection(.unspecified), errorEvents: nil) + + guard let token = try? anyDataProtectionKeychainStore.fetchToken() else { + // If fetching the token fails, we just assume we can't migrate anything and the user + // will need to re-enable NetP. + return + } + + do { + try sharedKeychainStore.store(token) + } catch { + print(String(describing: error)) + } + } + private func startupNetworkProtection() { guard #available(macOS 11.4, *) else { return } + migrateNetworkProtectionAuthTokenToSharedKeychainIfNecessary() + let loginItemsManager = NetworkProtectionLoginItemsManager() - let networkProtectionFeatureVisibility = NetworkProtectionKeychainTokenStore() + let keychainStore = NetworkProtectionKeychainTokenStore() - guard networkProtectionFeatureVisibility.isFeatureActivated else { + guard keychainStore.isFeatureActivated else { loginItemsManager.disableLoginItems() LocalPinningManager.shared.unpin(.networkProtection) return diff --git a/DuckDuckGo/DuckDuckGo.entitlements b/DuckDuckGo/DuckDuckGo.entitlements index 607a816ca4..a12f6a14bb 100644 --- a/DuckDuckGo/DuckDuckGo.entitlements +++ b/DuckDuckGo/DuckDuckGo.entitlements @@ -19,7 +19,7 @@ keychain-access-groups $(AppIdentifierPrefix)com.duckduckgo.macos.browser - $(AppIdentifierPrefix)com.duckduckgo.network-protection + $(NETP_APP_GROUP) com.apple.developer.system-extension.install diff --git a/DuckDuckGo/DuckDuckGoAppStore.entitlements b/DuckDuckGo/DuckDuckGoAppStore.entitlements index 9d0255e659..340f405420 100644 --- a/DuckDuckGo/DuckDuckGoAppStore.entitlements +++ b/DuckDuckGo/DuckDuckGoAppStore.entitlements @@ -30,6 +30,7 @@ keychain-access-groups $(AppIdentifierPrefix)com.duckduckgo.mobile.ios + $(NETP_APP_GROUP) diff --git a/DuckDuckGo/DuckDuckGoDebug.entitlements b/DuckDuckGo/DuckDuckGoDebug.entitlements index c5cb100fc2..6316638341 100644 --- a/DuckDuckGo/DuckDuckGoDebug.entitlements +++ b/DuckDuckGo/DuckDuckGoDebug.entitlements @@ -13,7 +13,7 @@ keychain-access-groups $(AppIdentifierPrefix)com.duckduckgo.macos.browser - $(AppIdentifierPrefix)com.duckduckgo.network-protection + $(NETP_APP_GROUP) com.apple.developer.usernotifications.time-sensitive diff --git a/DuckDuckGo/NetworkProtection/AppAndExtensionTargets/AppAndExtensionAndNotificationTargets/NetworkProtectionBundle.swift b/DuckDuckGo/NetworkProtection/AppAndExtensionTargets/AppAndExtensionAndNotificationTargets/NetworkProtectionBundle.swift index 3876c26209..3faab89430 100644 --- a/DuckDuckGo/NetworkProtection/AppAndExtensionTargets/AppAndExtensionAndNotificationTargets/NetworkProtectionBundle.swift +++ b/DuckDuckGo/NetworkProtection/AppAndExtensionTargets/AppAndExtensionAndNotificationTargets/NetworkProtectionBundle.swift @@ -17,6 +17,7 @@ // import Foundation +import NetworkProtection enum NetworkProtectionBundle { @@ -67,11 +68,11 @@ enum NetworkProtectionBundle { return extensionBundle } - static func usesSystemKeychain() -> Bool { + static let keychainType: KeychainType = { #if NETP_SYSTEM_EXTENSION - true + .system #else - false + .accessGroup(.named(Bundle.main.appGroupName)) #endif - } + }() } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/KeychainType+ClientDefault.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/KeychainType+ClientDefault.swift new file mode 100644 index 0000000000..b083cc93c8 --- /dev/null +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/KeychainType+ClientDefault.swift @@ -0,0 +1,30 @@ +// +// KeychainType+ClientDefault.swift +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import NetworkProtection + +/// Implements convenience default for the client apps making use of this. +/// +/// If you add this to a new target, please make sure this default is the correct one for the target. +/// Because the default may not be right for all targets, please avoid sharing this in a framework directly. +/// This is meant to be a client-specific definition by its own nature. +/// +extension KeychainType { + static let `default`: KeychainType = .dataProtection(.named(Bundle.main.appGroupName)) +} diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtection+ConvenienceInitializers.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtection+ConvenienceInitializers.swift index 4aaa5d4ad9..b73b218a34 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtection+ConvenienceInitializers.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtection+ConvenienceInitializers.swift @@ -40,14 +40,14 @@ extension NetworkProtectionCodeRedemptionCoordinator { extension NetworkProtectionKeychainTokenStore { convenience init() { - self.init(useSystemKeychain: false, + self.init(keychainType: .default, errorEvents: .networkProtectionAppDebugEvents) } } extension NetworkProtectionKeychainKeyStore { convenience init() { - self.init(useSystemKeychain: false, + self.init(keychainType: .default, errorEvents: .networkProtectionAppDebugEvents) } } diff --git a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift index b2a8a7e6a3..36990e0d8c 100644 --- a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift +++ b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift @@ -154,7 +154,7 @@ final class MacPacketTunnelProvider: PacketTunnelProvider { super.init(notificationsPresenter: Self.makeNotificationsPresenter(), tunnelHealthStore: tunnelHealthStore, controllerErrorStore: controllerErrorStore, - useSystemKeychain: NetworkProtectionBundle.usesSystemKeychain(), + keychainType: NetworkProtectionBundle.keychainType, debugEvents: Self.networkProtectionDebugEvents(controllerErrorStore: controllerErrorStore), providerEvents: Self.packetTunnelProviderEvents) diff --git a/DuckDuckGoAgent/DuckDuckGoAgent.entitlements b/DuckDuckGoAgent/DuckDuckGoAgent.entitlements index a8bfad46cd..4382d0cc65 100644 --- a/DuckDuckGoAgent/DuckDuckGoAgent.entitlements +++ b/DuckDuckGoAgent/DuckDuckGoAgent.entitlements @@ -4,6 +4,10 @@ com.apple.security.app-sandbox + keychain-access-groups + + $(NETP_APP_GROUP) + com.apple.security.application-groups $(NETP_APP_GROUP) diff --git a/DuckDuckGoAgent/DuckDuckGoAgentAppStore.entitlements b/DuckDuckGoAgent/DuckDuckGoAgentAppStore.entitlements index f70dc2d7d7..7de1c91761 100644 --- a/DuckDuckGoAgent/DuckDuckGoAgentAppStore.entitlements +++ b/DuckDuckGoAgent/DuckDuckGoAgentAppStore.entitlements @@ -4,6 +4,10 @@ com.apple.security.app-sandbox + keychain-access-groups + + $(NETP_APP_GROUP) + com.apple.security.application-groups $(TeamIdentifierPrefix)com.duckduckgo.macos.browser.network-protection From 2851381d2d6f63460ca45b5e9b774bf029dcf8ae Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Mon, 21 Aug 2023 20:19:53 +0200 Subject: [PATCH 02/13] Implements a mechanism to block the menu app from launching when there's no auth code --- DuckDuckGo.xcodeproj/project.pbxproj | 28 ++++ .../xcschemes/DuckDuckGoAgent.xcscheme | 2 +- DuckDuckGo/AppDelegate/AppDelegate.swift | 113 +-------------- .../Utilities/UserDefaultsWrapper.swift | 7 + .../NetworkProtectionAppEvents.swift | 129 ++++++++++++++++++ .../AppLauncher+DefaultInitializer.swift | 36 +++++ .../DuckDuckGoAgentAppDelegate.swift | 29 ++-- .../FeatureProtectedTunnelController.swift | 43 ++++++ .../NetworkProtectionBouncer.swift | 40 ++++++ DuckDuckGoAgent/UserText.swift | 27 ++++ .../UserText+NetworkProtectionUI.swift | 5 - .../Menu/NetworkProtectionStatusBarMenu.swift | 18 +-- 12 files changed, 336 insertions(+), 141 deletions(-) create mode 100644 DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift create mode 100644 DuckDuckGoAgent/AppLauncher+DefaultInitializer.swift create mode 100644 DuckDuckGoAgent/FeatureProtectedTunnelController.swift create mode 100644 DuckDuckGoAgent/NetworkProtectionBouncer.swift create mode 100644 DuckDuckGoAgent/UserText.swift diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 0f68c404c6..22286c5784 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1320,6 +1320,15 @@ 7B1E819E27C8874900FF0E60 /* ContentOverlayPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819B27C8874900FF0E60 /* ContentOverlayPopover.swift */; }; 7B1E819F27C8874900FF0E60 /* ContentOverlay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */; }; 7B1E81A027C8874900FF0E60 /* ContentOverlayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */; }; + 7B2DDCF82A93A8BB0039D884 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */; }; + 7B2DDCF92A93A8BB0039D884 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */; }; + 7B2DDCFA2A93B25F0039D884 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; + 7B2DDCFB2A93B25F0039D884 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; + 7B2DDD022A93BAA60039D884 /* NetworkProtectionBouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD012A93BAA60039D884 /* NetworkProtectionBouncer.swift */; }; + 7B2DDD032A93BBEC0039D884 /* NetworkProtectionBouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD012A93BAA60039D884 /* NetworkProtectionBouncer.swift */; }; + 7B2DDD052A93BEE20039D884 /* FeatureProtectedTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD042A93BEE20039D884 /* FeatureProtectedTunnelController.swift */; }; + 7B2DDD072A93C17D0039D884 /* UserText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD062A93C17D0039D884 /* UserText.swift */; }; + 7B2DDD092A93C2440039D884 /* AppLauncher+DefaultInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD082A93C2440039D884 /* AppLauncher+DefaultInitializer.swift */; }; 7B2E52252A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2E52242A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift */; }; 7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; 7B430EA22A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; @@ -2582,6 +2591,11 @@ 7B1E819B27C8874900FF0E60 /* ContentOverlayPopover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentOverlayPopover.swift; sourceTree = ""; }; 7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ContentOverlay.storyboard; sourceTree = ""; }; 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentOverlayViewController.swift; sourceTree = ""; }; + 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAppEvents.swift; sourceTree = ""; }; + 7B2DDD012A93BAA60039D884 /* NetworkProtectionBouncer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionBouncer.swift; sourceTree = ""; }; + 7B2DDD042A93BEE20039D884 /* FeatureProtectedTunnelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureProtectedTunnelController.swift; sourceTree = ""; }; + 7B2DDD062A93C17D0039D884 /* UserText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserText.swift; sourceTree = ""; }; + 7B2DDD082A93C2440039D884 /* AppLauncher+DefaultInitializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppLauncher+DefaultInitializer.swift"; sourceTree = ""; }; 7B2E52242A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAgentNotificationsPresenter.swift; sourceTree = ""; }; 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionSimulateFailureMenu.swift; sourceTree = ""; }; 7B4CE8DA26F02108009134B1 /* UI Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UI Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -3883,6 +3897,10 @@ isa = PBXGroup; children = ( 4B2D06512A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.swift */, + 7B2DDD082A93C2440039D884 /* AppLauncher+DefaultInitializer.swift */, + 7B2DDD042A93BEE20039D884 /* FeatureProtectedTunnelController.swift */, + 7B2DDD012A93BAA60039D884 /* NetworkProtectionBouncer.swift */, + 7B2DDD062A93C17D0039D884 /* UserText.swift */, 4B2D06522A11D19B00DE1F49 /* Assets.xcassets */, 4B2D06442A11CFBE00DE1F49 /* DuckDuckGoAgent.entitlements */, 4B2D06532A11D19B00DE1F49 /* DuckDuckGoAgentAppStore.entitlements */, @@ -4003,6 +4021,7 @@ 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */, 4B4D606B2A0B29FA00BCD287 /* Invite */, 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */, + 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */, ); path = BothAppTargets; sourceTree = ""; @@ -7529,6 +7548,7 @@ 3707C727294B5D2900682A9F /* WKWebView+SessionState.swift in Sources */, 3706FAA3293F65D500E42796 /* CrashReportPromptViewController.swift in Sources */, 3706FAA4293F65D500E42796 /* ContextMenuManager.swift in Sources */, + 7B2DDCF92A93A8BB0039D884 /* NetworkProtectionAppEvents.swift in Sources */, 3706FAA5293F65D500E42796 /* GradientView.swift in Sources */, 3706FAA6293F65D500E42796 /* PreferencesSidebar.swift in Sources */, 3706FAA7293F65D500E42796 /* NSPointExtension.swift in Sources */, @@ -8431,13 +8451,18 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7B2DDD052A93BEE20039D884 /* FeatureProtectedTunnelController.swift in Sources */, B6F92BA22A691580002ABA6B /* UserDefaultsWrapper.swift in Sources */, 4B2D065B2A11D1FF00DE1F49 /* Logging.swift in Sources */, 4B2D06572A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.swift in Sources */, + 7B2DDCFA2A93B25F0039D884 /* KeychainType+ClientDefault.swift in Sources */, + 7B2DDD072A93C17D0039D884 /* UserText.swift in Sources */, B6F92BAC2A6937B3002ABA6B /* OptionalExtension.swift in Sources */, + 7B2DDD092A93C2440039D884 /* AppLauncher+DefaultInitializer.swift in Sources */, B6F92BAA2A691A44002ABA6B /* NetworkProtectionUserDefaultsConstants.swift in Sources */, EEC589DB2A4F1CE700BCD60C /* AppLauncher.swift in Sources */, B65DA5EF2A77CC3A00CBEE8D /* Bundle+NetworkProtectionExtensions.swift in Sources */, + 7B2DDD022A93BAA60039D884 /* NetworkProtectionBouncer.swift in Sources */, B65DA5F12A77D2BC00CBEE8D /* BundleExtension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -8446,12 +8471,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7B2DDCFB2A93B25F0039D884 /* KeychainType+ClientDefault.swift in Sources */, B6F92BA32A691583002ABA6B /* UserDefaultsWrapper.swift in Sources */, 4B2D067C2A13340900DE1F49 /* Logging.swift in Sources */, 4B2D067A2A1333EF00DE1F49 /* DuckDuckGoAgentAppDelegate.swift in Sources */, B6F92BAD2A6937B5002ABA6B /* OptionalExtension.swift in Sources */, B6F92BAB2A691A44002ABA6B /* NetworkProtectionUserDefaultsConstants.swift in Sources */, EEC589DC2A4F1CE800BCD60C /* AppLauncher.swift in Sources */, + 7B2DDD032A93BBEC0039D884 /* NetworkProtectionBouncer.swift in Sources */, B65DA5F02A77CC3C00CBEE8D /* Bundle+NetworkProtectionExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -9132,6 +9159,7 @@ 856C98D52570116900A22F1F /* NSWindow+Toast.swift in Sources */, B31055C427A1BA1D001AC618 /* AutoconsentUserScript.swift in Sources */, 859E7D6B27453BF3009C2B69 /* BookmarksExporter.swift in Sources */, + 7B2DDCF82A93A8BB0039D884 /* NetworkProtectionAppEvents.swift in Sources */, 4B5FF67826B602B100D42879 /* FirefoxDataImporter.swift in Sources */, 37AFCE8B27DB69BC00471A10 /* PreferencesGeneralView.swift in Sources */, 37BF3F22286F0A7A00BD9014 /* PinnedTabsView.swift in Sources */, diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme index adc90361ec..f8f5c9a3ba 100644 --- a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme @@ -33,7 +33,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" + launchStyle = "1" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" diff --git a/DuckDuckGo/AppDelegate/AppDelegate.swift b/DuckDuckGo/AppDelegate/AppDelegate.swift index 041126560b..56f406128a 100644 --- a/DuckDuckGo/AppDelegate/AppDelegate.swift +++ b/DuckDuckGo/AppDelegate/AppDelegate.swift @@ -211,7 +211,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel UserDefaultsWrapper.clearRemovedKeys() #if NETWORK_PROTECTION - startupNetworkProtection() + if #available(macOS 11.4, *) { + NetworkProtectionAppEvents().appLaunchComplete() + } #endif } @@ -311,115 +313,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel } } - // MARK: - Network Protection - -#if NETWORK_PROTECTION - - /// If necessary, this method migrates the auth token from an unspecified data protection keychain (our previous - /// storage location), to the new shared keychain, which is where apps in our app group will try to access the NetP - /// auth token. - /// - /// This method bails out on any error condition - the user will probably have to re-enter their auth token if we can't - /// migrate this, and that's ok. This migration only affects internal users so it's not worth pixeling, and it's not worth - /// alerting the user to an error since they'll see Network Protection disable and eventually re-enable it. - /// - private func migrateNetworkProtectionAuthTokenToSharedKeychainIfNecessary() { - let sharedKeychainStore = NetworkProtectionKeychainTokenStore() - - guard !sharedKeychainStore.isFeatureActivated else { - // We only migrate if the auth token is missing from our new shared keychain. - return - } - - let anyDataProtectionKeychainStore = NetworkProtectionKeychainTokenStore(keychainType: .dataProtection(.unspecified), errorEvents: nil) - - guard let token = try? anyDataProtectionKeychainStore.fetchToken() else { - // If fetching the token fails, we just assume we can't migrate anything and the user - // will need to re-enable NetP. - return - } - - do { - try sharedKeychainStore.store(token) - } catch { - print(String(describing: error)) - } - } - - private func startupNetworkProtection() { - guard #available(macOS 11.4, *) else { return } - - migrateNetworkProtectionAuthTokenToSharedKeychainIfNecessary() - - let loginItemsManager = NetworkProtectionLoginItemsManager() - let keychainStore = NetworkProtectionKeychainTokenStore() - - guard keychainStore.isFeatureActivated else { - loginItemsManager.disableLoginItems() - LocalPinningManager.shared.unpin(.networkProtection) - return - } - - restartNetworkProtectionIfVersionChanged(using: loginItemsManager) - refreshNetworkProtectionServers() - } - - @available(macOS 11.4, *) - private func restartNetworkProtectionIfVersionChanged(using loginItemsManager: NetworkProtectionLoginItemsManager) { - let currentVersion = AppVersion.shared.versionNumber - let versionStore = NetworkProtectionLastVersionRunStore() - defer { - versionStore.lastVersionRun = currentVersion - } - - // should‘ve been run at least once with NetP enabled - guard let lastVersionRun = versionStore.lastVersionRun else { - os_log(.info, log: .networkProtection, "No last version found for the NetP login items, skipping update") - return - } - - if lastVersionRun != currentVersion { - os_log(.info, log: .networkProtection, "App updated from %{public}s to %{public}s: updating login items", lastVersionRun, currentVersion) - restartNetworkProtectionTunnelAndMenu(using: loginItemsManager) - } else { - // If login items failed to launch (e.g. because of the App bundle rename), launch using NSWorkspace - loginItemsManager.ensureLoginItemsAreRunning(.ifLoginItemsAreEnabled, after: 1) - } - } - - @available(macOS 11.4, *) - private func restartNetworkProtectionTunnelAndMenu(using loginItemsManager: NetworkProtectionLoginItemsManager) { - loginItemsManager.restartLoginItems() - - Task { - let provider = NetworkProtectionTunnelController() - - // Restart NetP SysEx on app update - if await provider.isConnected { - await provider.stop() - await provider.start() - } - } - } - - /// Fetches a new list of Network Protection servers, and updates the existing set. - @available(macOS 11.4, *) - private func refreshNetworkProtectionServers() { - Task { - let serverCount: Int - do { - serverCount = try await NetworkProtectionDeviceManager.create().refreshServerList().count - } catch { - os_log("Failed to update Network Protection servers", log: .networkProtection, type: .error) - return - } - - os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount) - } - } - -#endif - private func subscribeToEmailProtectionStatusNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(emailDidSignInNotification(_:)), diff --git a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift index d0fb89fa28..4c8dde1701 100644 --- a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift +++ b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift @@ -143,6 +143,13 @@ public struct UserDefaultsWrapper { case agentLaunchTime = "netp.agent.launch-time" + // Network Protection: Shared Defaults + // --- + // Please note that shared defaults MUST have a name that matches exactly their value, + // or else KVO will just not work as of 2023-08-07 + + case networkProtectionIsEnabled = "networkProtectionIsEnabled" + // Experiments case pixelExperimentInstalled = "pixel.experiment.installed" case pixelExperimentCohort = "pixel.experiment.cohort" diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift new file mode 100644 index 0000000000..3c5dd89b1c --- /dev/null +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift @@ -0,0 +1,129 @@ +// +// NetworkProtectionAppEvents.swift +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Common +import Foundation +import NetworkProtection + +/// Implements the sequence of steps that Network Protection needs to execute when the App starts up. +/// +@available(macOS 11.4, *) +final class NetworkProtectionAppEvents { + + /// Call this method when the app finishes launching, to run the startup logic for NetP. + /// + func appLaunchComplete() { + migrateNetworkProtectionAuthTokenToSharedKeychainIfNecessary() + + let loginItemsManager = NetworkProtectionLoginItemsManager() + let keychainStore = NetworkProtectionKeychainTokenStore() + + guard keychainStore.isFeatureActivated else { + loginItemsManager.disableLoginItems() + LocalPinningManager.shared.unpin(.networkProtection) + return + } + + restartNetworkProtectionIfVersionChanged(using: loginItemsManager) + refreshNetworkProtectionServers() + } + + /// If necessary, this method migrates the auth token from an unspecified data protection keychain (our previous + /// storage location), to the new shared keychain, which is where apps in our app group will try to access the NetP + /// auth token. + /// + /// This method bails out on any error condition - the user will probably have to re-enter their auth token if we can't + /// migrate this, and that's ok. This migration only affects internal users so it's not worth pixeling, and it's not worth + /// alerting the user to an error since they'll see Network Protection disable and eventually re-enable it. + /// + private func migrateNetworkProtectionAuthTokenToSharedKeychainIfNecessary() { + let sharedKeychainStore = NetworkProtectionKeychainTokenStore() + + guard !sharedKeychainStore.isFeatureActivated else { + // We only migrate if the auth token is missing from our new shared keychain. + return + } + + let anyDataProtectionKeychainStore = NetworkProtectionKeychainTokenStore(keychainType: .dataProtection(.unspecified), errorEvents: nil) + + guard let token = try? anyDataProtectionKeychainStore.fetchToken() else { + // If fetching the token fails, we just assume we can't migrate anything and the user + // will need to re-enable NetP. + return + } + + do { + try sharedKeychainStore.store(token) + } catch { + print(String(describing: error)) + } + } + + private func restartNetworkProtectionIfVersionChanged(using loginItemsManager: NetworkProtectionLoginItemsManager) { + let currentVersion = AppVersion.shared.versionNumber + let versionStore = NetworkProtectionLastVersionRunStore() + defer { + versionStore.lastVersionRun = currentVersion + } + + // should‘ve been run at least once with NetP enabled + guard let lastVersionRun = versionStore.lastVersionRun else { + os_log(.info, log: .networkProtection, "No last version found for the NetP login items, skipping update") + return + } + + if lastVersionRun != currentVersion { + os_log(.info, log: .networkProtection, "App updated from %{public}s to %{public}s: updating login items", lastVersionRun, currentVersion) + restartNetworkProtectionTunnelAndMenu(using: loginItemsManager) + } else { + // If login items failed to launch (e.g. because of the App bundle rename), launch using NSWorkspace + loginItemsManager.ensureLoginItemsAreRunning(.ifLoginItemsAreEnabled, after: 1) + } + } + + private func restartNetworkProtectionTunnelAndMenu(using loginItemsManager: NetworkProtectionLoginItemsManager) { + loginItemsManager.restartLoginItems() + + Task { + let provider = NetworkProtectionTunnelController() + + // Restart NetP SysEx on app update + if await provider.isConnected { + await provider.stop() + await provider.start() + } + } + } + + /// Fetches a new list of Network Protection servers, and updates the existing set. + /// + private func refreshNetworkProtectionServers() { + Task { + let serverCount: Int + do { + serverCount = try await NetworkProtectionDeviceManager.create().refreshServerList().count + } catch { + os_log("Failed to update Network Protection servers", log: .networkProtection, type: .error) + return + } + + os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount) + } + } + +} diff --git a/DuckDuckGoAgent/AppLauncher+DefaultInitializer.swift b/DuckDuckGoAgent/AppLauncher+DefaultInitializer.swift new file mode 100644 index 0000000000..08523cd486 --- /dev/null +++ b/DuckDuckGoAgent/AppLauncher+DefaultInitializer.swift @@ -0,0 +1,36 @@ +// +// AppLauncher+DefaultInitializer.swift +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// Includes a convenience default initializer for `AppLauncher` that's specific to this App target. +/// +extension AppLauncher { + convenience init() { + let appBundleURL: URL + let parentBundlePath = "../../../../" + + if #available(macOS 13, *) { + appBundleURL = URL(filePath: parentBundlePath, relativeTo: Bundle.main.bundleURL) + } else { + appBundleURL = URL(fileURLWithPath: parentBundlePath, relativeTo: Bundle.main.bundleURL) + } + + self.init(appBundleURL: appBundleURL) + } +} diff --git a/DuckDuckGoAgent/DuckDuckGoAgentAppDelegate.swift b/DuckDuckGoAgent/DuckDuckGoAgentAppDelegate.swift index 2e47dc4726..f315cfb046 100644 --- a/DuckDuckGoAgent/DuckDuckGoAgentAppDelegate.swift +++ b/DuckDuckGoAgent/DuckDuckGoAgentAppDelegate.swift @@ -17,10 +17,12 @@ // import Cocoa +import Combine import Common import NetworkExtension import NetworkProtection import NetworkProtectionUI +import ServiceManagement @objc(Application) final class DuckDuckGoAgentApplication: NSApplication { @@ -56,17 +58,11 @@ final class DuckDuckGoAgentAppDelegate: NSObject, NSApplicationDelegate { private var agentLaunchTime: Date private static let recentThreshold: TimeInterval = 5.0 - private lazy var appLauncher: AppLauncher = { - let appBundleURL: URL - let parentBundlePath = "../../../../" + private let appLauncher = AppLauncher() + private let bouncer = NetworkProtectionBouncer() - if #available(macOS 13, *) { - appBundleURL = URL(filePath: parentBundlePath, relativeTo: Bundle.main.bundleURL) - } else { - appBundleURL = URL(fileURLWithPath: parentBundlePath, relativeTo: Bundle.main.bundleURL) - } - - return AppLauncher(appBundleURL: appBundleURL) + private lazy var tunnelController: FeatureProtectingTunnelController = { + FeatureProtectingTunnelController(appLauncher: appLauncher, bouncer: bouncer) }() /// The status bar NetworkProtection menu @@ -82,13 +78,24 @@ final class DuckDuckGoAgentAppDelegate: NSObject, NSApplicationDelegate { let iconProvider = MenuIconProvider() #endif - return StatusBarMenu(appLauncher: appLauncher, iconProvider: iconProvider) + let menuItems = [ + StatusBarMenu.MenuItem(name: UserText.networkProtectionStatusMenuShareFeedback, action: { [weak self] in + await self?.appLauncher.launchApp(withCommand: .shareFeedback) + }), + StatusBarMenu.MenuItem(name: UserText.networkProtectionStatusMenuOpenDuckDuckGo, action: { [weak self] in + await self?.appLauncher.launchApp(withCommand: .justOpen) + }) + ] + + return StatusBarMenu(controller: tunnelController, iconProvider: iconProvider, menuItems: menuItems) }() func applicationDidFinishLaunching(_ aNotification: Notification) { os_log("DuckDuckGoAgent started", log: .networkProtectionLoginItemLog, type: .info) networkProtectionMenu.show() + bouncer.requireAuthTokenOrKillApp() + // Connect on Log In if shouldAutoConnect, // are we launched by the system? diff --git a/DuckDuckGoAgent/FeatureProtectedTunnelController.swift b/DuckDuckGoAgent/FeatureProtectedTunnelController.swift new file mode 100644 index 0000000000..bbff5da7a8 --- /dev/null +++ b/DuckDuckGoAgent/FeatureProtectedTunnelController.swift @@ -0,0 +1,43 @@ +// +// FeatureProtectedTunnelController.swift +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import NetworkProtection +import NetworkProtectionUI + +/// A tunnel controller that will kill the current app if Network Protection is disabled. +/// +final class FeatureProtectingTunnelController: TunnelController { + private let controller: AppLaunchingController + private let bouncer: NetworkProtectionBouncer + + init(appLauncher: AppLauncher, bouncer: NetworkProtectionBouncer) { + self.controller = AppLaunchingController(appLauncher: appLauncher) + self.bouncer = bouncer + } + + func start() async { + bouncer.requireAuthTokenOrKillApp() + await controller.start() + } + + func stop() async { + bouncer.requireAuthTokenOrKillApp() + await controller.stop() + } +} diff --git a/DuckDuckGoAgent/NetworkProtectionBouncer.swift b/DuckDuckGoAgent/NetworkProtectionBouncer.swift new file mode 100644 index 0000000000..a01834bb3e --- /dev/null +++ b/DuckDuckGoAgent/NetworkProtectionBouncer.swift @@ -0,0 +1,40 @@ +// +// NetworkProtectionBouncer.swift +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Common +import Foundation +import NetworkProtection +import ServiceManagement +import AppKit + +/// Class that implements the necessary logic to ensure Network Protection is enabled, or prevent the app from running otherwise. +/// +final class NetworkProtectionBouncer { + + /// Simply verifies that the Network Protection feature is enabled and if not, takes care of killing the + /// current app. + /// + func requireAuthTokenOrKillApp() { + let keychainStore = NetworkProtectionKeychainTokenStore(keychainType: .default, errorEvents: nil) + + guard keychainStore.isFeatureActivated else { + os_log(.error, log: .networkProtection, "🔴 Stopping: Network Protection not authorized.") + exit(EXIT_FAILURE) + } + } +} diff --git a/DuckDuckGoAgent/UserText.swift b/DuckDuckGoAgent/UserText.swift new file mode 100644 index 0000000000..188a050c95 --- /dev/null +++ b/DuckDuckGoAgent/UserText.swift @@ -0,0 +1,27 @@ +// +// UserText.swift +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +final class UserText { + // MARK: - Status Menu + + static let networkProtectionStatusMenuShareFeedback = NSLocalizedString("network.protection.status.menu.share.feedback", value: "Share Feedback...", comment: "The status menu 'Share Feedback' menu item") + static let networkProtectionStatusMenuOpenDuckDuckGo = NSLocalizedString("network.protection.status.menu.open.duckduckgo", value: "Open DuckDuckGo...", comment: "The status menu 'Open DuckDuckGo' menu item") +} + diff --git a/LocalPackages/NetworkProtectionUI/Sources/NetworkProtectionUI/Extensions/UserText+NetworkProtectionUI.swift b/LocalPackages/NetworkProtectionUI/Sources/NetworkProtectionUI/Extensions/UserText+NetworkProtectionUI.swift index ae5f5e67df..b5f58e7910 100644 --- a/LocalPackages/NetworkProtectionUI/Sources/NetworkProtectionUI/Extensions/UserText+NetworkProtectionUI.swift +++ b/LocalPackages/NetworkProtectionUI/Sources/NetworkProtectionUI/Extensions/UserText+NetworkProtectionUI.swift @@ -44,9 +44,4 @@ final class UserText { static let networkProtectionServerAddressUnknown = NSLocalizedString("network.protection.server.address.unknown", value: "Unknown", comment: "When we can't tell the user the IP of the NetP server is") static let networkProtectionServerLocationUnknown = NSLocalizedString("network.protection.server.location.unknown", value: "Unknown", comment: "When we can't tell the user the location of the NetP server") - - // MARK: - Status Menu - - static let networkProtectionStatusMenuShareFeedback = NSLocalizedString("network.protection.status.menu.share.feedback", value: "Share Feedback...", comment: "The status menu 'Share Feedback' menu item") - static let networkProtectionStatusMenuOpenDuckDuckGo = NSLocalizedString("network.protection.status.menu.open.duckduckgo", value: "Open DuckDuckGo...", comment: "The status menu 'Open DuckDuckGo' menu item") } diff --git a/LocalPackages/NetworkProtectionUI/Sources/NetworkProtectionUI/Menu/NetworkProtectionStatusBarMenu.swift b/LocalPackages/NetworkProtectionUI/Sources/NetworkProtectionUI/Menu/NetworkProtectionStatusBarMenu.swift index 86ae1eede9..73acb6e040 100644 --- a/LocalPackages/NetworkProtectionUI/Sources/NetworkProtectionUI/Menu/NetworkProtectionStatusBarMenu.swift +++ b/LocalPackages/NetworkProtectionUI/Sources/NetworkProtectionUI/Menu/NetworkProtectionStatusBarMenu.swift @@ -25,7 +25,7 @@ import NetworkProtection /// Abstraction of the the Network Protection status bar menu with a simple interface. /// public final class StatusBarMenu { - typealias MenuItem = NetworkProtectionStatusView.Model.MenuItem + public typealias MenuItem = NetworkProtectionStatusView.Model.MenuItem private let statusItem: NSStatusItem private let popover: NetworkProtectionPopover @@ -44,8 +44,9 @@ public final class StatusBarMenu { /// public init(statusItem: NSStatusItem? = nil, statusReporter: NetworkProtectionStatusReporter? = nil, - appLauncher: AppLaunching, - iconProvider: IconProvider) { + controller: TunnelController, + iconProvider: IconProvider, + menuItems: [MenuItem]) { let statusReporter = statusReporter ?? DefaultNetworkProtectionStatusReporter( statusObserver: ConnectionStatusObserverThroughDistributedNotifications(), @@ -58,17 +59,6 @@ public final class StatusBarMenu { self.statusItem = statusItem ?? NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) self.iconPublisher = NetworkProtectionIconPublisher(statusReporter: statusReporter, iconProvider: iconProvider) - let controller = AppLaunchingController(appLauncher: appLauncher) - - let menuItems = [ - MenuItem(name: UserText.networkProtectionStatusMenuShareFeedback, action: { - await appLauncher.launchApp(withCommand: .shareFeedback) - }), - MenuItem(name: UserText.networkProtectionStatusMenuOpenDuckDuckGo, action: { - await appLauncher.launchApp(withCommand: .justOpen) - }) - ] - popover = NetworkProtectionPopover(controller: controller, statusReporter: statusReporter, menuItems: menuItems) popover.behavior = .transient From fe5e5da1b6c24196f72904f1a9380b012a028148 Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Mon, 21 Aug 2023 20:31:54 +0200 Subject: [PATCH 03/13] Updates the BSK version --- DuckDuckGo.xcodeproj/project.pbxproj | 4 ++-- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 22286c5784..57924c8f91 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -10250,8 +10250,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { - kind = exactVersion; - version = 74.0.1; + kind = revision; + revision = 3b8f95fe624868cb502a78dc53dca3eeb6ede508; }; }; AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 91a2bfe995..d7faa74833 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -131,8 +131,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/wireguard-apple", "state" : { - "revision" : "cf3c0f5132dbb8de08c46155a1bbd5e5bb6a47c1", - "version" : "1.1.0" + "revision" : "2d8172c11478ab11b0f5ad49bdb4f93f4b3d5e0d", + "version" : "1.1.1" } } ], From 5d56ef3ee3a6371c37f81554c8a7b345de237275 Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Mon, 21 Aug 2023 21:00:13 +0200 Subject: [PATCH 04/13] Cleans up some code moving it to a class of its own --- DuckDuckGo.xcodeproj/project.pbxproj | 6 ++ .../xcshareddata/swiftpm/Package.resolved | 2 +- DuckDuckGo/AppDelegate/AppDelegate.swift | 80 +------------------ 3 files changed, 10 insertions(+), 78 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 7b6a333b62..81d5bb69bf 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1323,6 +1323,8 @@ 7B1E819E27C8874900FF0E60 /* ContentOverlayPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819B27C8874900FF0E60 /* ContentOverlayPopover.swift */; }; 7B1E819F27C8874900FF0E60 /* ContentOverlay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */; }; 7B1E81A027C8874900FF0E60 /* ContentOverlayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */; }; + 7B2DDD0B2A93EA570039D884 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD0A2A93EA570039D884 /* NetworkProtectionAppEvents.swift */; }; + 7B2DDD0D2A93EB630039D884 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD0A2A93EA570039D884 /* NetworkProtectionAppEvents.swift */; }; 7B2E52252A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2E52242A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift */; }; 7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; 7B430EA22A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; @@ -2586,6 +2588,7 @@ 7B1E819B27C8874900FF0E60 /* ContentOverlayPopover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentOverlayPopover.swift; sourceTree = ""; }; 7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ContentOverlay.storyboard; sourceTree = ""; }; 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentOverlayViewController.swift; sourceTree = ""; }; + 7B2DDD0A2A93EA570039D884 /* NetworkProtectionAppEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAppEvents.swift; sourceTree = ""; }; 7B2E52242A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAgentNotificationsPresenter.swift; sourceTree = ""; }; 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionSimulateFailureMenu.swift; sourceTree = ""; }; 7B4CE8DA26F02108009134B1 /* UI Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UI Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -4004,6 +4007,7 @@ 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */, 4B4D606B2A0B29FA00BCD287 /* Invite */, 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */, + 7B2DDD0A2A93EA570039D884 /* NetworkProtectionAppEvents.swift */, ); path = BothAppTargets; sourceTree = ""; @@ -7585,6 +7589,7 @@ 3706FAD2293F65D500E42796 /* Atb.swift in Sources */, 3706FAD3293F65D500E42796 /* DownloadsViewController.swift in Sources */, 3706FAD4293F65D500E42796 /* DataExtension.swift in Sources */, + 7B2DDD0D2A93EB630039D884 /* NetworkProtectionAppEvents.swift in Sources */, 3706FAD6293F65D500E42796 /* ConfigurationStore.swift in Sources */, 3706FAD7293F65D500E42796 /* Feedback.swift in Sources */, 3707C722294B5D2900682A9F /* WKWebViewExtension.swift in Sources */, @@ -8604,6 +8609,7 @@ 4B9292A426670D2A00AD2C21 /* PasteboardWriting.swift in Sources */, 4B92928D26670D1700AD2C21 /* BookmarkOutlineViewCell.swift in Sources */, B604085C274B8FBA00680351 /* UnprotectedDomains.xcdatamodeld in Sources */, + 7B2DDD0B2A93EA570039D884 /* NetworkProtectionAppEvents.swift in Sources */, 4BB88B5025B7BA2B006F6B06 /* TabInstrumentation.swift in Sources */, 4B59024326B35F7C00489384 /* BrowserImportViewController.swift in Sources */, 4B9292D72667124000AD2C21 /* NSPopUpButtonExtension.swift in Sources */, diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index a0404bd723..c32ad6ad05 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -129,7 +129,7 @@ { "identity" : "trackerradarkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/duckduckgo/TrackerRadarKit.git", + "location" : "https://github.com/duckduckgo/TrackerRadarKit", "state" : { "revision" : "4684440d03304e7638a2c8086895367e90987463", "version" : "1.2.1" diff --git a/DuckDuckGo/AppDelegate/AppDelegate.swift b/DuckDuckGo/AppDelegate/AppDelegate.swift index 7b8432e427..a0017dfa04 100644 --- a/DuckDuckGo/AppDelegate/AppDelegate.swift +++ b/DuckDuckGo/AppDelegate/AppDelegate.swift @@ -211,7 +211,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel UserDefaultsWrapper.clearRemovedKeys() #if NETWORK_PROTECTION - startupNetworkProtection() + if #available(macOS 11.4, *) { + NetworkProtectionAppEvents().appLaunchComplete() + } #endif } @@ -319,82 +321,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel } } - // MARK: - Network Protection - -#if NETWORK_PROTECTION - - private func startupNetworkProtection() { - guard #available(macOS 11.4, *) else { return } - - let loginItemsManager = NetworkProtectionLoginItemsManager() - let networkProtectionFeatureVisibility = NetworkProtectionKeychainTokenStore() - - guard networkProtectionFeatureVisibility.isFeatureActivated else { - loginItemsManager.disableLoginItems() - LocalPinningManager.shared.unpin(.networkProtection) - return - } - - restartNetworkProtectionIfVersionChanged(using: loginItemsManager) - refreshNetworkProtectionServers() - } - - @available(macOS 11.4, *) - private func restartNetworkProtectionIfVersionChanged(using loginItemsManager: NetworkProtectionLoginItemsManager) { - let currentVersion = AppVersion.shared.versionNumber - let versionStore = NetworkProtectionLastVersionRunStore() - defer { - versionStore.lastVersionRun = currentVersion - } - - // should‘ve been run at least once with NetP enabled - guard let lastVersionRun = versionStore.lastVersionRun else { - os_log(.info, log: .networkProtection, "No last version found for the NetP login items, skipping update") - return - } - - if lastVersionRun != currentVersion { - os_log(.info, log: .networkProtection, "App updated from %{public}s to %{public}s: updating login items", lastVersionRun, currentVersion) - restartNetworkProtectionTunnelAndMenu(using: loginItemsManager) - } else { - // If login items failed to launch (e.g. because of the App bundle rename), launch using NSWorkspace - loginItemsManager.ensureLoginItemsAreRunning(.ifLoginItemsAreEnabled, after: 1) - } - } - - @available(macOS 11.4, *) - private func restartNetworkProtectionTunnelAndMenu(using loginItemsManager: NetworkProtectionLoginItemsManager) { - loginItemsManager.restartLoginItems() - - Task { - let provider = NetworkProtectionTunnelController() - - // Restart NetP SysEx on app update - if await provider.isConnected { - await provider.stop() - await provider.start() - } - } - } - - /// Fetches a new list of Network Protection servers, and updates the existing set. - @available(macOS 11.4, *) - private func refreshNetworkProtectionServers() { - Task { - let serverCount: Int - do { - serverCount = try await NetworkProtectionDeviceManager.create().refreshServerList().count - } catch { - os_log("Failed to update Network Protection servers", log: .networkProtection, type: .error) - return - } - - os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount) - } - } - -#endif - private func subscribeToEmailProtectionStatusNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(emailDidSignInNotification(_:)), From f29ca42ac949850523758f1c54eb2f5f9d939acf Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Mon, 21 Aug 2023 21:00:52 +0200 Subject: [PATCH 05/13] Adds a missing file --- .../NetworkProtectionAppEvents.swift | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift new file mode 100644 index 0000000000..67aaac4e12 --- /dev/null +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift @@ -0,0 +1,99 @@ +// +// NetworkProtectionAppEvents.swift +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Common +import Foundation + +#if NETWORK_PROTECTION +import NetworkProtection + +/// Implements the sequence of steps that Network Protection needs to execute when the App starts up. +/// +@available(macOS 11.4, *) +final class NetworkProtectionAppEvents { + + /// Call this method when the app finishes launching, to run the startup logic for NetP. + /// + func appLaunchComplete() { + let loginItemsManager = NetworkProtectionLoginItemsManager() + let keychainStore = NetworkProtectionKeychainTokenStore() + + guard keychainStore.isFeatureActivated else { + loginItemsManager.disableLoginItems() + LocalPinningManager.shared.unpin(.networkProtection) + return + } + + restartNetworkProtectionIfVersionChanged(using: loginItemsManager) + refreshNetworkProtectionServers() + } + + private func restartNetworkProtectionIfVersionChanged(using loginItemsManager: NetworkProtectionLoginItemsManager) { + let currentVersion = AppVersion.shared.versionNumber + let versionStore = NetworkProtectionLastVersionRunStore() + defer { + versionStore.lastVersionRun = currentVersion + } + + // should‘ve been run at least once with NetP enabled + guard let lastVersionRun = versionStore.lastVersionRun else { + os_log(.info, log: .networkProtection, "No last version found for the NetP login items, skipping update") + return + } + + if lastVersionRun != currentVersion { + os_log(.info, log: .networkProtection, "App updated from %{public}s to %{public}s: updating login items", lastVersionRun, currentVersion) + restartNetworkProtectionTunnelAndMenu(using: loginItemsManager) + } else { + // If login items failed to launch (e.g. because of the App bundle rename), launch using NSWorkspace + loginItemsManager.ensureLoginItemsAreRunning(.ifLoginItemsAreEnabled, after: 1) + } + } + + private func restartNetworkProtectionTunnelAndMenu(using loginItemsManager: NetworkProtectionLoginItemsManager) { + loginItemsManager.restartLoginItems() + + Task { + let provider = NetworkProtectionTunnelController() + + // Restart NetP SysEx on app update + if await provider.isConnected { + await provider.stop() + await provider.start() + } + } + } + + /// Fetches a new list of Network Protection servers, and updates the existing set. + /// + private func refreshNetworkProtectionServers() { + Task { + let serverCount: Int + do { + serverCount = try await NetworkProtectionDeviceManager.create().refreshServerList().count + } catch { + os_log("Failed to update Network Protection servers", log: .networkProtection, type: .error) + return + } + + os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount) + } + } +} + +#endif From 8717049f60ac737a707267aba50e3f1a54e3c76b Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Mon, 21 Aug 2023 21:19:29 +0200 Subject: [PATCH 06/13] Rolls back an unintentional change --- .../xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme index f8f5c9a3ba..adc90361ec 100644 --- a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme @@ -33,7 +33,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "1" + launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" From 73065bd8ff0b3c0879c1ff51b9fdedf27afb902a Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Tue, 22 Aug 2023 14:51:01 +0200 Subject: [PATCH 07/13] Removes the local reference to BSK --- DuckDuckGo.xcodeproj/project.pbxproj | 2 -- .../xcshareddata/swiftpm/Package.resolved | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 9d4bd799f2..5b0b2d4f14 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -2615,7 +2615,6 @@ 7BB108582A43375D000AB95F /* PFMoveApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PFMoveApplication.m; sourceTree = ""; }; 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionDebugUtilities.swift; sourceTree = ""; }; 7BBD45B32A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionLoginItemsManager.swift; sourceTree = ""; }; - 7BD3AF5B2A8E77D8006F9F56 /* BrowserServicesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = BrowserServicesKit; path = ../../BrowserServicesKit; sourceTree = ""; }; 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeychainType+ClientDefault.swift"; sourceTree = ""; }; 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionDebugMenu.swift; sourceTree = ""; }; 85012B0129133F9F003D0DCC /* NavigationBarPopovers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarPopovers.swift; sourceTree = ""; }; @@ -3688,7 +3687,6 @@ 378E279C2970217400FCADA2 /* LocalPackages */ = { isa = PBXGroup; children = ( - 7BD3AF5B2A8E77D8006F9F56 /* BrowserServicesKit */, 378E279D2970217400FCADA2 /* BuildToolPlugins */, 4BE15DB32A0B0DD500898243 /* NetworkProtectionUI */, 4BE15DB12A0B0DD500898243 /* PixelKit */, diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index d7faa74833..6b3ab4c027 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,6 +9,14 @@ "version" : "3.0.0" } }, + { + "identity" : "browserserviceskit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/BrowserServicesKit", + "state" : { + "revision" : "3b8f95fe624868cb502a78dc53dca3eeb6ede508" + } + }, { "identity" : "content-scope-scripts", "kind" : "remoteSourceControl", From f6d0fb5df2e381c86ac077892a1e6ae77ce4739b Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Wed, 23 Aug 2023 15:32:09 +0200 Subject: [PATCH 08/13] Removes a line that wasn't really needed --- .../xcshareddata/swiftpm/Package.resolved | 3 ++- DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift | 7 ------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 6b3ab4c027..c32ad6ad05 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,7 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "3b8f95fe624868cb502a78dc53dca3eeb6ede508" + "revision" : "8d4c3d884762d954183a9496961b87d254b43539", + "version" : "75.0.2" } }, { diff --git a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift index 4c8dde1701..d0fb89fa28 100644 --- a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift +++ b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift @@ -143,13 +143,6 @@ public struct UserDefaultsWrapper { case agentLaunchTime = "netp.agent.launch-time" - // Network Protection: Shared Defaults - // --- - // Please note that shared defaults MUST have a name that matches exactly their value, - // or else KVO will just not work as of 2023-08-07 - - case networkProtectionIsEnabled = "networkProtectionIsEnabled" - // Experiments case pixelExperimentInstalled = "pixel.experiment.installed" case pixelExperimentCohort = "pixel.experiment.cohort" From a50a1b1b5f2adfec4f763e02e821b0de0df0504b Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Wed, 23 Aug 2023 15:36:42 +0200 Subject: [PATCH 09/13] swiftlint --autocorrect --- DuckDuckGo/Common/Localizables/UserText.swift | 5 ----- DuckDuckGoAgent/UserText.swift | 1 - 2 files changed, 6 deletions(-) diff --git a/DuckDuckGo/Common/Localizables/UserText.swift b/DuckDuckGo/Common/Localizables/UserText.swift index 2080344da8..deb713a3cf 100644 --- a/DuckDuckGo/Common/Localizables/UserText.swift +++ b/DuckDuckGo/Common/Localizables/UserText.swift @@ -811,9 +811,4 @@ struct UserText { static let disableEmailProtectionTitle = NSLocalizedString("disable.email.protection.title", value: "Disable Email Protection Autofill?", comment: "Title for alert shown when user disables email protection") static let disableEmailProtectionMessage = NSLocalizedString("disable.email.protection.mesage", value: "This will only disable Autofill for Duck Addresses in this browser. \n\n You can still manually enter Duck Addresses and continue to receive forwarded email.", comment: "Message for alert shown when user disables email protection") static let disable = NSLocalizedString("disable", value: "Disable", comment: "Email protection Disable button text") - - - - } - diff --git a/DuckDuckGoAgent/UserText.swift b/DuckDuckGoAgent/UserText.swift index 188a050c95..227f211608 100644 --- a/DuckDuckGoAgent/UserText.swift +++ b/DuckDuckGoAgent/UserText.swift @@ -24,4 +24,3 @@ final class UserText { static let networkProtectionStatusMenuShareFeedback = NSLocalizedString("network.protection.status.menu.share.feedback", value: "Share Feedback...", comment: "The status menu 'Share Feedback' menu item") static let networkProtectionStatusMenuOpenDuckDuckGo = NSLocalizedString("network.protection.status.menu.open.duckduckgo", value: "Open DuckDuckGo...", comment: "The status menu 'Open DuckDuckGo' menu item") } - From a5f22709879ff6d7d2acc1a9d5d82c70c6dadbd5 Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Wed, 23 Aug 2023 15:41:00 +0200 Subject: [PATCH 10/13] Renames a method to better follow our standard naming --- DuckDuckGo/AppDelegate/AppDelegate.swift | 2 +- .../AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/AppDelegate/AppDelegate.swift b/DuckDuckGo/AppDelegate/AppDelegate.swift index 56f406128a..83db2e1b8f 100644 --- a/DuckDuckGo/AppDelegate/AppDelegate.swift +++ b/DuckDuckGo/AppDelegate/AppDelegate.swift @@ -212,7 +212,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel #if NETWORK_PROTECTION if #available(macOS 11.4, *) { - NetworkProtectionAppEvents().appLaunchComplete() + NetworkProtectionAppEvents().applicationDidFinishLaunching() } #endif } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift index 67aaac4e12..814bd00233 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift @@ -29,7 +29,7 @@ final class NetworkProtectionAppEvents { /// Call this method when the app finishes launching, to run the startup logic for NetP. /// - func appLaunchComplete() { + func applicationDidFinishLaunching() { let loginItemsManager = NetworkProtectionLoginItemsManager() let keychainStore = NetworkProtectionKeychainTokenStore() From c4ace88fa2f68fa0cf14098650a1671a55f86a99 Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Wed, 23 Aug 2023 15:52:33 +0200 Subject: [PATCH 11/13] Updates to BSK 75.0.3 and fixes the unit tests --- DuckDuckGo.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- .../NetworkProtectionUI/Package.swift | 2 +- .../NetworkProtectionStatusBarMenuTests.swift | 18 ++++++++++++------ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index d9f365d927..b4fdb91ac7 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -10269,7 +10269,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 75.0.2; + version = 75.0.3; }; }; AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index c32ad6ad05..a1e77c3c7a 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" : "8d4c3d884762d954183a9496961b87d254b43539", - "version" : "75.0.2" + "revision" : "9bf7b16196ac4a78bf9189841d9823047b5c141b", + "version" : "75.0.3" } }, { diff --git a/LocalPackages/NetworkProtectionUI/Package.swift b/LocalPackages/NetworkProtectionUI/Package.swift index c5181eff24..fb0af3b63e 100644 --- a/LocalPackages/NetworkProtectionUI/Package.swift +++ b/LocalPackages/NetworkProtectionUI/Package.swift @@ -15,7 +15,7 @@ let package = Package( targets: ["NetworkProtectionUI"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "75.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "75.0.3"), .package(path: "../SwiftUIExtensions") ], targets: [ diff --git a/LocalPackages/NetworkProtectionUI/Tests/NetworkProtectionUITests/NetworkProtectionStatusBarMenuTests.swift b/LocalPackages/NetworkProtectionUI/Tests/NetworkProtectionUITests/NetworkProtectionStatusBarMenuTests.swift index 56b20659a3..bdffe04051 100644 --- a/LocalPackages/NetworkProtectionUI/Tests/NetworkProtectionUITests/NetworkProtectionStatusBarMenuTests.swift +++ b/LocalPackages/NetworkProtectionUI/Tests/NetworkProtectionUITests/NetworkProtectionStatusBarMenuTests.swift @@ -26,8 +26,12 @@ import NetworkProtectionTestUtils final class StatusBarMenuTests: XCTestCase { - private final class TestAppLauncher: AppLaunching { - func launchApp(withCommand command: NetworkProtection.AppLaunchCommand) async { + private final class TestTunnelController: TunnelController { + func start() async { + // no-op + } + + func stop() async { // no-op } } @@ -37,8 +41,9 @@ final class StatusBarMenuTests: XCTestCase { let menu = StatusBarMenu( statusItem: item, statusReporter: MockNetworkProtectionStatusReporter(), - appLauncher: TestAppLauncher(), - iconProvider: MenuIconProvider()) + controller: TestTunnelController(), + iconProvider: MenuIconProvider(), + menuItems: []) menu.show() @@ -50,8 +55,9 @@ final class StatusBarMenuTests: XCTestCase { let menu = StatusBarMenu( statusItem: item, statusReporter: MockNetworkProtectionStatusReporter(), - appLauncher: TestAppLauncher(), - iconProvider: MenuIconProvider()) + controller: TestTunnelController(), + iconProvider: MenuIconProvider(), + menuItems: []) menu.hide() From 799c2fb6662ff0e2989d5c7c5a625981e8fc5977 Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Wed, 23 Aug 2023 16:17:37 +0200 Subject: [PATCH 12/13] Resolves some building issues --- DuckDuckGo.xcodeproj/project.pbxproj | 6 ------ .../BothAppTargets/NetworkProtectionAppEvents.swift | 5 ++++- .../Plugins/InputFilesChecker/InputFilesChecker.swift | 5 ++++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index b4fdb91ac7..6dff7cd65c 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1112,7 +1112,6 @@ 4B4D60D32A0C84F700BCD287 /* UserText+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */; }; 4B4D60D42A0C84F700BCD287 /* UserText+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */; }; 4B4D60DD2A0C875E00BCD287 /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; }; - 4B4D60DE2A0C875E00BCD287 /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; 4B4D60DF2A0C875F00BCD287 /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; }; 4B4D60E02A0C875F00BCD287 /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; 4B4D60E22A0C883A00BCD287 /* Main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60E12A0C883A00BCD287 /* Main.swift */; }; @@ -1324,7 +1323,6 @@ 7B1E819F27C8874900FF0E60 /* ContentOverlay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */; }; 7B1E81A027C8874900FF0E60 /* ContentOverlayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */; }; 7B2DDCF82A93A8BB0039D884 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */; }; - 7B2DDCF92A93A8BB0039D884 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */; }; 7B2DDCFA2A93B25F0039D884 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; 7B2DDCFB2A93B25F0039D884 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; 7B2DDD022A93BAA60039D884 /* NetworkProtectionBouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD012A93BAA60039D884 /* NetworkProtectionBouncer.swift */; }; @@ -1346,7 +1344,6 @@ 7BBD45B42A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B32A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift */; }; 7BBD45B52A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B32A691C3A00C83CA9 /* NetworkProtectionLoginItemsManager.swift */; }; 7BD3AF5D2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; - 7BD3AF5E2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; 7BE146072A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */; }; 7BE146082A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */; }; 85012B0229133F9F003D0DCC /* NavigationBarPopovers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85012B0129133F9F003D0DCC /* NavigationBarPopovers.swift */; }; @@ -7534,7 +7531,6 @@ 37197EAB2942443D00394917 /* WebViewContainerView.swift in Sources */, 3706FA88293F65D500E42796 /* Logging.swift in Sources */, 3706FA89293F65D500E42796 /* CrashReportPromptPresenter.swift in Sources */, - 7BD3AF5E2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift in Sources */, 3706FA8B293F65D500E42796 /* PreferencesRootView.swift in Sources */, 3706FA8C293F65D500E42796 /* AppStateChangedPublisher.swift in Sources */, 3706FA8D293F65D500E42796 /* BookmarkTableCellView.swift in Sources */, @@ -7560,7 +7556,6 @@ 3707C727294B5D2900682A9F /* WKWebView+SessionState.swift in Sources */, 3706FAA3293F65D500E42796 /* CrashReportPromptViewController.swift in Sources */, 3706FAA4293F65D500E42796 /* ContextMenuManager.swift in Sources */, - 7B2DDCF92A93A8BB0039D884 /* NetworkProtectionAppEvents.swift in Sources */, 3706FAA5293F65D500E42796 /* GradientView.swift in Sources */, 3706FAA6293F65D500E42796 /* PreferencesSidebar.swift in Sources */, 3706FAA7293F65D500E42796 /* NSPointExtension.swift in Sources */, @@ -7743,7 +7738,6 @@ 3706FB46293F65D500E42796 /* FirePopoverWrapperViewController.swift in Sources */, 3706FB47293F65D500E42796 /* NSPasteboardItemExtension.swift in Sources */, 3706FB48293F65D500E42796 /* AutofillPreferencesModel.swift in Sources */, - 4B4D60DE2A0C875E00BCD287 /* NetworkProtectionBundle.swift in Sources */, 3706FB49293F65D500E42796 /* NSException+Catch.swift in Sources */, 3706FB4A293F65D500E42796 /* PasswordManagementNoteModel.swift in Sources */, 3706FB4B293F65D500E42796 /* CookieNotificationAnimationModel.swift in Sources */, diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift index 8a8aed100b..30ef263490 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift @@ -18,6 +18,8 @@ import Common import Foundation + +#if NETWORK_PROTECTION import NetworkProtection /// Implements the sequence of steps that Network Protection needs to execute when the App starts up. @@ -125,5 +127,6 @@ final class NetworkProtectionAppEvents { os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount) } } - } + +#endif diff --git a/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift b/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift index 950d9b86e9..fc0a06b67c 100644 --- a/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift +++ b/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift @@ -45,7 +45,10 @@ let extraInputFiles: [TargetName: Set] = [ .init("startVPN.app", .unknown), .init("stopVPN.app", .unknown), .init("enableOnDemand.app", .unknown), - .init("PFMoveApplication.m", .source) + .init("PFMoveApplication.m", .source), + .init("NetworkProtectionBundle.swift", .source), + .init("NetworkProtectionAppEvents.swift", .source), + .init("KeychainType+ClientDefault.swift", .source) ], "DuckDuckGo Privacy Browser App Store": [], From 31e33f64f9f3f024f7a9d39426fef8452b273de8 Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Wed, 23 Aug 2023 16:18:28 +0200 Subject: [PATCH 13/13] Resolves some building issues --- .../BothAppTargets/NetworkProtectionAppEvents.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift index 30ef263490..8a8aed100b 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift @@ -18,8 +18,6 @@ import Common import Foundation - -#if NETWORK_PROTECTION import NetworkProtection /// Implements the sequence of steps that Network Protection needs to execute when the App starts up. @@ -127,6 +125,5 @@ final class NetworkProtectionAppEvents { os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount) } } -} -#endif +}