diff --git a/.github/actions/install-certs-and-profiles/action.yml b/.github/actions/install-certs-and-profiles/action.yml index a436002469..466c511d2a 100644 --- a/.github/actions/install-certs-and-profiles/action.yml +++ b/.github/actions/install-certs-and-profiles/action.yml @@ -34,15 +34,6 @@ inputs: NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64: required: true type: string - NETP_START_VPN_PROVISION_PROFILE_BASE64: - required: true - type: string - NETP_STOP_VPN_PROVISION_PROFILE_BASE64: - required: true - type: string - NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64: - required: true - type: string access-token: description: "Asana access token" required: true @@ -70,9 +61,6 @@ runs: NETP_AGENT_REVIEW_PP_PATH=$RUNNER_TEMP/netp_agent_review_pp.provisionprofile NETP_NOTIFICATIONS_RELEASE_PP_PATH=$RUNNER_TEMP/netp_notifications_release_pp.provisionprofile NETP_NOTIFICATIONS_REVIEW_PP_PATH=$RUNNER_TEMP/netp_notifications_review_pp.provisionprofile - NETP_START_VPN_PP_PATH=$RUNNER_TEMP/netp_start_vpn_pp.provisionprofile - NETP_STOP_VPN_PP_PATH=$RUNNER_TEMP/netp_stop_vpn_pp.provisionprofile - NETP_ENABLE_ON_DEMAND_PP_PATH=$RUNNER_TEMP/netp_enable_on_demand_pp.provisionprofile # import certificate from secrets echo -n "${{ inputs.BUILD_CERTIFICATE_BASE64 }}" | base64 --decode -o $CERTIFICATE_PATH @@ -84,9 +72,6 @@ runs: echo -n "${{ inputs.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64 }}" | base64 --decode -o $NETP_AGENT_REVIEW_PP_PATH echo -n "${{ inputs.NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64 }}" | base64 --decode -o $NETP_NOTIFICATIONS_RELEASE_PP_PATH echo -n "${{ inputs.NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64 }}" | base64 --decode -o $NETP_NOTIFICATIONS_REVIEW_PP_PATH - echo -n "${{ inputs.NETP_START_VPN_PROVISION_PROFILE_BASE64 }}" | base64 --decode -o $NETP_START_VPN_PP_PATH - echo -n "${{ inputs.NETP_STOP_VPN_PROVISION_PROFILE_BASE64 }}" | base64 --decode -o $NETP_STOP_VPN_PP_PATH - echo -n "${{ inputs.NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64 }}" | base64 --decode -o $NETP_ENABLE_ON_DEMAND_PP_PATH # create temporary keychain security create-keychain -p "${{ inputs.KEYCHAIN_PASSWORD }}" $KEYCHAIN_PATH @@ -107,8 +92,5 @@ runs: $NETP_AGENT_REVIEW_PP_PATH \ $NETP_NOTIFICATIONS_RELEASE_PP_PATH \ $NETP_NOTIFICATIONS_REVIEW_PP_PATH \ - $NETP_START_VPN_PP_PATH \ - $NETP_STOP_VPN_PP_PATH \ - $NETP_ENABLE_ON_DEMAND_PP_PATH \ ~/Library/MobileDevice/Provisioning\ Profiles shell: bash diff --git a/.github/workflows/build_notarized.yml b/.github/workflows/build_notarized.yml index bfea0fd9dc..5ddbc2388d 100644 --- a/.github/workflows/build_notarized.yml +++ b/.github/workflows/build_notarized.yml @@ -49,24 +49,18 @@ on: required: true RELEASE_PROVISION_PROFILE_BASE64: required: true - NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64: + NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64_V2: required: true - NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64: + NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64_V2: required: true - NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64: + NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64_V2: required: true - NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64: + NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64_V2: required: true NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64: required: true NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64: required: true - NETP_START_VPN_PROVISION_PROFILE_BASE64: - required: true - NETP_STOP_VPN_PROVISION_PROFILE_BASE64: - required: true - NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64: - required: true SSH_PRIVATE_KEY_FIND_IN_PAGE: required: true APPLE_API_KEY_BASE64: @@ -121,15 +115,12 @@ jobs: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.REVIEW_PROVISION_PROFILE_BASE64 }} RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64 }} - NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64 }} + NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64_V2 }} + NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64_V2 }} + NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64_V2 }} + NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64_V2 }} NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64 }} NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64 }} - NETP_START_VPN_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_START_VPN_PROVISION_PROFILE_BASE64 }} - NETP_STOP_VPN_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_STOP_VPN_PROVISION_PROFILE_BASE64 }} - NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64 }} - name: Install xcbeautify if: runner.debug != '1' diff --git a/.github/workflows/create_variants.yml b/.github/workflows/create_variants.yml index 0b65c2d89a..758627690d 100644 --- a/.github/workflows/create_variants.yml +++ b/.github/workflows/create_variants.yml @@ -70,15 +70,12 @@ jobs: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.REVIEW_PROVISION_PROFILE_BASE64 }} RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64 }} - NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64 }} + NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64_V2 }} + NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64_V2 }} + NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64_V2 }} + NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64_V2 }} NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64 }} NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64 }} - NETP_START_VPN_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_START_VPN_PROVISION_PROFILE_BASE64 }} - NETP_STOP_VPN_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_STOP_VPN_PROVISION_PROFILE_BASE64 }} - NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64 }} - name: Set up variant working-directory: ${{ github.workspace }}/dmg diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index e710bebb36..75e1cc8cd1 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -236,15 +236,12 @@ jobs: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.REVIEW_PROVISION_PROFILE_BASE64 }} RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64 }} - NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64 }} + NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64_V2 }} + NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64_V2 }} + NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64_V2 }} + NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64_V2 }} NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64 }} NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64 }} - NETP_START_VPN_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_START_VPN_PROVISION_PROFILE_BASE64 }} - NETP_STOP_VPN_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_STOP_VPN_PROVISION_PROFILE_BASE64 }} - NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64 }} - name: Set cache key hash run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2033f2ce9f..41b5fffa3c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,15 +23,12 @@ jobs: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.REVIEW_PROVISION_PROFILE_BASE64 }} RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64 }} - NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64 }} - NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64 }} + NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64_V2: ${{ secrets.NETP_SYSEX_RELEASE_PROVISION_PROFILE_BASE64_V2 }} + NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64_V2: ${{ secrets.NETP_SYSEX_REVIEW_PROVISION_PROFILE_BASE64_V2 }} + NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64_V2: ${{ secrets.NETP_AGENT_RELEASE_PROVISION_PROFILE_BASE64_V2 }} + NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64_V2: ${{ secrets.NETP_AGENT_REVIEW_PROVISION_PROFILE_BASE64_V2 }} NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_NOTIFICATIONS_RELEASE_PROVISION_PROFILE_BASE64 }} NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_NOTIFICATIONS_REVIEW_PROVISION_PROFILE_BASE64 }} - NETP_START_VPN_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_START_VPN_PROVISION_PROFILE_BASE64 }} - NETP_STOP_VPN_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_STOP_VPN_PROVISION_PROFILE_BASE64 }} - NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64: ${{ secrets.NETP_ENABLE_ON_DEMAND_PROVISION_PROFILE_BASE64 }} SSH_PRIVATE_KEY_FIND_IN_PAGE: ${{ secrets.SSH_PRIVATE_KEY_FIND_IN_PAGE }} APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }} APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} diff --git a/Configuration/App/DuckDuckGo.xcconfig b/Configuration/App/DuckDuckGo.xcconfig index 2c85f56e17..08c9dcb67e 100644 --- a/Configuration/App/DuckDuckGo.xcconfig +++ b/Configuration/App/DuckDuckGo.xcconfig @@ -44,20 +44,6 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTE SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION DEBUG $(FEATURE_FLAGS) SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION REVIEW $(FEATURE_FLAGS) -AGENT_BUNDLE_ID[sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension.agent -AGENT_BUNDLE_ID[config=Debug][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension.agent.debug -AGENT_BUNDLE_ID[config=CI][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension.agent.debug -AGENT_BUNDLE_ID[config=Review][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension.agent.review - -// We could be tempted to use SYSEX_BUNDLE_ID = $(SYSEX_BUNDLE_ID_BASE).systemextension -// but Xcode is currently not expanding it well. You can check this in the project build -// settings. -SYSEX_BUNDLE_ID[sdk=*] = $(SYSEX_BUNDLE_ID_BASE).systemextension -SYSEX_BUNDLE_ID[config=CI][sdk=*] = $(SYSEX_BUNDLE_ID_BASE).systemextension -SYSEX_BUNDLE_ID[config=Review][sdk=*] = $(SYSEX_BUNDLE_ID_BASE).systemextension -SYSEX_BUNDLE_ID[config=Debug][sdk=*] = $(SYSEX_BUNDLE_ID_BASE).systemextension -SYSEX_BUNDLE_ID[config=Release][sdk=*] = $(SYSEX_BUNDLE_ID_BASE).systemextension - // Install Developer ID build to /Applications/DEBUG/ DEPLOYMENT_LOCATION[config=Debug] = YES; DSTROOT[config=Debug] = ${BUILT_PRODUCTS_DIR} diff --git a/Configuration/App/NetworkProtection/DuckDuckGoAgent.xcconfig b/Configuration/App/NetworkProtection/DuckDuckGoVPN.xcconfig similarity index 77% rename from Configuration/App/NetworkProtection/DuckDuckGoAgent.xcconfig rename to Configuration/App/NetworkProtection/DuckDuckGoVPN.xcconfig index c653903f5d..f464da1499 100644 --- a/Configuration/App/NetworkProtection/DuckDuckGoAgent.xcconfig +++ b/Configuration/App/NetworkProtection/DuckDuckGoVPN.xcconfig @@ -24,7 +24,7 @@ PRODUCT_BUNDLE_IDENTIFIER[config=Debug][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX) PRODUCT_BUNDLE_IDENTIFIER[config=CI][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX) PRODUCT_BUNDLE_IDENTIFIER[config=Review][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX) -INFOPLIST_FILE = DuckDuckGoAgent/Info.plist +INFOPLIST_FILE = DuckDuckGoVPN/Info.plist GENERATE_INFOPLIST_FILE = YES INFOPLIST_KEY_LSUIElement = YES INFOPLIST_KEY_NSPrincipalClass = Application @@ -33,10 +33,10 @@ INFOPLIST_KEY_NSPrincipalClass = Application //CODE_SIGN_STYLE[config=Debug][sdk=*] = Manual //CODE_SIGN_STYLE[config=Release][sdk=*] = Manual -CODE_SIGN_ENTITLEMENTS[config=Review][sdk=macosx*] = DuckDuckGoAgent/DuckDuckGoAgent.entitlements -CODE_SIGN_ENTITLEMENTS[config=CI][sdk=macosx*] = DuckDuckGoAgent/DuckDuckGoAgent.entitlements -CODE_SIGN_ENTITLEMENTS[config=Debug][sdk=macosx*] = DuckDuckGoAgent/DuckDuckGoAgent.entitlements -CODE_SIGN_ENTITLEMENTS[config=Release][sdk=macosx*] = DuckDuckGoAgent/DuckDuckGoAgent.entitlements +CODE_SIGN_ENTITLEMENTS[config=Review][sdk=macosx*] = DuckDuckGoVPN/DuckDuckGoVPN.entitlements +CODE_SIGN_ENTITLEMENTS[config=CI][sdk=macosx*] = DuckDuckGoVPN/DuckDuckGoVPN.entitlements +CODE_SIGN_ENTITLEMENTS[config=Debug][sdk=macosx*] = DuckDuckGoVPN/DuckDuckGoVPNDebug.entitlements +CODE_SIGN_ENTITLEMENTS[config=Release][sdk=macosx*] = DuckDuckGoVPN/DuckDuckGoVPN.entitlements CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development @@ -45,13 +45,13 @@ CODE_SIGN_IDENTITY[config=CI][sdk=macosx*] = PRODUCT_NAME = $(AGENT_PRODUCT_NAME) PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = -PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = macOS Network Protection Agent App Product Review -PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = macOS Network Protection Agent App (Distribution) +PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = macOS NetP VPN App - Review (XPC) +PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = macOS NetP VPN App - Release (XPC) -FEATURE_FLAGS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION -FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION -FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION -FEATURE_FLAGS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION +FEATURE_FLAGS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_PROTECTION +FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_PROTECTION +FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_PROTECTION +FEATURE_FLAGS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_PROTECTION SWIFT_OBJC_BRIDGING_HEADER = SKIP_INSTALL = YES diff --git a/Configuration/App/NetworkProtection/DuckDuckGoAgentAppStore.xcconfig b/Configuration/App/NetworkProtection/DuckDuckGoVPNAppStore.xcconfig similarity index 92% rename from Configuration/App/NetworkProtection/DuckDuckGoAgentAppStore.xcconfig rename to Configuration/App/NetworkProtection/DuckDuckGoVPNAppStore.xcconfig index 93dab9befe..6bbaffcaf7 100644 --- a/Configuration/App/NetworkProtection/DuckDuckGoAgentAppStore.xcconfig +++ b/Configuration/App/NetworkProtection/DuckDuckGoVPNAppStore.xcconfig @@ -24,7 +24,7 @@ PRODUCT_BUNDLE_IDENTIFIER[config=Debug][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).deb PRODUCT_BUNDLE_IDENTIFIER[config=CI][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).debug PRODUCT_BUNDLE_IDENTIFIER[config=Review][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).review -INFOPLIST_FILE = DuckDuckGoAgent/Info-AppStore.plist +INFOPLIST_FILE = DuckDuckGoVPN/Info-AppStore.plist GENERATE_INFOPLIST_FILE = YES INFOPLIST_KEY_LSUIElement = YES INFOPLIST_KEY_NSPrincipalClass = Application @@ -36,8 +36,8 @@ INFOPLIST_KEY_NSPrincipalClass = Application // Left empty intentionally as we currently only support debug and release builds CODE_SIGN_ENTITLEMENTS[config=Review][sdk=macosx*] = CODE_SIGN_ENTITLEMENTS[config=CI][sdk=macosx*] = -CODE_SIGN_ENTITLEMENTS[config=Debug][sdk=macosx*] = DuckDuckGoAgent/DuckDuckGoAgentAppStore.entitlements -CODE_SIGN_ENTITLEMENTS[config=Release][sdk=macosx*] = DuckDuckGoAgent/DuckDuckGoAgentAppStore.entitlements +CODE_SIGN_ENTITLEMENTS[config=Debug][sdk=macosx*] = DuckDuckGoVPN/DuckDuckGoVPNAppStore.entitlements +CODE_SIGN_ENTITLEMENTS[config=Release][sdk=macosx*] = DuckDuckGoVPN/DuckDuckGoVPNAppStore.entitlements CODE_SIGN_IDENTITY[sdk=macosx*] = 3rd Party Mac Developer Application CODE_SIGN_IDENTITY[config=Review][sdk=macosx*] = Developer ID Application diff --git a/Configuration/App/NetworkProtection/NetworkProtectionEnableOnDemand.xcconfig b/Configuration/App/NetworkProtection/NetworkProtectionEnableOnDemand.xcconfig deleted file mode 100644 index 5339b078d6..0000000000 --- a/Configuration/App/NetworkProtection/NetworkProtectionEnableOnDemand.xcconfig +++ /dev/null @@ -1,23 +0,0 @@ -// 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. -// - -#include "NetworkProtectionVPNHelpersBase.xcconfig" - -PRODUCT_BUNDLE_IDENTIFIER=com.duckduckgo.macos.browser.network-protection.enable-on-demand - -PROVISIONING_PROFILE_SPECIFIER[config=Debug][sdk=macosx*] = -PROVISIONING_PROFILE_SPECIFIER[config=CI][sdk=macosx*] = -PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = MacOS Browser NetP - Enable On-Demand -PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = MacOS Browser NetP - Enable On-Demand diff --git a/Configuration/App/NetworkProtection/NetworkProtectionStartVPN.xcconfig b/Configuration/App/NetworkProtection/NetworkProtectionStartVPN.xcconfig deleted file mode 100644 index 4df2675e3f..0000000000 --- a/Configuration/App/NetworkProtection/NetworkProtectionStartVPN.xcconfig +++ /dev/null @@ -1,23 +0,0 @@ -// 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. -// - -#include "NetworkProtectionVPNHelpersBase.xcconfig" - -PRODUCT_BUNDLE_IDENTIFIER=com.duckduckgo.macos.browser.network-protection.start-vpn - -PROVISIONING_PROFILE_SPECIFIER[config=Debug][sdk=macosx*] = -PROVISIONING_PROFILE_SPECIFIER[config=CI][sdk=macosx*] = -PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = MacOS Browser NetP - Start VPN -PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = MacOS Browser NetP - Start VPN diff --git a/Configuration/App/NetworkProtection/NetworkProtectionStopVPN.xcconfig b/Configuration/App/NetworkProtection/NetworkProtectionStopVPN.xcconfig deleted file mode 100644 index b3ab9f58b4..0000000000 --- a/Configuration/App/NetworkProtection/NetworkProtectionStopVPN.xcconfig +++ /dev/null @@ -1,23 +0,0 @@ -// 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. -// - -#include "NetworkProtectionVPNHelpersBase.xcconfig" - -PRODUCT_BUNDLE_IDENTIFIER=com.duckduckgo.macos.browser.network-protection.stop-vpn - -PROVISIONING_PROFILE_SPECIFIER[config=Debug][sdk=macosx*] = -PROVISIONING_PROFILE_SPECIFIER[config=CI][sdk=macosx*] = -PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = MacOS Browser NetP - Stop VPN -PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = MacOS Browser NetP - Stop VPN diff --git a/Configuration/App/NetworkProtection/NetworkProtectionVPNHelpersBase.xcconfig b/Configuration/App/NetworkProtection/NetworkProtectionVPNHelpersBase.xcconfig deleted file mode 100644 index 01016dc681..0000000000 --- a/Configuration/App/NetworkProtection/NetworkProtectionVPNHelpersBase.xcconfig +++ /dev/null @@ -1,82 +0,0 @@ -// 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. -// - -#include "../../Common.xcconfig" - -ALWAYS_SEARCH_USER_PATHS=NO -ASSETCATALOG_COMPILER_APPICON_NAME=AppIcon - -CODE_SIGN_ENTITLEMENTS=DuckDuckGo/NetworkProtectionVPNController.entitlements -CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application -CODE_SIGN_IDENTITY[config=CI][sdk=macosx*] = -CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development - -CODE_SIGN_STYLE[sdk=*] = Manual -CODE_SIGN_STYLE[config=Debug][sdk=*] = Automatic - -COMBINE_HIDPI_IMAGES=YES -COPY_PHASE_STRIP=NO - -DEBUG_INFORMATION_FORMAT[config=CI]=dwarf-with-dsym -DEBUG_INFORMATION_FORMAT[config=Debug]=dwarf -DEBUG_INFORMATION_FORMAT[config=Release]=dwarf-with-dsym -DEBUG_INFORMATION_FORMAT[config=Review]=dwarf-with-dsym - -ENABLE_HARDENED_RUNTIME=YES -ENABLE_NS_ASSERTIONS[config=CI]=NO -ENABLE_NS_ASSERTIONS[config=Release]=NO -ENABLE_NS_ASSERTIONS[config=Review]=NO -ENABLE_PREVIEWS=YES -ENABLE_STRICT_OBJC_MSGSEND=YES -ENABLE_TESTABILITY[config=Debug]=YES - -GCC_C_LANGUAGE_STANDARD=gnu11 -GCC_DYNAMIC_NO_PIC[config=Debug]=NO -GCC_NO_COMMON_BLOCKS=YES -GCC_OPTIMIZATION_LEVEL[config=Debug]=0 -GCC_PREPROCESSOR_DEFINITIONS[config=Debug]=DEBUG=1 $(inherited) -GCC_WARN_64_TO_32_BIT_CONVERSION=YES -GCC_WARN_ABOUT_RETURN_TYPE=YES_ERROR -GCC_WARN_UNDECLARED_SELECTOR=YES -GCC_WARN_UNINITIALIZED_AUTOS=YES_AGGRESSIVE -GCC_WARN_UNUSED_FUNCTION=YES -GCC_WARN_UNUSED_VARIABLE=YES -GENERATE_INFOPLIST_FILE=YES - -INFOPLIST_KEY_LSUIElement=YES -INFOPLIST_KEY_NSHumanReadableCopyright=Copyright © 2023 DuckDuckGo. All rights reserved. - -LD_RUNPATH_SEARCH_PATHS[config=CI]=$(inherited) @executable_path/../Frameworks -LD_RUNPATH_SEARCH_PATHS[config=Debug]=$(inherited) @executable_path/../Frameworks -LD_RUNPATH_SEARCH_PATHS[config=Release]=$(inherited) @executable_path/../Frameworks -LD_RUNPATH_SEARCH_PATHS[config=Review]=$(inherited) @executable_path/../Frameworks - -MTL_ENABLE_DEBUG_INFO[config=CI]=NO -MTL_ENABLE_DEBUG_INFO[config=Debug]=INCLUDE_SOURCE -MTL_ENABLE_DEBUG_INFO[config=Release]=NO -MTL_ENABLE_DEBUG_INFO[config=Review]=NO -MTL_FAST_MATH=YES - -ONLY_ACTIVE_ARCH[config=Debug]=YES -PRODUCT_NAME=$(TARGET_NAME) -SDKROOT=macosx - -SKIP_INSTALL=YES - -SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug]=DEBUG -SWIFT_COMPILATION_MODE[config=CI]=wholemodule -SWIFT_COMPILATION_MODE[config=Release]=wholemodule -SWIFT_COMPILATION_MODE[config=Review]=wholemodule -SWIFT_EMIT_LOC_STRINGS=YES diff --git a/Configuration/AppStore.xcconfig b/Configuration/AppStore.xcconfig index cf8d7df84a..804cd0af5f 100644 --- a/Configuration/AppStore.xcconfig +++ b/Configuration/AppStore.xcconfig @@ -46,4 +46,4 @@ AGENT_BUNDLE_ID[config=Debug][sdk=*] = HKE973VLUW.com.duckduckgo.macos.browser.n AGENT_BUNDLE_ID[config=CI][sdk=*] = HKE973VLUW.com.duckduckgo.macos.browser.network-protection.agent.debug AGENT_BUNDLE_ID[config=Review][sdk=*] = HKE973VLUW.com.duckduckgo.macos.browser.network-protection.agent.review -AGENT_PRODUCT_NAME = DuckDuckGo Agent App Store +AGENT_PRODUCT_NAME = DuckDuckGo VPN App Store diff --git a/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig b/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig index daa556afee..85a6dccf05 100644 --- a/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig +++ b/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig @@ -36,21 +36,21 @@ FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSIO FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION NETWORK_PROTECTION FEATURE_FLAGS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION NETWORK_PROTECTION -PRODUCT_BUNDLE_IDENTIFIER[sdk=*] = $(SYSEX_BUNDLE_ID_BASE) -PRODUCT_BUNDLE_IDENTIFIER[config=CI][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) -PRODUCT_BUNDLE_IDENTIFIER[config=Debug][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) -PRODUCT_BUNDLE_IDENTIFIER[config=Release][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) -PRODUCT_BUNDLE_IDENTIFIER[config=Review][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) - -PRODUCT_NAME[sdk=*] = $(SYSEX_BUNDLE_ID_BASE) -PRODUCT_NAME[config=CI][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) -PRODUCT_NAME[config=Debug][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) -PRODUCT_NAME[config=Release][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) -PRODUCT_NAME[config=Review][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) +PRODUCT_BUNDLE_IDENTIFIER[sdk=*] = $(SYSEX_BUNDLE_ID) +PRODUCT_BUNDLE_IDENTIFIER[config=CI][sdk=*] = $(SYSEX_BUNDLE_ID) +PRODUCT_BUNDLE_IDENTIFIER[config=Debug][sdk=*] = $(SYSEX_BUNDLE_ID) +PRODUCT_BUNDLE_IDENTIFIER[config=Release][sdk=*] = $(SYSEX_BUNDLE_ID) +PRODUCT_BUNDLE_IDENTIFIER[config=Review][sdk=*] = $(SYSEX_BUNDLE_ID) + +PRODUCT_NAME[sdk=*] = $(SYSEX_BUNDLE_ID) +PRODUCT_NAME[config=CI][sdk=*] = $(SYSEX_BUNDLE_ID) +PRODUCT_NAME[config=Debug][sdk=*] = $(SYSEX_BUNDLE_ID) +PRODUCT_NAME[config=Release][sdk=*] = $(SYSEX_BUNDLE_ID) +PRODUCT_NAME[config=Review][sdk=*] = $(SYSEX_BUNDLE_ID) PROVISIONING_PROFILE_SPECIFIER[config=CI][sdk=macosx*] = -PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = macOS NetP System Extension - Release -PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = macOS NetP System Extension - Review +PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = macOS NetP VPN SysEx - Release (XPC) +PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = macOS NetP VPN SysEx - Review (XPC) SDKROOT = macosx SKIP_INSTALL = YES diff --git a/Configuration/NetworkProtectionDeveloperID.xcconfig b/Configuration/NetworkProtectionDeveloperID.xcconfig index a7bf7d5007..f236ca2992 100644 --- a/Configuration/NetworkProtectionDeveloperID.xcconfig +++ b/Configuration/NetworkProtectionDeveloperID.xcconfig @@ -20,13 +20,19 @@ MAIN_BUNDLE_IDENTIFIER[config=Debug][sdk=*] = $(MAIN_BUNDLE_IDENTIFIER_PREFIX).d MAIN_BUNDLE_IDENTIFIER[config=CI][sdk=*] = $(MAIN_BUNDLE_IDENTIFIER_PREFIX).debug MAIN_BUNDLE_IDENTIFIER[config=Review][sdk=*] = $(MAIN_BUNDLE_IDENTIFIER_PREFIX).review -SYSEX_BUNDLE_ID_BASE[sdk=*] = com.duckduckgo.macos.browser.network-protection-extension -SYSEX_BUNDLE_ID_BASE[config=CI][sdk=*] = com.duckduckgo.macos.browser.debug.network-protection-extension -SYSEX_BUNDLE_ID_BASE[config=Review][sdk=*] = com.duckduckgo.macos.browser.review.network-protection-extension -SYSEX_BUNDLE_ID_BASE[config=Debug][sdk=*] = com.duckduckgo.macos.browser.debug.network-protection-extension -SYSEX_BUNDLE_ID_BASE[config=Release][sdk=*] = com.duckduckgo.macos.browser.network-protection-extension +SYSEX_BUNDLE_ID_BASE[sdk=*] = $(AGENT_BUNDLE_ID_BASE).network-extension +SYSEX_BUNDLE_ID_BASE[config=Debug][sdk=*] = $(AGENT_BUNDLE_ID_BASE).network-extension +SYSEX_BUNDLE_ID_BASE[config=CI][sdk=*] = $(AGENT_BUNDLE_ID_BASE).network-extension +SYSEX_BUNDLE_ID_BASE[config=Review][sdk=*] = $(AGENT_BUNDLE_ID_BASE).network-extension +SYSEX_BUNDLE_ID_BASE[config=Release][sdk=*] = $(AGENT_BUNDLE_ID_BASE).network-extension -DISTRIBUTED_NOTIFICATIONS_PREFIX_BASE = com.duckduckgo.macos.browser.network-protection.distributed-notification +SYSEX_BUNDLE_ID[sdk=*] = $(SYSEX_BUNDLE_ID_BASE) +SYSEX_BUNDLE_ID[config=Debug][sdk=*] = $(SYSEX_BUNDLE_ID_BASE).debug +SYSEX_BUNDLE_ID[config=CI][sdk=*] = $(SYSEX_BUNDLE_ID_BASE).debug +SYSEX_BUNDLE_ID[config=Review][sdk=*] = $(SYSEX_BUNDLE_ID_BASE).review +SYSEX_BUNDLE_ID[config=Release][sdk=*] = $(SYSEX_BUNDLE_ID_BASE) + +DISTRIBUTED_NOTIFICATIONS_PREFIX_BASE = $(SYSEX_BUNDLE_ID_BASE) DISTRIBUTED_NOTIFICATIONS_PREFIX[config=CI][sdk=*] = $(DISTRIBUTED_NOTIFICATIONS_PREFIX_BASE).ci DISTRIBUTED_NOTIFICATIONS_PREFIX[config=Review][sdk=*] = $(DISTRIBUTED_NOTIFICATIONS_PREFIX_BASE).review DISTRIBUTED_NOTIFICATIONS_PREFIX[config=Debug][sdk=*] = $(DISTRIBUTED_NOTIFICATIONS_PREFIX_BASE).debug @@ -49,10 +55,12 @@ NOTIFICATIONS_AGENT_BUNDLE_ID[config=Debug][sdk=*] = $(DEVELOPMENT_TEAM).com.duc NOTIFICATIONS_AGENT_BUNDLE_ID[config=CI][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.notifications.debug NOTIFICATIONS_AGENT_BUNDLE_ID[config=Review][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.notifications.review -AGENT_BUNDLE_ID[sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension.agent -AGENT_BUNDLE_ID[config=Debug][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension.agent.debug -AGENT_BUNDLE_ID[config=CI][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension.agent.debug -AGENT_BUNDLE_ID[config=Review][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension.agent.review +AGENT_BUNDLE_ID_BASE[sdk=*] = com.duckduckgo.macos.vpn + +AGENT_BUNDLE_ID[sdk=*] = $(AGENT_BUNDLE_ID_BASE) +AGENT_BUNDLE_ID[config=Debug][sdk=*] = $(AGENT_BUNDLE_ID_BASE).debug +AGENT_BUNDLE_ID[config=CI][sdk=*] = $(AGENT_BUNDLE_ID_BASE).debug +AGENT_BUNDLE_ID[config=Review][sdk=*] = $(AGENT_BUNDLE_ID_BASE).review -AGENT_PRODUCT_NAME = DuckDuckGo Agent +AGENT_PRODUCT_NAME = DuckDuckGo VPN NOTIFICATIONS_AGENT_PRODUCT_NAME = DuckDuckGo Notifications diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 6b58cca487..34e85c07fa 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -255,7 +255,6 @@ 3192A0282A4C4CFF0084EA89 /* DownloadListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B23526E732000031CB7F /* DownloadListItem.swift */; }; 3192A0292A4C4CFF0084EA89 /* DownloadsPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B1E87D26D5DA0E0062C350 /* DownloadsPopover.swift */; }; 3192A02A2A4C4CFF0084EA89 /* SpacerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929626670D2A00AD2C21 /* SpacerNode.swift */; }; - 3192A02C2A4C4CFF0084EA89 /* SystemExtensionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60622A0B29FA00BCD287 /* SystemExtensionManager.swift */; }; 3192A02D2A4C4CFF0084EA89 /* SyncManagementDialogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3775913529AB9A1C00E26367 /* SyncManagementDialogViewController.swift */; }; 3192A02E2A4C4CFF0084EA89 /* BookmarkExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0BB6629AEFF8100AE8E3C /* BookmarkExtension.swift */; }; 3192A02F2A4C4CFF0084EA89 /* PasswordManagementCreditCardModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6547B271FCD4D008D1D63 /* PasswordManagementCreditCardModel.swift */; }; @@ -421,7 +420,6 @@ 3192A0D52A4C4CFF0084EA89 /* PasteboardFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929226670D2A00AD2C21 /* PasteboardFolder.swift */; }; 3192A0D72A4C4CFF0084EA89 /* CookieManagedNotificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3171D6B72889849F0068632A /* CookieManagedNotificationView.swift */; }; 3192A0D82A4C4CFF0084EA89 /* PermissionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106BAA26A7BF1D0013B453 /* PermissionType.swift */; }; - 3192A0D92A4C4CFF0084EA89 /* NetworkProtectionTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */; }; 3192A0DA2A4C4CFF0084EA89 /* RecentlyClosedWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6881A28626C1900D54247 /* RecentlyClosedWindow.swift */; }; 3192A0DB2A4C4CFF0084EA89 /* ActionSpeech.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F29276A35FE00DC0649 /* ActionSpeech.swift */; }; 3192A0DC2A4C4CFF0084EA89 /* PrivacySecurityPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0511A6262CAA5A00F6079C /* PrivacySecurityPreferences.swift */; }; @@ -805,11 +803,8 @@ 3192A25D2A4C4CFF0084EA89 /* trackers-2.json in Resources */ = {isa = PBXBuildFile; fileRef = AA3439742754D55100B241FA /* trackers-2.json */; }; 3192A25E2A4C4CFF0084EA89 /* ProximaNova-Reg-webfont.woff2 in Resources */ = {isa = PBXBuildFile; fileRef = EAA29AE8278D2E43007070CF /* ProximaNova-Reg-webfont.woff2 */; }; 3192A25F2A4C4CFF0084EA89 /* clickToLoad.js in Resources */ = {isa = PBXBuildFile; fileRef = EAFAD6C92728BD1200F9DF00 /* clickToLoad.js */; }; - 3192A2612A4C4CFF0084EA89 /* DuckDuckGo Agent.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo Agent.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 3192A2612A4C4CFF0084EA89 /* DuckDuckGo VPN.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo VPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 3192A2622A4C4CFF0084EA89 /* DuckDuckGo Notifications.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B4BEC202A11B4E2001D9AC5 /* DuckDuckGo Notifications.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 3192A2642A4C4CFF0084EA89 /* enableOnDemand.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 7B736E5F2A4A22B700F9922A /* enableOnDemand.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 3192A2652A4C4CFF0084EA89 /* stopVPN.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 4B5F14E12A1476BD0060320F /* stopVPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 3192A2662A4C4CFF0084EA89 /* startVPN.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 4B5F14CB2A14702C0060320F /* startVPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 3192EC882A4DCF21001E97A5 /* DBPHomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3192EC872A4DCF21001E97A5 /* DBPHomeViewController.swift */; }; 3198FCAC2A5D8A3C002EF5F8 /* AppLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD7A6E2A1D3E1F002A24E7 /* AppLauncher.swift */; }; 31A031A6288191230090F792 /* CookieConsentAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A031A5288191230090F792 /* CookieConsentAnimationView.swift */; }; @@ -1762,7 +1757,6 @@ 4B2537772A11BFE100610219 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2537762A11BFE100610219 /* PixelKit */; }; 4B2537782A11C00F00610219 /* NetworkProtectionExtensionMachService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60782A0B29FA00BCD287 /* NetworkProtectionExtensionMachService.swift */; }; 4B25377A2A11C01700610219 /* UserText+NetworkProtectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */; }; - 4B25377C2A11C07600610219 /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60832A0B29FA00BCD287 /* NetworkProtectionPixelEvent.swift */; }; 4B29759728281F0900187C4E /* FirefoxEncryptionKeyReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B29759628281F0900187C4E /* FirefoxEncryptionKeyReader.swift */; }; 4B2975992828285900187C4E /* FirefoxKeyReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2975982828285900187C4E /* FirefoxKeyReaderTests.swift */; }; 4B2AAAF529E70DEA0026AFC0 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2AAAF429E70DEA0026AFC0 /* Lottie */; }; @@ -1773,14 +1767,9 @@ 4B2D06302A11C15900DE1F49 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2D062F2A11C15900DE1F49 /* Common */; }; 4B2D06322A11C1D300DE1F49 /* NSApplicationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C8F622591021700748EB7 /* NSApplicationExtension.swift */; }; 4B2D06332A11C1E300DE1F49 /* OptionalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B637273C26CCF0C200C8CB02 /* OptionalExtension.swift */; }; - 4B2D06342A11CC4600DE1F49 /* SystemExtensionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60622A0B29FA00BCD287 /* SystemExtensionManager.swift */; }; - 4B2D064F2A11D0D000DE1F49 /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2D064E2A11D0D000DE1F49 /* NetworkProtectionUI */; }; - 4B2D06572A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2D06512A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.swift */; }; - 4B2D06582A11D19B00DE1F49 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B2D06522A11D19B00DE1F49 /* Assets.xcassets */; }; 4B2D065B2A11D1FF00DE1F49 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4BEC322A11B509001D9AC5 /* Logging.swift */; }; 4B2D065E2A11D2D700DE1F49 /* DuckDuckGo Notifications.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B4BEC202A11B4E2001D9AC5 /* DuckDuckGo Notifications.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 4B2D065F2A11D2D700DE1F49 /* DuckDuckGo Agent.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo Agent.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 4B2D067A2A1333EF00DE1F49 /* DuckDuckGoAgentAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2D06512A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.swift */; }; + 4B2D065F2A11D2D700DE1F49 /* DuckDuckGo VPN.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo VPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 4B2D067C2A13340900DE1F49 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4BEC322A11B509001D9AC5 /* Logging.swift */; }; 4B2D067F2A1334D700DE1F49 /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2D067E2A1334D700DE1F49 /* NetworkProtectionUI */; }; 4B2E7D6326FF9D6500D2DB17 /* PrintingUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E7D6226FF9D6500D2DB17 /* PrintingUserScript.swift */; }; @@ -1806,7 +1795,6 @@ 4B4BEC482A11B61F001D9AC5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B4BEC342A11B509001D9AC5 /* Assets.xcassets */; }; 4B4D603F2A0B290200BCD287 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */; }; 4B4D60892A0B2A1C00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */; }; - 4B4D60932A0B2A3700BCD287 /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60832A0B29FA00BCD287 /* NetworkProtectionPixelEvent.swift */; }; 4B4D60982A0B2A5C00BCD287 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4B4D60972A0B2A5C00BCD287 /* PixelKit */; }; 4B4D609F2A0B2C7300BCD287 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85799C1725DEBB3F0007EC87 /* Logging.swift */; }; 4B4D60A02A0B2D5B00BCD287 /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; @@ -1849,10 +1837,6 @@ 4B59024C26B38BB800489384 /* ChromiumLoginReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59024B26B38BB800489384 /* ChromiumLoginReaderTests.swift */; }; 4B59CC8C290083240058F2F6 /* ConnectBitwardenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59CC8B290083240058F2F6 /* ConnectBitwardenViewModelTests.swift */; }; 4B5A4F4C27F3A5AA008FBD88 /* NSNotificationName+DataImport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A4F4B27F3A5AA008FBD88 /* NSNotificationName+DataImport.swift */; }; - 4B5F14DC2A1470AA0060320F /* Main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5F14C52A145D6A0060320F /* Main.swift */; }; - 4B5F14F22A1476EF0060320F /* Main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5F14C52A145D6A0060320F /* Main.swift */; }; - 4B5F14F42A14824F0060320F /* startVPN.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 4B5F14CB2A14702C0060320F /* startVPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 4B5F14F52A1482530060320F /* stopVPN.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 4B5F14E12A1476BD0060320F /* stopVPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 4B5FF67826B602B100D42879 /* FirefoxDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FF67726B602B100D42879 /* FirefoxDataImporter.swift */; }; 4B65143E263924B5005B46EB /* EmailUrlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B65143D263924B5005B46EB /* EmailUrlExtensions.swift */; }; 4B677432255DBEB800025BD8 /* httpsMobileV2BloomSpec.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B677427255DBEB800025BD8 /* httpsMobileV2BloomSpec.json */; }; @@ -1902,8 +1886,6 @@ 4B8AD0B127A86D9200AE44D6 /* WKWebsiteDataStoreExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8AD0B027A86D9200AE44D6 /* WKWebsiteDataStoreExtensionTests.swift */; }; 4B8D9062276D1D880078DB17 /* LocaleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8D9061276D1D880078DB17 /* LocaleExtension.swift */; }; 4B8F52352A169D2D00BE7131 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 4B8F52342A169D2D00BE7131 /* Common */; }; - 4B8F52412A18326600BE7131 /* NetworkProtectionTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */; }; - 4B8F52422A18326600BE7131 /* NetworkProtectionTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */; }; 4B92928B26670D1700AD2C21 /* BookmarksOutlineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92928526670D1600AD2C21 /* BookmarksOutlineView.swift */; }; 4B92928C26670D1700AD2C21 /* OutlineSeparatorViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92928626670D1600AD2C21 /* OutlineSeparatorViewCell.swift */; }; 4B92928D26670D1700AD2C21 /* BookmarkOutlineViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92928726670D1600AD2C21 /* BookmarkOutlineViewCell.swift */; }; @@ -2095,7 +2077,6 @@ 4B9579DB2AC7AE700062CA31 /* DownloadsPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B1E87D26D5DA0E0062C350 /* DownloadsPopover.swift */; }; 4B9579DC2AC7AE700062CA31 /* BookmarksBarMenuFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85774AFE2A713D3B00DE0561 /* BookmarksBarMenuFactory.swift */; }; 4B9579DD2AC7AE700062CA31 /* SpacerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929626670D2A00AD2C21 /* SpacerNode.swift */; }; - 4B9579DE2AC7AE700062CA31 /* SystemExtensionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60622A0B29FA00BCD287 /* SystemExtensionManager.swift */; }; 4B9579DF2AC7AE700062CA31 /* SyncManagementDialogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3775913529AB9A1C00E26367 /* SyncManagementDialogViewController.swift */; }; 4B9579E02AC7AE700062CA31 /* BookmarkExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0BB6629AEFF8100AE8E3C /* BookmarkExtension.swift */; }; 4B9579E12AC7AE700062CA31 /* PasswordManagementCreditCardModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6547B271FCD4D008D1D63 /* PasswordManagementCreditCardModel.swift */; }; @@ -2280,7 +2261,6 @@ 4B957A942AC7AE700062CA31 /* PasteboardFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929226670D2A00AD2C21 /* PasteboardFolder.swift */; }; 4B957A952AC7AE700062CA31 /* CookieManagedNotificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3171D6B72889849F0068632A /* CookieManagedNotificationView.swift */; }; 4B957A962AC7AE700062CA31 /* PermissionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106BAA26A7BF1D0013B453 /* PermissionType.swift */; }; - 4B957A972AC7AE700062CA31 /* NetworkProtectionTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */; }; 4B957A982AC7AE700062CA31 /* RecentlyClosedWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6881A28626C1900D54247 /* RecentlyClosedWindow.swift */; }; 4B957A992AC7AE700062CA31 /* ActionSpeech.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F29276A35FE00DC0649 /* ActionSpeech.swift */; }; 4B957A9A2AC7AE700062CA31 /* PrivacySecurityPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0511A6262CAA5A00F6079C /* PrivacySecurityPreferences.swift */; }; @@ -2687,11 +2667,8 @@ 4B957C2F2AC7AE700062CA31 /* trackers-2.json in Resources */ = {isa = PBXBuildFile; fileRef = AA3439742754D55100B241FA /* trackers-2.json */; }; 4B957C302AC7AE700062CA31 /* ProximaNova-Reg-webfont.woff2 in Resources */ = {isa = PBXBuildFile; fileRef = EAA29AE8278D2E43007070CF /* ProximaNova-Reg-webfont.woff2 */; }; 4B957C312AC7AE700062CA31 /* clickToLoad.js in Resources */ = {isa = PBXBuildFile; fileRef = EAFAD6C92728BD1200F9DF00 /* clickToLoad.js */; }; - 4B957C342AC7AE700062CA31 /* DuckDuckGo Agent.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo Agent.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 4B957C342AC7AE700062CA31 /* DuckDuckGo VPN.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo VPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 4B957C352AC7AE700062CA31 /* DuckDuckGo Notifications.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B4BEC202A11B4E2001D9AC5 /* DuckDuckGo Notifications.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 4B957C372AC7AE700062CA31 /* enableOnDemand.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 7B736E5F2A4A22B700F9922A /* enableOnDemand.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 4B957C382AC7AE700062CA31 /* stopVPN.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 4B5F14E12A1476BD0060320F /* stopVPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 4B957C392AC7AE700062CA31 /* startVPN.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 4B5F14CB2A14702C0060320F /* startVPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 4B9754EC2984300100D7B834 /* EmailManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B848F297A0E1000A384BD /* EmailManagerExtension.swift */; }; 4B980E212817604000282EE1 /* NSNotificationName+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B980E202817604000282EE1 /* NSNotificationName+Debug.swift */; }; 4B98D27A28D95F1A003C2B6F /* ChromiumFaviconsReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B98D27928D95F1A003C2B6F /* ChromiumFaviconsReaderTests.swift */; }; @@ -2832,6 +2809,21 @@ 4BE65481271FCD4D008D1D63 /* PasswordManagementNoteModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6547D271FCD4D008D1D63 /* PasswordManagementNoteModel.swift */; }; 4BE65485271FCD7B008D1D63 /* LoginFaviconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE65484271FCD7B008D1D63 /* LoginFaviconView.swift */; }; 4BF01C00272AE74C00884A61 /* CountryList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE65482271FCD53008D1D63 /* CountryList.swift */; }; + 4BF0E5052AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; + 4BF0E5062AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; + 4BF0E5072AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; + 4BF0E5082AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; + 4BF0E5092AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; + 4BF0E50A2AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; + 4BF0E50B2AD2552200FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; + 4BF0E50C2AD2552300FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; + 4BF0E50E2AD2555D00FFEC9E /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + 4BF0E5122AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; + 4BF0E5132AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; + 4BF0E5142AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; + 4BF0E5152AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; + 4BF0E5162AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; + 4BF0E5172AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; 4BF4951826C08395000547B8 /* ThirdPartyBrowserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4951726C08395000547B8 /* ThirdPartyBrowserTests.swift */; }; 4BF4EA5027C71F26004E57C4 /* PasswordManagementListSectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4EA4F27C71F26004E57C4 /* PasswordManagementListSectionTests.swift */; }; 4BF6961D28BE911100D402D4 /* RecentlyVisitedSiteModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6961C28BE911100D402D4 /* RecentlyVisitedSiteModelTests.swift */; }; @@ -2875,36 +2867,75 @@ 7B2DDCF82A93A8BB0039D884 /* 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 */; }; + 7B31FD882AD124620086AA24 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + 7B31FD8A2AD124680086AA24 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + 7B31FD8C2AD125620086AA24 /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7B31FD8B2AD125620086AA24 /* NetworkProtectionIPC */; }; + 7B31FD8E2AD125760086AA24 /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7B31FD8D2AD125760086AA24 /* NetworkProtectionIPC */; }; + 7B31FD902AD1257B0086AA24 /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7B31FD8F2AD1257B0086AA24 /* NetworkProtectionIPC */; }; + 7B3618C22ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */; }; + 7B3618C42ADE77D2000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */; }; + 7B3618C52ADE77D3000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */; }; 7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; 7B430EA22A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; 7B4CE8E726F02135009134B1 /* TabBarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4CE8E626F02134009134B1 /* TabBarTests.swift */; }; - 7B736E582A4A22B700F9922A /* Main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5F14C52A145D6A0060320F /* Main.swift */; }; - 7B736E6A2A4A22FC00F9922A /* enableOnDemand.app in Embed NetP Controller Apps */ = {isa = PBXBuildFile; fileRef = 7B736E5F2A4A22B700F9922A /* enableOnDemand.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 7B838C382A1DD8DD00E05A13 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B2D06522A11D19B00DE1F49 /* Assets.xcassets */; }; + 7B5F9A752AE2BE4E002AEBC0 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */; }; 7B934C412A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */; }; 7B96D0DC2ADFDB8E007E02C8 /* DataBrokerProtectionPixelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B96D0DB2ADFDB8E007E02C8 /* DataBrokerProtectionPixelTests.swift */; }; 7BA4727D26F01BC400EAA165 /* CoreDataTestUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C42667104B00AD2C21 /* CoreDataTestUtilities.swift */; }; + 7BA59C9B2AE18B49009A97B1 /* SystemExtensionManager in Frameworks */ = {isa = PBXBuildFile; productRef = 7BA59C9A2AE18B49009A97B1 /* SystemExtensionManager */; }; + 7BA7CC392AD11E2D0042E5CE /* DuckDuckGoVPNAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC0E2AD11DC80042E5CE /* DuckDuckGoVPNAppDelegate.swift */; }; + 7BA7CC3A2AD11E2D0042E5CE /* DuckDuckGoVPNAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC0E2AD11DC80042E5CE /* DuckDuckGoVPNAppDelegate.swift */; }; + 7BA7CC3B2AD11E330042E5CE /* Bundle+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC0F2AD11DC80042E5CE /* Bundle+Configuration.swift */; }; + 7BA7CC3C2AD11E330042E5CE /* Bundle+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC0F2AD11DC80042E5CE /* Bundle+Configuration.swift */; }; + 7BA7CC3D2AD11E380042E5CE /* TunnelControllerIPCService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC112AD11DC80042E5CE /* TunnelControllerIPCService.swift */; }; + 7BA7CC3E2AD11E380042E5CE /* TunnelControllerIPCService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC112AD11DC80042E5CE /* TunnelControllerIPCService.swift */; }; + 7BA7CC3F2AD11E3D0042E5CE /* AppLauncher+DefaultInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC132AD11DC80042E5CE /* AppLauncher+DefaultInitializer.swift */; }; + 7BA7CC402AD11E3D0042E5CE /* AppLauncher+DefaultInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC132AD11DC80042E5CE /* AppLauncher+DefaultInitializer.swift */; }; + 7BA7CC412AD11E420042E5CE /* NetworkProtectionBouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC152AD11DC80042E5CE /* NetworkProtectionBouncer.swift */; }; + 7BA7CC422AD11E420042E5CE /* NetworkProtectionBouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC152AD11DC80042E5CE /* NetworkProtectionBouncer.swift */; }; + 7BA7CC432AD11E480042E5CE /* UserText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC172AD11DC80042E5CE /* UserText.swift */; }; + 7BA7CC442AD11E490042E5CE /* UserText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC172AD11DC80042E5CE /* UserText.swift */; }; + 7BA7CC472AD11E5C0042E5CE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7BA7CC122AD11DC80042E5CE /* Assets.xcassets */; }; + 7BA7CC482AD11E5C0042E5CE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7BA7CC122AD11DC80042E5CE /* Assets.xcassets */; }; + 7BA7CC4A2AD11EA00042E5CE /* NetworkProtectionTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */; }; + 7BA7CC4B2AD11EC60042E5CE /* NetworkProtectionControllerErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */; }; + 7BA7CC4C2AD11EC70042E5CE /* NetworkProtectionControllerErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */; }; + 7BA7CC4E2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC4D2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift */; }; + 7BA7CC4F2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC4D2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift */; }; + 7BA7CC502AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC4D2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift */; }; + 7BA7CC532AD11FCE0042E5CE /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; + 7BA7CC542AD11FCE0042E5CE /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; + 7BA7CC552AD11FFB0042E5CE /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; }; + 7BA7CC562AD11FFB0042E5CE /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; }; + 7BA7CC582AD1203A0042E5CE /* UserText+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */; }; + 7BA7CC592AD1203B0042E5CE /* UserText+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */; }; + 7BA7CC5A2AD120640042E5CE /* NetworkProtection+ConvenienceInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */; }; + 7BA7CC5B2AD120640042E5CE /* NetworkProtection+ConvenienceInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */; }; + 7BA7CC5C2AD120C30042E5CE /* EventMapping+NetworkProtectionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */; }; + 7BA7CC5D2AD120C30042E5CE /* EventMapping+NetworkProtectionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */; }; + 7BA7CC5F2AD1210C0042E5CE /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 7BA7CC5E2AD1210C0042E5CE /* Networking */; }; + 7BA7CC612AD1211C0042E5CE /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 7BA7CC602AD1211C0042E5CE /* Networking */; }; 7BAF9E4B2A8A3CC9002D3B6E /* UserDefaults+NetworkProtectionShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */; }; 7BAF9E4C2A8A3CCA002D3B6E /* UserDefaults+NetworkProtectionShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */; }; 7BAF9E4D2A8A3CCB002D3B6E /* UserDefaults+NetworkProtectionShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */; }; 7BB108592A43375D000AB95F /* PFMoveApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BB108582A43375D000AB95F /* PFMoveApplication.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 7BBD44282AD730A400D0A064 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BBD44272AD730A400D0A064 /* PixelKit */; }; 7BBD45B12A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */; }; 7BBD45B22A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */; }; + 7BD1688E2AD4A4C400D24876 /* NetworkExtensionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD1688D2AD4A4C400D24876 /* NetworkExtensionController.swift */; }; 7BD3AF5D2A8E7AF1006F9F56 /* 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 */; }; + 7BEC182F2AD5D8DC00D30536 /* SystemExtensionManager in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEC182E2AD5D8DC00D30536 /* SystemExtensionManager */; }; + 7BEEA5122AD1235B00A9E72B /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5112AD1235B00A9E72B /* NetworkProtectionIPC */; }; + 7BEEA5142AD1236300A9E72B /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5132AD1236300A9E72B /* NetworkProtectionIPC */; }; + 7BEEA5162AD1236E00A9E72B /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5152AD1236E00A9E72B /* NetworkProtectionUI */; }; 7BF1A9D82AE054D300FCA683 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7BF1A9D72AE054D300FCA683 /* Info.plist */; }; 7BF1A9DC2AE0551C00FCA683 /* DBPUnitTests.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 7BF1A9DB2AE0551C00FCA683 /* DBPUnitTests.xcconfig */; }; 7BF7705F2AD6C999001C9182 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BF7705E2AD6C999001C9182 /* PixelKit */; }; - 7BF770612AD6CA06001C9182 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BF770602AD6CA06001C9182 /* PixelKit */; }; - 7BF770632AD6CA0E001C9182 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BF770622AD6CA0E001C9182 /* PixelKit */; }; - 7BF770652AD6CA14001C9182 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BF770642AD6CA14001C9182 /* PixelKit */; }; + 7BFCB74E2ADE7E1A00DA3EA7 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */; }; + 7BFCB7502ADE7E2300DA3EA7 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */; }; 7BFE95522A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */; }; 7BFE95542A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */; }; 7BFE95552A9DF2990081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */; }; @@ -3636,13 +3667,6 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 31929F7E2A4C4CFF0084EA89 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B2537592A11BE7300610219; - remoteInfo = NetworkProtectionSystemExtension; - }; 37079A92294236F20031BB3C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; @@ -3664,20 +3688,6 @@ remoteGlobalIDString = AA585D7D248FD31100E9A3E2; remoteInfo = "DuckDuckGo Privacy Browser"; }; - 4B2537632A11BE7600610219 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B2537592A11BE7300610219; - remoteInfo = NetworkProtectionSystemExtension; - }; - 4B9579282AC7AE700062CA31 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B2537592A11BE7300610219; - remoteInfo = NetworkProtectionSystemExtension; - }; 7B4CE8DF26F02108009134B1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; @@ -3692,6 +3702,13 @@ remoteGlobalIDString = 31929F7B2A4C4CFF0084EA89; remoteInfo = "DuckDuckGo DBP"; }; + 7BEC18302AD5DA3300D30536 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B2537592A11BE7300610219; + remoteInfo = NetworkProtectionSystemExtension; + }; AA585D91248FD31400E9A3E2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; @@ -3722,75 +3739,36 @@ dstPath = Contents/Library/LoginItems; dstSubfolderSpec = 1; files = ( - 3192A2612A4C4CFF0084EA89 /* DuckDuckGo Agent.app in Embed Login Items */, + 3192A2612A4C4CFF0084EA89 /* DuckDuckGo VPN.app in Embed Login Items */, 3192A2622A4C4CFF0084EA89 /* DuckDuckGo Notifications.app in Embed Login Items */, ); name = "Embed Login Items"; runOnlyForDeploymentPostprocessing = 0; }; - 3192A2632A4C4CFF0084EA89 /* Embed NetP Controller Apps */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 7; - files = ( - 3192A2642A4C4CFF0084EA89 /* enableOnDemand.app in Embed NetP Controller Apps */, - 3192A2652A4C4CFF0084EA89 /* stopVPN.app in Embed NetP Controller Apps */, - 3192A2662A4C4CFF0084EA89 /* startVPN.app in Embed NetP Controller Apps */, - ); - name = "Embed NetP Controller Apps"; - runOnlyForDeploymentPostprocessing = 0; - }; 4B2D065D2A11D2AE00DE1F49 /* Embed Login Items */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = Contents/Library/LoginItems; dstSubfolderSpec = 1; files = ( - 4B2D065F2A11D2D700DE1F49 /* DuckDuckGo Agent.app in Embed Login Items */, + 4B2D065F2A11D2D700DE1F49 /* DuckDuckGo VPN.app in Embed Login Items */, 4B2D065E2A11D2D700DE1F49 /* DuckDuckGo Notifications.app in Embed Login Items */, ); name = "Embed Login Items"; runOnlyForDeploymentPostprocessing = 0; }; - 4B5F14F32A14823D0060320F /* Embed NetP Controller Apps */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 7; - files = ( - 7B736E6A2A4A22FC00F9922A /* enableOnDemand.app in Embed NetP Controller Apps */, - 4B5F14F52A1482530060320F /* stopVPN.app in Embed NetP Controller Apps */, - 4B5F14F42A14824F0060320F /* startVPN.app in Embed NetP Controller Apps */, - ); - name = "Embed NetP Controller Apps"; - runOnlyForDeploymentPostprocessing = 0; - }; 4B957C332AC7AE700062CA31 /* Embed Login Items */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = Contents/Library/LoginItems; dstSubfolderSpec = 1; files = ( - 4B957C342AC7AE700062CA31 /* DuckDuckGo Agent.app in Embed Login Items */, + 4B957C342AC7AE700062CA31 /* DuckDuckGo VPN.app in Embed Login Items */, 4B957C352AC7AE700062CA31 /* DuckDuckGo Notifications.app in Embed Login Items */, ); name = "Embed Login Items"; runOnlyForDeploymentPostprocessing = 0; }; - 4B957C362AC7AE700062CA31 /* Embed NetP Controller Apps */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 7; - files = ( - 4B957C372AC7AE700062CA31 /* enableOnDemand.app in Embed NetP Controller Apps */, - 4B957C382AC7AE700062CA31 /* stopVPN.app in Embed NetP Controller Apps */, - 4B957C392AC7AE700062CA31 /* startVPN.app in Embed NetP Controller Apps */, - ); - name = "Embed NetP Controller Apps"; - runOnlyForDeploymentPostprocessing = 0; - }; B6EC37E629B5DA2A001ACE79 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -4017,9 +3995,6 @@ 4B11060925903EAC0039B979 /* CoreDataEncryptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataEncryptionTests.swift; sourceTree = ""; }; 4B117F7C276C0CB5002F3D8C /* LocalStatisticsStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalStatisticsStoreTests.swift; sourceTree = ""; }; 4B139AFC26B60BD800894F82 /* NSImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImageExtensions.swift; sourceTree = ""; }; - 4B18E3232A1D32B1005D0AAA /* NetworkProtectionStartVPN.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = NetworkProtectionStartVPN.xcconfig; path = Configuration/App/NetworkProtection/NetworkProtectionStartVPN.xcconfig; sourceTree = SOURCE_ROOT; }; - 4B18E3252A1D3581005D0AAA /* NetworkProtectionStopVPN.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = NetworkProtectionStopVPN.xcconfig; path = Configuration/App/NetworkProtection/NetworkProtectionStopVPN.xcconfig; sourceTree = SOURCE_ROOT; }; - 4B18E3272A1D3896005D0AAA /* NetworkProtectionVPNHelpersBase.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetworkProtectionVPNHelpersBase.xcconfig; sourceTree = ""; }; 4B1AD89D25FC27E200261379 /* Integration Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Integration Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 4B1AD8A125FC27E200261379 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4B1AD91625FC46FB00261379 /* CoreDataEncryptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataEncryptionTests.swift; sourceTree = ""; }; @@ -4027,24 +4002,16 @@ 4B1E6EEC27AB5E5100F51793 /* PasswordManagementListSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordManagementListSection.swift; sourceTree = ""; }; 4B1E6EEF27AB5E5D00F51793 /* NSPopUpButtonView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSPopUpButtonView.swift; sourceTree = ""; }; 4B1E6EF027AB5E5D00F51793 /* PasswordManagementItemList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordManagementItemList.swift; sourceTree = ""; }; - 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.browser.debug.network-protection-extension.systemextension */ = {isa = PBXFileReference; explicitFileType = "wrapper.system-extension"; includeInIndex = 0; path = "com.duckduckgo.macos.browser.debug.network-protection-extension.systemextension"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.vpn.network-extension.debug.systemextension */ = {isa = PBXFileReference; explicitFileType = "wrapper.system-extension"; includeInIndex = 0; path = "com.duckduckgo.macos.vpn.network-extension.debug.systemextension"; sourceTree = BUILT_PRODUCTS_DIR; }; 4B25376C2A11BF6D00610219 /* NetworkProtectionSystemExtension_Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = NetworkProtectionSystemExtension_Release.entitlements; sourceTree = ""; }; 4B25376D2A11BF6D00610219 /* NetworkProtectionSystemExtension_Debug.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = NetworkProtectionSystemExtension_Debug.entitlements; sourceTree = ""; }; 4B25376E2A11BF8B00610219 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4B25376F2A11BF8B00610219 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 4B29759628281F0900187C4E /* FirefoxEncryptionKeyReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirefoxEncryptionKeyReader.swift; sourceTree = ""; }; 4B2975982828285900187C4E /* FirefoxKeyReaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirefoxKeyReaderTests.swift; sourceTree = ""; }; - 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo Agent.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DuckDuckGo Agent.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B2D06442A11CFBE00DE1F49 /* DuckDuckGoAgent.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DuckDuckGoAgent.entitlements; sourceTree = ""; }; - 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DuckDuckGoAgent.xcconfig; sourceTree = ""; }; - 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DuckDuckGoAgentAppStore.xcconfig; sourceTree = ""; }; - 4B2D06502A11D19B00DE1F49 /* Info-AppStore.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-AppStore.plist"; sourceTree = ""; }; - 4B2D06512A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DuckDuckGoAgentAppDelegate.swift; sourceTree = ""; }; - 4B2D06522A11D19B00DE1F49 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 4B2D06532A11D19B00DE1F49 /* DuckDuckGoAgentAppStore.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = DuckDuckGoAgentAppStore.entitlements; sourceTree = ""; }; - 4B2D06542A11D19B00DE1F49 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo VPN.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DuckDuckGo VPN.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 4B2D06642A132F3A00DE1F49 /* NetworkProtectionAppExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetworkProtectionAppExtension.entitlements; sourceTree = ""; }; - 4B2D06692A13318400DE1F49 /* DuckDuckGo Agent App Store.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DuckDuckGo Agent App Store.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B2D06692A13318400DE1F49 /* DuckDuckGo VPN App Store.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DuckDuckGo VPN App Store.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 4B2E7D6226FF9D6500D2DB17 /* PrintingUserScript.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrintingUserScript.swift; sourceTree = ""; }; 4B379C1427BD91E3008A968E /* QuartzIdleStateProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuartzIdleStateProvider.swift; sourceTree = ""; }; 4B379C1D27BDB7FF008A968E /* DeviceAuthenticator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceAuthenticator.swift; sourceTree = ""; }; @@ -4069,7 +4036,6 @@ 4B4D60512A0B293C00BCD287 /* ExtensionBase.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ExtensionBase.xcconfig; sourceTree = ""; }; 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionBundle.swift; sourceTree = ""; }; 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionOptionKeyExtension.swift; sourceTree = ""; }; - 4B4D60622A0B29FA00BCD287 /* SystemExtensionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemExtensionManager.swift; sourceTree = ""; }; 4B4D60652A0B29FA00BCD287 /* NetworkProtectionNavBarButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionNavBarButtonModel.swift; sourceTree = ""; }; 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkProtection+ConvenienceInitializers.swift"; sourceTree = ""; }; 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionControllerErrorStore.swift; sourceTree = ""; }; @@ -4080,7 +4046,6 @@ 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionUNNotificationsPresenter.swift; sourceTree = ""; }; 4B4D60782A0B29FA00BCD287 /* NetworkProtectionExtensionMachService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionExtensionMachService.swift; sourceTree = ""; }; 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserText+NetworkProtectionExtensions.swift"; sourceTree = ""; }; - 4B4D60832A0B29FA00BCD287 /* NetworkProtectionPixelEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionPixelEvent.swift; sourceTree = ""; }; 4B4D609C2A0B2C2300BCD287 /* DuckDuckGo_NetP_Release.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DuckDuckGo_NetP_Release.entitlements; sourceTree = ""; }; 4B4D609E2A0B2C2300BCD287 /* DuckDuckGo_NetP_Debug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DuckDuckGo_NetP_Debug.entitlements; sourceTree = ""; }; 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserText+NetworkProtection.swift"; sourceTree = ""; }; @@ -4096,9 +4061,6 @@ 4B59CC8B290083240058F2F6 /* ConnectBitwardenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectBitwardenViewModelTests.swift; sourceTree = ""; }; 4B5A4F4B27F3A5AA008FBD88 /* NSNotificationName+DataImport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSNotificationName+DataImport.swift"; sourceTree = ""; }; 4B5F14C42A145D6A0060320F /* NetworkProtectionVPNController.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetworkProtectionVPNController.entitlements; sourceTree = ""; }; - 4B5F14C52A145D6A0060320F /* Main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Main.swift; sourceTree = ""; }; - 4B5F14CB2A14702C0060320F /* startVPN.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = startVPN.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B5F14E12A1476BD0060320F /* stopVPN.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = stopVPN.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5F14F82A148B230060320F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4B5F15032A1570F10060320F /* DuckDuckGoDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DuckDuckGoDebug.entitlements; sourceTree = ""; }; 4B5FF67726B602B100D42879 /* FirefoxDataImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirefoxDataImporter.swift; sourceTree = ""; }; @@ -4280,6 +4242,8 @@ 4BE6547D271FCD4D008D1D63 /* PasswordManagementNoteModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordManagementNoteModel.swift; sourceTree = ""; }; 4BE65482271FCD53008D1D63 /* CountryList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryList.swift; sourceTree = ""; }; 4BE65484271FCD7B008D1D63 /* LoginFaviconView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginFaviconView.swift; sourceTree = ""; }; + 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionPixelEvent.swift; sourceTree = ""; }; + 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DuckDuckGoUserAgent.swift; sourceTree = ""; }; 4BF4951726C08395000547B8 /* ThirdPartyBrowserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartyBrowserTests.swift; sourceTree = ""; }; 4BF4EA4F27C71F26004E57C4 /* PasswordManagementListSectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordManagementListSectionTests.swift; sourceTree = ""; }; 4BF6961C28BE911100D402D4 /* RecentlyVisitedSiteModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentlyVisitedSiteModelTests.swift; sourceTree = ""; }; @@ -4306,33 +4270,45 @@ 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentOverlayViewController.swift; sourceTree = ""; }; 7B25FE322AD12C990012AFAB /* NetworkProtectionMac */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = NetworkProtectionMac; 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 = ""; }; + 7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionNavBarPopoverManager.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; }; 7B4CE8DE26F02108009134B1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7B4CE8E626F02134009134B1 /* TabBarTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarTests.swift; sourceTree = ""; }; 7B5291882A1697680022E406 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7B5291892A169BC90022E406 /* NetworkProtectionDeveloperID.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetworkProtectionDeveloperID.xcconfig; sourceTree = ""; }; - 7B736E5F2A4A22B700F9922A /* enableOnDemand.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = enableOnDemand.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B76E6852AD5D77600186A84 /* XPCHelper */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = XPCHelper; sourceTree = ""; }; 7B934C3D2A866CFF00FC8F9C /* NetworkProtectionOnboardingMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionOnboardingMenu.swift; sourceTree = ""; }; 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserDefaults+NetworkProtectionShared.swift"; sourceTree = ""; }; - 7B9459632A4A5BAF0012535A /* NetworkProtectionEnableOnDemand.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetworkProtectionEnableOnDemand.xcconfig; sourceTree = ""; }; 7B96D0CF2ADFDA7E007E02C8 /* DuckDuckGoDBPTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DuckDuckGoDBPTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 7B96D0DB2ADFDB8E007E02C8 /* DataBrokerProtectionPixelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionPixelTests.swift; sourceTree = ""; }; + 7BA7CC0B2AD11D1E0042E5CE /* DuckDuckGoVPNAppStore.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DuckDuckGoVPNAppStore.xcconfig; sourceTree = ""; }; + 7BA7CC0C2AD11D1E0042E5CE /* DuckDuckGoVPN.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DuckDuckGoVPN.xcconfig; sourceTree = ""; }; + 7BA7CC0E2AD11DC80042E5CE /* DuckDuckGoVPNAppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DuckDuckGoVPNAppDelegate.swift; sourceTree = ""; }; + 7BA7CC0F2AD11DC80042E5CE /* Bundle+Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bundle+Configuration.swift"; sourceTree = ""; }; + 7BA7CC102AD11DC80042E5CE /* Info-AppStore.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-AppStore.plist"; sourceTree = ""; }; + 7BA7CC112AD11DC80042E5CE /* TunnelControllerIPCService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelControllerIPCService.swift; sourceTree = ""; }; + 7BA7CC122AD11DC80042E5CE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7BA7CC132AD11DC80042E5CE /* AppLauncher+DefaultInitializer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AppLauncher+DefaultInitializer.swift"; sourceTree = ""; }; + 7BA7CC142AD11DC80042E5CE /* DuckDuckGoVPNAppStore.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = DuckDuckGoVPNAppStore.entitlements; sourceTree = ""; }; + 7BA7CC152AD11DC80042E5CE /* NetworkProtectionBouncer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionBouncer.swift; sourceTree = ""; }; + 7BA7CC162AD11DC80042E5CE /* DuckDuckGoVPN.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = DuckDuckGoVPN.entitlements; sourceTree = ""; }; + 7BA7CC172AD11DC80042E5CE /* UserText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserText.swift; sourceTree = ""; }; + 7BA7CC182AD11DC80042E5CE /* DuckDuckGoVPNDebug.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = DuckDuckGoVPNDebug.entitlements; sourceTree = ""; }; + 7BA7CC1A2AD11DC80042E5CE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7BA7CC4D2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionIPCTunnelController.swift; sourceTree = ""; }; 7BB108572A43375D000AB95F /* PFMoveApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PFMoveApplication.h; sourceTree = ""; }; 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 = ""; }; - 7BC185EA2AD6CB4900F9D9DC /* XPC */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = XPC; sourceTree = ""; }; + 7BD1688D2AD4A4C400D24876 /* NetworkExtensionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkExtensionController.swift; sourceTree = ""; }; 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeychainType+ClientDefault.swift"; sourceTree = ""; }; 7BD8679A2A9E9E000063B9F7 /* NetworkProtectionFeatureVisibility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionFeatureVisibility.swift; sourceTree = ""; }; 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionDebugMenu.swift; sourceTree = ""; }; - 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift; sourceTree = ""; }; + 7BEC182D2AD5D89C00D30536 /* SystemExtensionManager */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = SystemExtensionManager; sourceTree = ""; }; 7BF1A9D72AE054D300FCA683 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7BF1A9DB2AE0551C00FCA683 /* DBPUnitTests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DBPUnitTests.xcconfig; sourceTree = ""; }; + 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift; sourceTree = ""; }; 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserDefaults+NetworkProtectionWaitlist.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 = ""; }; @@ -4906,10 +4882,10 @@ files = ( 3192A2062A4C4CFF0084EA89 /* QuickLookUI.framework in Frameworks */, 3192A2072A4C4CFF0084EA89 /* BrowserServicesKit in Frameworks */, - 7BF770632AD6CA0E001C9182 /* PixelKit in Frameworks */, 3192A2082A4C4CFF0084EA89 /* Bookmarks in Frameworks */, 3192A2092A4C4CFF0084EA89 /* ContentBlocking in Frameworks */, 3192A20A2A4C4CFF0084EA89 /* SwiftUIExtensions in Frameworks */, + 7B31FD8E2AD125760086AA24 /* NetworkProtectionIPC in Frameworks */, 3192A20B2A4C4CFF0084EA89 /* UserScript in Frameworks */, 3192A20C2A4C4CFF0084EA89 /* TrackerRadarKit in Frameworks */, 3192A20D2A4C4CFF0084EA89 /* Configuration in Frameworks */, @@ -4933,7 +4909,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7BF770612AD6CA06001C9182 /* PixelKit in Frameworks */, + 7B5F9A752AE2BE4E002AEBC0 /* PixelKit in Frameworks */, B6F7128229F6820A00594A45 /* QuickLookUI.framework in Frameworks */, 984FD3BF299ACF35007334DD /* Bookmarks in Frameworks */, 37A5E2F0298AA1B20047046B /* Persistence in Frameworks */, @@ -4995,8 +4971,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 7BEEA5122AD1235B00A9E72B /* NetworkProtectionIPC in Frameworks */, + 7BA7CC5F2AD1210C0042E5CE /* Networking in Frameworks */, + 7BEEA5162AD1236E00A9E72B /* NetworkProtectionUI in Frameworks */, + 7BFCB74E2ADE7E1A00DA3EA7 /* PixelKit in Frameworks */, EE7295ED2A545C0A008C0991 /* NetworkProtection in Frameworks */, - 4B2D064F2A11D0D000DE1F49 /* NetworkProtectionUI in Frameworks */, + 7B31FD882AD124620086AA24 /* (null) in Frameworks */, + 7BEC182F2AD5D8DC00D30536 /* SystemExtensionManager in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5004,8 +4985,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 7BFCB7502ADE7E2300DA3EA7 /* PixelKit in Frameworks */, + 7BA7CC612AD1211C0042E5CE /* Networking in Frameworks */, + 7BEEA5142AD1236300A9E72B /* NetworkProtectionIPC in Frameworks */, EE7295EF2A545C12008C0991 /* NetworkProtection in Frameworks */, 4B2D067F2A1334D700DE1F49 /* NetworkProtectionUI in Frameworks */, + 7B31FD8A2AD124680086AA24 /* (null) in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5029,20 +5014,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4B5F14C82A14702C0060320F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4B5F14DE2A1476BC0060320F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 4B957BD42AC7AE700062CA31 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -5056,6 +5027,8 @@ 4B957BDB2AC7AE700062CA31 /* ContentBlocking in Frameworks */, 4B957BDC2AC7AE700062CA31 /* SwiftUIExtensions in Frameworks */, 4B957BDD2AC7AE700062CA31 /* UserScript in Frameworks */, + 7BBD44282AD730A400D0A064 /* PixelKit in Frameworks */, + 7B31FD902AD1257B0086AA24 /* NetworkProtectionIPC in Frameworks */, 4B957BDE2AC7AE700062CA31 /* Configuration in Frameworks */, 4B957BDF2AC7AE700062CA31 /* Purchase in Frameworks */, 4B957BE02AC7AE700062CA31 /* Lottie in Frameworks */, @@ -5065,7 +5038,6 @@ 4B957BE42AC7AE700062CA31 /* DDGSync in Frameworks */, 4B957BE52AC7AE700062CA31 /* OpenSSL in Frameworks */, 4B957BE62AC7AE700062CA31 /* PrivacyDashboard in Frameworks */, - 7BF770652AD6CA14001C9182 /* PixelKit in Frameworks */, 4B957BE72AC7AE700062CA31 /* SyncDataProviders in Frameworks */, 4B957BE82AC7AE700062CA31 /* SyncUI in Frameworks */, 4B957BE92AC7AE700062CA31 /* NetworkProtectionUI in Frameworks */, @@ -5081,13 +5053,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7B736E592A4A22B700F9922A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 7B96D0CC2ADFDA7E007E02C8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -5110,14 +5075,17 @@ 378F44E429B4BDE900899924 /* SwiftUIExtensions in Frameworks */, 1E950E432912A10D0051A99B /* UserScript in Frameworks */, CBC83E3629B63D380008E19C /* Configuration in Frameworks */, + 7B31FD8C2AD125620086AA24 /* NetworkProtectionIPC in Frameworks */, 1E3ED4FD2AC1E0290075F60F /* Purchase in Frameworks */, 4B2AAAF529E70DEA0026AFC0 /* Lottie in Frameworks */, AA06B6B72672AF8100F541C5 /* Sparkle in Frameworks */, 7BF7705F2AD6C999001C9182 /* PixelKit in Frameworks */, B6B77BE8297973D4001E68A1 /* Navigation in Frameworks */, 3739326729AE4B42009346AE /* DDGSync in Frameworks */, + 7BA59C9B2AE18B49009A97B1 /* SystemExtensionManager in Frameworks */, 371D00E129D8509400EC8598 /* OpenSSL in Frameworks */, 1E950E412912A10D0051A99B /* PrivacyDashboard in Frameworks */, + 4BF0E50E2AD2555D00FFEC9E /* (null) in Frameworks */, 37DF000529F9C056002B7D3E /* SyncDataProviders in Frameworks */, 37BA812D29B3CD690053F1A3 /* SyncUI in Frameworks */, 4B4D60B12A0C83B900BCD287 /* NetworkProtectionUI in Frameworks */, @@ -5505,7 +5473,8 @@ 378F44E229B4B7B600899924 /* SwiftUIExtensions */, 37BA812B29B3CB8A0053F1A3 /* SyncUI */, 1E862A882A9FC01200F84D4B /* Subscription */, - 7BC185EA2AD6CB4900F9D9DC /* XPC */, + 7BEC182D2AD5D89C00D30536 /* SystemExtensionManager */, + 7B76E6852AD5D77600186A84 /* XPCHelper */, ); path = LocalPackages; sourceTree = ""; @@ -5661,13 +5630,9 @@ 4B18E3222A1D31E4005D0AAA /* NetworkProtection */ = { isa = PBXGroup; children = ( - 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */, - 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */, 4B4BEC182A11B3EA001D9AC5 /* DuckDuckGoNotifications.xcconfig */, - 7B9459632A4A5BAF0012535A /* NetworkProtectionEnableOnDemand.xcconfig */, - 4B18E3272A1D3896005D0AAA /* NetworkProtectionVPNHelpersBase.xcconfig */, - 4B18E3232A1D32B1005D0AAA /* NetworkProtectionStartVPN.xcconfig */, - 4B18E3252A1D3581005D0AAA /* NetworkProtectionStopVPN.xcconfig */, + 7BA7CC0C2AD11D1E0042E5CE /* DuckDuckGoVPN.xcconfig */, + 7BA7CC0B2AD11D1E0042E5CE /* DuckDuckGoVPNAppStore.xcconfig */, ); path = NetworkProtection; sourceTree = ""; @@ -5711,23 +5676,6 @@ path = NetworkProtectionSystemExtension; sourceTree = ""; }; - 4B2D063A2A11CFBD00DE1F49 /* DuckDuckGoAgent */ = { - 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 */, - 4B2D06502A11D19B00DE1F49 /* Info-AppStore.plist */, - 4B2D06542A11D19B00DE1F49 /* Info.plist */, - ); - path = DuckDuckGoAgent; - sourceTree = ""; - }; 4B379C1C27BDB7EA008A968E /* DeviceAuthentication */ = { isa = PBXGroup; children = ( @@ -5819,7 +5767,7 @@ isa = PBXGroup; children = ( 4BCF15D52ABB83D70083F6DF /* NetworkProtectionRemoteMessaging */, - 4B4D60622A0B29FA00BCD287 /* SystemExtensionManager.swift */, + 7BA7CC4D2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift */, ); path = DeveloperIDTarget; sourceTree = ""; @@ -5836,6 +5784,7 @@ 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */, B602E81C2A1E25B0006D261F /* NEOnDemandRuleExtension.swift */, 4B4D60652A0B29FA00BCD287 /* NetworkProtectionNavBarButtonModel.swift */, + 7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */, 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */, 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */, 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */, @@ -5896,7 +5845,6 @@ 4B4D607D2A0B29FA00BCD287 /* NetworkExtensionTargets */ = { isa = PBXGroup; children = ( - 4B4D60832A0B29FA00BCD287 /* NetworkProtectionPixelEvent.swift */, EEF12E6D2A2111880023E6BF /* MacPacketTunnelProvider.swift */, ); path = NetworkExtensionTargets; @@ -5923,14 +5871,6 @@ path = Bitwarden; sourceTree = ""; }; - 4B5F14C32A145D6A0060320F /* NetworkProtectionVPNController */ = { - isa = PBXGroup; - children = ( - 4B5F14C52A145D6A0060320F /* Main.swift */, - ); - path = NetworkProtectionVPNController; - sourceTree = ""; - }; 4B5F14F72A148B230060320F /* NetworkProtectionAppExtension */ = { isa = PBXGroup; children = ( @@ -6505,6 +6445,26 @@ path = DuckDuckGoDBPTests; sourceTree = ""; }; + 7BA7CC0D2AD11DC80042E5CE /* DuckDuckGoVPN */ = { + isa = PBXGroup; + children = ( + 7BA7CC132AD11DC80042E5CE /* AppLauncher+DefaultInitializer.swift */, + 7BA7CC0F2AD11DC80042E5CE /* Bundle+Configuration.swift */, + 7BA7CC0E2AD11DC80042E5CE /* DuckDuckGoVPNAppDelegate.swift */, + 7BD1688D2AD4A4C400D24876 /* NetworkExtensionController.swift */, + 7BA7CC152AD11DC80042E5CE /* NetworkProtectionBouncer.swift */, + 7BA7CC112AD11DC80042E5CE /* TunnelControllerIPCService.swift */, + 7BA7CC172AD11DC80042E5CE /* UserText.swift */, + 7BA7CC122AD11DC80042E5CE /* Assets.xcassets */, + 7BA7CC162AD11DC80042E5CE /* DuckDuckGoVPN.entitlements */, + 7BA7CC182AD11DC80042E5CE /* DuckDuckGoVPNDebug.entitlements */, + 7BA7CC142AD11DC80042E5CE /* DuckDuckGoVPNAppStore.entitlements */, + 7BA7CC1A2AD11DC80042E5CE /* Info.plist */, + 7BA7CC102AD11DC80042E5CE /* Info-AppStore.plist */, + ); + path = DuckDuckGoVPN; + sourceTree = ""; + }; 7BB108552A43375D000AB95F /* LocalThirdParty */ = { isa = PBXGroup; children = ( @@ -6909,6 +6869,7 @@ isa = PBXGroup; children = ( 14505A07256084EF00272CC6 /* UserAgent.swift */, + 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */, ); path = Model; sourceTree = ""; @@ -6983,8 +6944,7 @@ 7B96D0D02ADFDA7F007E02C8 /* DuckDuckGoDBPTests */, 4B5F14F72A148B230060320F /* NetworkProtectionAppExtension */, 4B25375C2A11BE7500610219 /* NetworkProtectionSystemExtension */, - 4B5F14C32A145D6A0060320F /* NetworkProtectionVPNController */, - 4B2D063A2A11CFBD00DE1F49 /* DuckDuckGoAgent */, + 7BA7CC0D2AD11DC80042E5CE /* DuckDuckGoVPN */, AA585D7F248FD31100E9A3E2 /* Products */, 85AE2FF024A33A2D002D507F /* Frameworks */, ); @@ -7003,12 +6963,9 @@ B6EC37E829B5DA2A001ACE79 /* tests-server */, 4B4D603D2A0B290200BCD287 /* NetworkProtectionAppExtension.appex */, 4B4BEC202A11B4E2001D9AC5 /* DuckDuckGo Notifications.app */, - 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.browser.debug.network-protection-extension.systemextension */, - 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo Agent.app */, - 4B2D06692A13318400DE1F49 /* DuckDuckGo Agent App Store.app */, - 4B5F14CB2A14702C0060320F /* startVPN.app */, - 4B5F14E12A1476BD0060320F /* stopVPN.app */, - 7B736E5F2A4A22B700F9922A /* enableOnDemand.app */, + 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.vpn.network-extension.debug.systemextension */, + 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo VPN.app */, + 4B2D06692A13318400DE1F49 /* DuckDuckGo VPN App Store.app */, 3192A26E2A4C4CFF0084EA89 /* DuckDuckGoDBP.app */, 4B957C412AC7AE700062CA31 /* DuckDuckGo Privacy Pro.app */, 7B96D0CF2ADFDA7E007E02C8 /* DuckDuckGoDBPTests.xctest */, @@ -8512,6 +8469,7 @@ isa = PBXGroup; children = ( EEAD7A6E2A1D3E1F002A24E7 /* AppLauncher.swift */, + 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */, B6F92BA42A691A44002ABA6B /* NetworkProtectionUserDefaultsConstants.swift */, 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */, 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */, @@ -8541,15 +8499,12 @@ 3192A2052A4C4CFF0084EA89 /* Frameworks */, 3192A2192A4C4CFF0084EA89 /* Resources */, 3192A2602A4C4CFF0084EA89 /* Embed Login Items */, - 3192A2632A4C4CFF0084EA89 /* Embed NetP Controller Apps */, - 3192A2672A4C4CFF0084EA89 /* Replace VPN Controllers with Symlinks */, - 3192A2682A4C4CFF0084EA89 /* Embed System Network Extension */, + 7B31FD932AD126E50086AA24 /* Embed System Network Extension */, ); buildRules = ( ); dependencies = ( 31929F7C2A4C4CFF0084EA89 /* PBXTargetDependency */, - 31929F7D2A4C4CFF0084EA89 /* PBXTargetDependency */, ); name = "DuckDuckGo DBP"; packageProductDependencies = ( @@ -8573,7 +8528,7 @@ 31929F952A4C4CFF0084EA89 /* NetworkProtectionUI */, 31A93F502A5D8AF0008BB88D /* DataBrokerProtection */, 9DB6E7252AA0DC6600A17F3C /* LoginItems */, - 7BF770622AD6CA0E001C9182 /* PixelKit */, + 7B31FD8D2AD125760086AA24 /* NetworkProtectionIPC */, ); productName = DuckDuckGo; productReference = 3192A26E2A4C4CFF0084EA89 /* DuckDuckGoDBP.app */; @@ -8614,7 +8569,7 @@ B6EC37FE29B8D915001ACE79 /* Configuration */, 37DF000629F9C061002B7D3E /* SyncDataProviders */, 9DC70B192AA1FA5B005A844B /* LoginItems */, - 7BF770602AD6CA06001C9182 /* PixelKit */, + 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */, ); productName = DuckDuckGo; productReference = 3706FD05293F65D500E42796 /* DuckDuckGo App Store.app */; @@ -8704,34 +8659,40 @@ EE7295E82A545BC4008C0991 /* NetworkProtection */, ); productName = NetworkProtectionSystemExtension; - productReference = 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.browser.debug.network-protection-extension.systemextension */; + productReference = 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.vpn.network-extension.debug.systemextension */; productType = "com.apple.product-type.system-extension"; }; - 4B2D06382A11CFBA00DE1F49 /* DuckDuckGoAgent */ = { + 4B2D06382A11CFBA00DE1F49 /* DuckDuckGoVPN */ = { isa = PBXNativeTarget; - buildConfigurationList = 4B2D06452A11CFBE00DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoAgent" */; + buildConfigurationList = 4B2D06452A11CFBE00DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoVPN" */; buildPhases = ( 4B2D06352A11CFBA00DE1F49 /* Sources */, 4B2D06362A11CFBA00DE1F49 /* Frameworks */, 4B2D06372A11CFBA00DE1F49 /* Resources */, 4B2D065C2A11D23600DE1F49 /* Copy Assets */, + 7B31FD922AD126C40086AA24 /* Embed System Network Extension */, ); buildRules = ( ); dependencies = ( + 7BEC18312AD5DA3300D30536 /* PBXTargetDependency */, ); - name = DuckDuckGoAgent; + name = DuckDuckGoVPN; packageProductDependencies = ( - 4B2D064E2A11D0D000DE1F49 /* NetworkProtectionUI */, EE7295EC2A545C0A008C0991 /* NetworkProtection */, + 7BA7CC5E2AD1210C0042E5CE /* Networking */, + 7BEEA5112AD1235B00A9E72B /* NetworkProtectionIPC */, + 7BEEA5152AD1236E00A9E72B /* NetworkProtectionUI */, + 7BEC182E2AD5D8DC00D30536 /* SystemExtensionManager */, + 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */, ); productName = DuckDuckGoAgent; - productReference = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo Agent.app */; + productReference = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo VPN.app */; productType = "com.apple.product-type.application"; }; - 4B2D06682A13318400DE1F49 /* DuckDuckGoAgentAppStore */ = { + 4B2D06682A13318400DE1F49 /* DuckDuckGoVPNAppStore */ = { isa = PBXNativeTarget; - buildConfigurationList = 4B2D06752A13318600DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoAgentAppStore" */; + buildConfigurationList = 4B2D06752A13318600DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoVPNAppStore" */; buildPhases = ( 4B2D06652A13318400DE1F49 /* Sources */, 4B2D06662A13318400DE1F49 /* Frameworks */, @@ -8742,13 +8703,16 @@ ); dependencies = ( ); - name = DuckDuckGoAgentAppStore; + name = DuckDuckGoVPNAppStore; packageProductDependencies = ( 4B2D067E2A1334D700DE1F49 /* NetworkProtectionUI */, EE7295EE2A545C12008C0991 /* NetworkProtection */, + 7BA7CC602AD1211C0042E5CE /* Networking */, + 7BEEA5132AD1236300A9E72B /* NetworkProtectionIPC */, + 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */, ); productName = DuckDuckGoAgentAppStore; - productReference = 4B2D06692A13318400DE1F49 /* DuckDuckGo Agent App Store.app */; + productReference = 4B2D06692A13318400DE1F49 /* DuckDuckGo VPN App Store.app */; productType = "com.apple.product-type.application"; }; 4B4BEC1F2A11B4E2001D9AC5 /* DuckDuckGoNotifications */ = { @@ -8795,38 +8759,6 @@ productReference = 4B4D603D2A0B290200BCD287 /* NetworkProtectionAppExtension.appex */; productType = "com.apple.product-type.app-extension"; }; - 4B5F14CA2A14702C0060320F /* startVPN */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4B5F14D72A14702E0060320F /* Build configuration list for PBXNativeTarget "startVPN" */; - buildPhases = ( - 4B5F14C72A14702C0060320F /* Sources */, - 4B5F14C82A14702C0060320F /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = startVPN; - productName = startVPN; - productReference = 4B5F14CB2A14702C0060320F /* startVPN.app */; - productType = "com.apple.product-type.application"; - }; - 4B5F14E02A1476BC0060320F /* stopVPN */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4B5F14ED2A1476C20060320F /* Build configuration list for PBXNativeTarget "stopVPN" */; - buildPhases = ( - 4B5F14DD2A1476BC0060320F /* Sources */, - 4B5F14DE2A1476BC0060320F /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = stopVPN; - productName = stopVPN; - productReference = 4B5F14E12A1476BD0060320F /* stopVPN.app */; - productType = "com.apple.product-type.application"; - }; 4B9579252AC7AE700062CA31 /* DuckDuckGo Privacy Pro */ = { isa = PBXNativeTarget; buildConfigurationList = 4B957C3C2AC7AE700062CA31 /* Build configuration list for PBXNativeTarget "DuckDuckGo Privacy Pro" */; @@ -8839,15 +8771,12 @@ 4B957BEC2AC7AE700062CA31 /* Resources */, 4B957C322AC7AE700062CA31 /* Make /Applications symlink, remove app on Clean build */, 4B957C332AC7AE700062CA31 /* Embed Login Items */, - 4B957C362AC7AE700062CA31 /* Embed NetP Controller Apps */, - 4B957C3A2AC7AE700062CA31 /* Replace VPN Controllers with Symlinks */, - 4B957C3B2AC7AE700062CA31 /* Embed System Network Extension */, + 7B31FD942AD126FA0086AA24 /* Embed System Network Extension */, ); buildRules = ( ); dependencies = ( 4B9579262AC7AE700062CA31 /* PBXTargetDependency */, - 4B9579272AC7AE700062CA31 /* PBXTargetDependency */, ); name = "DuckDuckGo Privacy Pro"; packageProductDependencies = ( @@ -8873,7 +8802,7 @@ 4B9579402AC7AE700062CA31 /* Subscription */, 4B9579412AC7AE700062CA31 /* Account */, 4B9579422AC7AE700062CA31 /* Purchase */, - 7BF770642AD6CA14001C9182 /* PixelKit */, + 7B31FD8F2AD1257B0086AA24 /* NetworkProtectionIPC */, ); productName = DuckDuckGo; productReference = 4B957C412AC7AE700062CA31 /* DuckDuckGo Privacy Pro.app */; @@ -8897,22 +8826,6 @@ productReference = 7B4CE8DA26F02108009134B1 /* UI Tests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; - 7B736E562A4A22B700F9922A /* enableOnDemand */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7B736E5A2A4A22B700F9922A /* Build configuration list for PBXNativeTarget "enableOnDemand" */; - buildPhases = ( - 7B736E572A4A22B700F9922A /* Sources */, - 7B736E592A4A22B700F9922A /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = enableOnDemand; - productName = stopVPN; - productReference = 7B736E5F2A4A22B700F9922A /* enableOnDemand.app */; - productType = "com.apple.product-type.application"; - }; 7B96D0CE2ADFDA7E007E02C8 /* DuckDuckGoDBPTests */ = { isa = PBXNativeTarget; buildConfigurationList = 7B96D0D52ADFDA7F007E02C8 /* Build configuration list for PBXNativeTarget "DuckDuckGoDBPTests" */; @@ -8947,15 +8860,11 @@ AA585D7C248FD31100E9A3E2 /* Resources */, B6F2C8722A7A4C7D000498CF /* Make /Applications symlink, remove app on Clean build */, 4B2D065D2A11D2AE00DE1F49 /* Embed Login Items */, - 4B5F14F32A14823D0060320F /* Embed NetP Controller Apps */, - 4B5F14F62A14825A0060320F /* Replace VPN Controllers with Symlinks */, - 7B6469992A165AE00095095A /* Embed System Network Extension */, ); buildRules = ( ); dependencies = ( 4B5F14FC2A15291D0060320F /* PBXTargetDependency */, - 4B2537642A11BE7600610219 /* PBXTargetDependency */, ); name = "DuckDuckGo Privacy Browser"; packageProductDependencies = ( @@ -8980,7 +8889,9 @@ 9DB6E7232AA0DC5800A17F3C /* LoginItems */, 1EC88CA02AC1DD63003A4471 /* Account */, 1E3ED4FC2AC1E0290075F60F /* Purchase */, + 7B31FD8B2AD125620086AA24 /* NetworkProtectionIPC */, 7BF7705E2AD6C999001C9182 /* PixelKit */, + 7BA59C9A2AE18B49009A97B1 /* SystemExtensionManager */, ); productName = DuckDuckGo; productReference = AA585D7E248FD31100E9A3E2 /* DuckDuckGo.app */; @@ -9065,12 +8976,6 @@ 4B4D603C2A0B290200BCD287 = { CreatedOnToolsVersion = 14.3; }; - 4B5F14CA2A14702C0060320F = { - CreatedOnToolsVersion = 14.3; - }; - 4B5F14E02A1476BC0060320F = { - CreatedOnToolsVersion = 14.3; - }; 7B4CE8D926F02108009134B1 = { CreatedOnToolsVersion = 12.5.1; TestTargetID = AA585D7D248FD31100E9A3E2; @@ -9123,11 +9028,8 @@ 4B4D603C2A0B290200BCD287 /* NetworkProtectionAppExtension */, 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */, 4B4BEC1F2A11B4E2001D9AC5 /* DuckDuckGoNotifications */, - 4B2D06382A11CFBA00DE1F49 /* DuckDuckGoAgent */, - 4B2D06682A13318400DE1F49 /* DuckDuckGoAgentAppStore */, - 4B5F14CA2A14702C0060320F /* startVPN */, - 4B5F14E02A1476BC0060320F /* stopVPN */, - 7B736E562A4A22B700F9922A /* enableOnDemand */, + 4B2D06382A11CFBA00DE1F49 /* DuckDuckGoVPN */, + 4B2D06682A13318400DE1F49 /* DuckDuckGoVPNAppStore */, 31929F7B2A4C4CFF0084EA89 /* DuckDuckGo DBP */, 7B96D0CE2ADFDA7E007E02C8 /* DuckDuckGoDBPTests */, 4B9579252AC7AE700062CA31 /* DuckDuckGo Privacy Pro */, @@ -9319,7 +9221,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B2D06582A11D19B00DE1F49 /* Assets.xcassets in Resources */, + 7BA7CC482AD11E5C0042E5CE /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9327,7 +9229,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7B838C382A1DD8DD00E05A13 /* Assets.xcassets in Resources */, + 7BA7CC472AD11E5C0042E5CE /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9581,44 +9483,6 @@ shellPath = /bin/zsh; shellScript = "./lint.sh\n"; }; - 3192A2672A4C4CFF0084EA89 /* Replace VPN Controllers with Symlinks */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Replace VPN Controllers with Symlinks"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"Replace and Sign\" # for easier build log search\n\n# startVPN\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/startVPN.app/Contents/MacOS\"\nrm ./startVPN\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./startVPN\npopd\n\n# stopVPN\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/stopVPN.app/Contents/MacOS\"\nrm ./stopVPN\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./stopVPN\ncd ../../.. \npopd\n\n# enableOnDemand\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/enableOnDemand.app/Contents/MacOS\"\nrm ./enableOnDemand\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./enableOnDemand\ncd ../../.. \npopd\n"; - }; - 3192A2682A4C4CFF0084EA89 /* Embed System Network Extension */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Embed System Network Extension"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID} $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}\" || exit 1\n"; - }; 3705272528992C8A000C06A2 /* Check Embedded Config URLs */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -9731,25 +9595,6 @@ shellPath = /bin/sh; shellScript = "# We had issues where the Swift Package resources were not being added to the Agent Apps,\n# so we're manually coping them here.\n# It seems to be a known issue: https://forums.swift.org/t/swift-packages-resource-bundle-not-present-in-xcarchive-when-framework-using-said-package-is-archived/50084/2\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/NetworkProtectionMac_NetworkProtectionUI.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; }; - 4B5F14F62A14825A0060320F /* Replace VPN Controllers with Symlinks */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Replace VPN Controllers with Symlinks"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"Replace and Sign\" # for easier build log search\n\n# startVPN\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/startVPN.app/Contents/MacOS\"\nrm ./startVPN\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./startVPN\npopd\n\n# stopVPN\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/stopVPN.app/Contents/MacOS\"\nrm ./stopVPN\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./stopVPN\ncd ../../.. \npopd\n\n# enableOnDemand\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/enableOnDemand.app/Contents/MacOS\"\nrm ./enableOnDemand\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./enableOnDemand\ncd ../../.. \npopd\n"; - }; 4B9579432AC7AE700062CA31 /* Assert Xcode version */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -9826,9 +9671,8 @@ shellPath = /bin/sh; shellScript = "if [[ \"${CONFIGURATION}\" != \"Debug\" ]]; then\n # run only for Debug builds\n exit 0\nfi\n\n# if Xcode created real Applications directory inside BUILT_PRODUCTS_DIR \nif [[ ! -L ${BUILT_PRODUCTS_DIR}/Applications ]]; then\n # we only get here on clean build, remove an existing app in /Applications/DEBUG on clean build\n echo \"rm -rf /${INSTALL_PATH}/${PRODUCT_NAME}.app\"\n rm -rf \"/${INSTALL_PATH}/${PRODUCT_NAME}.app\"\n\n # create /Applications/DEBUG dir\n echo \"mkdir -p /${INSTALL_PATH}\"\n mkdir -p \"/${INSTALL_PATH}\"\n\n # move the app bundle to /Applications/DEBUG\n echo \"mv ${DSTROOT}/${INSTALL_PATH}/${PRODUCT_NAME}.app /${INSTALL_PATH}/${PRODUCT_NAME}.app\"\n mv \"${DSTROOT}/${INSTALL_PATH}/${PRODUCT_NAME}.app\" \"/${INSTALL_PATH}/${PRODUCT_NAME}.app\"\n\n # rm ${BUILT_PRODUCTS_DIR}/Applications directory created by Xcode\n echo \"rm -rf ${BUILT_PRODUCTS_DIR}/Applications\" \n rm -rf \"${BUILT_PRODUCTS_DIR}/Applications\"\n # create ${BUILT_PRODUCTS_DIR}/Applications symlink to /Applications\n echo \"ln -s /Applications ${BUILT_PRODUCTS_DIR}/Applications\"\n ln -s /Applications \"${BUILT_PRODUCTS_DIR}/Applications\"\nfi\n"; }; - 4B957C3A2AC7AE700062CA31 /* Replace VPN Controllers with Symlinks */ = { + 7B31FD922AD126C40086AA24 /* Embed System Network Extension */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -9836,18 +9680,17 @@ ); inputPaths = ( ); - name = "Replace VPN Controllers with Symlinks"; + name = "Embed System Network Extension"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"Replace and Sign\" # for easier build log search\n\n# startVPN\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/startVPN.app/Contents/MacOS\"\nrm ./startVPN\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./startVPN\npopd\n\n# stopVPN\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/stopVPN.app/Contents/MacOS\"\nrm ./stopVPN\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./stopVPN\ncd ../../.. \npopd\n\n# enableOnDemand\n\npushd \"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/enableOnDemand.app/Contents/MacOS\"\nrm ./enableOnDemand\nln -s \"../../../../MacOS/${PRODUCT_NAME}\" ./enableOnDemand\ncd ../../.. \npopd\n"; + shellScript = "if [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\" || exit 1\n"; }; - 4B957C3B2AC7AE700062CA31 /* Embed System Network Extension */ = { + 7B31FD932AD126E50086AA24 /* Embed System Network Extension */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -9862,9 +9705,9 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID} $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}\" || exit 1\n"; + shellScript = "if [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\" || exit 1\n"; }; - 7B6469992A165AE00095095A /* Embed System Network Extension */ = { + 7B31FD942AD126FA0086AA24 /* Embed System Network Extension */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -9881,7 +9724,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\nif [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID} $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}\" || exit 1\n"; + shellScript = "if [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\" || exit 1\n"; }; AA8EDF2824925E940071C2E8 /* Swift Lint */ = { isa = PBXShellScriptBuildPhase; @@ -10134,7 +9977,6 @@ 3192A02A2A4C4CFF0084EA89 /* SpacerNode.swift in Sources */, 4B9DB0252A983B24000927DB /* WaitlistRequest.swift in Sources */, 316C7A862A7E9C2F00AA3BAE /* NetworkProtectionUserDefaultsConstants.swift in Sources */, - 3192A02C2A4C4CFF0084EA89 /* SystemExtensionManager.swift in Sources */, 3192A02D2A4C4CFF0084EA89 /* SyncManagementDialogViewController.swift in Sources */, 3192A02E2A4C4CFF0084EA89 /* BookmarkExtension.swift in Sources */, 4B6785412AA7C726008A5004 /* DailyPixel.swift in Sources */, @@ -10197,6 +10039,7 @@ 3192A0642A4C4CFF0084EA89 /* PasswordManagerCoordinator.swift in Sources */, 3192A0652A4C4CFF0084EA89 /* PasswordManagementIdentityModel.swift in Sources */, 3192A0662A4C4CFF0084EA89 /* UserDefaultsWrapper.swift in Sources */, + 4BF0E5092AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, 3192A0672A4C4CFF0084EA89 /* PasswordManagementPopover.swift in Sources */, 4BCF15DE2ABB970D0083F6DF /* NetworkProtectionRemoteMessage.swift in Sources */, 3192A0682A4C4CFF0084EA89 /* BWCommunicator.swift in Sources */, @@ -10322,7 +10165,6 @@ 3192A0D52A4C4CFF0084EA89 /* PasteboardFolder.swift in Sources */, 3192A0D72A4C4CFF0084EA89 /* CookieManagedNotificationView.swift in Sources */, 3192A0D82A4C4CFF0084EA89 /* PermissionType.swift in Sources */, - 3192A0D92A4C4CFF0084EA89 /* NetworkProtectionTunnelController.swift in Sources */, 3192A0DA2A4C4CFF0084EA89 /* RecentlyClosedWindow.swift in Sources */, 3192A0DB2A4C4CFF0084EA89 /* ActionSpeech.swift in Sources */, 3192A0DC2A4C4CFF0084EA89 /* PrivacySecurityPreferences.swift in Sources */, @@ -10437,6 +10279,7 @@ 3192A1402A4C4CFF0084EA89 /* UpdateController.swift in Sources */, 3192A1412A4C4CFF0084EA89 /* FindInPageModel.swift in Sources */, 3192A1422A4C4CFF0084EA89 /* PseudoFolder.swift in Sources */, + 7BA7CC4F2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */, 3192A1432A4C4CFF0084EA89 /* Visit.swift in Sources */, 3192A1442A4C4CFF0084EA89 /* PixelDataStore.swift in Sources */, 3192A1452A4C4CFF0084EA89 /* Pixel.swift in Sources */, @@ -10474,6 +10317,7 @@ 3192A1642A4C4CFF0084EA89 /* OnboardingFlow.swift in Sources */, 3192A1652A4C4CFF0084EA89 /* PasswordManagementLoginModel.swift in Sources */, BB5CB0A12A7AD59D00B312D1 /* NetworkProtectionDebugUtilities.swift in Sources */, + 4BF0E5162AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, 3192A1662A4C4CFF0084EA89 /* TabViewModel.swift in Sources */, B6676BE32AA986A700525A21 /* AddressBarTextEditor.swift in Sources */, 3192A1672A4C4CFF0084EA89 /* TabDragAndDropManager.swift in Sources */, @@ -10627,6 +10471,7 @@ 3192A1EB2A4C4CFF0084EA89 /* URLExtension.swift in Sources */, 3192A1EC2A4C4CFF0084EA89 /* Tab+UIDelegate.swift in Sources */, 3192A1ED2A4C4CFF0084EA89 /* CookieConsentAnimationView.swift in Sources */, + 7B3618C42ADE77D2000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */, 3192A1EE2A4C4CFF0084EA89 /* NSStoryboardExtension.swift in Sources */, 3192A1EF2A4C4CFF0084EA89 /* PreferencesViewController.swift in Sources */, 3192A1F02A4C4CFF0084EA89 /* FireproofDomains.swift in Sources */, @@ -10790,6 +10635,7 @@ 3706FAF6293F65D500E42796 /* LoginFaviconView.swift in Sources */, 3706FEC0293F6EFF00E42796 /* BWRequest.swift in Sources */, 3706FAF7293F65D500E42796 /* FireproofDomainsViewController.swift in Sources */, + 4BF0E5062AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, 3706FAF8293F65D500E42796 /* URLEventHandler.swift in Sources */, 37197EA72942443D00394917 /* AuthenticationAlert.swift in Sources */, 3706FEC3293F6F0600E42796 /* BWCommunicator.swift in Sources */, @@ -10817,7 +10663,6 @@ 3706FB0B293F65D500E42796 /* DefaultBrowserPromptView.swift in Sources */, 3706FB0D293F65D500E42796 /* BrowserImportSummaryViewController.swift in Sources */, 3706FB0E293F65D500E42796 /* FaviconManager.swift in Sources */, - 4B8F52422A18326600BE7131 /* NetworkProtectionTunnelController.swift in Sources */, 3706FB0F293F65D500E42796 /* ChromiumFaviconsReader.swift in Sources */, 4B0BD7B82A9FE6E600EF609D /* NetworkProtectionOnboardingMenu.swift in Sources */, 3706FB10293F65D500E42796 /* SuggestionTableRowView.swift in Sources */, @@ -11259,6 +11104,7 @@ 3706FC76293F65D500E42796 /* PixelDataRecord.swift in Sources */, 7BFE955A2A9DF4550081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */, 3706FC77293F65D500E42796 /* PageObserverUserScript.swift in Sources */, + 4BF0E5132AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, 3706FC78293F65D500E42796 /* SecureVaultErrorReporter.swift in Sources */, 3706FC79293F65D500E42796 /* NSImageExtensions.swift in Sources */, 3706FEBD293F6EFF00E42796 /* BWCommand.swift in Sources */, @@ -11611,11 +11457,11 @@ B6F92BA82A691A44002ABA6B /* NetworkProtectionUserDefaultsConstants.swift in Sources */, B602E8232A1E260E006D261F /* Bundle+NetworkProtectionExtensions.swift in Sources */, EEAD7A7B2A1D3E20002A24E7 /* AppLauncher.swift in Sources */, - 4B25377C2A11C07600610219 /* NetworkProtectionPixelEvent.swift in Sources */, 4B2D062A2A11C0C900DE1F49 /* NetworkProtectionOptionKeyExtension.swift in Sources */, B602E8192A1E2570006D261F /* URL+NetworkProtection.swift in Sources */, 4B2D06322A11C1D300DE1F49 /* NSApplicationExtension.swift in Sources */, 4B2D06332A11C1E300DE1F49 /* OptionalExtension.swift in Sources */, + 4BF0E50B2AD2552200FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, 4B2537782A11C00F00610219 /* NetworkProtectionExtensionMachService.swift in Sources */, B65DA5F32A77D3C700CBEE8D /* UserDefaultsWrapper.swift in Sources */, 4B2537722A11BF8B00610219 /* main.swift in Sources */, @@ -11628,20 +11474,31 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7B2DDD052A93BEE20039D884 /* FeatureProtectedTunnelController.swift in Sources */, B6F92BA22A691580002ABA6B /* UserDefaultsWrapper.swift in Sources */, 4B2D065B2A11D1FF00DE1F49 /* Logging.swift in Sources */, + 7BA7CC5B2AD120640042E5CE /* NetworkProtection+ConvenienceInitializers.swift in Sources */, + 7BA7CC3A2AD11E2D0042E5CE /* DuckDuckGoVPNAppDelegate.swift in Sources */, 7BAF9E4C2A8A3CCA002D3B6E /* UserDefaults+NetworkProtectionShared.swift in Sources */, - 4B2D06572A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.swift in Sources */, + 7BA7CC592AD1203B0042E5CE /* UserText+NetworkProtection.swift in Sources */, + 7BA7CC562AD11FFB0042E5CE /* NetworkProtectionOptionKeyExtension.swift in Sources */, 7B2DDCFA2A93B25F0039D884 /* KeychainType+ClientDefault.swift in Sources */, - 7B2DDD072A93C17D0039D884 /* UserText.swift in Sources */, + 7BA7CC4C2AD11EC70042E5CE /* NetworkProtectionControllerErrorStore.swift in Sources */, B6F92BAC2A6937B3002ABA6B /* OptionalExtension.swift in Sources */, + 7BA7CC532AD11FCE0042E5CE /* NetworkProtectionBundle.swift in Sources */, + 7BA7CC3C2AD11E330042E5CE /* Bundle+Configuration.swift in Sources */, 7BFE95562A9DF29B0081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */, - 7B2DDD092A93C2440039D884 /* AppLauncher+DefaultInitializer.swift in Sources */, + 7BA7CC5D2AD120C30042E5CE /* EventMapping+NetworkProtectionError.swift in Sources */, + 7BA7CC4A2AD11EA00042E5CE /* NetworkProtectionTunnelController.swift in Sources */, + 7BD1688E2AD4A4C400D24876 /* NetworkExtensionController.swift in Sources */, + 7BA7CC3E2AD11E380042E5CE /* TunnelControllerIPCService.swift in Sources */, B6F92BAA2A691A44002ABA6B /* NetworkProtectionUserDefaultsConstants.swift in Sources */, + 7BA7CC402AD11E3D0042E5CE /* AppLauncher+DefaultInitializer.swift in Sources */, EEC589DB2A4F1CE700BCD60C /* AppLauncher.swift in Sources */, B65DA5EF2A77CC3A00CBEE8D /* Bundle+NetworkProtectionExtensions.swift in Sources */, - 7B2DDD022A93BAA60039D884 /* NetworkProtectionBouncer.swift in Sources */, + 4BF0E5072AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, + 7BA7CC442AD11E490042E5CE /* UserText.swift in Sources */, + 4BF0E5142AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, + 7BA7CC422AD11E420042E5CE /* NetworkProtectionBouncer.swift in Sources */, B65DA5F12A77D2BC00CBEE8D /* BundleExtension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -11653,14 +11510,26 @@ 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 */, + 7BA7CC5A2AD120640042E5CE /* NetworkProtection+ConvenienceInitializers.swift in Sources */, + 7BA7CC3B2AD11E330042E5CE /* Bundle+Configuration.swift in Sources */, EEC589DC2A4F1CE800BCD60C /* AppLauncher.swift in Sources */, + 7BA7CC3F2AD11E3D0042E5CE /* AppLauncher+DefaultInitializer.swift in Sources */, + 7BA7CC412AD11E420042E5CE /* NetworkProtectionBouncer.swift in Sources */, + 4BF0E5082AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, + 7BA7CC582AD1203A0042E5CE /* UserText+NetworkProtection.swift in Sources */, + 7BA7CC4B2AD11EC60042E5CE /* NetworkProtectionControllerErrorStore.swift in Sources */, + 4BF0E5152AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, 7BFE95592A9DF2AF0081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */, - 7B2DDD032A93BBEC0039D884 /* NetworkProtectionBouncer.swift in Sources */, + 7BA7CC5C2AD120C30042E5CE /* EventMapping+NetworkProtectionError.swift in Sources */, B65DA5F02A77CC3C00CBEE8D /* Bundle+NetworkProtectionExtensions.swift in Sources */, 7BAF9E4D2A8A3CCB002D3B6E /* UserDefaults+NetworkProtectionShared.swift in Sources */, + 7BA7CC392AD11E2D0042E5CE /* DuckDuckGoVPNAppDelegate.swift in Sources */, + 7BA7CC552AD11FFB0042E5CE /* NetworkProtectionOptionKeyExtension.swift in Sources */, + 7BA7CC3D2AD11E380042E5CE /* TunnelControllerIPCService.swift in Sources */, + 7BA7CC432AD11E480042E5CE /* UserText.swift in Sources */, + 7BA7CC542AD11FCE0042E5CE /* NetworkProtectionBundle.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -11692,10 +11561,10 @@ B65DA5F52A77D3FA00CBEE8D /* BundleExtension.swift in Sources */, 4B4D60892A0B2A1C00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */, 4B4D60A02A0B2D5B00BCD287 /* NetworkProtectionBundle.swift in Sources */, - 4B4D60932A0B2A3700BCD287 /* NetworkProtectionPixelEvent.swift in Sources */, 4B4D60AD2A0C807300BCD287 /* NSApplicationExtension.swift in Sources */, 4B4D60A52A0B2EC000BCD287 /* UserText+NetworkProtectionExtensions.swift in Sources */, EEF12E6E2A2111880023E6BF /* MacPacketTunnelProvider.swift in Sources */, + 4BF0E50C2AD2552300FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, 4B4D60AC2A0C804B00BCD287 /* OptionalExtension.swift in Sources */, B6F92BA72A691A44002ABA6B /* NetworkProtectionUserDefaultsConstants.swift in Sources */, B65DA5F22A77D3C600CBEE8D /* UserDefaultsWrapper.swift in Sources */, @@ -11703,22 +11572,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4B5F14C72A14702C0060320F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4B5F14DC2A1470AA0060320F /* Main.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4B5F14DD2A1476BC0060320F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4B5F14F22A1476EF0060320F /* Main.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 4B9579452AC7AE700062CA31 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -11875,7 +11728,6 @@ 4B9579DB2AC7AE700062CA31 /* DownloadsPopover.swift in Sources */, 4B9579DC2AC7AE700062CA31 /* BookmarksBarMenuFactory.swift in Sources */, 4B9579DD2AC7AE700062CA31 /* SpacerNode.swift in Sources */, - 4B9579DE2AC7AE700062CA31 /* SystemExtensionManager.swift in Sources */, B62B483C2ADE46FC000DECE5 /* Application.swift in Sources */, 4B9579DF2AC7AE700062CA31 /* SyncManagementDialogViewController.swift in Sources */, 4B9579E02AC7AE700062CA31 /* BookmarkExtension.swift in Sources */, @@ -12011,6 +11863,7 @@ 4B957A5E2AC7AE700062CA31 /* DownloadListCoordinator.swift in Sources */, 4B957A5F2AC7AE700062CA31 /* AdClickAttributionTabExtension.swift in Sources */, 1E2AE4CC2ACB224A00684E0A /* NetworkProtectionRemoteMessagingRequest.swift in Sources */, + 7B3618C52ADE77D3000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */, 4B957A602AC7AE700062CA31 /* NSNotificationName+Debug.swift in Sources */, 4B957A612AC7AE700062CA31 /* NavigationBarBadgeAnimationView.swift in Sources */, 4B957A622AC7AE700062CA31 /* AddressBarButton.swift in Sources */, @@ -12035,6 +11888,7 @@ 4B957A752AC7AE700062CA31 /* ASN1Parser.swift in Sources */, 4B957A762AC7AE700062CA31 /* FileDownloadManager.swift in Sources */, 4B957A772AC7AE700062CA31 /* BookmarkImport.swift in Sources */, + 4BF0E5172AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, 4B957A782AC7AE700062CA31 /* KeySetDictionary.swift in Sources */, B68D21CB2ACBC9A3002DA3C2 /* ContentBlockingMock.swift in Sources */, 4B957A792AC7AE700062CA31 /* HistoryTabExtension.swift in Sources */, @@ -12068,7 +11922,6 @@ 4B957A942AC7AE700062CA31 /* PasteboardFolder.swift in Sources */, 4B957A952AC7AE700062CA31 /* CookieManagedNotificationView.swift in Sources */, 4B957A962AC7AE700062CA31 /* PermissionType.swift in Sources */, - 4B957A972AC7AE700062CA31 /* NetworkProtectionTunnelController.swift in Sources */, 4B957A982AC7AE700062CA31 /* RecentlyClosedWindow.swift in Sources */, 4B957A992AC7AE700062CA31 /* ActionSpeech.swift in Sources */, 4B957A9A2AC7AE700062CA31 /* PrivacySecurityPreferences.swift in Sources */, @@ -12300,6 +12153,7 @@ 4B957B7C2AC7AE700062CA31 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */, 4B957B7D2AC7AE700062CA31 /* TabBarCollectionView.swift in Sources */, 4B957B7E2AC7AE700062CA31 /* NetworkProtection+ConvenienceInitializers.swift in Sources */, + 7BA7CC502AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */, 4B957B7F2AC7AE700062CA31 /* NavigationActionExtension.swift in Sources */, 4B957B802AC7AE700062CA31 /* NSAlertExtension.swift in Sources */, 4B957B812AC7AE700062CA31 /* ThirdPartyBrowser.swift in Sources */, @@ -12361,6 +12215,7 @@ 4B957BB72AC7AE700062CA31 /* PinnedTabsView.swift in Sources */, 4B957BB82AC7AE700062CA31 /* FireproofInfoViewController.swift in Sources */, 4B957BB92AC7AE700062CA31 /* SyncErrorHandler.swift in Sources */, + 4BF0E50A2AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, 4B957BBA2AC7AE700062CA31 /* URLExtension.swift in Sources */, 4B957BBB2AC7AE700062CA31 /* Tab+UIDelegate.swift in Sources */, 1E2AE4C92ACB217800684E0A /* NetworkProtectionRemoteMessagingStorage.swift in Sources */, @@ -12401,14 +12256,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7B736E572A4A22B700F9922A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7B736E582A4A22B700F9922A /* Main.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 7B96D0CB2ADFDA7E007E02C8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -12471,6 +12318,7 @@ 37AFCE8527DA2D3900471A10 /* PreferencesSidebar.swift in Sources */, B6C00ED5292FB21E009C73A6 /* HoveredLinkTabExtension.swift in Sources */, AA5C8F5E2590EEE800748EB7 /* NSPointExtension.swift in Sources */, + 4BF0E5122AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, AA6EF9AD25066F42004754E6 /* WindowsManager.swift in Sources */, 1D43EB3A292B63B00065E5D6 /* BWRequest.swift in Sources */, B68458CD25C7EB9000DC17B6 /* WKWebViewConfigurationExtensions.swift in Sources */, @@ -12572,7 +12420,6 @@ B6B1E87E26D5DA0E0062C350 /* DownloadsPopover.swift in Sources */, 85774AFF2A713D3B00DE0561 /* BookmarksBarMenuFactory.swift in Sources */, 4B9292A026670D2A00AD2C21 /* SpacerNode.swift in Sources */, - 4B2D06342A11CC4600DE1F49 /* SystemExtensionManager.swift in Sources */, 3775913629AB9A1C00E26367 /* SyncManagementDialogViewController.swift in Sources */, B6C0BB6729AEFF8100AE8E3C /* BookmarkExtension.swift in Sources */, 4BE6547F271FCD4D008D1D63 /* PasswordManagementCreditCardModel.swift in Sources */, @@ -12604,7 +12451,6 @@ AAC5E4D025D6A709007F5990 /* Bookmark.swift in Sources */, 4BBDEE9328FC14760092FAA6 /* ConnectBitwardenViewModel.swift in Sources */, 4B5A4F4C27F3A5AA008FBD88 /* NSNotificationName+DataImport.swift in Sources */, - 7B96D0C62ADFD460007E02C8 /* DataBrokerProtectionPixelTests.swift in Sources */, B64C853826944B880048FEBE /* StoredPermission.swift in Sources */, AAE246F8270A406200BEEAEE /* FirePopoverCollectionViewHeader.swift in Sources */, AAB7320926DD0CD9002FACF9 /* FireViewController.swift in Sources */, @@ -12762,7 +12608,6 @@ 4B92929C26670D2A00AD2C21 /* PasteboardFolder.swift in Sources */, 3171D6B82889849F0068632A /* CookieManagedNotificationView.swift in Sources */, B6106BAB26A7BF1D0013B453 /* PermissionType.swift in Sources */, - 4B8F52412A18326600BE7131 /* NetworkProtectionTunnelController.swift in Sources */, AAC6881B28626C1900D54247 /* RecentlyClosedWindow.swift in Sources */, 85707F2A276A35FE00DC0649 /* ActionSpeech.swift in Sources */, 4B0511BD262CAA5A00F6079C /* PrivacySecurityPreferences.swift in Sources */, @@ -12771,6 +12616,7 @@ 7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */, 1E7E2E942902AC0E00C01B54 /* PrivacyDashboardPermissionHandler.swift in Sources */, AA9FF95F24A1FB690039E328 /* TabCollectionViewModel.swift in Sources */, + 4BF0E5052AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, AAC5E4D125D6A709007F5990 /* BookmarkManager.swift in Sources */, 37CD54CD27F2FDD100F1F7B9 /* AboutModel.swift in Sources */, 4BE65476271FCD41008D1D63 /* PasswordManagementCreditCardItemView.swift in Sources */, @@ -12875,6 +12721,7 @@ 85CC1D7D26A05F250062F04E /* PasswordManagementItemModel.swift in Sources */, AAD86E52267A0DFF005C11BE /* UpdateController.swift in Sources */, 85A0118225AF60E700FA6A0C /* FindInPageModel.swift in Sources */, + 7BA7CC4E2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */, 4B9292A226670D2A00AD2C21 /* PseudoFolder.swift in Sources */, AA7E919A2875B39300AB6B62 /* Visit.swift in Sources */, 4BCF15D92ABB8A7F0083F6DF /* NetworkProtectionRemoteMessage.swift in Sources */, @@ -13051,6 +12898,7 @@ AA7412B224D0B3AC00D22FE0 /* TabBarViewItem.swift in Sources */, 856C98D52570116900A22F1F /* NSWindow+Toast.swift in Sources */, B31055C427A1BA1D001AC618 /* AutoconsentUserScript.swift in Sources */, + 7B3618C22ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */, 859E7D6B27453BF3009C2B69 /* BookmarksExporter.swift in Sources */, 7B2DDCF82A93A8BB0039D884 /* NetworkProtectionAppEvents.swift in Sources */, 4B5FF67826B602B100D42879 /* FirefoxDataImporter.swift in Sources */, @@ -13329,11 +13177,6 @@ isa = PBXTargetDependency; productRef = 4B5F14FB2A15291D0060320F /* InputFilesChecker */; }; - 31929F7D2A4C4CFF0084EA89 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */; - targetProxy = 31929F7E2A4C4CFF0084EA89 /* PBXContainerItemProxy */; - }; 37079A93294236F20031BB3C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 3706FA6A293F65D500E42796 /* DuckDuckGo Privacy Browser App Store */; @@ -13349,11 +13192,6 @@ target = AA585D7D248FD31100E9A3E2 /* DuckDuckGo Privacy Browser */; targetProxy = 4B1AD8A225FC27E200261379 /* PBXContainerItemProxy */; }; - 4B2537642A11BE7600610219 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */; - targetProxy = 4B2537632A11BE7600610219 /* PBXContainerItemProxy */; - }; 4B4BEC4A2A11B627001D9AC5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; productRef = 4B4BEC492A11B627001D9AC5 /* NetworkProtection */; @@ -13374,11 +13212,6 @@ isa = PBXTargetDependency; productRef = 4B5F14FB2A15291D0060320F /* InputFilesChecker */; }; - 4B9579272AC7AE700062CA31 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */; - targetProxy = 4B9579282AC7AE700062CA31 /* PBXContainerItemProxy */; - }; 7B20D5C82ADFEC730053C42A /* PBXTargetDependency */ = { isa = PBXTargetDependency; productRef = 7B20D5C72ADFEC730053C42A /* PixelKitTestingUtilities */; @@ -13393,6 +13226,11 @@ target = 31929F7B2A4C4CFF0084EA89 /* DuckDuckGo DBP */; targetProxy = 7B96D0D32ADFDA7F007E02C8 /* PBXContainerItemProxy */; }; + 7BEC18312AD5DA3300D30536 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */; + targetProxy = 7BEC18302AD5DA3300D30536 /* PBXContainerItemProxy */; + }; AA585D92248FD31400E9A3E2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AA585D7D248FD31100E9A3E2 /* DuckDuckGo Privacy Browser */; @@ -13638,56 +13476,56 @@ }; 4B2D06462A11CFBE00DE1F49 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */; + baseConfigurationReference = 7BA7CC0C2AD11D1E0042E5CE /* DuckDuckGoVPN.xcconfig */; buildSettings = { }; name = Debug; }; 4B2D06472A11CFBE00DE1F49 /* CI */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */; + baseConfigurationReference = 7BA7CC0C2AD11D1E0042E5CE /* DuckDuckGoVPN.xcconfig */; buildSettings = { }; name = CI; }; 4B2D06482A11CFBE00DE1F49 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */; + baseConfigurationReference = 7BA7CC0C2AD11D1E0042E5CE /* DuckDuckGoVPN.xcconfig */; buildSettings = { }; name = Release; }; 4B2D06492A11CFBE00DE1F49 /* Review */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */; + baseConfigurationReference = 7BA7CC0C2AD11D1E0042E5CE /* DuckDuckGoVPN.xcconfig */; buildSettings = { }; name = Review; }; 4B2D06762A13318600DE1F49 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */; + baseConfigurationReference = 7BA7CC0B2AD11D1E0042E5CE /* DuckDuckGoVPNAppStore.xcconfig */; buildSettings = { }; name = Debug; }; 4B2D06772A13318600DE1F49 /* CI */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */; + baseConfigurationReference = 7BA7CC0B2AD11D1E0042E5CE /* DuckDuckGoVPNAppStore.xcconfig */; buildSettings = { }; name = CI; }; 4B2D06782A13318600DE1F49 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */; + baseConfigurationReference = 7BA7CC0B2AD11D1E0042E5CE /* DuckDuckGoVPNAppStore.xcconfig */; buildSettings = { }; name = Release; }; 4B2D06792A13318600DE1F49 /* Review */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */; + baseConfigurationReference = 7BA7CC0B2AD11D1E0042E5CE /* DuckDuckGoVPNAppStore.xcconfig */; buildSettings = { }; name = Review; @@ -13748,62 +13586,6 @@ }; name = Review; }; - 4B5F14D82A14702E0060320F /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B18E3232A1D32B1005D0AAA /* NetworkProtectionStartVPN.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 4B5F14D92A14702E0060320F /* CI */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B18E3232A1D32B1005D0AAA /* NetworkProtectionStartVPN.xcconfig */; - buildSettings = { - }; - name = CI; - }; - 4B5F14DA2A14702E0060320F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B18E3232A1D32B1005D0AAA /* NetworkProtectionStartVPN.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 4B5F14DB2A14702E0060320F /* Review */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B18E3232A1D32B1005D0AAA /* NetworkProtectionStartVPN.xcconfig */; - buildSettings = { - }; - name = Review; - }; - 4B5F14EE2A1476C20060320F /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B18E3252A1D3581005D0AAA /* NetworkProtectionStopVPN.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 4B5F14EF2A1476C20060320F /* CI */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B18E3252A1D3581005D0AAA /* NetworkProtectionStopVPN.xcconfig */; - buildSettings = { - }; - name = CI; - }; - 4B5F14F02A1476C20060320F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B18E3252A1D3581005D0AAA /* NetworkProtectionStopVPN.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 4B5F14F12A1476C20060320F /* Review */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B18E3252A1D3581005D0AAA /* NetworkProtectionStopVPN.xcconfig */; - buildSettings = { - }; - name = Review; - }; 4B957C3D2AC7AE700062CA31 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 4B957C432AC7AF190062CA31 /* DuckDuckGoPrivacyPro.xcconfig */; @@ -13853,34 +13635,6 @@ }; name = Release; }; - 7B736E5B2A4A22B700F9922A /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7B9459632A4A5BAF0012535A /* NetworkProtectionEnableOnDemand.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 7B736E5C2A4A22B700F9922A /* CI */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7B9459632A4A5BAF0012535A /* NetworkProtectionEnableOnDemand.xcconfig */; - buildSettings = { - }; - name = CI; - }; - 7B736E5D2A4A22B700F9922A /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7B9459632A4A5BAF0012535A /* NetworkProtectionEnableOnDemand.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 7B736E5E2A4A22B700F9922A /* Review */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7B9459632A4A5BAF0012535A /* NetworkProtectionEnableOnDemand.xcconfig */; - buildSettings = { - }; - name = Review; - }; 7B96D0D62ADFDA7F007E02C8 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7BF1A9DB2AE0551C00FCA683 /* DBPUnitTests.xcconfig */; @@ -14083,7 +13837,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4B2D06452A11CFBE00DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoAgent" */ = { + 4B2D06452A11CFBE00DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoVPN" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B2D06462A11CFBE00DE1F49 /* Debug */, @@ -14094,7 +13848,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4B2D06752A13318600DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoAgentAppStore" */ = { + 4B2D06752A13318600DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoVPNAppStore" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B2D06762A13318600DE1F49 /* Debug */, @@ -14127,28 +13881,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4B5F14D72A14702E0060320F /* Build configuration list for PBXNativeTarget "startVPN" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4B5F14D82A14702E0060320F /* Debug */, - 4B5F14D92A14702E0060320F /* CI */, - 4B5F14DA2A14702E0060320F /* Release */, - 4B5F14DB2A14702E0060320F /* Review */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 4B5F14ED2A1476C20060320F /* Build configuration list for PBXNativeTarget "stopVPN" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4B5F14EE2A1476C20060320F /* Debug */, - 4B5F14EF2A1476C20060320F /* CI */, - 4B5F14F02A1476C20060320F /* Release */, - 4B5F14F12A1476C20060320F /* Review */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 4B957C3C2AC7AE700062CA31 /* Build configuration list for PBXNativeTarget "DuckDuckGo Privacy Pro" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -14171,17 +13903,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 7B736E5A2A4A22B700F9922A /* Build configuration list for PBXNativeTarget "enableOnDemand" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7B736E5B2A4A22B700F9922A /* Debug */, - 7B736E5C2A4A22B700F9922A /* CI */, - 7B736E5D2A4A22B700F9922A /* Release */, - 7B736E5E2A4A22B700F9922A /* Review */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 7B96D0D52ADFDA7F007E02C8 /* Build configuration list for PBXNativeTarget "DuckDuckGoDBPTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -14365,7 +14086,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 81.4.1; + version = 81.5.0; }; }; AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */ = { @@ -14629,10 +14350,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Common; }; - 4B2D064E2A11D0D000DE1F49 /* NetworkProtectionUI */ = { - isa = XCSwiftPackageProductDependency; - productName = NetworkProtectionUI; - }; 4B2D067E2A1334D700DE1F49 /* NetworkProtectionUI */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionUI; @@ -14782,19 +14499,65 @@ isa = XCSwiftPackageProductDependency; productName = PixelKitTestingUtilities; }; - 7BF7705E2AD6C999001C9182 /* PixelKit */ = { + 7B31FD8B2AD125620086AA24 /* NetworkProtectionIPC */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionIPC; + }; + 7B31FD8D2AD125760086AA24 /* NetworkProtectionIPC */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionIPC; + }; + 7B31FD8F2AD1257B0086AA24 /* NetworkProtectionIPC */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionIPC; + }; + 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */ = { isa = XCSwiftPackageProductDependency; productName = PixelKit; }; - 7BF770602AD6CA06001C9182 /* PixelKit */ = { + 7BA59C9A2AE18B49009A97B1 /* SystemExtensionManager */ = { + isa = XCSwiftPackageProductDependency; + productName = SystemExtensionManager; + }; + 7BA7CC5E2AD1210C0042E5CE /* Networking */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Networking; + }; + 7BA7CC602AD1211C0042E5CE /* Networking */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Networking; + }; + 7BBD44272AD730A400D0A064 /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + productName = PixelKit; + }; + 7BEC182E2AD5D8DC00D30536 /* SystemExtensionManager */ = { + isa = XCSwiftPackageProductDependency; + productName = SystemExtensionManager; + }; + 7BEEA5112AD1235B00A9E72B /* NetworkProtectionIPC */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionIPC; + }; + 7BEEA5132AD1236300A9E72B /* NetworkProtectionIPC */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionIPC; + }; + 7BEEA5152AD1236E00A9E72B /* NetworkProtectionUI */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionUI; + }; + 7BF7705E2AD6C999001C9182 /* PixelKit */ = { isa = XCSwiftPackageProductDependency; productName = PixelKit; }; - 7BF770622AD6CA0E001C9182 /* PixelKit */ = { + 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */ = { isa = XCSwiftPackageProductDependency; productName = PixelKit; }; - 7BF770642AD6CA14001C9182 /* PixelKit */ = { + 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */ = { isa = XCSwiftPackageProductDependency; productName = PixelKit; }; diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 61ace75b6c..34f9f56ede 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" : "57d8ed94cf503fdbd348420e821df00142660333", - "version" : "81.4.1" + "revision" : "c427dc63421c4b394f54c245de8e5665bcd6966a", + "version" : "81.5.0" } }, { diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoVPN.xcscheme similarity index 89% rename from DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme rename to DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoVPN.xcscheme index adc90361ec..83d1615164 100644 --- a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoVPN.xcscheme @@ -15,8 +15,8 @@ @@ -44,8 +44,8 @@ @@ -61,8 +61,8 @@ diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoVPNAppStore.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoVPNAppStore.xcscheme new file mode 100644 index 0000000000..3367c080ae --- /dev/null +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoVPNAppStore.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DuckDuckGo/Common/Extensions/URLExtension.swift b/DuckDuckGo/Common/Extensions/URLExtension.swift index da4a435127..0b3193e87e 100644 --- a/DuckDuckGo/Common/Extensions/URLExtension.swift +++ b/DuckDuckGo/Common/Extensions/URLExtension.swift @@ -136,18 +136,6 @@ extension URL { return NavigationalScheme.validSchemes.contains(scheme) } - // MARK: Pixel - - static let pixelBase = ProcessInfo.processInfo.environment["PIXEL_BASE_URL", default: "https://improving.duckduckgo.com"] - - static func pixelUrl(forPixelNamed pixelName: String) -> URL { - let urlString = "\(Self.pixelBase)/t/\(pixelName)" - let url = URL(string: urlString)! - // url = url.addParameter(name: \"atb\", value: statisticsStore.atbWithVariant ?? \"\")") - // https://app.asana.com/0/1177771139624306/1199951074455863/f - return url - } - // MARK: ATB static var devMode: String { diff --git a/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift b/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift index cf6dc4e7e7..517541bcd5 100644 --- a/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift +++ b/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift @@ -52,6 +52,7 @@ extension UserText { } } + static let networkProtectionUnknownActivationError = NSLocalizedString("network.protection.system.extension.unknown.activation.error", value: "There as an unexpected error. Please try again.", comment: "Message shown to users when they try to enable NetP and there is an unexpected activation error.") static let networkProtectionPleaseReboot = NSLocalizedString("network.protection.system.extension.please.reboot", value: "Please reboot to activate Network Protection", comment: "Message shown to users when they try to enable NetP and they need to reboot the computer to complete the installation") } diff --git a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift index 5ee0aca781..5cfe2a744b 100644 --- a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift +++ b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift @@ -136,18 +136,7 @@ public struct UserDefaultsWrapper { // Network Protection - case networkProtectionShouldEnforceRoutes = "netp.enforce-routes" - case networkProtectionShouldIncludeAllNetworks = "netp.include-all-networks" - case networkProtectionExcludedRoutes = "netp.excluded-routes" - case networkProtectionShouldExcludeLocalRoutes = "netp.exclude-local-routes" - case networkProtectionConnectionTesterEnabled = "netp.connection-tester-enabled" - - case networkProtectionConnectOnLogIn = "netp.connect-on-login" - - case networkProtectionRegistrationKeyValidity = "com.duckduckgo.network-protection.NetworkProtectionTunnelController.registrationKeyValidityKey" - - case netpMenuAgentLaunchTime = "netp.agent.launch-time" case networkProtectionTermsAndConditionsAccepted = "network-protection.waitlist-terms-and-conditions.accepted" @@ -176,6 +165,13 @@ public struct UserDefaultsWrapper { case passwordManagerDoNotPromptDomains = "com.duckduckgo.passwordmanager.do-not-prompt-domains" case incrementalFeatureFlagTestHasSentPixel = "network-protection.incremental-feature-flag-test.has-sent-pixel" case homePageShowNetworkProtectionBetaEndedNotice = "home.page.network-protection.show-beta-ended-notice" + + // NetP removed keys + case networkProtectionShouldEnforceRoutes = "netp.enforce-routes" + case networkProtectionShouldIncludeAllNetworks = "netp.include-all-networks" + case networkProtectionConnectionTesterEnabled = "netp.connection-tester-enabled" + case networkProtectionShouldExcludeLocalNetworks = "netp.exclude-local-routes" + case networkProtectionRegistrationKeyValidity = "com.duckduckgo.network-protection.NetworkProtectionTunnelController.registrationKeyValidityKey" } private let key: Key diff --git a/DuckDuckGo/LoginItems/LoginItemsManager.swift b/DuckDuckGo/LoginItems/LoginItemsManager.swift index 461931b4f0..c6d741ce9a 100644 --- a/DuckDuckGo/LoginItems/LoginItemsManager.swift +++ b/DuckDuckGo/LoginItems/LoginItemsManager.swift @@ -23,30 +23,14 @@ import LoginItems /// Class to manage the login items for Network Protection and DBP /// final class LoginItemsManager { - - /// Save agent last launch time to distinguish between system launch at Log In and Main App launch - /// Used for the Connect On Log In feature to prevent connection when started by the Main App - /// Ideally we should remove this to make this class completely generic - @UserDefaultsWrapper(key: .netpMenuAgentLaunchTime, defaults: .shared) - private var netpMenuAgentLaunchTime: Date? - // MARK: - Main Interactions func enableLoginItems(_ items: Set, log: OSLog) { - -#if NETWORK_PROTECTION - if items.contains(.vpnMenu) { - netpMenuAgentLaunchTime = Date() - } -#endif - updateLoginItems(items, whatAreWeDoing: "enable", using: LoginItem.enable) - ensureLoginItemsAreRunning(items, log: log) } func restartLoginItems(_ items: Set, log: OSLog) { updateLoginItems(items, whatAreWeDoing: "restart", using: LoginItem.restart) - ensureLoginItemsAreRunning(items, log: log, condition: .ifLoginItemsAreEnabled) } func disableLoginItems(_ items: Set) { @@ -85,36 +69,4 @@ final class LoginItemsManager { self == .none } } - - /// Ensures that the login items are running. If an item that's supposed to be running is not, this method launches it manually. - /// - func ensureLoginItemsAreRunning(_ items: Set, log: OSLog, condition: LoginItemCheckCondition = .none, after interval: TimeInterval = .seconds(5)) { - - Task { - try await Task.sleep(interval: interval) - - os_log(.info, log: log, "Checking whether login agents are enabled and running") - - for item in items { - guard !item.isRunning && (condition.shouldIgnoreItemStatus || item.status.isEnabled) else { - os_log(.info, log: log, "Login item with ID '%{public}s': ok", item.debugDescription) - continue - } - - os_log(.error, log: log, "%{public}s is not running, launching manually", item.debugDescription) - - do { -#if NETWORK_PROTECTION - if item == .vpnMenu { - netpMenuAgentLaunchTime = Date() - } -#endif - try await item.launch() - os_log(.info, log: log, "Launched login item with ID '%{public}s'", item.debugDescription) - } catch { - os_log(.error, log: log, "Login item with ID '%{public}s' could not be launched. Error: %{public}s", item.debugDescription, "\(error)") - } - } - } - } } diff --git a/DuckDuckGo/Main/Main.swift b/DuckDuckGo/Main/Main.swift index 39cd889519..862af2fa26 100644 --- a/DuckDuckGo/Main/Main.swift +++ b/DuckDuckGo/Main/Main.swift @@ -38,57 +38,6 @@ final class AppMain { } static func main() { -#if NETWORK_PROTECTION - - // If the app is sandboxed, attempt to use the symlink approach for determining launch command: - if let launchPath = (CommandLine.arguments.first as NSString?)?.lastPathComponent { - switch launchPath { - case AppLaunchCommand.startVPN.rawValue: - swizzleMainBundle() - - Task { - await NetworkProtectionTunnelController().start(enableLoginItems: false) - exit(0) - } - - dispatchMain() - - case AppLaunchCommand.stopVPN.rawValue: - swizzleMainBundle() - - Task { - await NetworkProtectionTunnelController().stop() - exit(0) - } - - dispatchMain() - default: break - } - } - - // If the app is not sandboxed, read the process arguments to determine launch command: - if ProcessInfo.processInfo.arguments.contains(AppLaunchCommand.startVPN.rawValue) { - swizzleMainBundle() - - Task { - await NetworkProtectionTunnelController().start(enableLoginItems: false) - exit(0) - } - - dispatchMain() - } else if ProcessInfo.processInfo.arguments.contains(AppLaunchCommand.stopVPN.rawValue) { - swizzleMainBundle() - - Task { - await NetworkProtectionTunnelController().stop() - exit(0) - } - - dispatchMain() - } - -#endif - #if !APPSTORE && !DEBUG && !DBP PFMoveToApplicationsFolderIfNecessary() #endif diff --git a/DuckDuckGo/NavigationBar/View/NavigationBarPopovers.swift b/DuckDuckGo/NavigationBar/View/NavigationBarPopovers.swift index cddd8e0812..0d0f567b5c 100644 --- a/DuckDuckGo/NavigationBar/View/NavigationBarPopovers.swift +++ b/DuckDuckGo/NavigationBar/View/NavigationBarPopovers.swift @@ -24,6 +24,7 @@ import AppKit import Combine import NetworkProtection import NetworkProtectionUI +import NetworkProtectionIPC #endif final class NavigationBarPopovers { @@ -40,7 +41,11 @@ final class NavigationBarPopovers { private(set) var downloadsPopover: DownloadsPopover? #if NETWORK_PROTECTION - private(set) var networkProtectionPopover: NetworkProtectionPopover? + private let networkProtectionPopoverManager: NetworkProtectionNavBarPopoverManager + + init(networkProtectionPopoverManager: NetworkProtectionNavBarPopoverManager) { + self.networkProtectionPopoverManager = networkProtectionPopoverManager + } #endif var passwordManagementDomain: String? { @@ -68,7 +73,7 @@ final class NavigationBarPopovers { @MainActor var isNetworkProtectionPopoverShown: Bool { #if NETWORK_PROTECTION - networkProtectionPopover?.isShown ?? false + networkProtectionPopoverManager.isShown #else return false #endif @@ -96,17 +101,7 @@ final class NavigationBarPopovers { func toggleNetworkProtectionPopover(usingView view: NSView, withDelegate delegate: NSPopoverDelegate) { #if NETWORK_PROTECTION - if let networkProtectionPopover, networkProtectionPopover.isShown { - networkProtectionPopover.close() - } else { - let featureVisibility = DefaultNetworkProtectionVisibility() - - if featureVisibility.isNetworkProtectionVisible() { - showNetworkProtectionPopover(usingView: view, withDelegate: delegate) - } else { - featureVisibility.disableForWaitlistUsers() - } - } + networkProtectionPopoverManager.toggle(positionedBelow: view, withDelegate: delegate) #endif } @@ -166,8 +161,8 @@ final class NavigationBarPopovers { } #if NETWORK_PROTECTION - if networkProtectionPopover?.isShown ?? false { - networkProtectionPopover?.close() + if networkProtectionPopoverManager.isShown { + networkProtectionPopoverManager.close() } #endif @@ -287,41 +282,10 @@ final class NavigationBarPopovers { // MARK: - Network Protection #if NETWORK_PROTECTION - func showNetworkProtectionPopover(usingView view: NSView, withDelegate delegate: NSPopoverDelegate) { - let popover = networkProtectionPopover ?? { - let controller = NetworkProtectionTunnelController() - let statusObserver = ConnectionStatusObserverThroughSession(platformNotificationCenter: NSWorkspace.shared.notificationCenter, - platformDidWakeNotification: NSWorkspace.didWakeNotification) - let statusInfoObserver = ConnectionServerInfoObserverThroughSession(platformNotificationCenter: NSWorkspace.shared.notificationCenter, - platformDidWakeNotification: NSWorkspace.didWakeNotification) - let connectionErrorObserver = ConnectionErrorObserverThroughSession(platformNotificationCenter: NSWorkspace.shared.notificationCenter, - platformDidWakeNotification: NSWorkspace.didWakeNotification) - let statusReporter = DefaultNetworkProtectionStatusReporter( - statusObserver: statusObserver, - serverInfoObserver: statusInfoObserver, - connectionErrorObserver: connectionErrorObserver, - connectivityIssuesObserver: ConnectivityIssueObserverThroughDistributedNotifications(), - controllerErrorMessageObserver: ControllerErrorMesssageObserverThroughDistributedNotifications() - ) - - let menuItems = [ - NetworkProtectionStatusView.Model.MenuItem( - name: UserText.networkProtectionNavBarStatusViewShareFeedback, - action: { - let appLauncher = AppLauncher(appBundleURL: Bundle.main.bundleURL) - await appLauncher.launchApp(withCommand: .shareFeedback) - }) - ] - - let onboardingStatusPublisher = UserDefaults.shared.networkProtectionOnboardingStatusPublisher - - let popover = NetworkProtectionPopover(controller: controller, onboardingStatusPublisher: onboardingStatusPublisher, statusReporter: statusReporter, menuItems: menuItems) - popover.delegate = delegate - - networkProtectionPopover = popover - return popover - }() - show(popover, positionedBelow: view) + func showNetworkProtectionPopover( + positionedBelow view: NSView, + withDelegate delegate: NSPopoverDelegate) { + networkProtectionPopoverManager.show(positionedBelow: view, withDelegate: delegate) } #endif } diff --git a/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift b/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift index c89610e6f7..e4f88b8708 100644 --- a/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift +++ b/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift @@ -23,6 +23,7 @@ import BrowserServicesKit #if NETWORK_PROTECTION import NetworkProtection +import NetworkProtectionIPC import NetworkProtectionUI #endif @@ -78,7 +79,8 @@ final class NavigationBarViewController: NSViewController { private let goForwardButtonMenuDelegate: NavigationButtonMenuDelegate // swiftlint:enable weak_delegate - private var popovers = NavigationBarPopovers() + private var popovers: NavigationBarPopovers + var isDownloadsPopoverShown: Bool { popovers.isDownloadsPopoverShown } @@ -105,8 +107,16 @@ final class NavigationBarViewController: NSViewController { #if NETWORK_PROTECTION init?(coder: NSCoder, tabCollectionViewModel: TabCollectionViewModel, isBurner: Bool, networkProtectionFeatureActivation: NetworkProtectionFeatureActivation = NetworkProtectionKeychainTokenStore()) { + + let vpnBundleID = Bundle.main.vpnMenuAgentBundleId + let ipcClient = TunnelControllerIPCClient(machServiceName: vpnBundleID) + ipcClient.register() + + let networkProtectionPopoverManager = NetworkProtectionNavBarPopoverManager(ipcClient: ipcClient) + + self.popovers = NavigationBarPopovers(networkProtectionPopoverManager: networkProtectionPopoverManager) self.tabCollectionViewModel = tabCollectionViewModel - self.networkProtectionButtonModel = NetworkProtectionNavBarButtonModel(popovers: popovers) + self.networkProtectionButtonModel = NetworkProtectionNavBarButtonModel(popoverManager: networkProtectionPopoverManager) self.isBurner = isBurner self.networkProtectionFeatureActivation = networkProtectionFeatureActivation goBackButtonMenuDelegate = NavigationButtonMenuDelegate(buttonType: .back, tabCollectionViewModel: tabCollectionViewModel) @@ -115,6 +125,7 @@ final class NavigationBarViewController: NSViewController { } #else init?(coder: NSCoder, tabCollectionViewModel: TabCollectionViewModel, isBurner: Bool) { + self.popovers = NavigationBarPopovers() self.tabCollectionViewModel = tabCollectionViewModel self.isBurner = isBurner goBackButtonMenuDelegate = NavigationButtonMenuDelegate(buttonType: .back, tabCollectionViewModel: tabCollectionViewModel) @@ -843,7 +854,7 @@ extension NavigationBarViewController: NSMenuDelegate { let featureVisibility = DefaultNetworkProtectionVisibility() if featureVisibility.isNetworkProtectionVisible() { - popovers.showNetworkProtectionPopover(usingView: networkProtectionButton, + popovers.showNetworkProtectionPopover(positionedBelow: networkProtectionButton, withDelegate: networkProtectionButtonModel) } else { featureVisibility.disableForWaitlistUsers() diff --git a/DuckDuckGo/NetworkProtection/AppAndExtensionAndAgentTargets/NetworkProtectionUserDefaultsConstants.swift b/DuckDuckGo/NetworkProtection/AppAndExtensionAndAgentTargets/NetworkProtectionUserDefaultsConstants.swift index 345f00f30c..165f2c37db 100644 --- a/DuckDuckGo/NetworkProtection/AppAndExtensionAndAgentTargets/NetworkProtectionUserDefaultsConstants.swift +++ b/DuckDuckGo/NetworkProtection/AppAndExtensionAndAgentTargets/NetworkProtectionUserDefaultsConstants.swift @@ -25,7 +25,7 @@ enum NetworkProtectionUserDefaultsConstants { static let shouldConnectOnLogIn = false static let shouldEnforceRoutes = false static let shouldIncludeAllNetworks = false - static let shouldExcludeLocalRoutes = false + static let shouldExcludeLocalNetworks = false static let isConnectionTesterEnabled = true } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift index 7ff941f4cb..625cbc0c90 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift @@ -18,14 +18,14 @@ #if NETWORK_PROTECTION +import Common import Foundation import NetworkProtection -import Common +import PixelKit extension EventMapping where Event == NetworkProtectionError { static var networkProtectionAppDebugEvents: EventMapping = .init { event, _, _, _ in - - let domainEvent: Pixel.Event.Debug + let domainEvent: NetworkProtectionPixelEvent switch event { case .failedToEncodeRedeemRequest: @@ -78,7 +78,9 @@ extension EventMapping where Event == NetworkProtectionError { return } - Pixel.fire(.debug(event: domainEvent)) + + let debugEvent = DebugEvent(eventType: .custom(domainEvent)) + PixelKit.fire(debugEvent, frequency: .standard, includeAppVersionParameter: true) } } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/LoginItem+NetworkProtection.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/LoginItem+NetworkProtection.swift index 0c21abdf21..ee34e73d09 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/LoginItem+NetworkProtection.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/LoginItem+NetworkProtection.swift @@ -21,10 +21,9 @@ import LoginItems extension LoginItem { - - static let vpnMenu = LoginItem(bundleId: Bundle.main.vpnMenuAgentBundleId, url: Bundle.main.vpnMenuAgentURL, log: .networkProtection) + static let vpnMenu = LoginItem(bundleId: Bundle.main.vpnMenuAgentBundleId, log: .networkProtection) #if NETP_SYSTEM_EXTENSION - static let notificationsAgent = LoginItem(bundleId: Bundle.main.notificationsAgentBundleId, url: Bundle.main.notificationsAgentURL, log: .networkProtection) + static let notificationsAgent = LoginItem(bundleId: Bundle.main.notificationsAgentBundleId, log: .networkProtection) #endif } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift index abeb52d243..8091238710 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionAppEvents.swift @@ -16,16 +16,35 @@ // limitations under the License. // +#if NETWORK_PROTECTION import Common import Foundation - -#if NETWORK_PROTECTION +import LoginItems import NetworkProtection +import NetworkProtectionIPC +import NetworkExtension /// Implements the sequence of steps that Network Protection needs to execute when the App starts up. /// final class NetworkProtectionAppEvents { + // MARK: - Legacy VPN Item and Extension + +#if NETP_SYSTEM_EXTENSION +#if DEBUG + private let legacyAgentBundleID = "HKE973VLUW.com.duckduckgo.macos.browser.network-protection.system-extension.agent.debug" + private let legacySystemExtensionBundleID = "com.duckduckgo.macos.browser.debug.network-protection-extension" +#elseif REVIEW + private let legacyAgentBundleID = "HKE973VLUW.com.duckduckgo.macos.browser.network-protection.system-extension.agent.review" + private let legacySystemExtensionBundleID = "com.duckduckgo.macos.browser.review.network-protection-extension" +#else + private let legacyAgentBundleID = "HKE973VLUW.com.duckduckgo.macos.browser.network-protection.system-extension.agent" + private let legacySystemExtensionBundleID = "com.duckduckgo.macos.browser.network-protection-extension" +#endif // DEBUG || REVIEW || RELEASE +#endif // NETP_SYSTEM_EXTENSION + + // MARK: - Feature Visibility + private let featureVisibility: NetworkProtectionFeatureVisibility init(featureVisibility: NetworkProtectionFeatureVisibility = DefaultNetworkProtectionVisibility()) { @@ -35,16 +54,20 @@ final class NetworkProtectionAppEvents { /// Call this method when the app finishes launching, to run the startup logic for NetP. /// func applicationDidFinishLaunching() { - migrateNetworkProtectionAuthTokenToSharedKeychainIfNecessary() + let loginItemsManager = LoginItemsManager() - guard featureVisibility.isNetworkProtectionVisible() else { - featureVisibility.disableForAllUsers() - return - } + Task { + await removeLegacyLoginItemAndVPNConfiguration() + migrateNetworkProtectionAuthTokenToSharedKeychainIfNecessary() - let loginItemsManager = LoginItemsManager() - restartNetworkProtectionIfVersionChanged(using: loginItemsManager) - refreshNetworkProtectionServers() + guard featureVisibility.isNetworkProtectionVisible() else { + featureVisibility.disableForAllUsers() + return + } + + restartNetworkProtectionIfVersionChanged(using: loginItemsManager) + refreshNetworkProtectionServers() + } } /// Call this method when the app becomes active to run the associated NetP logic. @@ -106,22 +129,22 @@ final class NetworkProtectionAppEvents { 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(LoginItemsManager.networkProtectionLoginItems, log: .networkProtection, condition: .ifLoginItemsAreEnabled, after: 1) } } private func restartNetworkProtectionTunnelAndMenu(using loginItemsManager: LoginItemsManager) { + loginItemsManager.restartLoginItems(LoginItemsManager.networkProtectionLoginItems, log: .networkProtection) Task { - let provider = NetworkProtectionTunnelController() + let machServiceName = Bundle.main.vpnMenuAgentBundleId + let ipcClient = TunnelControllerIPCClient(machServiceName: machServiceName) + let controller = NetworkProtectionIPCTunnelController(ipcClient: ipcClient) // Restart NetP SysEx on app update - if await provider.isConnected { - await provider.stop() - await provider.start() + if controller.isConnected { + await controller.stop() + await controller.start() } } } @@ -141,6 +164,23 @@ final class NetworkProtectionAppEvents { os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount) } } + + // MARK: - Legacy Login Item and Extension + + private func removeLegacyLoginItemAndVPNConfiguration() async { + LoginItem(bundleId: legacyAgentBundleID).forceStop() + + let tunnels = try? await NETunnelProviderManager.loadAllFromPreferences() + let tunnel = tunnels?.first { + ($0.protocolConfiguration as? NETunnelProviderProtocol)?.providerBundleIdentifier == legacySystemExtensionBundleID + } + + guard let tunnel else { + return + } + + try? await tunnel.removeFromPreferences() + } } #endif diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugMenu.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugMenu.swift index 700a54865f..877775be80 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugMenu.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugMenu.swift @@ -160,6 +160,10 @@ final class NetworkProtectionDebugMenu: NSMenu { fatalError("init(coder:) has not been implemented") } + // MARK: - Tunnel Settings + + private let settings = TunnelSettings(defaults: .shared) + // MARK: - Debug Logic private let debugUtilities = NetworkProtectionDebugUtilities() @@ -224,7 +228,7 @@ final class NetworkProtectionDebugMenu: NSMenu { /// @objc func setSelectedServer(_ menuItem: NSMenuItem) { let title = menuItem.title - let selectedServer: SelectedNetworkProtectionServer + let selectedServer: TunnelSettings.SelectedServer if title == "Automatic" { selectedServer = .automatic @@ -233,7 +237,7 @@ final class NetworkProtectionDebugMenu: NSMenu { selectedServer = .endpoint(titleComponents.first!) } - debugUtilities.setSelectedServer(selectedServer: selectedServer) + settings.selectedServer = selectedServer } /// Expires the registration key immediately. @@ -247,34 +251,39 @@ final class NetworkProtectionDebugMenu: NSMenu { /// Sets the registration key validity. /// @objc func setRegistrationKeyValidity(_ menuItem: NSMenuItem) { - // nil means automatic - let validity = menuItem.representedObject as? TimeInterval + guard let timeInterval = menuItem.representedObject as? TimeInterval else { + settings.registrationKeyValidity = .automatic + return + } - debugUtilities.registrationKeyValidity = validity + settings.registrationKeyValidity = .custom(timeInterval) } @objc func toggleEnforceRoutesAction(_ sender: Any?) { - NetworkProtectionTunnelController().toggleShouldEnforceRoutes() + settings.enforceRoutes.toggle() } @objc func toggleIncludeAllNetworks(_ sender: Any?) { - NetworkProtectionTunnelController().toggleShouldIncludeAllNetworks() + settings.includeAllNetworks.toggle() } @objc func toggleShouldExcludeLocalRoutes(_ sender: Any?) { - NetworkProtectionTunnelController().toggleShouldExcludeLocalRoutes() + settings.excludeLocalNetworks.toggle() } @objc func toggleConnectOnLogInAction(_ sender: Any?) { - NetworkProtectionTunnelController().toggleShouldAutoConnectOnLogIn() + // Temporarily disabled: https://app.asana.com/0/0/1205766100762904/f } @objc func toggleExclusionAction(_ sender: NSMenuItem) { + // Temporarily disabled: https://app.asana.com/0/0/1205766100762904/f + /* guard let addressRange = sender.representedObject as? String else { assertionFailure("Unexpected representedObject") return } - NetworkProtectionTunnelController().setExcludedRoute(addressRange, enabled: sender.state == .off) + + NetworkProtectionTunnelController().setExcludedRoute(addressRange, enabled: sender.state == .off)*/ } @objc func openAppContainerInFinder(_ sender: Any?) { @@ -347,7 +356,7 @@ final class NetworkProtectionDebugMenu: NSMenu { private func populateExclusionsMenuItems() { exclusionsMenu.removeAllItems() - for item in NetworkProtectionTunnelController.exclusionList { + for item in settings.exclusionList { let menuItem: NSMenuItem switch item { case .section(let title): @@ -379,58 +388,53 @@ final class NetworkProtectionDebugMenu: NSMenu { } private func updatePreferredServerMenu() { - let selectedServerName = debugUtilities.selectedServerName() + let selectedServer = settings.selectedServer - if selectedServerName == nil { + switch selectedServer { + case .automatic: preferredServerMenu.items.first?.state = .on - } else { + case .endpoint(let selectedServerName): preferredServerMenu.items.first?.state = .off - } - // We're skipping the first two items because they're the automatic menu item and - // the separator line. - let serverItems = preferredServerMenu.items.dropFirst(2) + // We're skipping the first two items because they're the automatic menu item and + // the separator line. + let serverItems = preferredServerMenu.items.dropFirst(2) - for item in serverItems { - if let selectedServerName, - item.title.hasPrefix(selectedServerName) { - item.state = .on - } else { - item.state = .off + for item in serverItems { + if item.title.hasPrefix(selectedServerName) { + item.state = .on + } else { + item.state = .off + } } } } private func updateRekeyValidityMenu() { - let selectedValidity = debugUtilities.registrationKeyValidity - - if selectedValidity == nil { + switch settings.registrationKeyValidity { + case .automatic: registrationKeyValidityMenu.items.first?.state = .on - } else { + case .custom(let timeInterval): registrationKeyValidityMenu.items.first?.state = .off - } - // We're skipping the first two items because they're the automatic menu item and - // the separator line. - let serverItems = registrationKeyValidityMenu.items.dropFirst(2) + // We're skipping the first two items because they're the automatic menu item and + // the separator line. + let serverItems = registrationKeyValidityMenu.items.dropFirst(2) - for item in serverItems { - if item.representedObject as? TimeInterval == selectedValidity { - item.state = .on - } else { - item.state = .off + for item in serverItems { + if item.representedObject as? TimeInterval == timeInterval { + item.state = .on + } else { + item.state = .off + } } } } private func updateNetworkProtectionMenuItemsState() { - let controller = NetworkProtectionTunnelController() - - shouldEnforceRoutesMenuItem.state = controller.shouldEnforceRoutes ? .on : .off - shouldIncludeAllNetworksMenuItem.state = controller.shouldIncludeAllNetworks ? .on : .off - connectOnLogInMenuItem.state = controller.shouldAutoConnectOnLogIn ? .on : .off - - excludeLocalNetworksMenuItem.state = controller.shouldExcludeLocalRoutes ? .on : .off + shouldEnforceRoutesMenuItem.state = settings.enforceRoutes ? .on : .off + shouldIncludeAllNetworksMenuItem.state = settings.includeAllNetworks ? .on : .off + excludeLocalNetworksMenuItem.state = settings.excludeLocalNetworks ? .on : .off } private func updateNetworkProtectionItems() { @@ -529,11 +533,13 @@ final class NetworkProtectionDebugMenu: NSMenu { return "" } } - } + extension NetworkProtectionDebugMenu: NSMenuDelegate { func menuNeedsUpdate(_ menu: NSMenu) { + // Temporarily disabled: https://app.asana.com/0/0/1205766100762904/f + /* if menu === exclusionsMenu { let controller = NetworkProtectionTunnelController() for item in menu.items { @@ -543,8 +549,8 @@ extension NetworkProtectionDebugMenu: NSMenuDelegate { item.isEnabled = !(controller.shouldEnforceRoutes && route == "10.0.0.0/8") } } + */ } - } #if DEBUG diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugUtilities.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugUtilities.swift index 9b0d941b82..4c2babed28 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugUtilities.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugUtilities.swift @@ -25,36 +25,28 @@ import NetworkProtectionUI import NetworkExtension import SystemExtensions import LoginItems +import NetworkProtectionIPC /// Utility code to help implement our debug menu options for Network Protection. /// final class NetworkProtectionDebugUtilities { - // MARK: - Registration Key Validity - - @UserDefaultsWrapper(key: .networkProtectionRegistrationKeyValidity, defaultValue: nil) - var registrationKeyValidity: TimeInterval? { - didSet { - Task { - await sendRegistrationKeyValidityToProvider() - } - } - } - - private let networkProtectionFeatureDisabler = NetworkProtectionFeatureDisabler() + private let ipcClient: TunnelControllerIPCClient + private let networkProtectionFeatureDisabler: NetworkProtectionFeatureDisabler // MARK: - Login Items Management private let loginItemsManager: LoginItemsManager - // MARK: - Server Selection - - private let selectedServerStore = NetworkProtectionSelectedServerUserDefaultsStore() - // MARK: - Initializers init(loginItemsManager: LoginItemsManager = .init()) { self.loginItemsManager = loginItemsManager + + let ipcClient = TunnelControllerIPCClient(machServiceName: Bundle.main.vpnMenuAgentBundleId) + + self.ipcClient = ipcClient + self.networkProtectionFeatureDisabler = NetworkProtectionFeatureDisabler(ipcClient: ipcClient) } // MARK: - Debug commands for the extension @@ -71,52 +63,16 @@ final class NetworkProtectionDebugUtilities { } func removeSystemExtensionAndAgents() async throws { + await networkProtectionFeatureDisabler.resetAllStateForVPNApp(uninstallSystemExtension: true) networkProtectionFeatureDisabler.disableLoginItems() - try await networkProtectionFeatureDisabler.disableSystemExtension() } func sendTestNotificationRequest() async throws { - guard let activeSession = try? await ConnectionSessionUtilities.activeSession() else { - return - } - - try? activeSession.sendProviderMessage(.triggerTestNotification) - } - - // MARK: - Registation Key - - private func sendRegistrationKeyValidityToProvider() async { - guard let activeSession = try? await ConnectionSessionUtilities.activeSession() else { - return - } - - try? activeSession.sendProviderMessage(.setKeyValidity(registrationKeyValidity)) + await ipcClient.debugCommand(.sendTestNotification) } func expireRegistrationKeyNow() async { - guard let activeSession = try? await ConnectionSessionUtilities.activeSession() else { - return - } - - try? activeSession.sendProviderMessage(.expireRegistrationKey) - } - - // MARK: - Server Selection - - func selectedServerName() -> String? { - selectedServerStore.selectedServer.stringValue - } - - func setSelectedServer(selectedServer: SelectedNetworkProtectionServer) { - selectedServerStore.selectedServer = selectedServer - - Task { - guard let activeSession = try? await ConnectionSessionUtilities.activeSession() else { - return - } - - try? activeSession.sendProviderMessage(.setSelectedServer(selectedServer.stringValue)) - } + await ipcClient.debugCommand(.expireRegistrationKey) } } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarButtonModel.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarButtonModel.swift index 118c29cdaa..ee11210d3f 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarButtonModel.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarButtonModel.swift @@ -22,6 +22,7 @@ import AppKit import Combine import Foundation import NetworkProtection +import NetworkProtectionIPC import NetworkProtectionUI /// Model for managing the NetP button in the Nav Bar. @@ -30,9 +31,15 @@ final class NetworkProtectionNavBarButtonModel: NSObject, ObservableObject { private let networkProtectionStatusReporter: NetworkProtectionStatusReporter private var status: NetworkProtection.ConnectionStatus = .disconnected - private let popovers: NavigationBarPopovers + private let popoverManager: NetworkProtectionNavBarPopoverManager private let waitlistActivationDateStore: DefaultWaitlistActivationDateStore + // MARK: - IPC + + public var ipcClient: TunnelControllerIPCClient { + popoverManager.ipcClient + } + // MARK: - Subscriptions private var statusChangeCancellable: AnyCancellable? @@ -67,26 +74,25 @@ final class NetworkProtectionNavBarButtonModel: NSObject, ObservableObject { // MARK: - Initialization - init(popovers: NavigationBarPopovers, + init(popoverManager: NetworkProtectionNavBarPopoverManager, pinningManager: PinningManager = LocalPinningManager.shared, statusReporter: NetworkProtectionStatusReporter? = nil, iconProvider: IconProvider = NavigationBarIconProvider()) { - let statusObserver = ConnectionStatusObserverThroughSession(platformNotificationCenter: NSWorkspace.shared.notificationCenter, - platformDidWakeNotification: NSWorkspace.didWakeNotification) - let statusInfoObserver = ConnectionServerInfoObserverThroughSession(platformNotificationCenter: NSWorkspace.shared.notificationCenter, - platformDidWakeNotification: NSWorkspace.didWakeNotification) - let connectionErrorObserver = ConnectionErrorObserverThroughSession(platformNotificationCenter: NSWorkspace.shared.notificationCenter, - platformDidWakeNotification: NSWorkspace.didWakeNotification) - self.networkProtectionStatusReporter = statusReporter ?? DefaultNetworkProtectionStatusReporter( - statusObserver: statusObserver, - serverInfoObserver: statusInfoObserver, - connectionErrorObserver: connectionErrorObserver, - connectivityIssuesObserver: ConnectivityIssueObserverThroughDistributedNotifications(), - controllerErrorMessageObserver: ControllerErrorMesssageObserverThroughDistributedNotifications() + let vpnBundleID = Bundle.main.vpnMenuAgentBundleId + self.popoverManager = popoverManager + + let ipcClient = popoverManager.ipcClient + + self.networkProtectionStatusReporter = statusReporter + ?? DefaultNetworkProtectionStatusReporter( + statusObserver: ipcClient.connectionStatusObserver, + serverInfoObserver: ipcClient.serverInfoObserver, + connectionErrorObserver: ipcClient.connectionErrorObserver, + connectivityIssuesObserver: ConnectivityIssueObserverThroughDistributedNotifications(), + controllerErrorMessageObserver: ControllerErrorMesssageObserverThroughDistributedNotifications() ) self.iconPublisher = NetworkProtectionIconPublisher(statusReporter: networkProtectionStatusReporter, iconProvider: iconProvider) - self.popovers = popovers self.pinningManager = pinningManager isPinned = pinningManager.isPinned(.networkProtection) @@ -185,7 +191,7 @@ final class NetworkProtectionNavBarButtonModel: NSObject, ObservableObject { } guard !isPinned, - !popovers.isNetworkProtectionPopoverShown else { + !popoverManager.isShown else { showButton = true return } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarPopoverManager.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarPopoverManager.swift new file mode 100644 index 0000000000..4a66937ea2 --- /dev/null +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarPopoverManager.swift @@ -0,0 +1,100 @@ +// +// NetworkProtectionNavBarPopoverModel.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 NetworkProtectionIPC +import NetworkProtectionUI + +#if NETWORK_PROTECTION +final class NetworkProtectionNavBarPopoverManager { + private var networkProtectionPopover: NetworkProtectionPopover? + let ipcClient: TunnelControllerIPCClient + + init(ipcClient: TunnelControllerIPCClient) { + self.ipcClient = ipcClient + } + + var isShown: Bool { +#if NETWORK_PROTECTION + networkProtectionPopover?.isShown ?? false +#else + return false +#endif + } + + private func show(_ popover: NSPopover, positionedBelow view: NSView) { + view.isHidden = false + + popover.show(positionedBelow: view.bounds.insetFromLineOfDeath(flipped: view.isFlipped), in: view) + } + + func show(positionedBelow view: NSView, withDelegate delegate: NSPopoverDelegate) { + + let popover = networkProtectionPopover ?? { + + let controller = NetworkProtectionIPCTunnelController(ipcClient: ipcClient) + + let statusReporter = DefaultNetworkProtectionStatusReporter( + statusObserver: ipcClient.connectionStatusObserver, + serverInfoObserver: ipcClient.serverInfoObserver, + connectionErrorObserver: ipcClient.connectionErrorObserver, + connectivityIssuesObserver: ConnectivityIssueObserverThroughDistributedNotifications(), + controllerErrorMessageObserver: ControllerErrorMesssageObserverThroughDistributedNotifications() + ) + + let menuItems = [ + NetworkProtectionStatusView.Model.MenuItem( + name: UserText.networkProtectionNavBarStatusViewShareFeedback, + action: { + let appLauncher = AppLauncher(appBundleURL: Bundle.main.bundleURL) + await appLauncher.launchApp(withCommand: .shareFeedback) + }) + ] + + let onboardingStatusPublisher = UserDefaults.shared.networkProtectionOnboardingStatusPublisher + + let popover = NetworkProtectionPopover(controller: controller, onboardingStatusPublisher: onboardingStatusPublisher, statusReporter: statusReporter, menuItems: menuItems) + popover.delegate = delegate + + networkProtectionPopover = popover + return popover + }() + + show(popover, positionedBelow: view) + } + + func toggle(positionedBelow view: NSView, withDelegate delegate: NSPopoverDelegate) { + if let networkProtectionPopover, networkProtectionPopover.isShown { + networkProtectionPopover.close() + } else { + let featureVisibility = DefaultNetworkProtectionVisibility() + + if featureVisibility.isNetworkProtectionVisible() { + show(positionedBelow: view, withDelegate: delegate) + } else { + featureVisibility.disableForWaitlistUsers() + } + } + } + + func close() { + networkProtectionPopover?.close() + } +} +#endif diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionSimulateFailureMenu.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionSimulateFailureMenu.swift index b0a3d7dcb3..f495cac5d6 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionSimulateFailureMenu.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionSimulateFailureMenu.swift @@ -52,7 +52,8 @@ final class NetworkProtectionSimulateFailureMenu: NSMenu { } private var simulationOptions: NetworkProtectionSimulationOptions { - NetworkProtectionTunnelController.simulationOptions + // Temporarily disabled: https://app.asana.com/0/0/1205766100762904/f + NetworkProtectionSimulationOptions() } /// Simulates a controller failure the next time Network Protection is started. @@ -64,17 +65,20 @@ final class NetworkProtectionSimulateFailureMenu: NSMenu { /// Simulates a tunnel failure the next time Network Protection is started. /// @objc func simulateTunnelFailure(_ menuItem: NSMenuItem) { - simulateFailure(NetworkProtectionTunnelController().toggleShouldSimulateTunnelFailure) + // Temporarily disabled: https://app.asana.com/0/0/1205766100762904/f + // simulateFailure(NetworkProtectionTunnelController().toggleShouldSimulateTunnelFailure) } /// Simulates a fatal error on the tunnel the next time Network Protection is started. /// @objc func simulateTunnelCrash(_ menuItem: NSMenuItem) { - simulateFailure(NetworkProtectionTunnelController().toggleShouldSimulateTunnelFatalError) + // Temporarily disabled: https://app.asana.com/0/0/1205766100762904/f + // simulateFailure(NetworkProtectionTunnelController().toggleShouldSimulateTunnelFatalError) } @objc func simulateConnectionInterruption(_ menuItem: NSMenuItem) { - simulateFailure(NetworkProtectionTunnelController().toggleShouldSimulateConnectionInterruption) + // Temporarily disabled: https://app.asana.com/0/0/1205766100762904/f + // simulateFailure(NetworkProtectionTunnelController().toggleShouldSimulateConnectionInterruption) } private func simulateFailure(_ simulationFunction: @escaping () async throws -> Void) { diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionTunnelController.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionTunnelController.swift index db5ecd841c..bc5ac23bc7 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionTunnelController.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionTunnelController.swift @@ -25,15 +25,22 @@ import Common import NetworkExtension import NetworkProtection import NetworkProtectionUI +import SystemExtensionManager import SystemExtensions import Networking -import LoginItems +import PixelKit typealias NetworkProtectionStatusChangeHandler = (NetworkProtection.ConnectionStatus) -> Void typealias NetworkProtectionConfigChangeHandler = () -> Void final class NetworkProtectionTunnelController: NetworkProtection.TunnelController { + let settings: TunnelSettings + + // MARK: - Combine Cancellables + + private var cancellables = Set() + // MARK: - Debug Helpers /// Debug simulation options to aid with testing NetP. @@ -55,43 +62,18 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle /// Auth token store private let tokenStore: NetworkProtectionTokenStore - // MARK: - Login Items - - private let loginItemsManager = LoginItemsManager() - // MARK: - Debug Options Support - private let debugUtilities = NetworkProtectionDebugUtilities() + private let networkExtensionBundleID: String + private let networkExtensionController: NetworkExtensionController - /// Kill Switch: Enable enforceRoutes flag - /// - /// Applies enforceRoutes setting, sets up excludedRoutes in MacPacketTunnelProvider and disables disconnect on failure - @MainActor - @UserDefaultsWrapper(key: .networkProtectionShouldEnforceRoutes, defaultValue: NetworkProtectionUserDefaultsConstants.shouldEnforceRoutes) - private(set) var shouldEnforceRoutes: Bool - - @MainActor - @UserDefaultsWrapper(key: .networkProtectionShouldIncludeAllNetworks, defaultValue: NetworkProtectionUserDefaultsConstants.shouldIncludeAllNetworks) - private(set) var shouldIncludeAllNetworks + // MARK: - User Defaults /// Test setting to exclude duckduckgo route from VPN @MainActor @UserDefaultsWrapper(key: .networkProtectionExcludedRoutes, defaultValue: [:]) private(set) var excludedRoutesPreferences: [String: Bool] - @MainActor - @UserDefaultsWrapper(key: .networkProtectionShouldExcludeLocalRoutes, defaultValue: NetworkProtectionUserDefaultsConstants.shouldExcludeLocalRoutes) - private(set) var shouldExcludeLocalRoutes: Bool - - /// When enabled VPN connection will be automatically initiated by DuckDuckGoAgentAppDelegate on launch even if disconnected manually (Always On rule disabled) - @MainActor - @UserDefaultsWrapper(key: .networkProtectionConnectOnLogIn, defaultValue: NetworkProtectionUserDefaultsConstants.shouldConnectOnLogIn, defaults: .shared) - private(set) var shouldAutoConnectOnLogIn: Bool - - @MainActor - @UserDefaultsWrapper(key: .networkProtectionConnectionTesterEnabled, defaultValue: NetworkProtectionUserDefaultsConstants.isConnectionTesterEnabled, defaults: .shared) - private(set) var isConnectionTesterEnabled: Bool - @UserDefaultsWrapper(key: .networkProtectionOnboardingStatusRawValue, defaultValue: OnboardingStatus.default.rawValue, defaults: .shared) private(set) var onboardingStatusRawValue: OnboardingStatus.RawValue @@ -106,7 +88,10 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle /// a VPN-access popup to the user. /// private func loadTunnelManager() async -> NETunnelProviderManager? { - try? await NETunnelProviderManager.loadAllFromPreferences().first + let tunnels = try? await NETunnelProviderManager.loadAllFromPreferences() + return tunnels?.first { + ($0.protocolConfiguration as? NETunnelProviderProtocol)?.providerBundleIdentifier == networkExtensionBundleID + } } private func loadOrMakeTunnelManager() async throws -> NETunnelProviderManager { @@ -130,12 +115,96 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle /// - notificationCenter: (meant for testing) the notification center that this object will use. /// - logger: (meant for testing) the logger that this object will use. /// - init(notificationCenter: NotificationCenter = .default, + init(networkExtensionBundleID: String, + networkExtensionController: NetworkExtensionController, + settings: TunnelSettings, + notificationCenter: NotificationCenter = .default, tokenStore: NetworkProtectionTokenStore = NetworkProtectionKeychainTokenStore(), logger: NetworkProtectionLogger = DefaultNetworkProtectionLogger()) { self.logger = logger + self.networkExtensionBundleID = networkExtensionBundleID + self.networkExtensionController = networkExtensionController + self.settings = settings self.tokenStore = tokenStore + + subscribeToSettingsChanges() + } + + // MARK: - Tunnel Settings + + private func subscribeToSettingsChanges() { + settings.changePublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] change in + guard let self else { return } + + Task { + // Offer the extension a chance to handle the settings change + try? await self.relaySettingsChange(change) + + // Handle the settings change right in the controller + try? await self.handleSettingsChange(change) + } + } + .store(in: &cancellables) + } + + /// This is where the tunnel has a chance to handle the settings change locally. + /// + /// The extension can also handle these changes so not everything needs to be handled here. + /// + private func handleSettingsChange(_ change: TunnelSettings.Change) async throws { + switch change { + case .setIncludeAllNetworks(let includeAllNetworks): + try await handleSetIncludeAllNetworks(includeAllNetworks) + case .setEnforceRoutes(let enforceRoutes): + try await handleSetEnforceRoutes(enforceRoutes) + case .setExcludeLocalNetworks(let excludeLocalNetworks): + try await handleSetExcludeLocalNetworks(excludeLocalNetworks) + case .setRegistrationKeyValidity, + .setSelectedServer: + // Intentional no-op as this is handled by the extension + break + } + } + + private func handleSetIncludeAllNetworks(_ includeAllNetworks: Bool) async throws { + guard let tunnelManager = await loadTunnelManager(), + tunnelManager.protocolConfiguration?.includeAllNetworks == !includeAllNetworks else { + return + } + + try await setupAndSave(tunnelManager) + } + + private func handleSetEnforceRoutes(_ enforceRoutes: Bool) async throws { + guard let tunnelManager = await loadTunnelManager(), + tunnelManager.protocolConfiguration?.enforceRoutes == !enforceRoutes else { + return + } + + try await setupAndSave(tunnelManager) + } + + private func handleSetExcludeLocalNetworks(_ excludeLocalNetworks: Bool) async throws { + guard let tunnelManager = await loadTunnelManager(), + tunnelManager.protocolConfiguration?.excludeLocalNetworks == !excludeLocalNetworks else { + return + } + + try await setupAndSave(tunnelManager) + updateRoutes() + } + + private func relaySettingsChange(_ change: TunnelSettings.Change) async throws { + guard await isConnected, + let activeSession = try await ConnectionSessionUtilities.activeSession(networkExtensionBundleID: networkExtensionBundleID) else { return } + + let errorMessage: ExtensionMessageString? = try await activeSession.sendProviderRequest(.changeTunnelSetting(change)) + if let errorMessage { + throw TunnelFailureError(errorDescription: errorMessage.value) + } } // MARK: - Tunnel Configuration @@ -166,11 +235,10 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle protocolConfiguration.disconnectOnSleep = false // kill switch - protocolConfiguration.enforceRoutes = shouldEnforceRoutes + protocolConfiguration.enforceRoutes = settings.enforceRoutes // this setting breaks Connection Tester - protocolConfiguration.includeAllNetworks = shouldIncludeAllNetworks - - protocolConfiguration.excludeLocalNetworks = shouldExcludeLocalRoutes + protocolConfiguration.includeAllNetworks = settings.includeAllNetworks + protocolConfiguration.excludeLocalNetworks = settings.excludeLocalNetworks return protocolConfiguration }() @@ -200,25 +268,47 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle // MARK: - Ensure things are working #if NETP_SYSTEM_EXTENSION - /// - Returns: `true` if the system extension and the background agent were activated successfully + /// Ensures that the system extension is activated if necessary. /// - private func ensureSystemExtensionIsActivated() async throws -> Bool { - var activated = false - - for try await event in SystemExtensionManager().activate() { - switch event { - case .waitingForUserApproval: - onboardingStatusRawValue = OnboardingStatus.isOnboarding(step: .userNeedsToAllowExtension).rawValue - case .activated: - self.controllerErrorStore.lastErrorMessage = nil - activated = true - case .willActivateAfterReboot: + private func activateSystemExtension(waitingForUserApproval: @escaping () -> Void) async throws { + do { + try await networkExtensionController.activateSystemExtension( + waitingForUserApproval: waitingForUserApproval) + } catch { + switch error { + case OSSystemExtensionError.requestSuperseded: + // Even if the installation request is superseded we want to show the message that tells the user + // to go to System Settings to allow the extension + controllerErrorStore.lastErrorMessage = UserText.networkProtectionSystemSettings + case SystemExtensionRequestError.unknownRequestResult: + controllerErrorStore.lastErrorMessage = UserText.networkProtectionUnknownActivationError + + PixelKit.fire( + NetworkProtectionPixelEvent.networkProtectionSystemExtensionUnknownActivationResult, + frequency: .standard, + includeAppVersionParameter: true) + case SystemExtensionRequestError.willActivateAfterReboot: controllerErrorStore.lastErrorMessage = UserText.networkProtectionPleaseReboot + default: + controllerErrorStore.lastErrorMessage = error.localizedDescription } + + return } - try? await Task.sleep(nanoseconds: 300 * NSEC_PER_MSEC) - return activated + self.controllerErrorStore.lastErrorMessage = nil + + // We'll only update to completed if we were showing the onboarding step to + // allow the system extension. Otherwise we may override the allow-VPN + // onboarding step. + // + // Additionally if the onboarding step was allowing the system extension, we won't + // start the tunnel at once, and instead require that the user enables the toggle. + // + if onboardingStatusRawValue == OnboardingStatus.isOnboarding(step: .userNeedsToAllowExtension).rawValue { + onboardingStatusRawValue = OnboardingStatus.isOnboarding(step: .userNeedsToAllowVPNConfiguration).rawValue + return + } } #endif @@ -245,31 +335,23 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle /// Starts the VPN connection used for Network Protection /// func start() async { - await start(enableLoginItems: true) - } - - func start(enableLoginItems: Bool) async { controllerErrorStore.lastErrorMessage = nil - do { #if NETP_SYSTEM_EXTENSION - guard try await ensureSystemExtensionIsActivated() else { - return - } - - // We'll only update to completed if we were showing the onboarding step to - // allow the system extension. Otherwise we may override the allow-VPN - // onboarding step. - // - // Additionally if the onboarding step was allowing the system extension, we won't - // start the tunnel at once, and instead require that the user enables the toggle. - // - if onboardingStatusRawValue == OnboardingStatus.isOnboarding(step: .userNeedsToAllowExtension).rawValue { - onboardingStatusRawValue = OnboardingStatus.isOnboarding(step: .userNeedsToAllowVPNConfiguration).rawValue - return + do { + try await activateSystemExtension { [weak self] in + // If we're waiting for user approval we wanna make sure the + // onboarding step is set correctly. This can be useful to + // help prevent the value from being de-synchronized. + self?.onboardingStatusRawValue = OnboardingStatus.isOnboarding(step: .userNeedsToAllowExtension).rawValue } + } catch { + await stop() + return + } #endif + do { let tunnelManager: NETunnelProviderManager do { @@ -283,10 +365,6 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle } onboardingStatusRawValue = OnboardingStatus.completed.rawValue - if enableLoginItems { - loginItemsManager.enableLoginItems(LoginItemsManager.networkProtectionLoginItems, log: .networkProtection) - } - switch tunnelManager.connection.status { case .invalid: throw StartError.connectionStatusInvalid @@ -296,11 +374,6 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle default: try await start(tunnelManager) } - } catch OSSystemExtensionError.requestSuperseded { - await stop() - // Even if the installation request is superseded we want to show the message that tells the user - // to go to System Settings to allow the extension - controllerErrorStore.lastErrorMessage = UserText.networkProtectionSystemSettings } catch { await stop() controllerErrorStore.lastErrorMessage = error.localizedDescription @@ -312,8 +385,11 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle options[NetworkProtectionOptionKey.activationAttemptId] = UUID().uuidString as NSString options[NetworkProtectionOptionKey.authToken] = try tokenStore.fetchToken() as NSString? - options[NetworkProtectionOptionKey.selectedServer] = debugUtilities.selectedServerName() as NSString? - options[NetworkProtectionOptionKey.keyValidity] = debugUtilities.registrationKeyValidity.map(String.init(describing:)) as NSString? + options[NetworkProtectionOptionKey.selectedServer] = settings.selectedServer.stringValue as? NSString + + if case .custom(let keyValidity) = settings.registrationKeyValidity { + options[NetworkProtectionOptionKey.keyValidity] = String(describing: keyValidity) as NSString + } if Self.simulationOptions.isEnabled(.tunnelFailure) { Self.simulationOptions.setEnabled(false, option: .tunnelFailure) @@ -366,7 +442,10 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle @MainActor func enableOnDemand(tunnelManager: NETunnelProviderManager) async throws { - tunnelManager.onDemandRules = [NEOnDemandRuleConnect(interfaceType: .any)] + let rule = NEOnDemandRuleConnect() + rule.interfaceTypeMatch = .any + + tunnelManager.onDemandRules = [rule] tunnelManager.isOnDemandEnabled = true try await tunnelManager.saveToPreferences() @@ -379,112 +458,16 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle try await tunnelManager.saveToPreferences() } - @MainActor - func enableEnforceRoutes() async throws { - shouldEnforceRoutes = true - - // calls setupAndSave where configuration is done - _=try await loadOrMakeTunnelManager() - } - - @MainActor - func disableEnforceRoutes() async throws { - shouldEnforceRoutes = false - - guard let tunnelManager = await loadTunnelManager(), - tunnelManager.protocolConfiguration?.enforceRoutes == true else { return } - - try await setupAndSave(tunnelManager) - } - - @MainActor - func enableIncludeAllNetworks() async throws { - shouldIncludeAllNetworks = true - - // calls setupAndSave where configuration is done - _=try await loadOrMakeTunnelManager() - } - - @MainActor - func disableIncludeAllNetworks() async throws { - shouldIncludeAllNetworks = false - - guard let tunnelManager = await loadTunnelManager(), - tunnelManager.protocolConfiguration?.includeAllNetworks == true else { return } - - try await setupAndSave(tunnelManager) - } - - @MainActor - func toggleShouldEnforceRoutes() { - shouldEnforceRoutes.toggle() - - // update configuration if connected - Task { [shouldEnforceRoutes] in - guard await isConnected else { return } - - if shouldEnforceRoutes { - try await enableEnforceRoutes() - } else { - try await disableEnforceRoutes() - } - } - } - - @MainActor - func toggleShouldIncludeAllNetworks() { - shouldIncludeAllNetworks.toggle() - - // update configuration if connected - Task { [shouldIncludeAllNetworks] in - guard await isConnected else { return } - - if shouldIncludeAllNetworks { - try await enableIncludeAllNetworks() - } else { - try await disableIncludeAllNetworks() - } - } - } - - // TO BE Refactored when the Exclusion List is added - enum ExclusionListItem { - case section(String) - case exclusion(range: NetworkProtection.IPAddressRange, description: String? = nil, `default`: Bool) - } - static let exclusionList: [ExclusionListItem] = [ - .section("IPv4 Local Routes"), - - .exclusion(range: "10.0.0.0/8" /* 255.0.0.0 */, description: "disabled for enforceRoutes", default: true), - .exclusion(range: "172.16.0.0/12" /* 255.240.0.0 */, default: true), - .exclusion(range: "192.168.0.0/16" /* 255.255.0.0 */, default: true), - .exclusion(range: "169.254.0.0/16" /* 255.255.0.0 */, description: "Link-local", default: true), - .exclusion(range: "127.0.0.0/8" /* 255.0.0.0 */, description: "Loopback", default: true), - .exclusion(range: "224.0.0.0/4" /* 240.0.0.0 (corrected subnet mask) */, description: "Multicast", default: true), - .exclusion(range: "100.64.0.0/16" /* 255.255.0.0 */, description: "Shared Address Space", default: true), - - .section("IPv6 Local Routes"), - .exclusion(range: "fe80::/10", description: "link local", default: false), - .exclusion(range: "ff00::/8", description: "multicast", default: false), - .exclusion(range: "fc00::/7", description: "local unicast", default: false), - .exclusion(range: "::1/128", description: "loopback", default: false), - - .section("duckduckgo.com"), - .exclusion(range: "52.142.124.215/32", default: false), - .exclusion(range: "52.250.42.157/32", default: false), - .exclusion(range: "40.114.177.156/32", default: false), - ] - @MainActor private func excludedRoutes() -> [NetworkProtection.IPAddressRange] { - Self.exclusionList.compactMap { [excludedRoutesPreferences] item -> NetworkProtection.IPAddressRange? in + settings.exclusionList.compactMap { [excludedRoutesPreferences] item -> NetworkProtection.IPAddressRange? in guard case .exclusion(range: let range, description: _, default: let defaultValue) = item, excludedRoutesPreferences[range.stringRepresentation, default: defaultValue] == true else { return nil } // TO BE fixed: // when 10.11.12.1 DNS is used 10.0.0.0/8 should be included (not excluded) // but marking 10.11.12.1 as an Included Route breaks tunnel (probably these routes are conflicting) - if shouldEnforceRoutes && range == "10.0.0.0/8" { + if settings.enforceRoutes && range == "10.0.0.0/8" { return nil } @@ -498,12 +481,6 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle [] } - @MainActor - func toggleShouldExcludeLocalRoutes() { - shouldExcludeLocalRoutes.toggle() - updateRoutes() - } - @MainActor func setExcludedRoute(_ route: String, enabled: Bool) { excludedRoutesPreferences[route] = enabled @@ -513,7 +490,7 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle @MainActor func isExcludedRouteEnabled(_ route: String) -> Bool { guard let range = IPAddressRange(from: route), - let exclusionListItem = Self.exclusionList.first(where: { + let exclusionListItem = settings.exclusionList.first(where: { if case .exclusion(range: range, description: _, default: _) = $0 { return true } return false }), @@ -523,7 +500,7 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle return false } // TO BE fixed: see excludedRoutes() - if shouldEnforceRoutes && route == "10.0.0.0/8" { + if settings.enforceRoutes && route == "10.0.0.0/8" { return false } return excludedRoutesPreferences[route, default: defaultValue] @@ -538,16 +515,6 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle } } - @MainActor - func toggleShouldAutoConnectOnLogIn() { - shouldAutoConnectOnLogIn.toggle() - } - - @MainActor - func toggleConnectionTesterEnabled() { - isConnectionTesterEnabled.toggle() - } - struct TunnelFailureError: LocalizedError { let errorDescription: String? } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionIPCTunnelController.swift b/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionIPCTunnelController.swift new file mode 100644 index 0000000000..e8b22a737b --- /dev/null +++ b/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionIPCTunnelController.swift @@ -0,0 +1,66 @@ +// +// NetworkProtectionIPCClient.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 NetworkProtectionIPC + +final class NetworkProtectionIPCTunnelController: TunnelController { + + private let loginItemsManager: LoginItemsManager + private let ipcClient: TunnelControllerIPCClient + + init(loginItemsManager: LoginItemsManager = LoginItemsManager(), + ipcClient: TunnelControllerIPCClient) { + + self.loginItemsManager = loginItemsManager + self.ipcClient = ipcClient + } + + func start() async { + enableLoginItems() + + ipcClient.start() + } + + func stop() async { + enableLoginItems() + + ipcClient.stop() + } + + /// Queries Network Protection to know if its VPN is connected. + /// + /// - Returns: `true` if the VPN is connected, connecting or reasserting, and `false` otherwise. + /// + var isConnected: Bool { + get { + if case .connected = ipcClient.connectionStatusObserver.recentValue { + return true + } + + return false + } + } + + // MARK: - Login Items Manager + + private func enableLoginItems() { + loginItemsManager.enableLoginItems(LoginItemsManager.networkProtectionLoginItems, log: .networkProtection) + } +} diff --git a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift index 85efd12c35..cea664b796 100644 --- a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift +++ b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift @@ -134,6 +134,7 @@ final class MacPacketTunnelProvider: PacketTunnelProvider { case .unhandledError(function: let function, line: let line, error: let error): domainEvent = .networkProtectionUnhandledError(function: function, line: line, error: error) } + PixelKit.fire(domainEvent, frequency: .dailyAndContinuous, includeAppVersionParameter: true) } } @@ -143,6 +144,7 @@ final class MacPacketTunnelProvider: PacketTunnelProvider { // MARK: - PacketTunnelProvider.Event reporting private static var packetTunnelProviderEvents: EventMapping = .init { event, _, _, _ in + switch event { case .userBecameActive: PixelKit.fire( @@ -332,7 +334,7 @@ final class MacPacketTunnelProvider: PacketTunnelProvider { log: .networkProtectionPixel) { (pixelName: String, headers: [String: String], parameters: [String: String], _, _, onComplete: @escaping (Error?) -> Void) in let url = URL.pixelUrl(forPixelNamed: pixelName) - let apiHeaders = APIRequest.Headers(additionalHeaders: headers) // workaround - Pixel class should really handle APIRequest.Headers by itself + let apiHeaders = APIRequest.Headers(additionalHeaders: headers) let configuration = APIRequest.Configuration(url: url, method: .get, queryParameters: parameters, headers: apiHeaders) let request = APIRequest(configuration: configuration) diff --git a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/NetworkProtectionPixelEvent.swift b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/NetworkProtectionPixelEvent.swift deleted file mode 100644 index a25cc9c7d9..0000000000 --- a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/NetworkProtectionPixelEvent.swift +++ /dev/null @@ -1,264 +0,0 @@ -// -// NetworkProtectionPixel.swift -// -// Copyright © 2023 DuckDuckGo. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#if NETWORK_PROTECTION - -import Foundation -import PixelKit -import NetworkProtection - -enum NetworkProtectionPixelEvent: PixelKitEvent { - - case networkProtectionActiveUser - - case networkProtectionTunnelConfigurationNoServerRegistrationInfo - case networkProtectionTunnelConfigurationCouldNotSelectClosestServer - case networkProtectionTunnelConfigurationCouldNotGetPeerPublicKey - case networkProtectionTunnelConfigurationCouldNotGetPeerHostName - case networkProtectionTunnelConfigurationCouldNotGetInterfaceAddressRange - - case networkProtectionClientFailedToFetchServerList(error: Error?) - case networkProtectionClientFailedToParseServerListResponse - case networkProtectionClientFailedToEncodeRegisterKeyRequest - case networkProtectionClientFailedToFetchRegisteredServers(error: Error?) - case networkProtectionClientFailedToParseRegisteredServersResponse - case networkProtectionClientFailedToEncodeRedeemRequest - case networkProtectionClientInvalidInviteCode - case networkProtectionClientFailedToRedeemInviteCode(error: Error?) - case networkProtectionClientFailedToParseRedeemResponse(error: Error) - case networkProtectionClientInvalidAuthToken - - case networkProtectionServerListStoreFailedToEncodeServerList - case networkProtectionServerListStoreFailedToDecodeServerList - case networkProtectionServerListStoreFailedToWriteServerList(error: Error) - case networkProtectionServerListStoreFailedToReadServerList(error: Error) - - case networkProtectionKeychainErrorFailedToCastKeychainValueToData(field: String) - case networkProtectionKeychainReadError(field: String, status: Int32) - case networkProtectionKeychainWriteError(field: String, status: Int32) - case networkProtectionKeychainDeleteError(status: Int32) - - case networkProtectionWireguardErrorCannotLocateTunnelFileDescriptor - case networkProtectionWireguardErrorInvalidState - case networkProtectionWireguardErrorFailedDNSResolution - case networkProtectionWireguardErrorCannotSetNetworkSettings(error: Error) - case networkProtectionWireguardErrorCannotStartWireguardBackend(code: Int32) - - case networkProtectionNoAuthTokenFoundError - - case networkProtectionRekeyCompleted - - case networkProtectionLatency(ms: Int, server: String, networkType: NetworkConnectionType) - - case networkProtectionSystemExtensionUnknownActivationResult - - case networkProtectionUnhandledError(function: String, line: Int, error: Error) - - var name: String { - switch self { - - case .networkProtectionActiveUser: - return "m_mac_netp_daily_active" - - case .networkProtectionTunnelConfigurationNoServerRegistrationInfo: - return "m_mac_netp_tunnel_config_error_no_server_registration_info" - - case .networkProtectionTunnelConfigurationCouldNotSelectClosestServer: - return "m_mac_netp_tunnel_config_error_could_not_select_closest_server" - - case .networkProtectionTunnelConfigurationCouldNotGetPeerPublicKey: - return "m_mac_netp_tunnel_config_error_could_not_get_peer_public_key" - - case .networkProtectionTunnelConfigurationCouldNotGetPeerHostName: - return "m_mac_netp_tunnel_config_error_could_not_get_peer_host_name" - - case .networkProtectionTunnelConfigurationCouldNotGetInterfaceAddressRange: - return "m_mac_netp_tunnel_config_error_could_not_get_interface_address_range" - - case .networkProtectionClientFailedToFetchServerList: - return "m_mac_netp_backend_api_error_failed_to_fetch_server_list" - - case .networkProtectionClientFailedToParseServerListResponse: - return "m_mac_netp_backend_api_error_parsing_server_list_response_failed" - - case .networkProtectionClientFailedToEncodeRegisterKeyRequest: - return "m_mac_netp_backend_api_error_encoding_register_request_body_failed" - - case .networkProtectionClientFailedToFetchRegisteredServers: - return "m_mac_netp_backend_api_error_failed_to_fetch_registered_servers" - - case .networkProtectionClientFailedToParseRegisteredServersResponse: - return "m_mac_netp_backend_api_error_parsing_device_registration_response_failed" - - case .networkProtectionClientFailedToEncodeRedeemRequest: - return "m_mac_netp_backend_api_error_encoding_redeem_request_body_failed" - - case .networkProtectionClientInvalidInviteCode: - return "m_mac_netp_backend_api_error_invalid_invite_code" - - case .networkProtectionClientFailedToRedeemInviteCode: - return "m_mac_netp_backend_api_error_failed_to_redeem_invite_code" - - case .networkProtectionClientFailedToParseRedeemResponse: - return "m_mac_netp_backend_api_error_parsing_redeem_response_failed" - - case .networkProtectionClientInvalidAuthToken: - return "m_mac_netp_backend_api_error_invalid_auth_token" - - case .networkProtectionServerListStoreFailedToEncodeServerList: - return "m_mac_netp_storage_error_failed_to_encode_server_list" - - case .networkProtectionServerListStoreFailedToDecodeServerList: - return "m_mac_netp_storage_error_failed_to_decode_server_list" - - case .networkProtectionServerListStoreFailedToWriteServerList: - return "m_mac_netp_storage_error_server_list_file_system_write_failed" - - case .networkProtectionServerListStoreFailedToReadServerList: - return "m_mac_netp_storage_error_server_list_file_system_read_failed" - - case .networkProtectionKeychainErrorFailedToCastKeychainValueToData: - return "m_mac_netp_keychain_error_failed_to_cast_keychain_value_to_data" - - case .networkProtectionKeychainReadError: - return "m_mac_netp_keychain_error_read_failed" - - case .networkProtectionKeychainWriteError: - return "m_mac_netp_keychain_error_write_failed" - - case .networkProtectionKeychainDeleteError: - return "m_mac_netp_keychain_error_delete_failed" - - case .networkProtectionWireguardErrorCannotLocateTunnelFileDescriptor: - return "m_mac_netp_wireguard_error_cannot_locate_tunnel_file_descriptor" - - case .networkProtectionWireguardErrorInvalidState: - return "m_mac_netp_wireguard_error_invalid_state" - - case .networkProtectionWireguardErrorFailedDNSResolution: - return "m_mac_netp_wireguard_error_failed_dns_resolution" - - case .networkProtectionWireguardErrorCannotSetNetworkSettings: - return "m_mac_netp_wireguard_error_cannot_set_network_settings" - - case .networkProtectionWireguardErrorCannotStartWireguardBackend: - return "m_mac_netp_wireguard_error_cannot_start_wireguard_backend" - - case .networkProtectionNoAuthTokenFoundError: - return "m_mac_netp_no_auth_token_found_error" - - case .networkProtectionRekeyCompleted: - return "m_mac_netp_rekey_completed" - - case .networkProtectionLatency: - return "m_mac_netp_latency" - - case .networkProtectionSystemExtensionUnknownActivationResult: - return "m_mac_netp_system_extension_unknown_activation_result" - - case .networkProtectionUnhandledError: - return "m_mac_netp_unhandled_error" - } - } - - var parameters: [String: String]? { - switch self { - case .networkProtectionKeychainErrorFailedToCastKeychainValueToData(let field): - return [PixelKit.Parameters.keychainFieldName: field] - - case .networkProtectionKeychainReadError(let field, let status): - return [ - PixelKit.Parameters.keychainFieldName: field, - PixelKit.Parameters.errorCode: String(status) - ] - - case .networkProtectionKeychainWriteError(let field, let status): - return [ - PixelKit.Parameters.keychainFieldName: field, - PixelKit.Parameters.errorCode: String(status) - ] - - case .networkProtectionKeychainDeleteError(let status): - return [ - PixelKit.Parameters.errorCode: String(status) - ] - - case .networkProtectionServerListStoreFailedToWriteServerList(let error): - return error.pixelParameters - - case .networkProtectionServerListStoreFailedToReadServerList(let error): - return error.pixelParameters - - case .networkProtectionClientFailedToFetchServerList(let error): - return error?.pixelParameters - - case .networkProtectionClientFailedToFetchRegisteredServers(let error): - return error?.pixelParameters - - case .networkProtectionClientFailedToRedeemInviteCode(error: let error): - return error?.pixelParameters - - case .networkProtectionUnhandledError(let function, let line, let error): - var parameters = error.pixelParameters - parameters[PixelKit.Parameters.function] = function - parameters[PixelKit.Parameters.line] = String(line) - return parameters - - case .networkProtectionLatency(ms: let latency, server: let server, networkType: let networkType): - return [ - PixelKit.Parameters.latency: String(latency), - PixelKit.Parameters.server: server, - PixelKit.Parameters.networkType: networkType.description - ] - - case .networkProtectionWireguardErrorCannotSetNetworkSettings(error: let error): - return error.pixelParameters - - case .networkProtectionWireguardErrorCannotStartWireguardBackend(code: let code): - return [ - PixelKit.Parameters.errorCode: String(code) - ] - - case .networkProtectionTunnelConfigurationNoServerRegistrationInfo, - .networkProtectionTunnelConfigurationCouldNotSelectClosestServer, - .networkProtectionTunnelConfigurationCouldNotGetPeerPublicKey, - .networkProtectionTunnelConfigurationCouldNotGetPeerHostName, - .networkProtectionTunnelConfigurationCouldNotGetInterfaceAddressRange, - .networkProtectionClientFailedToParseServerListResponse, - .networkProtectionClientFailedToEncodeRegisterKeyRequest, - .networkProtectionClientFailedToParseRegisteredServersResponse, - .networkProtectionClientFailedToParseRedeemResponse, - .networkProtectionClientInvalidInviteCode, - .networkProtectionClientFailedToEncodeRedeemRequest, - .networkProtectionClientInvalidAuthToken, - .networkProtectionServerListStoreFailedToEncodeServerList, - .networkProtectionServerListStoreFailedToDecodeServerList, - .networkProtectionNoAuthTokenFoundError, - .networkProtectionRekeyCompleted, - .networkProtectionWireguardErrorCannotLocateTunnelFileDescriptor, - .networkProtectionWireguardErrorInvalidState, - .networkProtectionWireguardErrorFailedDNSResolution, - .networkProtectionSystemExtensionUnknownActivationResult, - .networkProtectionActiveUser: - - return nil - } - } -} - -#endif diff --git a/DuckDuckGo/Statistics/PixelEvent.swift b/DuckDuckGo/Statistics/PixelEvent.swift index 378f69b640..d0fb923493 100644 --- a/DuckDuckGo/Statistics/PixelEvent.swift +++ b/DuckDuckGo/Statistics/PixelEvent.swift @@ -123,8 +123,6 @@ extension Pixel { case jsPixel(_ pixel: AutofillUserScript.JSPixel) - case networkProtectionSystemExtensionUnknownActivationResult - case debug(event: Debug, error: Error? = nil) // Activation Points @@ -272,18 +270,6 @@ extension Pixel { case userSelectedToInstallUpdate case userSelectedToDismissUpdate - case networkProtectionClientFailedToEncodeRedeemRequest - case networkProtectionClientInvalidInviteCode - case networkProtectionClientFailedToRedeemInviteCode(error: Error?) - case networkProtectionClientFailedToParseRedeemResponse(error: Error) - case networkProtectionClientInvalidAuthToken - case networkProtectionKeychainErrorFailedToCastKeychainValueToData(field: String) - case networkProtectionKeychainReadError(field: String, status: Int32) - case networkProtectionKeychainWriteError(field: String, status: Int32) - case networkProtectionKeychainDeleteError(status: Int32) - case networkProtectionNoAuthTokenFoundError - case networkProtectionUnhandledError(function: String, line: Int, error: Error) - case faviconDecryptionFailedUnique case downloadListItemDecryptionFailedUnique case historyEntryDecryptionFailedUnique @@ -412,8 +398,6 @@ extension Pixel.Event { return "m_mac.import-data.initial" case .newTabInitial: return "m_mac.new-tab-opened.initial" - case .networkProtectionSystemExtensionUnknownActivationResult: - return "m_mac_netp_system_extension_unknown_activation_result" case .favoriteSectionHidden: return "m_mac.favorite-section-hidden" case .recentActivitySectionHidden: @@ -677,29 +661,6 @@ extension Pixel.Event.Debug { case .userSelectedToDismissUpdate: return "user_selected_to_dismiss_update" - case .networkProtectionClientFailedToEncodeRedeemRequest: - return "netp_backend_api_error_encoding_redeem_request_body_failed" - case .networkProtectionClientInvalidInviteCode: - return "netp_backend_api_error_invalid_invite_code" - case .networkProtectionClientFailedToRedeemInviteCode: - return "netp_backend_api_error_failed_to_redeem_invite_code" - case .networkProtectionClientFailedToParseRedeemResponse: - return "netp_backend_api_error_parsing_redeem_response_failed" - case .networkProtectionClientInvalidAuthToken: - return "netp_backend_api_error_invalid_auth_token" - case .networkProtectionKeychainErrorFailedToCastKeychainValueToData: - return "netp_keychain_error_failed_to_cast_keychain_value_to_data" - case .networkProtectionKeychainReadError: - return "netp_keychain_error_read_failed" - case .networkProtectionKeychainWriteError: - return "netp_keychain_error_write_failed" - case .networkProtectionKeychainDeleteError: - return "netp_keychain_error_delete_failed" - case .networkProtectionNoAuthTokenFoundError: - return "netp_no_auth_token_found_error" - case .networkProtectionUnhandledError: - return "netp_unhandled_error" - case .faviconDecryptionFailedUnique: return "favicon_decryption_failed_unique" case .downloadListItemDecryptionFailedUnique: diff --git a/DuckDuckGo/Statistics/PixelParameters.swift b/DuckDuckGo/Statistics/PixelParameters.swift index 2fab15b4f1..642a598223 100644 --- a/DuckDuckGo/Statistics/PixelParameters.swift +++ b/DuckDuckGo/Statistics/PixelParameters.swift @@ -78,7 +78,6 @@ extension Pixel.Event { .watchInDuckPlayerInitial, .importDataInitial, .newTabInitial, - .networkProtectionSystemExtensionUnknownActivationResult, .favoriteSectionHidden, .recentActivitySectionHidden, .continueSetUpSectionHidden, diff --git a/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionUI/Controllers/AppLaunchingController.swift b/DuckDuckGo/UserAgent/Model/DuckDuckGoUserAgent.swift similarity index 59% rename from LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionUI/Controllers/AppLaunchingController.swift rename to DuckDuckGo/UserAgent/Model/DuckDuckGoUserAgent.swift index e56f6cee90..d5584675c2 100644 --- a/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionUI/Controllers/AppLaunchingController.swift +++ b/DuckDuckGo/UserAgent/Model/DuckDuckGoUserAgent.swift @@ -1,5 +1,5 @@ // -// AppLaunchingController.swift +// DuckDuckGoUserAgent.swift // // Copyright © 2023 DuckDuckGo. All rights reserved. // @@ -17,20 +17,14 @@ // import Foundation -import NetworkProtection +import Common -public final class AppLaunchingController: TunnelController { - private let appLauncher: AppLaunching +enum UserAgent { - public init(appLauncher: AppLaunching) { - self.appLauncher = appLauncher + static func duckDuckGoUserAgent(appVersion: String = AppVersion.shared.versionNumber, + appID: String = AppVersion.shared.identifier, + systemVersion: String = ProcessInfo.processInfo.operatingSystemVersionString) -> String { + return "ddg_mac/\(appVersion) (\(appID); macOS \(systemVersion))" } - public func start() async { - await appLauncher.launchApp(withCommand: .startVPN) - } - - public func stop() async { - await appLauncher.launchApp(withCommand: .stopVPN) - } } diff --git a/DuckDuckGo/UserAgent/Model/UserAgent.swift b/DuckDuckGo/UserAgent/Model/UserAgent.swift index 97d59953b1..276f88fc9a 100644 --- a/DuckDuckGo/UserAgent/Model/UserAgent.swift +++ b/DuckDuckGo/UserAgent/Model/UserAgent.swift @@ -20,7 +20,7 @@ import Foundation import BrowserServicesKit import Common -enum UserAgent { +extension UserAgent { // MARK: - Fallback versions @@ -68,12 +68,6 @@ enum UserAgent { regex("https://duckduckgo\\.com/.*"): UserAgent.webViewDefault ] - static func duckDuckGoUserAgent(appVersion: String = AppVersion.shared.versionNumber, - appID: String = AppVersion.shared.identifier, - systemVersion: String = ProcessInfo.processInfo.operatingSystemVersionString) -> String { - return "ddg_mac/\(appVersion) (\(appID); macOS \(systemVersion))" - } - static func `for`(_ url: URL?, privacyConfig: PrivacyConfiguration = ContentBlocking.shared.privacyConfigurationManager.privacyConfig) -> String { guard let absoluteString = url?.absoluteString else { diff --git a/DuckDuckGo/Waitlist/NetworkProtectionFeatureDisabler.swift b/DuckDuckGo/Waitlist/NetworkProtectionFeatureDisabler.swift index 828224bb14..6f21a07abc 100644 --- a/DuckDuckGo/Waitlist/NetworkProtectionFeatureDisabler.swift +++ b/DuckDuckGo/Waitlist/NetworkProtectionFeatureDisabler.swift @@ -22,6 +22,7 @@ import BrowserServicesKit import Common import NetworkExtension import NetworkProtection +import NetworkProtectionIPC import NetworkProtectionUI import SystemExtensions @@ -33,20 +34,23 @@ final class NetworkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling private let log: OSLog private let loginItemsManager: LoginItemsManager private let pinningManager: LocalPinningManager - private let selectedServerUserDefaultsStore: NetworkProtectionSelectedServerUserDefaultsStore + private let settings: TunnelSettings private let userDefaults: UserDefaults + private let ipcClient: TunnelControllerIPCClient init(loginItemsManager: LoginItemsManager = LoginItemsManager(), pinningManager: LocalPinningManager = .shared, userDefaults: UserDefaults = .shared, - selectedServerUserDefaultsStore: NetworkProtectionSelectedServerUserDefaultsStore = NetworkProtectionSelectedServerUserDefaultsStore(), + settings: TunnelSettings = .init(defaults: .shared), + ipcClient: TunnelControllerIPCClient = TunnelControllerIPCClient(machServiceName: Bundle.main.vpnMenuAgentBundleId), log: OSLog = .networkProtection) { self.log = log self.loginItemsManager = loginItemsManager self.pinningManager = pinningManager - self.selectedServerUserDefaultsStore = selectedServerUserDefaultsStore + self.settings = settings self.userDefaults = userDefaults + self.ipcClient = ipcClient } /// This method disables Network Protection and clear all of its state. @@ -58,6 +62,11 @@ final class NetworkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling func disable(keepAuthToken: Bool, uninstallSystemExtension: Bool) { Task { unpinNetworkProtection() + + if uninstallSystemExtension { + await resetAllStateForVPNApp(uninstallSystemExtension: uninstallSystemExtension) + } + disableLoginItems() await resetNetworkExtensionState() @@ -72,10 +81,6 @@ final class NetworkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling if !keepAuthToken { try? removeAppAuthToken() } - - if uninstallSystemExtension { - try? await disableSystemExtension() - } } } @@ -83,16 +88,11 @@ final class NetworkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling loginItemsManager.disableLoginItems(LoginItemsManager.networkProtectionLoginItems) } - func disableSystemExtension() async throws { + func resetAllStateForVPNApp(uninstallSystemExtension: Bool) async { + await ipcClient.resetAll(uninstallSystemExtension: uninstallSystemExtension) + #if NETP_SYSTEM_EXTENSION - do { - try await SystemExtensionManager().deactivate() - userDefaults.networkProtectionOnboardingStatusRawValue = OnboardingStatus.default.rawValue - } catch OSSystemExtensionError.extensionNotFound { - // This is an intentional no-op to silence this type of error - } catch { - throw error - } + userDefaults.networkProtectionOnboardingStatusRawValue = OnboardingStatus.default.rawValue #endif } @@ -124,8 +124,8 @@ final class NetworkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling } private func resetUserDefaults() { - selectedServerUserDefaultsStore.reset() - userDefaults.networkProtectionOnboardingStatusRawValue = OnboardingStatus.isOnboarding(step: .userNeedsToAllowVPNConfiguration).rawValue + settings.resetToDefaults() + userDefaults.networkProtectionOnboardingStatusRawValue = OnboardingStatus.default.rawValue } } diff --git a/DuckDuckGo/Waitlist/Waitlist.swift b/DuckDuckGo/Waitlist/Waitlist.swift index 8321a79e37..39886b0505 100644 --- a/DuckDuckGo/Waitlist/Waitlist.swift +++ b/DuckDuckGo/Waitlist/Waitlist.swift @@ -209,7 +209,6 @@ struct NetworkProtectionWaitlist: Waitlist { NotificationCenter.default.post(name: .networkProtectionWaitlistAccessChanged, object: nil) completion(nil) } catch { - assertionFailure("Failed to redeem invite code") completion(.failure(error)) } } diff --git a/DuckDuckGoAgent/FeatureProtectedTunnelController.swift b/DuckDuckGoAgent/FeatureProtectedTunnelController.swift deleted file mode 100644 index bbff5da7a8..0000000000 --- a/DuckDuckGoAgent/FeatureProtectedTunnelController.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// 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/AppLauncher+DefaultInitializer.swift b/DuckDuckGoVPN/AppLauncher+DefaultInitializer.swift similarity index 100% rename from DuckDuckGoAgent/AppLauncher+DefaultInitializer.swift rename to DuckDuckGoVPN/AppLauncher+DefaultInitializer.swift diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-128.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-128.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-128.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-128.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-128@2x.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-128@2x.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-128@2x.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-128@2x.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-16.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-16.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-16.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-16.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-16@2x.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-16@2x.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-16@2x.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-16@2x.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-256.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-256.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-256.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-256.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-256@2x.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-256@2x.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-256@2x.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-256@2x.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-32.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-32.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-32.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-32.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-32@2x.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-32@2x.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-32@2x.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-32@2x.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-512.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-512.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-512.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-512.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-512@2x.png b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-512@2x.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Browser-512@2x.png rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Browser-512@2x.png diff --git a/DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Contents.json b/DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/AppIcon.appiconset/Contents.json rename to DuckDuckGoVPN/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/DuckDuckGoAgent/Assets.xcassets/Contents.json b/DuckDuckGoVPN/Assets.xcassets/Contents.json similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Contents.json rename to DuckDuckGoVPN/Assets.xcassets/Contents.json diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Contents.json b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Contents.json similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Contents.json rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Contents.json diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-1024.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-1024.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-1024.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-1024.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-128.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-128.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-128.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-128.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-16.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-16.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-16.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-16.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-256.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-256.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-256.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-256.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-257.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-257.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-257.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-257.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-32.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-32.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-32.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-32.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-33.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-33.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-33.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-33.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-512.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-512.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-512.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-512.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-513.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-513.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-513.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-513.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-64.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-64.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-64.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Debug.appiconset/Debug Icon-64.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-1024.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-1024.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-1024.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-1024.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-128.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-128.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-128.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-128.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-16.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-16.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-16.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-16.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-256.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-256.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-256.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-256.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-257.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-257.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-257.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-257.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-32.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-32.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-32.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-32.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-33.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-33.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-33.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-33.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-512.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-512.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-512.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-512.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-513.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-513.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-513.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-513.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-64.png b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-64.png similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Beta Icon-64.png rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Beta Icon-64.png diff --git a/DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Contents.json b/DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Contents.json similarity index 100% rename from DuckDuckGoAgent/Assets.xcassets/Icon - Review.appiconset/Contents.json rename to DuckDuckGoVPN/Assets.xcassets/Icon - Review.appiconset/Contents.json diff --git a/NetworkProtectionVPNController/Main.swift b/DuckDuckGoVPN/Bundle+Configuration.swift similarity index 62% rename from NetworkProtectionVPNController/Main.swift rename to DuckDuckGoVPN/Bundle+Configuration.swift index 4b1d144bd7..936c44a4a8 100644 --- a/NetworkProtectionVPNController/Main.swift +++ b/DuckDuckGoVPN/Bundle+Configuration.swift @@ -1,5 +1,5 @@ // -// Main.swift +// Bundle+Configuration.swift // // Copyright © 2023 DuckDuckGo. All rights reserved. // @@ -18,8 +18,14 @@ import Foundation -@main -final class AppMain { - static func main() throws { +extension Bundle { + private static let networkExtensionBundleIDKey = "SYSEX_BUNDLE_ID" + + var networkExtensionBundleID: String { + guard let bundleID = object(forInfoDictionaryKey: Self.networkExtensionBundleIDKey) as? String else { + fatalError("Info.plist is missing \(Self.networkExtensionBundleIDKey)") + } + + return bundleID } } diff --git a/DuckDuckGoVPN/DuckDuckGoVPN.entitlements b/DuckDuckGoVPN/DuckDuckGoVPN.entitlements new file mode 100644 index 0000000000..653311b9ec --- /dev/null +++ b/DuckDuckGoVPN/DuckDuckGoVPN.entitlements @@ -0,0 +1,20 @@ + + + + + com.apple.developer.networking.networkextension + + packet-tunnel-provider-systemextension + + com.apple.developer.system-extension.install + + com.apple.security.application-groups + + $(NETP_APP_GROUP) + + keychain-access-groups + + $(NETP_APP_GROUP) + + + diff --git a/DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift b/DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift new file mode 100644 index 0000000000..39492c7f20 --- /dev/null +++ b/DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift @@ -0,0 +1,180 @@ +// +// DuckDuckGoVPNAppDelegate.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 Cocoa +import Combine +import Common +import Networking +import NetworkExtension +import NetworkProtection +import NetworkProtectionIPC +import NetworkProtectionUI +import ServiceManagement +import PixelKit + +@objc(Application) +final class DuckDuckGoVPNApplication: NSApplication { + private let _delegate = DuckDuckGoVPNAppDelegate() + + override init() { + os_log(.error, log: .networkProtection, "🟢 Status Bar Agent starting: %{public}d", NSRunningApplication.current.processIdentifier) + + // prevent agent from running twice + if let anotherInstance = NSRunningApplication.runningApplications(withBundleIdentifier: Bundle.main.bundleIdentifier!).first(where: { $0 != .current }) { + os_log(.error, log: .networkProtection, "🔴 Stopping: another instance is running: %{public}d.", anotherInstance.processIdentifier) + exit(0) + } + + super.init() + self.delegate = _delegate + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +@main +final class DuckDuckGoVPNAppDelegate: NSObject, NSApplicationDelegate { + + private static let recentThreshold: TimeInterval = 5.0 + + private let appLauncher = AppLauncher() + private let bouncer = NetworkProtectionBouncer() + + var networkExtensionBundleID: String { + Bundle.main.networkExtensionBundleID + } + +#if NETP_SYSTEM_EXTENSION + private lazy var networkExtensionController = NetworkExtensionController(extensionBundleID: networkExtensionBundleID) +#endif + + private lazy var tunnelController = NetworkProtectionTunnelController( + networkExtensionBundleID: networkExtensionBundleID, + networkExtensionController: networkExtensionController, + settings: .init(defaults: .shared)) + + /// An IPC server that provides access to the tunnel controller. + /// + /// This is used by our main app to control the tunnel through the VPN login item. + /// + private lazy var tunnelControllerIPCService: TunnelControllerIPCService = { + let ipcServer = TunnelControllerIPCService( + tunnelController: tunnelController, + networkExtensionController: networkExtensionController, + statusReporter: statusReporter) + ipcServer.activate() + return ipcServer + }() + + private lazy var statusReporter: NetworkProtectionStatusReporter = { + let errorObserver = ConnectionErrorObserverThroughSession( + platformNotificationCenter: NSWorkspace.shared.notificationCenter, + platformDidWakeNotification: NSWorkspace.didWakeNotification) + + let statusObserver = ConnectionStatusObserverThroughSession( + platformNotificationCenter: NSWorkspace.shared.notificationCenter, + platformDidWakeNotification: NSWorkspace.didWakeNotification) + + let serverInfoObserver = ConnectionServerInfoObserverThroughSession( + platformNotificationCenter: NSWorkspace.shared.notificationCenter, + platformDidWakeNotification: NSWorkspace.didWakeNotification) + + return DefaultNetworkProtectionStatusReporter( + statusObserver: statusObserver, + serverInfoObserver: serverInfoObserver, + connectionErrorObserver: errorObserver, + connectivityIssuesObserver: ConnectivityIssueObserverThroughDistributedNotifications(), + controllerErrorMessageObserver: ControllerErrorMesssageObserverThroughDistributedNotifications() + ) + }() + + /// The status bar NetworkProtection menu + /// + /// For some reason the App will crash if this is initialized right away, which is why it was changed to be lazy. + /// + @MainActor + private lazy var networkProtectionMenu: StatusBarMenu = { + #if DEBUG + let iconProvider = DebugMenuIconProvider() + #elseif REVIEW + let iconProvider = ReviewMenuIconProvider() + #else + let iconProvider = MenuIconProvider() + #endif + + 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) + }) + ] + + let onboardingStatusPublisher = UserDefaults.shared.publisher(for: \.networkProtectionOnboardingStatusRawValue).map { rawValue in + OnboardingStatus(rawValue: rawValue) ?? .default + }.eraseToAnyPublisher() + + return StatusBarMenu( + onboardingStatusPublisher: onboardingStatusPublisher, + statusReporter: statusReporter, + controller: tunnelController, + iconProvider: iconProvider, + menuItems: menuItems) + }() + + func applicationDidFinishLaunching(_ aNotification: Notification) { + APIRequest.Headers.setUserAgent(UserAgent.duckDuckGoUserAgent()) + + os_log("DuckDuckGoVPN started", log: .networkProtectionLoginItemLog, type: .info) + networkProtectionMenu.show() + + bouncer.requireAuthTokenOrKillApp() + + // Initialize the IPC server + _ = tunnelControllerIPCService + + PixelKit.setUp(dryRun: false, appVersion: AppVersion.shared.versionNumber, defaultHeaders: [:], log: .networkProtectionPixel) { (pixelName: String, headers: [String: String], parameters: [String: String], _, _, onComplete: @escaping (Error?) -> Void) in + + let url = URL.pixelUrl(forPixelNamed: pixelName) + let apiHeaders = APIRequest.Headers(additionalHeaders: headers) // workaround - Pixel class should really handle APIRequest.Headers by itself + let configuration = APIRequest.Configuration(url: url, method: .get, queryParameters: parameters, headers: apiHeaders) + let request = APIRequest(configuration: configuration) + + request.fetch { _, error in + onComplete(error) + } + } + } +} + +extension NSApplication { + + enum RunType: Int, CustomStringConvertible { + case normal + var description: String { + switch self { + case .normal: return "normal" + } + } + } + static var runType: RunType { .normal } + +} diff --git a/DuckDuckGoAgent/DuckDuckGoAgentAppStore.entitlements b/DuckDuckGoVPN/DuckDuckGoVPNAppStore.entitlements similarity index 100% rename from DuckDuckGoAgent/DuckDuckGoAgentAppStore.entitlements rename to DuckDuckGoVPN/DuckDuckGoVPNAppStore.entitlements diff --git a/DuckDuckGoAgent/DuckDuckGoAgent.entitlements b/DuckDuckGoVPN/DuckDuckGoVPNDebug.entitlements similarity index 67% rename from DuckDuckGoAgent/DuckDuckGoAgent.entitlements rename to DuckDuckGoVPN/DuckDuckGoVPNDebug.entitlements index 789b6b3174..a6ed34f64f 100644 --- a/DuckDuckGoAgent/DuckDuckGoAgent.entitlements +++ b/DuckDuckGoVPN/DuckDuckGoVPNDebug.entitlements @@ -2,13 +2,19 @@ - keychain-access-groups + com.apple.developer.networking.networkextension - $(NETP_APP_GROUP) + packet-tunnel-provider + com.apple.developer.system-extension.install + com.apple.security.application-groups $(NETP_APP_GROUP) + keychain-access-groups + + $(NETP_APP_GROUP) + diff --git a/DuckDuckGoAgent/Info-AppStore.plist b/DuckDuckGoVPN/Info-AppStore.plist similarity index 100% rename from DuckDuckGoAgent/Info-AppStore.plist rename to DuckDuckGoVPN/Info-AppStore.plist diff --git a/DuckDuckGoAgent/Info.plist b/DuckDuckGoVPN/Info.plist similarity index 88% rename from DuckDuckGoAgent/Info.plist rename to DuckDuckGoVPN/Info.plist index 5d64b03a02..7627fdd9c9 100644 --- a/DuckDuckGoAgent/Info.plist +++ b/DuckDuckGoVPN/Info.plist @@ -6,6 +6,8 @@ $(DISTRIBUTED_NOTIFICATIONS_PREFIX) NETP_APP_GROUP $(NETP_APP_GROUP) + SYSEX_BUNDLE_ID + $(SYSEX_BUNDLE_ID) LSApplicationCategoryType public.app-category.productivity CFBundleShortVersionString diff --git a/DuckDuckGoVPN/NetworkExtensionController.swift b/DuckDuckGoVPN/NetworkExtensionController.swift new file mode 100644 index 0000000000..954f47f8ee --- /dev/null +++ b/DuckDuckGoVPN/NetworkExtensionController.swift @@ -0,0 +1,55 @@ +// +// NetworkExtensionController.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 NetworkProtectionUI +import SystemExtensionManager +import SystemExtensions + +/// Network Protection's network extension session object. +/// +/// Through this class the app that owns the VPN can interact with the network extension. +/// +final class NetworkExtensionController { + + private let systemExtensionManager: SystemExtensionManager + + init(extensionBundleID: String) { + systemExtensionManager = SystemExtensionManager(extensionBundleID: extensionBundleID) + } +} + +extension NetworkExtensionController { + func activateSystemExtension(waitingForUserApproval: @escaping () -> Void) async throws { + try await systemExtensionManager.activate( + waitingForUserApproval: waitingForUserApproval) + + try? await Task.sleep(nanoseconds: 300 * NSEC_PER_MSEC) + } + + func deactivateSystemExtension() async throws { + do { + try await systemExtensionManager.deactivate() + } catch OSSystemExtensionError.extensionNotFound { + // This is an intentional no-op to silence this type of error + // since on deactivation this is ok. + } catch { + throw error + } + } +} diff --git a/DuckDuckGoAgent/NetworkProtectionBouncer.swift b/DuckDuckGoVPN/NetworkProtectionBouncer.swift similarity index 100% rename from DuckDuckGoAgent/NetworkProtectionBouncer.swift rename to DuckDuckGoVPN/NetworkProtectionBouncer.swift diff --git a/DuckDuckGoVPN/TunnelControllerIPCService.swift b/DuckDuckGoVPN/TunnelControllerIPCService.swift new file mode 100644 index 0000000000..7d6f8263dc --- /dev/null +++ b/DuckDuckGoVPN/TunnelControllerIPCService.swift @@ -0,0 +1,117 @@ +// +// TunnelControllerIPCService.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 Combine +import Foundation +import NetworkProtection +import NetworkProtectionIPC + +/// Takes care of handling incoming IPC requests from clients that need to be relayed to the tunnel, and handling state +/// changes that need to be relayed back to IPC clients. +/// +/// This also includes the tunnel settings which are controller through shared `UserDefaults` as a form of IPC. +/// Clients can edit those defaults and this class will observe the changes and relay them to the runnel. +/// +final class TunnelControllerIPCService { + private let tunnelController: TunnelController + private let networkExtensionController: NetworkExtensionController + private let server: NetworkProtectionIPC.TunnelControllerIPCServer + private let statusReporter: NetworkProtectionStatusReporter + private var cancellables = Set() + + init(tunnelController: TunnelController, + networkExtensionController: NetworkExtensionController, + statusReporter: NetworkProtectionStatusReporter) { + + self.tunnelController = tunnelController + self.networkExtensionController = networkExtensionController + server = .init(machServiceName: Bundle.main.bundleIdentifier!) + self.statusReporter = statusReporter + + subscribeToErrorChanges() + subscribeToStatusUpdates() + subscribeToServerChanges() + + server.serverDelegate = self + } + + public func activate() { + server.activate() + } + + private func subscribeToErrorChanges() { + statusReporter.connectionErrorObserver.publisher + .subscribe(on: DispatchQueue.main) + .sink { [weak self] error in + self?.server.errorChanged(error) + } + .store(in: &cancellables) + } + + private func subscribeToServerChanges() { + statusReporter.serverInfoObserver.publisher + .subscribe(on: DispatchQueue.main) + .sink { [weak self] serverInfo in + self?.server.serverInfoChanged(serverInfo) + } + .store(in: &cancellables) + } + + private func subscribeToStatusUpdates() { + statusReporter.statusObserver.publisher + .subscribe(on: DispatchQueue.main) + .sink { [weak self] status in + self?.server.statusChanged(status) + } + .store(in: &cancellables) + } +} + +// MARK: - Requests from the client + +extension TunnelControllerIPCService: IPCServerInterface { + + func register() { + server.serverInfoChanged(statusReporter.serverInfoObserver.recentValue) + server.statusChanged(statusReporter.statusObserver.recentValue) + } + + func start() { + Task { + await tunnelController.start() + } + } + + func stop() { + Task { + await tunnelController.stop() + } + } + + func resetAll(uninstallSystemExtension: Bool) async { + try? await networkExtensionController.deactivateSystemExtension() + } + + func debugCommand(_ command: DebugCommand) async { + guard let activeSession = try? await ConnectionSessionUtilities.activeSession(networkExtensionBundleID: Bundle.main.networkExtensionBundleID) else { + return + } + + try? await activeSession.sendProviderRequest(.debugCommand(command)) + } +} diff --git a/DuckDuckGoAgent/UserText.swift b/DuckDuckGoVPN/UserText.swift similarity index 100% rename from DuckDuckGoAgent/UserText.swift rename to DuckDuckGoVPN/UserText.swift diff --git a/LocalPackages/Account/Package.swift b/LocalPackages/Account/Package.swift index 896df7c3df..e27d552c00 100644 --- a/LocalPackages/Account/Package.swift +++ b/LocalPackages/Account/Package.swift @@ -12,7 +12,7 @@ let package = Package( targets: ["Account"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "81.4.1"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "81.5.0"), .package(path: "../Purchase") ], targets: [ diff --git a/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift b/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift index 196f5a1c20..465cc664ac 100644 --- a/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift +++ b/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift @@ -25,15 +25,13 @@ let nonSandboxedExtraInputFiles: Set = [ .init("BWEncryptionOutput.m", .source), .init("BWManager.swift", .source), .init("UpdateController.swift", .source), - .init("SystemExtensionManager.swift", .source), - .init("DuckDuckGo Agent.app", .unknown), + .init("DuckDuckGo VPN.app", .unknown), .init("DuckDuckGo Notifications.app", .unknown), - .init("startVPN.app", .unknown), - .init("stopVPN.app", .unknown), - .init("enableOnDemand.app", .unknown), .init("PFMoveApplication.m", .source), .init("NetworkProtectionBundle.swift", .source), .init("NetworkProtectionAppEvents.swift", .source), + .init("NetworkProtectionIPCTunnelController.swift", .source), + .init("NetworkProtectionNavBarPopoverManager.swift", .source), .init("KeychainType+ClientDefault.swift", .source) ] diff --git a/LocalPackages/DataBrokerProtection/Package.swift b/LocalPackages/DataBrokerProtection/Package.swift index e0c106350f..9b64c6775e 100644 --- a/LocalPackages/DataBrokerProtection/Package.swift +++ b/LocalPackages/DataBrokerProtection/Package.swift @@ -29,7 +29,7 @@ let package = Package( targets: ["DataBrokerProtection"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "81.4.1"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "81.5.0"), .package(path: "../PixelKit"), .package(path: "../SwiftUIExtensions") ], diff --git a/LocalPackages/LoginItems/Sources/LoginItems/LoginItem.swift b/LocalPackages/LoginItems/Sources/LoginItems/LoginItem.swift index 04b430f83b..a826b70904 100644 --- a/LocalPackages/LoginItems/Sources/LoginItems/LoginItem.swift +++ b/LocalPackages/LoginItems/Sources/LoginItems/LoginItem.swift @@ -26,7 +26,6 @@ import ServiceManagement public struct LoginItem: Equatable, Hashable { let agentBundleID: String - let url: URL private let log: OSLog public var isRunning: Bool { @@ -71,9 +70,8 @@ public struct LoginItem: Equatable, Hashable { return Status(SMAppService.loginItem(identifier: agentBundleID).status) } - public init(bundleId: String, url: URL, log: OSLog) { + public init(bundleId: String, log: OSLog = .disabled) { self.agentBundleID = bundleId - self.url = url self.log = log } @@ -95,7 +93,6 @@ public struct LoginItem: Equatable, Hashable { } else { SMLoginItemSetEnabled(agentBundleID as CFString, false) } - stop() } /// Restarts a login item. @@ -111,17 +108,11 @@ public struct LoginItem: Equatable, Hashable { try enable() } - public func launch() async throws { - os_log("🟢 launching login item %{public}@", log: log, self.debugDescription) - _ = try await NSWorkspace.shared.openApplication(at: url, configuration: .init()) - } - - private func stop() { + public func forceStop() { let runningApplications = runningApplications os_log("🟢 stopping %{public}@", log: log, runningApplications.map { $0.processIdentifier }.description) runningApplications.forEach { $0.terminate() } } - } extension LoginItem: CustomDebugStringConvertible { diff --git a/LocalPackages/NetworkProtectionMac/Package.swift b/LocalPackages/NetworkProtectionMac/Package.swift index 535d7df188..5283f115be 100644 --- a/LocalPackages/NetworkProtectionMac/Package.swift +++ b/LocalPackages/NetworkProtectionMac/Package.swift @@ -31,8 +31,8 @@ let package = Package( .library(name: "NetworkProtectionUI", targets: ["NetworkProtectionUI"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "81.4.1"), - .package(path: "../XPC"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "81.5.0"), + .package(path: "../XPCHelper"), .package(path: "../SwiftUIExtensions") ], targets: [ @@ -42,7 +42,7 @@ let package = Package( name: "NetworkProtectionIPC", dependencies: [ .product(name: "NetworkProtection", package: "BrowserServicesKit"), - .product(name: "XPC", package: "XPC") + .product(name: "XPCHelper", package: "XPCHelper") ]), // MARK: - NetworkProtectionUI diff --git a/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionIPC/TunnelControllerIPCClient.swift b/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionIPC/TunnelControllerIPCClient.swift index 26b547d6d7..8143bc7ca9 100644 --- a/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionIPC/TunnelControllerIPCClient.swift +++ b/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionIPC/TunnelControllerIPCClient.swift @@ -18,7 +18,7 @@ import Foundation import NetworkProtection -import XPC +import XPCHelper /// This protocol describes the client-side IPC interface for controlling the tunnel /// @@ -79,6 +79,18 @@ extension TunnelControllerIPCClient: IPCServerInterface { public func stop() { try? xpc.server().stop() } + + public func resetAll(uninstallSystemExtension: Bool) async { + try? await xpc.server().resetAll(uninstallSystemExtension: uninstallSystemExtension) + } + + public func debugCommand(_ command: DebugCommand) async { + guard let payload = try? JSONEncoder().encode(command) else { + return + } + + try? await xpc.server().debugCommand(payload) + } } // MARK: - Incoming communication from the server diff --git a/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionIPC/TunnelControllerIPCServer.swift b/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionIPC/TunnelControllerIPCServer.swift index 46a4c33631..ccabc5f144 100644 --- a/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionIPC/TunnelControllerIPCServer.swift +++ b/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionIPC/TunnelControllerIPCServer.swift @@ -18,7 +18,7 @@ import Foundation import NetworkProtection -import XPC +import XPCHelper /// This protocol describes the server-side IPC interface for controlling the tunnel /// @@ -36,6 +36,14 @@ public protocol IPCServerInterface: AnyObject { /// Stop the VPN tunnel. /// func stop() + + /// Resets all of Network Protection's state that's handled by the server + /// + func resetAll(uninstallSystemExtension: Bool) async + + /// Debug commands + /// + func debugCommand(_ command: DebugCommand) async } /// This protocol describes the server-side XPC interface. @@ -58,6 +66,14 @@ protocol XPCServerInterface { /// Stop the VPN tunnel. /// func stop() + + /// Resets all of Network Protection's state that's handled by the server + /// + func resetAll(uninstallSystemExtension: Bool) async + + /// Debug commands + /// + func debugCommand(_ payload: Data) async } public final class TunnelControllerIPCServer { @@ -139,4 +155,16 @@ extension TunnelControllerIPCServer: XPCServerInterface { func stop() { serverDelegate?.stop() } + + func resetAll(uninstallSystemExtension: Bool) async { + await serverDelegate?.resetAll(uninstallSystemExtension: uninstallSystemExtension) + } + + func debugCommand(_ payload: Data) async { + guard let command = try? JSONDecoder().decode(DebugCommand.self, from: payload) else { + return + } + + await serverDelegate?.debugCommand(command) + } } diff --git a/LocalPackages/NetworkProtectionMac/Tests/NetworkProtectionUITests/NetworkProtectionStatusBarMenuTests.swift b/LocalPackages/NetworkProtectionMac/Tests/NetworkProtectionUITests/NetworkProtectionStatusBarMenuTests.swift index 06611c6e95..39236a194e 100644 --- a/LocalPackages/NetworkProtectionMac/Tests/NetworkProtectionUITests/NetworkProtectionStatusBarMenuTests.swift +++ b/LocalPackages/NetworkProtectionMac/Tests/NetworkProtectionUITests/NetworkProtectionStatusBarMenuTests.swift @@ -34,6 +34,10 @@ final class StatusBarMenuTests: XCTestCase { func stop() async { // no-op } + + var isConnected: Bool { + true + } } @MainActor diff --git a/LocalPackages/NetworkProtectionMac/Tests/NetworkProtectionUITests/TunnelControllerViewModelTests.swift b/LocalPackages/NetworkProtectionMac/Tests/NetworkProtectionUITests/TunnelControllerViewModelTests.swift index 2070272881..f49264b5fb 100644 --- a/LocalPackages/NetworkProtectionMac/Tests/NetworkProtectionUITests/TunnelControllerViewModelTests.swift +++ b/LocalPackages/NetworkProtectionMac/Tests/NetworkProtectionUITests/TunnelControllerViewModelTests.swift @@ -79,7 +79,7 @@ final class TunnelControllerViewModelTests: XCTestCase { var startCallback: (() -> Void)? var stopCallback: (() -> Void)? - func isConnected() async -> Bool { + var isConnected: Bool { connected } diff --git a/LocalPackages/SystemExtensionManager/.gitignore b/LocalPackages/SystemExtensionManager/.gitignore new file mode 100644 index 0000000000..0023a53406 --- /dev/null +++ b/LocalPackages/SystemExtensionManager/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/LocalPackages/XPC/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/LocalPackages/SystemExtensionManager/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from LocalPackages/XPC/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to LocalPackages/SystemExtensionManager/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/LocalPackages/SystemExtensionManager/Package.swift b/LocalPackages/SystemExtensionManager/Package.swift new file mode 100644 index 0000000000..a8797ae4a1 --- /dev/null +++ b/LocalPackages/SystemExtensionManager/Package.swift @@ -0,0 +1,24 @@ +// swift-tools-version: 5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SystemExtensionManager", + platforms: [ + .iOS("14.0"), + .macOS("11.4") + ], + products: [ + // Products define the executables and libraries a package produces, making them visible to other packages. + .library( + name: "SystemExtensionManager", + targets: ["SystemExtensionManager"]), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "SystemExtensionManager") + ] +) diff --git a/LocalPackages/SystemExtensionManager/README.md b/LocalPackages/SystemExtensionManager/README.md new file mode 100644 index 0000000000..55d6a36ae9 --- /dev/null +++ b/LocalPackages/SystemExtensionManager/README.md @@ -0,0 +1,5 @@ +# SystemExtensionManager + +SystemExtensionManager library. + +- Offers convenience code for interacting and managing System Extensions diff --git a/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/SystemExtensionManager.swift b/LocalPackages/SystemExtensionManager/Sources/SystemExtensionManager/SystemExtensionManager.swift similarity index 72% rename from DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/SystemExtensionManager.swift rename to LocalPackages/SystemExtensionManager/Sources/SystemExtensionManager/SystemExtensionManager.swift index c3198e08d2..64d7ca5a62 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/SystemExtensionManager.swift +++ b/LocalPackages/SystemExtensionManager/Sources/SystemExtensionManager/SystemExtensionManager.swift @@ -21,30 +21,30 @@ import Cocoa import Combine @preconcurrency import SystemExtensions -struct SystemExtensionManager { +public enum SystemExtensionRequestError: Error { + case unknownRequestResult + case willActivateAfterReboot +} - enum ActivationRequestEvent { - case waitingForUserApproval - case activated - case willActivateAfterReboot - } +public struct SystemExtensionManager { private static let systemSettingsSecurityURL = "x-apple.systempreferences:com.apple.preference.security?Security" - private let bundleID: String + private let extensionBundleID: String private let manager: OSSystemExtensionManager private let workspace: NSWorkspace - init(bundleID: String = NetworkProtectionBundle.extensionBundle().bundleIdentifier!, - manager: OSSystemExtensionManager = .shared, - workspace: NSWorkspace = .shared) { + public init( + extensionBundleID: String, + manager: OSSystemExtensionManager = .shared, + workspace: NSWorkspace = .shared) { - self.bundleID = bundleID + self.extensionBundleID = extensionBundleID self.manager = manager self.workspace = workspace } - func activate() -> AsyncThrowingStream { + public func activate(waitingForUserApproval: @escaping () -> Void) async throws { /// Documenting a workaround for the issue discussed in https://app.asana.com/0/0/1205275221447702/f /// Background: For a lot of users, the system won't show the system-extension-blocked alert if there's a previous request /// to activate the extension. You can see active requests in your console using command `systemextensionsctl list`. @@ -62,11 +62,18 @@ struct SystemExtensionManager { openSystemSettingsSecurity() } - return SystemExtensionRequest.activationRequest(forExtensionWithIdentifier: bundleID, manager: manager).submit() + return try await SystemExtensionRequest.activationRequest( + forExtensionWithIdentifier: extensionBundleID, + manager: manager, + waitingForUserApproval: waitingForUserApproval) + .submit() } - func deactivate() async throws { - for try await _ in SystemExtensionRequest.deactivationRequest(forExtensionWithIdentifier: bundleID, manager: manager).submit() {} + public func deactivate() async throws { + try await SystemExtensionRequest.deactivationRequest( + forExtensionWithIdentifier: extensionBundleID, + manager: manager) + .submit() } // MARK: - Activation: Checking if there are pending requests @@ -84,7 +91,7 @@ struct SystemExtensionManager { task.standardOutput = pipe task.launchPath = "/bin/bash" // Specify the shell to use - task.arguments = ["-c", "$(which systemextensionsctl) list | $(which egrep) -c '(?:\(bundleID)).+(?:activated waiting for user)+'"] + task.arguments = ["-c", "$(which systemextensionsctl) list | $(which egrep) -c '(?:\(extensionBundleID)).+(?:activated waiting for user)+'"] task.launch() task.waitUntilExit() @@ -102,43 +109,40 @@ struct SystemExtensionManager { } final class SystemExtensionRequest: NSObject { - typealias Event = SystemExtensionManager.ActivationRequestEvent private let request: OSSystemExtensionRequest private let manager: OSSystemExtensionManager + private let waitingForUserApproval: (() -> Void)? - private var continuation: AsyncThrowingStream.Continuation? + private var continuation: CheckedContinuation? - private init(request: OSSystemExtensionRequest, manager: OSSystemExtensionManager) { + private init(request: OSSystemExtensionRequest, manager: OSSystemExtensionManager, waitingForUserApproval: (() -> Void)? = nil) { self.manager = manager self.request = request + self.waitingForUserApproval = waitingForUserApproval super.init() } - static func activationRequest(forExtensionWithIdentifier bundleId: String, manager: OSSystemExtensionManager) -> Self { - self.init(request: .activationRequest(forExtensionWithIdentifier: bundleId, queue: .global()), manager: manager) + static func activationRequest(forExtensionWithIdentifier bundleId: String, manager: OSSystemExtensionManager, waitingForUserApproval: (() -> Void)?) -> Self { + self.init(request: .activationRequest(forExtensionWithIdentifier: bundleId, queue: .global()), manager: manager, waitingForUserApproval: waitingForUserApproval) } static func deactivationRequest(forExtensionWithIdentifier bundleId: String, manager: OSSystemExtensionManager) -> Self { self.init(request: .deactivationRequest(forExtensionWithIdentifier: bundleId, queue: .global()), manager: manager) } - /// submitting the request returns an Async Iterator providing the OSSystemExtensionRequest state change events - /// until an Event is received. - func submit() -> AsyncThrowingStream { + /// Submit the request + /// + func submit() async throws { assert(continuation == nil, "Request can only be submitted once") - defer { + try await withCheckedThrowingContinuation { continuation in + self.continuation = continuation + request.delegate = self manager.submitRequest(request) } - return AsyncThrowingStream { [self /* keep the request delegate alive */] continuation in - continuation.onTermination = { _ in - withExtendedLifetime(self) {} - } - self.continuation = continuation - } } } @@ -150,26 +154,26 @@ extension SystemExtensionRequest: OSSystemExtensionRequestDelegate { } func requestNeedsUserApproval(_ request: OSSystemExtensionRequest) { - continuation?.yield(.waitingForUserApproval) + waitingForUserApproval?() } func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) { switch result { case .completed: - continuation?.yield(.activated) + continuation?.resume() case .willCompleteAfterReboot: - continuation?.yield(.willActivateAfterReboot) + continuation?.resume(throwing: SystemExtensionRequestError.willActivateAfterReboot) + return @unknown default: - // Not much we can do about this, so let's assume it's a good result and not show any errors - continuation?.yield(.activated) - Pixel.fire(.networkProtectionSystemExtensionUnknownActivationResult) + // Not much we can do about this, so we just let the owning app decide + // what to do about this. + continuation?.resume(throwing: SystemExtensionRequestError.unknownRequestResult) + return } - - continuation?.finish() } func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) { - continuation?.finish(throwing: error) + continuation?.resume(throwing: error) } } diff --git a/LocalPackages/XPC/README.md b/LocalPackages/XPC/README.md deleted file mode 100644 index a60d3d9736..0000000000 --- a/LocalPackages/XPC/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# XPC - -XPC library. - -- Offers XPC Communication convenience classes. diff --git a/LocalPackages/XPC/.gitignore b/LocalPackages/XPCHelper/.gitignore similarity index 100% rename from LocalPackages/XPC/.gitignore rename to LocalPackages/XPCHelper/.gitignore diff --git a/LocalPackages/XPCHelper/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/LocalPackages/XPCHelper/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/LocalPackages/XPCHelper/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/LocalPackages/XPC/.swiftpm/xcode/xcshareddata/xcschemes/Intercom.xcscheme b/LocalPackages/XPCHelper/.swiftpm/xcode/xcshareddata/xcschemes/Intercom.xcscheme similarity index 100% rename from LocalPackages/XPC/.swiftpm/xcode/xcshareddata/xcschemes/Intercom.xcscheme rename to LocalPackages/XPCHelper/.swiftpm/xcode/xcshareddata/xcschemes/Intercom.xcscheme diff --git a/LocalPackages/XPCHelper/.swiftpm/xcode/xcshareddata/xcschemes/XPC.xcscheme b/LocalPackages/XPCHelper/.swiftpm/xcode/xcshareddata/xcschemes/XPC.xcscheme new file mode 100644 index 0000000000..f1880e533b --- /dev/null +++ b/LocalPackages/XPCHelper/.swiftpm/xcode/xcshareddata/xcschemes/XPC.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LocalPackages/XPC/Package.swift b/LocalPackages/XPCHelper/Package.swift similarity index 92% rename from LocalPackages/XPC/Package.swift rename to LocalPackages/XPCHelper/Package.swift index 7bb423e313..5eef7930ba 100644 --- a/LocalPackages/XPC/Package.swift +++ b/LocalPackages/XPCHelper/Package.swift @@ -21,14 +21,13 @@ import PackageDescription let package = Package( - name: "XPC", + name: "XPCHelper", platforms: [ - .iOS("14.0"), .macOS("11.4") ], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. - .library(name: "XPC", targets: ["XPC"]), + .library(name: "XPCHelper", targets: ["XPCHelper"]), ], dependencies: [ // Dependencies declare other packages that this package depends on. @@ -38,7 +37,7 @@ let package = Package( // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( - name: "XPC", + name: "XPCHelper", dependencies: []) ] ) diff --git a/LocalPackages/XPCHelper/README.md b/LocalPackages/XPCHelper/README.md new file mode 100644 index 0000000000..463d4fb03c --- /dev/null +++ b/LocalPackages/XPCHelper/README.md @@ -0,0 +1,5 @@ +# XPCHelper + +XPC helpers library. + +- Offers XPC Communication helper code diff --git a/LocalPackages/XPC/Sources/XPC/XPCClient.swift b/LocalPackages/XPCHelper/Sources/XPCHelper/XPCClient.swift similarity index 100% rename from LocalPackages/XPC/Sources/XPC/XPCClient.swift rename to LocalPackages/XPCHelper/Sources/XPCHelper/XPCClient.swift diff --git a/LocalPackages/XPC/Sources/XPC/XPCServer.swift b/LocalPackages/XPCHelper/Sources/XPCHelper/XPCServer.swift similarity index 100% rename from LocalPackages/XPC/Sources/XPC/XPCServer.swift rename to LocalPackages/XPCHelper/Sources/XPCHelper/XPCServer.swift diff --git a/scripts/assets/ExportOptions.plist b/scripts/assets/ExportOptions.plist index e44b4b5089..ac199e54dd 100644 --- a/scripts/assets/ExportOptions.plist +++ b/scripts/assets/ExportOptions.plist @@ -18,14 +18,14 @@ Sandbox MacOS Browser Release com.duckduckgo.mobile.ios.review Sandbox MacOS Browser Product Review - com.duckduckgo.macos.browser.network-protection-extension - macOS NetP System Extension - Release - com.duckduckgo.macos.browser.review.network-protection-extension - macOS NetP System Extension - Review - HKE973VLUW.com.duckduckgo.macos.browser.network-protection.system-extension.agent - macOS Network Protection Agent App (Distribution) - HKE973VLUW.com.duckduckgo.macos.browser.network-protection.system-extension.agent.review - macOS Network Protection Agent App Product Review + com.duckduckgo.macos.vpn.network-extension + macOS NetP VPN SysEx - Release (XPC) + com.duckduckgo.macos.vpn.network-extension.review + macOS NetP VPN SysEx - Review (XPC) + com.duckduckgo.macos.vpn + macOS NetP VPN App - Release (XPC) + com.duckduckgo.macos.vpn.review + macOS NetP VPN App - Review (XPC) HKE973VLUW.com.duckduckgo.macos.browser.network-protection.notifications Mac Browser NetP Developer ID Not. (Distribution) HKE973VLUW.com.duckduckgo.macos.browser.network-protection.notifications.review