diff --git a/Configuration/App/AppTargetsBase.xcconfig b/Configuration/App/AppTargetsBase.xcconfig index 421cb83bb9..2b0615645f 100644 --- a/Configuration/App/AppTargetsBase.xcconfig +++ b/Configuration/App/AppTargetsBase.xcconfig @@ -15,10 +15,10 @@ #include "../Common.xcconfig" -ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon -ASSETCATALOG_COMPILER_APPICON_NAME[config=Debug] = Icon - Debug -ASSETCATALOG_COMPILER_APPICON_NAME[config=CI] = Icon - Debug -ASSETCATALOG_COMPILER_APPICON_NAME[config=Review] = Icon - Review +ASSETCATALOG_COMPILER_APPICON_NAME[sdk=*] = AppIcon +ASSETCATALOG_COMPILER_APPICON_NAME[config=Debug][sdk=*] = Icon - Debug +ASSETCATALOG_COMPILER_APPICON_NAME[config=CI][sdk=*] = Icon - Debug +ASSETCATALOG_COMPILER_APPICON_NAME[config=Review][sdk=*] = Icon - Review ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = GlobalAccentColor diff --git a/Configuration/App/DuckDuckGo.xcconfig b/Configuration/App/DuckDuckGo.xcconfig index 53e3bf56dd..9f937ea63b 100644 --- a/Configuration/App/DuckDuckGo.xcconfig +++ b/Configuration/App/DuckDuckGo.xcconfig @@ -14,20 +14,53 @@ // #include "AppTargetsBase.xcconfig" +#include "../NetworkProtectionDeveloperID.xcconfig" BUNDLE_IDENTIFIER_PREFIX = com.duckduckgo.macos.browser CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGo.entitlements +CODE_SIGN_ENTITLEMENTS[config=Debug][arch=*][sdk=*] = DuckDuckGo/DuckDuckGoDebug.entitlements CODE_SIGN_ENTITLEMENTS[config=CI][arch=*][sdk=*] = DuckDuckGo/DuckDuckGoCI.entitlements CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development CODE_SIGN_IDENTITY[config=CI][sdk=macosx*] = +FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION + PRODUCT_NAME_PREFIX = DuckDuckGo PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = MacOS Browser PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = MacOS Browser Product Review +GCC_PREPROCESSOR_DEFINITIONS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION=1 +GCC_PREPROCESSOR_DEFINITIONS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION=1 DEBUG=1 CI=1 $(inherited) +GCC_PREPROCESSOR_DEFINITIONS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION=1 DEBUG=1 $(inherited) +GCC_PREPROCESSOR_DEFINITIONS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION=1 REVIEW=1 $(inherited) + +SWIFT_ACTIVE_COMPILATION_CONDITIONS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION $(FEATURE_FLAGS) +SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION DEBUG CI $(FEATURE_FLAGS) +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] = /; +INSTALL_PATH[config=Debug] = Applications/DEBUG; + #include? "../../LocalOverrides.xcconfig" diff --git a/Configuration/App/DuckDuckGoAppStore.xcconfig b/Configuration/App/DuckDuckGoAppStore.xcconfig index 0de25b2b11..62b292f820 100644 --- a/Configuration/App/DuckDuckGoAppStore.xcconfig +++ b/Configuration/App/DuckDuckGoAppStore.xcconfig @@ -17,6 +17,11 @@ #include "../AppStore.xcconfig" #include "ManualAppStoreRelease.xcconfig" +AGENT_BUNDLE_ID[sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.agent +AGENT_BUNDLE_ID[config=Debug][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.agent.debug +AGENT_BUNDLE_ID[config=CI][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.agent.debug +AGENT_BUNDLE_ID[config=Review][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.agent.review + BUNDLE_IDENTIFIER_PREFIX = com.duckduckgo.mobile.ios CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGoAppStore.entitlements diff --git a/Configuration/App/NetworkProtection/DuckDuckGoAgent.xcconfig b/Configuration/App/NetworkProtection/DuckDuckGoAgent.xcconfig new file mode 100644 index 0000000000..56fbe6f393 --- /dev/null +++ b/Configuration/App/NetworkProtection/DuckDuckGoAgent.xcconfig @@ -0,0 +1,62 @@ +// 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 "../AppTargetsBase.xcconfig" +#include "../../NetworkProtectionDeveloperID.xcconfig" + +BUNDLE_IDENTIFIER_PREFIX = $(AGENT_BUNDLE_ID) + +// Override AppTargetsBase.xcconfig until we resolve bundle IDs. +PRODUCT_BUNDLE_IDENTIFIER[sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX) +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 +GENERATE_INFOPLIST_FILE = YES +INFOPLIST_KEY_LSUIElement = YES +INFOPLIST_KEY_NSPrincipalClass = Application + +// Just make sure to override anything set by the AppTargetBase.xcconfig +//CODE_SIGN_STYLE[config=Debug][sdk=*] = Manual +//CODE_SIGN_STYLE[config=Release][sdk=*] = Manual + +// 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/DuckDuckGoAgent.entitlements +CODE_SIGN_ENTITLEMENTS[config=Release][sdk=macosx*] = DuckDuckGoAgent/DuckDuckGoAgent.entitlements + +CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application +CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development +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) + +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 + +ENABLE_APP_SANDBOX = YES +SWIFT_OBJC_BRIDGING_HEADER = +SKIP_INSTALL = YES +ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = + +#include? "../../../LocalOverrides.xcconfig" diff --git a/Configuration/App/NetworkProtection/DuckDuckGoAgentAppStore.xcconfig b/Configuration/App/NetworkProtection/DuckDuckGoAgentAppStore.xcconfig new file mode 100644 index 0000000000..93dab9befe --- /dev/null +++ b/Configuration/App/NetworkProtection/DuckDuckGoAgentAppStore.xcconfig @@ -0,0 +1,62 @@ +// 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 "../AppTargetsBase.xcconfig" +#include "../../AppStore.xcconfig" + +BUNDLE_IDENTIFIER_PREFIX = HKE973VLUW.com.duckduckgo.macos.browser.network-protection.agent + +// Override AppTargetsBase.xcconfig until we resolve bundle IDs. +PRODUCT_BUNDLE_IDENTIFIER[sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX) +PRODUCT_BUNDLE_IDENTIFIER[config=Debug][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).debug +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 +GENERATE_INFOPLIST_FILE = YES +INFOPLIST_KEY_LSUIElement = YES +INFOPLIST_KEY_NSPrincipalClass = Application + +// Just make sure to override anything set by the AppTargetBase.xcconfig +//CODE_SIGN_STYLE[config=Debug][sdk=*] = Manual +//CODE_SIGN_STYLE[config=Release][sdk=*] = Manual + +// 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_IDENTITY[sdk=macosx*] = 3rd Party Mac Developer Application +CODE_SIGN_IDENTITY[config=Review][sdk=macosx*] = Developer ID Application +CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development +CODE_SIGN_IDENTITY[config=CI][sdk=macosx*] = + +PRODUCT_NAME = $(AGENT_PRODUCT_NAME) + +PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = +PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = Mac Browser NetP Developer ID Not. (Distribution) + +FEATURE_FLAGS[arch=*][sdk=*] = +FEATURE_FLAGS[config=CI][arch=*][sdk=*] = +FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = +FEATURE_FLAGS[config=Review][arch=*][sdk=*] = + +ENABLE_APP_SANDBOX = YES +SWIFT_OBJC_BRIDGING_HEADER = +SKIP_INSTALL = YES +ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = + +#include? "../../../LocalOverrides.xcconfig" diff --git a/Configuration/App/NetworkProtection/DuckDuckGoNotifications.xcconfig b/Configuration/App/NetworkProtection/DuckDuckGoNotifications.xcconfig new file mode 100644 index 0000000000..c1b60b0bc1 --- /dev/null +++ b/Configuration/App/NetworkProtection/DuckDuckGoNotifications.xcconfig @@ -0,0 +1,58 @@ +// 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 "../AppTargetsBase.xcconfig" +#include "../../NetworkProtectionDeveloperID.xcconfig" + +BUNDLE_IDENTIFIER_PREFIX = $(NOTIFICATIONS_AGENT_BUNDLE_ID) + +// Override AppTargetsBase.xcconfig until we resolve bundle IDs. +PRODUCT_BUNDLE_IDENTIFIER[sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX) +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 = DuckDuckGoNotifications/Info.plist +GENERATE_INFOPLIST_FILE = YES +INFOPLIST_KEY_LSUIElement = YES +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*] = DuckDuckGoNotifications/DuckDuckGoNotifications.entitlements +CODE_SIGN_ENTITLEMENTS[config=Release][sdk=macosx*] = DuckDuckGoNotifications/DuckDuckGoNotifications.entitlements + +CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application +CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development +CODE_SIGN_IDENTITY[config=CI][sdk=macosx*] = + +PRODUCT_NAME_PREFIX = $(NOTIFICATIONS_AGENT_PRODUCT_NAME) +PRODUCT_NAME[config=Review][arch=*][sdk=*] = $(NOTIFICATIONS_AGENT_PRODUCT_NAME) + +PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = +PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = MacOS Browser NetP Notifications Product Review +PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = Mac Browser NetP Developer ID Not. (Distribution) + +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 + +SWIFT_OBJC_BRIDGING_HEADER = +SKIP_INSTALL = YES +ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = + +#include? "../../../LocalOverrides.xcconfig" diff --git a/Configuration/App/NetworkProtection/NetworkProtectionStartStopVPNBase.xcconfig b/Configuration/App/NetworkProtection/NetworkProtectionStartStopVPNBase.xcconfig new file mode 100644 index 0000000000..01016dc681 --- /dev/null +++ b/Configuration/App/NetworkProtection/NetworkProtectionStartStopVPNBase.xcconfig @@ -0,0 +1,82 @@ +// 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/App/NetworkProtection/NetworkProtectionStartVPN.xcconfig b/Configuration/App/NetworkProtection/NetworkProtectionStartVPN.xcconfig new file mode 100644 index 0000000000..736bd03fd6 --- /dev/null +++ b/Configuration/App/NetworkProtection/NetworkProtectionStartVPN.xcconfig @@ -0,0 +1,23 @@ +// 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 "NetworkProtectionStartStopVPNBase.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 new file mode 100644 index 0000000000..93605fdcf2 --- /dev/null +++ b/Configuration/App/NetworkProtection/NetworkProtectionStopVPN.xcconfig @@ -0,0 +1,23 @@ +// 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 "NetworkProtectionStartStopVPNBase.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/AppStore.xcconfig b/Configuration/AppStore.xcconfig index d79d56f070..bb3cd9a4d3 100644 --- a/Configuration/AppStore.xcconfig +++ b/Configuration/AppStore.xcconfig @@ -27,3 +27,16 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS[arch=*][sdk=*] = APPSTORE $(FEATURE_FLAGS) SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=CI][arch=*][sdk=*] = APPSTORE DEBUG CI $(FEATURE_FLAGS) SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug][arch=*][sdk=*] = APPSTORE DEBUG $(FEATURE_FLAGS) SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Review][arch=*][sdk=*] = APPSTORE REVIEW $(FEATURE_FLAGS) + +NETP_BASE_APP_GROUP = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection +NETP_APP_GROUP[config=CI][sdk=macos*] = $(NETP_BASE_APP_GROUP).debug +NETP_APP_GROUP[config=Review][sdk=macos*] = $(NETP_BASE_APP_GROUP).review +NETP_APP_GROUP[config=Debug][sdk=macos*] = $(NETP_BASE_APP_GROUP).debug +NETP_APP_GROUP[config=Release][sdk=macos*] = $(NETP_BASE_APP_GROUP) + +AGENT_BUNDLE_ID[sdk=*] = HKE973VLUW.com.duckduckgo.macos.browser.network-protection.agent +AGENT_BUNDLE_ID[config=Debug][sdk=*] = HKE973VLUW.com.duckduckgo.macos.browser.network-protection.agent.debug +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 diff --git a/Configuration/Extensions/ExtensionBase.xcconfig b/Configuration/Extensions/ExtensionBase.xcconfig new file mode 100644 index 0000000000..076f1bfc2c --- /dev/null +++ b/Configuration/Extensions/ExtensionBase.xcconfig @@ -0,0 +1,39 @@ +// Copyright © 2022 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" + +CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES +CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES + +CODE_SIGN_STYLE[sdk=*] = Manual + +CURRENT_PROJECT_VERSION = $(MARKETING_VERSION) + +ENABLE_HARDENED_RUNTIME = YES + +PRODUCT_BUNDLE_IDENTIFIER[sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX) +PRODUCT_BUNDLE_IDENTIFIER[config=Debug][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).debug +PRODUCT_BUNDLE_IDENTIFIER[config=CI][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).debug +PRODUCT_BUNDLE_IDENTIFIER[config=Review][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).review + +LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks + +PRODUCT_NAME = $(TARGET_NAME) +INFOPLIST_KEY_CFBundleDisplayName = $(TARGET_NAME) + +SWIFT_OBJC_BRIDGING_HEADER = + +SWIFT_STRICT_CONCURRENCY = minimal; // Temporarily disabled to expedite the NetP merge diff --git a/Configuration/Extensions/NetworkProtection/NetworkProtectionAppExtension.xcconfig b/Configuration/Extensions/NetworkProtection/NetworkProtectionAppExtension.xcconfig new file mode 100644 index 0000000000..52e0e2aa00 --- /dev/null +++ b/Configuration/Extensions/NetworkProtection/NetworkProtectionAppExtension.xcconfig @@ -0,0 +1,47 @@ +// 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 "../ExtensionBase.xcconfig" + +// Since we're using nonstandard bundle IDs we'll just define them here, but we should consider +// standardizing the bundle IDs so we can just define BUNDLE_IDENTIFIER_PREFIX +BUNDLE_IDENTIFIER_PREFIX = com.duckduckgo.mobile.ios + +CODE_SIGN_ENTITLEMENTS[config=CI][sdk=macosx*] = +CODE_SIGN_ENTITLEMENTS[config=Debug][sdk=macosx*] = DuckDuckGo/NetworkProtectionAppExtension.entitlements +CODE_SIGN_ENTITLEMENTS[config=Release][sdk=macosx*] = DuckDuckGo/NetworkProtectionAppExtension.entitlements +CODE_SIGN_ENTITLEMENTS[config=Review][sdk=macosx*] = DuckDuckGo/NetworkProtectionAppExtension.entitlements +CODE_SIGN_STYLE[config=Debug][sdk=*] = Automatic + +GENERATE_INFOPLIST_FILE = YES +INFOPLIST_FILE = NetworkProtectionAppExtension/Info.plist +INFOPLIST_KEY_NSHumanReadableCopyright = Copyright © 2023 DuckDuckGo. All rights reserved. + +FEATURE_FLAGS[arch=*][sdk=*] = NETWORK_EXTENSION NETWORK_PROTECTION +FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETWORK_EXTENSION NETWORK_PROTECTION +FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = NETWORK_EXTENSION NETWORK_PROTECTION +FEATURE_FLAGS[config=Review][arch=*][sdk=*] = NETWORK_EXTENSION NETWORK_PROTECTION + +PRODUCT_BUNDLE_IDENTIFIER[sdk=*] = +PRODUCT_BUNDLE_IDENTIFIER[config=CI][sdk=*] = +PRODUCT_BUNDLE_IDENTIFIER[config=Debug][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).debug.network-protection-extension +PRODUCT_BUNDLE_IDENTIFIER[config=Release][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).network-protection-extension +PRODUCT_BUNDLE_IDENTIFIER[config=Review][sdk=*] = $(BUNDLE_IDENTIFIER_PREFIX).review.network-protection-extension + +SDKROOT = macosx +SKIP_INSTALL = YES +SWIFT_EMIT_LOC_STRINGS = YES + +LD_RUNPATH_SEARCH_PATHS = @executable_path/../Frameworks @executable_path/../../../../Frameworks diff --git a/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig b/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig new file mode 100644 index 0000000000..96ca03be5d --- /dev/null +++ b/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig @@ -0,0 +1,57 @@ +// 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 "../ExtensionBase.xcconfig" +#include "../../NetworkProtectionDeveloperID.xcconfig" + +CODE_SIGN_ENTITLEMENTS[config=CI][sdk=macosx*] = +CODE_SIGN_ENTITLEMENTS[config=Debug][sdk=macosx*] = NetworkProtectionSystemExtension/NetworkProtectionSystemExtension_Debug.entitlements +CODE_SIGN_ENTITLEMENTS[config=Release][sdk=macosx*] = NetworkProtectionSystemExtension/NetworkProtectionSystemExtension_Release.entitlements +CODE_SIGN_ENTITLEMENTS[config=Review][sdk=macosx*] = NetworkProtectionSystemExtension/NetworkProtectionSystemExtension_Release.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 + +GENERATE_INFOPLIST_FILE = YES +INFOPLIST_FILE = NetworkProtectionSystemExtension/Info.plist +INFOPLIST_KEY_NSHumanReadableCopyright = Copyright © 2023 DuckDuckGo. All rights reserved. +INFOPLIST_KEY_NSSystemExtensionUsageDescription = Network Protection + +FEATURE_FLAGS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION NETWORK_PROTECTION +FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION NETWORK_PROTECTION +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) + +PROVISIONING_PROFILE_SPECIFIER[config=CI][sdk=macosx*] = +PROVISIONING_PROFILE_SPECIFIER[config=Debug][sdk=macosx*] = macOS NetP System Extension - Debug +PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = macOS NetP System Extension - Release +PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = macOS NetP System Extension - Review + +SDKROOT = macosx +SKIP_INSTALL = YES +SWIFT_EMIT_LOC_STRINGS = YES diff --git a/Configuration/Global.xcconfig b/Configuration/Global.xcconfig index 3435affdee..5e7a712154 100644 --- a/Configuration/Global.xcconfig +++ b/Configuration/Global.xcconfig @@ -81,6 +81,8 @@ ONLY_ACTIVE_ARCH[config=CI][arch=*][sdk=*] = YES SDKROOT = macosx +SWIFT_VERSION = 5.0 + SWIFT_OPTIMIZATION_LEVEL = -O SWIFT_OPTIMIZATION_LEVEL[config=CI][arch=*][sdk=*] = -Onone SWIFT_OPTIMIZATION_LEVEL[config=Debug][arch=*][sdk=*] = -Onone @@ -89,4 +91,7 @@ SWIFT_COMPILATION_MODE = wholemodule SWIFT_COMPILATION_MODE[config=CI][arch=*][sdk=*] = SWIFT_COMPILATION_MODE[config=Debug][arch=*][sdk=*] = -SWIFT_STRICT_CONCURRENCY = targeted; +// This is temporarily set back to its default value, as a part of merging Network Protection. There are a small number of warnings introduced in +// that feature, and more time is needed to address them. To avoid bothering other developers, this is being disabled and a task to fix it will be +// prioritized. +SWIFT_STRICT_CONCURRENCY = minimal; diff --git a/Configuration/NetworkProtectionDeveloperID.xcconfig b/Configuration/NetworkProtectionDeveloperID.xcconfig new file mode 100644 index 0000000000..1d60d8601c --- /dev/null +++ b/Configuration/NetworkProtectionDeveloperID.xcconfig @@ -0,0 +1,45 @@ +// 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. +// + +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 + +NETP_BASE_APP_GROUP = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.system-extension +NETP_APP_GROUP[config=CI][sdk=*] = $(NETP_BASE_APP_GROUP).debug +NETP_APP_GROUP[config=Review][sdk=*] = $(NETP_BASE_APP_GROUP).review +NETP_APP_GROUP[config=Debug][sdk=*] = $(NETP_BASE_APP_GROUP).debug +NETP_APP_GROUP[config=Release][sdk=*] = $(NETP_BASE_APP_GROUP) + +SYSEX_MACH_SERVICE_NAME[sdk=*] = $(NETP_APP_GROUP).ipc +SYSEX_MACH_SERVICE_NAME[config=CI][sdk=*] = $(NETP_APP_GROUP).ipc +SYSEX_MACH_SERVICE_NAME[config=Review][sdk=*] = $(NETP_APP_GROUP).ipc +SYSEX_MACH_SERVICE_NAME[config=Debug][sdk=*] = $(NETP_APP_GROUP).ipc +SYSEX_MACH_SERVICE_NAME[config=Release][sdk=*] = $(NETP_APP_GROUP).ipc + +NOTIFICATIONS_AGENT_BUNDLE_ID[sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.notifications +NOTIFICATIONS_AGENT_BUNDLE_ID[config=Debug][sdk=*] = $(DEVELOPMENT_TEAM).com.duckduckgo.macos.browser.network-protection.notifications.debug +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_PRODUCT_NAME = DuckDuckGo Agent +NOTIFICATIONS_AGENT_PRODUCT_NAME = DuckDuckGo Notifications diff --git a/Configuration/Tests/IntegrationTests.xcconfig b/Configuration/Tests/IntegrationTests.xcconfig index 643e71b87e..c159406d40 100644 --- a/Configuration/Tests/IntegrationTests.xcconfig +++ b/Configuration/Tests/IntegrationTests.xcconfig @@ -17,6 +17,8 @@ MACOSX_DEPLOYMENT_TARGET = 11.1 +FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION + INFOPLIST_FILE = IntegrationTests/Info.plist PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.Integration-Tests diff --git a/Configuration/Tests/UnitTests.xcconfig b/Configuration/Tests/UnitTests.xcconfig index de8c8ed4b7..e81034ac32 100644 --- a/Configuration/Tests/UnitTests.xcconfig +++ b/Configuration/Tests/UnitTests.xcconfig @@ -17,6 +17,8 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION + INFOPLIST_FILE = UnitTests/Info.plist PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.macos.browser.DuckDuckGoTests diff --git a/Configuration/Tests/UnitTestsAppStore.xcconfig b/Configuration/Tests/UnitTestsAppStore.xcconfig index c76db6bdc2..fb90843360 100644 --- a/Configuration/Tests/UnitTestsAppStore.xcconfig +++ b/Configuration/Tests/UnitTestsAppStore.xcconfig @@ -16,6 +16,8 @@ #include "UnitTests.xcconfig" #include "../AppStore.xcconfig" +FEATURE_FLAGS = FEEDBACK + PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.mobile.ios.DuckDuckGoTests TEST_HOST=$(BUILT_PRODUCTS_DIR)/DuckDuckGo App Store.app/Contents/MacOS/DuckDuckGo App Store diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 4564ea34d9..351f092142 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1030,9 +1030,47 @@ 4B1E6EEE27AB5E5100F51793 /* PasswordManagementListSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EEC27AB5E5100F51793 /* PasswordManagementListSection.swift */; }; 4B1E6EF127AB5E5D00F51793 /* NSPopUpButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EEF27AB5E5D00F51793 /* NSPopUpButtonView.swift */; }; 4B1E6EF227AB5E5D00F51793 /* PasswordManagementItemList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EF027AB5E5D00F51793 /* PasswordManagementItemList.swift */; }; + 4B25375B2A11BE7300610219 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */; }; + 4B2537722A11BF8B00610219 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B25376F2A11BF8B00610219 /* main.swift */; }; + 4B2537732A11BF8C00610219 /* NetworkProtectionIPCNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2537702A11BF8B00610219 /* NetworkProtectionIPCNotificationsPresenter.swift */; }; + 4B2537752A11BFDE00610219 /* NetworkProtection in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2537742A11BFDE00610219 /* NetworkProtection */; }; + 4B2537772A11BFE100610219 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2537762A11BFE100610219 /* PixelKit */; }; + 4B2537782A11C00F00610219 /* NetworkProtectionExtensionMachService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60782A0B29FA00BCD287 /* NetworkProtectionExtensionMachService.swift */; }; + 4B2537792A11C00F00610219 /* IPCConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60792A0B29FA00BCD287 /* IPCConnection.swift */; }; + 4B25377A2A11C01700610219 /* UserText+NetworkProtectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */; }; + 4B25377B2A11C01700610219 /* NetworkProtectionNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607B2A0B29FA00BCD287 /* NetworkProtectionNotificationsPresenter.swift */; }; + 4B25377C2A11C07600610219 /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60832A0B29FA00BCD287 /* NetworkProtectionPixelEvent.swift */; }; + 4B25377D2A11C07600610219 /* NetworkProtectionConnectionTester.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607E2A0B29FA00BCD287 /* NetworkProtectionConnectionTester.swift */; }; + 4B25377E2A11C07600610219 /* NetworkProtectionTunnelHealthStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60882A0B29FA00BCD287 /* NetworkProtectionTunnelHealthStore.swift */; }; + 4B2537812A11C07600610219 /* NetworkConnectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60812A0B29FA00BCD287 /* NetworkConnectionType.swift */; }; + 4B2537822A11C07600610219 /* NetworkProtectionTunnelErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60842A0B29FA00BCD287 /* NetworkProtectionTunnelErrorStore.swift */; }; + 4B2537832A11C07600610219 /* NetworkProtectionLatencyReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60872A0B29FA00BCD287 /* NetworkProtectionLatencyReporter.swift */; }; + 4B2537842A11C07600610219 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60802A0B29FA00BCD287 /* PacketTunnelProvider.swift */; }; + 4B2537852A11C07600610219 /* NetworkProtectionConnectionBandwidthAnalyzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607F2A0B29FA00BCD287 /* NetworkProtectionConnectionBandwidthAnalyzer.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 */; }; + 4B2D06262A11C0C500DE1F49 /* String+ArrayConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605A2A0B29FA00BCD287 /* String+ArrayConversion.swift */; }; + 4B2D06272A11C0C500DE1F49 /* TunnelConfiguration+WgQuickConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60592A0B29FA00BCD287 /* TunnelConfiguration+WgQuickConfig.swift */; }; + 4B2D06282A11C0C500DE1F49 /* NetworkProtectionSelectedServerStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605C2A0B29FA00BCD287 /* NetworkProtectionSelectedServerStore.swift */; }; + 4B2D06292A11C0C900DE1F49 /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; + 4B2D062A2A11C0C900DE1F49 /* NetworkProtectionSharedState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionSharedState.swift */; }; + 4B2D062C2A11C0E100DE1F49 /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2D062B2A11C0E100DE1F49 /* Networking */; }; + 4B2D062D2A11C12300DE1F49 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85799C1725DEBB3F0007EC87 /* Logging.swift */; }; + 4B2D06302A11C15900DE1F49 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2D062F2A11C15900DE1F49 /* Common */; }; + 4B2D06312A11C18C00DE1F49 /* UserDefaultsWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C6A29525CC1FFD00EEB5F1 /* UserDefaultsWrapper.swift */; }; + 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 */; }; + 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 */; }; 4B379C1527BD91E3008A968E /* QuartzIdleStateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C1427BD91E3008A968E /* QuartzIdleStateProvider.swift */; }; 4B379C1E27BDB7FF008A968E /* DeviceAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C1D27BDB7FF008A968E /* DeviceAuthenticator.swift */; }; @@ -1043,6 +1081,75 @@ 4B3F641E27A8D3BD00E0C118 /* BrowserProfileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F641D27A8D3BD00E0C118 /* BrowserProfileTests.swift */; }; 4B434690285ED7A100177407 /* BookmarksBarViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B43468F285ED7A100177407 /* BookmarksBarViewModelTests.swift */; }; 4B43469528655D1400177407 /* FirefoxDataImporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B43469428655D1400177407 /* FirefoxDataImporterTests.swift */; }; + 4B4BEC3D2A11B56B001D9AC5 /* DuckDuckGoNotificationsAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4BEC382A11B509001D9AC5 /* DuckDuckGoNotificationsAppDelegate.swift */; }; + 4B4BEC3E2A11B56E001D9AC5 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4BEC322A11B509001D9AC5 /* Logging.swift */; }; + 4B4BEC3F2A11B5AE001D9AC5 /* IPCConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60792A0B29FA00BCD287 /* IPCConnection.swift */; }; + 4B4BEC402A11B5B5001D9AC5 /* NetworkProtectionExtensionMachService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60782A0B29FA00BCD287 /* NetworkProtectionExtensionMachService.swift */; }; + 4B4BEC412A11B5BD001D9AC5 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */; }; + 4B4BEC422A11B5C7001D9AC5 /* NetworkProtectionSharedState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionSharedState.swift */; }; + 4B4BEC432A11B5C7001D9AC5 /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; + 4B4BEC442A11B5DE001D9AC5 /* NetworkProtectionNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607B2A0B29FA00BCD287 /* NetworkProtectionNotificationsPresenter.swift */; }; + 4B4BEC452A11B5EE001D9AC5 /* UserText+NetworkProtectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */; }; + 4B4BEC472A11B600001D9AC5 /* NetworkProtection in Frameworks */ = {isa = PBXBuildFile; productRef = 4B4BEC462A11B600001D9AC5 /* NetworkProtection */; }; + 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 */; }; + 4B4D608A2A0B2A3700BCD287 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60802A0B29FA00BCD287 /* PacketTunnelProvider.swift */; }; + 4B4D608B2A0B2A3700BCD287 /* NetworkProtectionTunnelErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60842A0B29FA00BCD287 /* NetworkProtectionTunnelErrorStore.swift */; }; + 4B4D608C2A0B2A3700BCD287 /* NetworkProtectionLatencyReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60872A0B29FA00BCD287 /* NetworkProtectionLatencyReporter.swift */; }; + 4B4D608D2A0B2A3700BCD287 /* NetworkProtectionConnectionTester.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607E2A0B29FA00BCD287 /* NetworkProtectionConnectionTester.swift */; }; + 4B4D608E2A0B2A3700BCD287 /* NetworkProtectionTunnelHealthStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60882A0B29FA00BCD287 /* NetworkProtectionTunnelHealthStore.swift */; }; + 4B4D60922A0B2A3700BCD287 /* NetworkConnectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60812A0B29FA00BCD287 /* NetworkConnectionType.swift */; }; + 4B4D60932A0B2A3700BCD287 /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60832A0B29FA00BCD287 /* NetworkProtectionPixelEvent.swift */; }; + 4B4D60942A0B2A3700BCD287 /* NetworkProtectionConnectionBandwidthAnalyzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607F2A0B29FA00BCD287 /* NetworkProtectionConnectionBandwidthAnalyzer.swift */; }; + 4B4D60962A0B2A5800BCD287 /* NetworkProtection in Frameworks */ = {isa = PBXBuildFile; productRef = 4B4D60952A0B2A5800BCD287 /* NetworkProtection */; }; + 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 */; }; + 4B4D60A12A0B2D6100BCD287 /* NetworkProtectionSharedState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionSharedState.swift */; }; + 4B4D60A52A0B2EC000BCD287 /* UserText+NetworkProtectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */; }; + 4B4D60A62A0B2ECC00BCD287 /* String+ArrayConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605A2A0B29FA00BCD287 /* String+ArrayConversion.swift */; }; + 4B4D60A72A0B2F0600BCD287 /* NetworkProtectionSelectedServerStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605C2A0B29FA00BCD287 /* NetworkProtectionSelectedServerStore.swift */; }; + 4B4D60A82A0B2F0B00BCD287 /* TunnelConfiguration+WgQuickConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60592A0B29FA00BCD287 /* TunnelConfiguration+WgQuickConfig.swift */; }; + 4B4D60AA2A0C7FDD00BCD287 /* NetworkProtectionNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607B2A0B29FA00BCD287 /* NetworkProtectionNotificationsPresenter.swift */; }; + 4B4D60AB2A0C7FEA00BCD287 /* UserDefaultsWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C6A29525CC1FFD00EEB5F1 /* UserDefaultsWrapper.swift */; }; + 4B4D60AC2A0C804B00BCD287 /* OptionalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B637273C26CCF0C200C8CB02 /* OptionalExtension.swift */; }; + 4B4D60AD2A0C807300BCD287 /* NSApplicationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C8F622591021700748EB7 /* NSApplicationExtension.swift */; }; + 4B4D60AF2A0C837F00BCD287 /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 4B4D60AE2A0C837F00BCD287 /* Networking */; }; + 4B4D60B12A0C83B900BCD287 /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4B4D60B02A0C83B900BCD287 /* NetworkProtectionUI */; }; + 4B4D60B42A0C847900BCD287 /* LoginItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60642A0B29FA00BCD287 /* LoginItem.swift */; }; + 4B4D60B52A0C847A00BCD287 /* LoginItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60642A0B29FA00BCD287 /* LoginItem.swift */; }; + 4B4D60B62A0C847D00BCD287 /* NetworkProtectionNavBarButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60652A0B29FA00BCD287 /* NetworkProtectionNavBarButtonModel.swift */; }; + 4B4D60B72A0C847D00BCD287 /* NetworkProtectionNavBarButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60652A0B29FA00BCD287 /* NetworkProtectionNavBarButtonModel.swift */; }; + 4B4D60BE2A0C848A00BCD287 /* NetworkProtection+ConvenienceInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */; }; + 4B4D60BF2A0C848A00BCD287 /* NetworkProtection+ConvenienceInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */; }; + 4B4D60C02A0C848D00BCD287 /* NetworkProtectionControllerErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */; }; + 4B4D60C12A0C848E00BCD287 /* NetworkProtectionControllerErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */; }; + 4B4D60C22A0C849000BCD287 /* EventMapping+NetworkProtectionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */; }; + 4B4D60C32A0C849100BCD287 /* EventMapping+NetworkProtectionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */; }; + 4B4D60C42A0C849600BCD287 /* NetworkProtectionInvitePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606F2A0B29FA00BCD287 /* NetworkProtectionInvitePresenter.swift */; }; + 4B4D60C52A0C849600BCD287 /* NetworkProtectionInviteSuccessView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606D2A0B29FA00BCD287 /* NetworkProtectionInviteSuccessView.swift */; }; + 4B4D60C62A0C849600BCD287 /* NetworkProtectionInviteCodeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60702A0B29FA00BCD287 /* NetworkProtectionInviteCodeViewModel.swift */; }; + 4B4D60C82A0C849600BCD287 /* NetworkProtectionInviteCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606E2A0B29FA00BCD287 /* NetworkProtectionInviteCodeView.swift */; }; + 4B4D60CA2A0C849600BCD287 /* NetworkProtectionInvitePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606F2A0B29FA00BCD287 /* NetworkProtectionInvitePresenter.swift */; }; + 4B4D60CB2A0C849600BCD287 /* NetworkProtectionInviteSuccessView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606D2A0B29FA00BCD287 /* NetworkProtectionInviteSuccessView.swift */; }; + 4B4D60CC2A0C849600BCD287 /* NetworkProtectionInviteCodeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60702A0B29FA00BCD287 /* NetworkProtectionInviteCodeViewModel.swift */; }; + 4B4D60CE2A0C849600BCD287 /* NetworkProtectionInviteCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606E2A0B29FA00BCD287 /* NetworkProtectionInviteCodeView.swift */; }; + 4B4D60CF2A0C849600BCD287 /* NetworkProtectionInviteDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606C2A0B29FA00BCD287 /* NetworkProtectionInviteDialog.swift */; }; + 4B4D60D32A0C84F700BCD287 /* UserText+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */; }; + 4B4D60D42A0C84F700BCD287 /* UserText+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */; }; + 4B4D60D52A0C873C00BCD287 /* TunnelConfiguration+WgQuickConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60592A0B29FA00BCD287 /* TunnelConfiguration+WgQuickConfig.swift */; }; + 4B4D60D62A0C873C00BCD287 /* TunnelConfiguration+WgQuickConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60592A0B29FA00BCD287 /* TunnelConfiguration+WgQuickConfig.swift */; }; + 4B4D60D72A0C874E00BCD287 /* String+ArrayConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605A2A0B29FA00BCD287 /* String+ArrayConversion.swift */; }; + 4B4D60D82A0C875100BCD287 /* String+ArrayConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605A2A0B29FA00BCD287 /* String+ArrayConversion.swift */; }; + 4B4D60DA2A0C875800BCD287 /* NetworkProtectionSelectedServerStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605C2A0B29FA00BCD287 /* NetworkProtectionSelectedServerStore.swift */; }; + 4B4D60DC2A0C875800BCD287 /* NetworkProtectionSelectedServerStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605C2A0B29FA00BCD287 /* NetworkProtectionSelectedServerStore.swift */; }; + 4B4D60DD2A0C875E00BCD287 /* NetworkProtectionSharedState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionSharedState.swift */; }; + 4B4D60DE2A0C875E00BCD287 /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; + 4B4D60DF2A0C875F00BCD287 /* NetworkProtectionSharedState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionSharedState.swift */; }; + 4B4D60E02A0C875F00BCD287 /* NetworkProtectionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */; }; + 4B4D60E22A0C883A00BCD287 /* Main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60E12A0C883A00BCD287 /* Main.swift */; }; + 4B4D60E32A0C883A00BCD287 /* Main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60E12A0C883A00BCD287 /* Main.swift */; }; 4B4F72EC266B2ED300814C60 /* CollectionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F72EB266B2ED300814C60 /* CollectionExtension.swift */; }; 4B59023D26B35F3600489384 /* ChromeDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59023826B35F3600489384 /* ChromeDataImporter.swift */; }; 4B59023E26B35F3600489384 /* ChromiumLoginReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59023926B35F3600489384 /* ChromiumLoginReader.swift */; }; @@ -1053,6 +1160,10 @@ 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 */; }; @@ -1077,6 +1188,7 @@ 4B723E1226B0006E00E14D75 /* DataImport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DEB26B0002B00E14D75 /* DataImport.swift */; }; 4B723E1326B0007A00E14D75 /* CSVLoginExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DFD26B0002B00E14D75 /* CSVLoginExporter.swift */; }; 4B723E1926B000DC00E14D75 /* TemporaryFileCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723E1726B000DC00E14D75 /* TemporaryFileCreator.swift */; }; + 4B7534CC2A1FD7EA00158A99 /* NetworkProtectionInviteDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606C2A0B29FA00BCD287 /* NetworkProtectionInviteDialog.swift */; }; 4B78A86B26BB3ADD0071BB16 /* BrowserImportSummaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B78A86A26BB3ADD0071BB16 /* BrowserImportSummaryViewController.swift */; }; 4B7A57CF279A4EF300B1C70E /* ChromePreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A57CE279A4EF300B1C70E /* ChromePreferences.swift */; }; 4B7A60A1273E0BE400BBDFEB /* WKWebsiteDataStoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A60A0273E0BE400BBDFEB /* WKWebsiteDataStoreExtension.swift */; }; @@ -1093,6 +1205,9 @@ 4B8AC93D26B49BE600879451 /* FirefoxLoginReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8AC93C26B49BE600879451 /* FirefoxLoginReaderTests.swift */; }; 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 */; }; @@ -1215,6 +1330,7 @@ 7B1E819F27C8874900FF0E60 /* ContentOverlay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */; }; 7B1E81A027C8874900FF0E60 /* ContentOverlayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */; }; 7B4CE8E726F02135009134B1 /* TabBarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4CE8E626F02134009134B1 /* TabBarTests.swift */; }; + 7B838C382A1DD8DD00E05A13 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B2D06522A11D19B00DE1F49 /* Assets.xcassets */; }; 7BA4727D26F01BC400EAA165 /* CoreDataTestUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C42667104B00AD2C21 /* CoreDataTestUtilities.swift */; }; 85012B0229133F9F003D0DCC /* NavigationBarPopovers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85012B0129133F9F003D0DCC /* NavigationBarPopovers.swift */; }; 8511E18425F82B34002F516B /* 01_Fire_really_small.json in Resources */ = {isa = PBXBuildFile; fileRef = 8511E18325F82B34002F516B /* 01_Fire_really_small.json */; }; @@ -1872,6 +1988,13 @@ remoteGlobalIDString = AA585D7D248FD31100E9A3E2; remoteInfo = "DuckDuckGo Privacy Browser"; }; + 4B2537632A11BE7600610219 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B2537592A11BE7300610219; + remoteInfo = NetworkProtectionSystemExtension; + }; 7B4CE8DF26F02108009134B1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; @@ -1903,6 +2026,30 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 4B2D065D2A11D2AE00DE1F49 /* Embed Login Items */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = Contents/Library/LoginItems; + dstSubfolderSpec = 1; + files = ( + 4B2D065F2A11D2D700DE1F49 /* DuckDuckGo Agent.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 = ( + 4B5F14F52A1482530060320F /* stopVPN.app in Embed NetP Controller Apps */, + 4B5F14F42A14824F0060320F /* startVPN.app in Embed NetP Controller Apps */, + ); + name = "Embed NetP Controller Apps"; + runOnlyForDeploymentPostprocessing = 0; + }; B6EC37E629B5DA2A001ACE79 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -2113,6 +2260,9 @@ 4B117F7C276C0CB5002F3D8C /* LocalStatisticsStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalStatisticsStoreTests.swift; sourceTree = ""; }; 4B139AFC26B60BD800894F82 /* NSImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImageExtensions.swift; sourceTree = ""; }; 4B17E2D3287380390003BD39 /* PersistentAppInterfaceSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistentAppInterfaceSettings.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 /* NetworkProtectionStartStopVPNBase.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetworkProtectionStartStopVPNBase.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 = ""; }; @@ -2120,8 +2270,25 @@ 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; }; + 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 = ""; }; + 4B2537702A11BF8B00610219 /* NetworkProtectionIPCNotificationsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionIPCNotificationsPresenter.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 = ""; }; + 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; }; 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 = ""; }; @@ -2132,6 +2299,50 @@ 4B3F641D27A8D3BD00E0C118 /* BrowserProfileTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserProfileTests.swift; sourceTree = ""; }; 4B43468F285ED7A100177407 /* BookmarksBarViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksBarViewModelTests.swift; sourceTree = ""; }; 4B43469428655D1400177407 /* FirefoxDataImporterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirefoxDataImporterTests.swift; sourceTree = ""; }; + 4B4BEC182A11B3EA001D9AC5 /* DuckDuckGoNotifications.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DuckDuckGoNotifications.xcconfig; sourceTree = ""; }; + 4B4BEC202A11B4E2001D9AC5 /* DuckDuckGo Notifications.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DuckDuckGo Notifications.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B4BEC322A11B509001D9AC5 /* Logging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = ""; }; + 4B4BEC332A11B509001D9AC5 /* DuckDuckGoNotifications.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DuckDuckGoNotifications.entitlements; sourceTree = ""; }; + 4B4BEC342A11B509001D9AC5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 4B4BEC382A11B509001D9AC5 /* DuckDuckGoNotificationsAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DuckDuckGoNotificationsAppDelegate.swift; sourceTree = ""; }; + 4B4D603D2A0B290200BCD287 /* NetworkProtectionAppExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NetworkProtectionAppExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; + 4B4D604F2A0B293C00BCD287 /* NetworkProtectionSystemExtension.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetworkProtectionSystemExtension.xcconfig; sourceTree = ""; }; + 4B4D60502A0B293C00BCD287 /* NetworkProtectionAppExtension.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetworkProtectionAppExtension.xcconfig; sourceTree = ""; }; + 4B4D60512A0B293C00BCD287 /* ExtensionBase.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ExtensionBase.xcconfig; sourceTree = ""; }; + 4B4D60592A0B29FA00BCD287 /* TunnelConfiguration+WgQuickConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelConfiguration+WgQuickConfig.swift"; sourceTree = ""; }; + 4B4D605A2A0B29FA00BCD287 /* String+ArrayConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ArrayConversion.swift"; sourceTree = ""; }; + 4B4D605C2A0B29FA00BCD287 /* NetworkProtectionSelectedServerStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionSelectedServerStore.swift; sourceTree = ""; }; + 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionBundle.swift; sourceTree = ""; }; + 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionSharedState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionSharedState.swift; sourceTree = ""; }; + 4B4D60622A0B29FA00BCD287 /* SystemExtensionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemExtensionManager.swift; sourceTree = ""; }; + 4B4D60642A0B29FA00BCD287 /* LoginItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginItem.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 = ""; }; + 4B4D606C2A0B29FA00BCD287 /* NetworkProtectionInviteDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionInviteDialog.swift; sourceTree = ""; }; + 4B4D606D2A0B29FA00BCD287 /* NetworkProtectionInviteSuccessView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionInviteSuccessView.swift; sourceTree = ""; }; + 4B4D606E2A0B29FA00BCD287 /* NetworkProtectionInviteCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionInviteCodeView.swift; sourceTree = ""; }; + 4B4D606F2A0B29FA00BCD287 /* NetworkProtectionInvitePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionInvitePresenter.swift; sourceTree = ""; }; + 4B4D60702A0B29FA00BCD287 /* NetworkProtectionInviteCodeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionInviteCodeViewModel.swift; sourceTree = ""; }; + 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EventMapping+NetworkProtectionError.swift"; sourceTree = ""; }; + 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionUNNotificationsPresenter.swift; sourceTree = ""; }; + 4B4D60782A0B29FA00BCD287 /* NetworkProtectionExtensionMachService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionExtensionMachService.swift; sourceTree = ""; }; + 4B4D60792A0B29FA00BCD287 /* IPCConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPCConnection.swift; sourceTree = ""; }; + 4B4D607B2A0B29FA00BCD287 /* NetworkProtectionNotificationsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionNotificationsPresenter.swift; sourceTree = ""; }; + 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserText+NetworkProtectionExtensions.swift"; sourceTree = ""; }; + 4B4D607E2A0B29FA00BCD287 /* NetworkProtectionConnectionTester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionConnectionTester.swift; sourceTree = ""; }; + 4B4D607F2A0B29FA00BCD287 /* NetworkProtectionConnectionBandwidthAnalyzer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionConnectionBandwidthAnalyzer.swift; sourceTree = ""; }; + 4B4D60802A0B29FA00BCD287 /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = ""; }; + 4B4D60812A0B29FA00BCD287 /* NetworkConnectionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConnectionType.swift; sourceTree = ""; }; + 4B4D60832A0B29FA00BCD287 /* NetworkProtectionPixelEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionPixelEvent.swift; sourceTree = ""; }; + 4B4D60842A0B29FA00BCD287 /* NetworkProtectionTunnelErrorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionTunnelErrorStore.swift; sourceTree = ""; }; + 4B4D60872A0B29FA00BCD287 /* NetworkProtectionLatencyReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionLatencyReporter.swift; sourceTree = ""; }; + 4B4D60882A0B29FA00BCD287 /* NetworkProtectionTunnelHealthStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionTunnelHealthStore.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 = ""; }; + 4B4D60E12A0C883A00BCD287 /* Main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Main.swift; sourceTree = ""; }; 4B4F72EB266B2ED300814C60 /* CollectionExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtension.swift; sourceTree = ""; }; 4B59023826B35F3600489384 /* ChromeDataImporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChromeDataImporter.swift; sourceTree = ""; }; 4B59023926B35F3600489384 /* ChromiumLoginReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChromiumLoginReader.swift; sourceTree = ""; }; @@ -2142,6 +2353,13 @@ 4B59024B26B38BB800489384 /* ChromiumLoginReaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromiumLoginReaderTests.swift; sourceTree = ""; }; 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 = ""; }; + 4B5F14C62A145D6A0060320F /* DuckDuckGo Network Protection */ = {isa = PBXFileReference; lastKnownFileType = text; path = "DuckDuckGo Network Protection"; 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 = ""; }; 4B65143D263924B5005B46EB /* EmailUrlExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailUrlExtensions.swift; sourceTree = ""; }; 4B677427255DBEB800025BD8 /* httpsMobileV2BloomSpec.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = httpsMobileV2BloomSpec.json; sourceTree = ""; }; @@ -2181,6 +2399,7 @@ 4B8AC93C26B49BE600879451 /* FirefoxLoginReaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirefoxLoginReaderTests.swift; sourceTree = ""; }; 4B8AD0B027A86D9200AE44D6 /* WKWebsiteDataStoreExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKWebsiteDataStoreExtensionTests.swift; sourceTree = ""; }; 4B8D9061276D1D880078DB17 /* LocaleExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleExtension.swift; sourceTree = ""; }; + 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionTunnelController.swift; sourceTree = ""; }; 4B92928526670D1600AD2C21 /* BookmarksOutlineView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarksOutlineView.swift; sourceTree = ""; }; 4B92928626670D1600AD2C21 /* OutlineSeparatorViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutlineSeparatorViewCell.swift; sourceTree = ""; }; 4B92928726670D1600AD2C21 /* BookmarkOutlineViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkOutlineViewCell.swift; sourceTree = ""; }; @@ -2269,6 +2488,9 @@ 4BD18F04283F151F00058124 /* BookmarksBar.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = BookmarksBar.storyboard; sourceTree = ""; }; 4BDFA4AD27BF19E500648192 /* ToggleableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleableScrollView.swift; sourceTree = ""; }; 4BE0DF0426781961006337B7 /* NSStoryboardExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSStoryboardExtension.swift; sourceTree = ""; }; + 4BE15DB12A0B0DD500898243 /* PixelKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = PixelKit; sourceTree = ""; }; + 4BE15DB22A0B0DD500898243 /* NetworkProtection */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = NetworkProtection; sourceTree = ""; }; + 4BE15DB32A0B0DD500898243 /* NetworkProtectionUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = NetworkProtectionUI; sourceTree = ""; }; 4BE4005227CF3DC3007D3161 /* SavePaymentMethodPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavePaymentMethodPopover.swift; sourceTree = ""; }; 4BE4005427CF3F19007D3161 /* SavePaymentMethodViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavePaymentMethodViewController.swift; sourceTree = ""; }; 4BE41A5D28446EAD00760399 /* BookmarksBarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksBarViewModel.swift; sourceTree = ""; }; @@ -2301,6 +2523,8 @@ 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 = ""; }; 85012B0129133F9F003D0DCC /* NavigationBarPopovers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarPopovers.swift; sourceTree = ""; }; 8511E18325F82B34002F516B /* 01_Fire_really_small.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = 01_Fire_really_small.json; sourceTree = ""; }; 853014D525E671A000FB8205 /* PageObserverUserScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageObserverUserScript.swift; sourceTree = ""; }; @@ -2907,6 +3131,68 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B2537572A11BE7300610219 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B2D06302A11C15900DE1F49 /* Common in Frameworks */, + 4B2537772A11BFE100610219 /* PixelKit in Frameworks */, + 4B2537752A11BFDE00610219 /* NetworkProtection in Frameworks */, + 4B2D062C2A11C0E100DE1F49 /* Networking in Frameworks */, + 4B25375B2A11BE7300610219 /* NetworkExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B2D06362A11CFBA00DE1F49 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B2D064F2A11D0D000DE1F49 /* NetworkProtectionUI in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B2D06662A13318400DE1F49 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B2D067F2A1334D700DE1F49 /* NetworkProtectionUI in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B4BEC1D2A11B4E2001D9AC5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B4BEC472A11B600001D9AC5 /* NetworkProtection in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B4D603A2A0B290200BCD287 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B8F52352A169D2D00BE7131 /* Common in Frameworks */, + 4B4D60982A0B2A5C00BCD287 /* PixelKit in Frameworks */, + 4B4D60962A0B2A5800BCD287 /* NetworkProtection in Frameworks */, + 4B4D60AF2A0C837F00BCD287 /* Networking in Frameworks */, + 4B4D603F2A0B290200BCD287 /* NetworkExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B5F14C82A14702C0060320F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B5F14DE2A1476BC0060320F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7B4CE8D726F02108009134B1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2934,6 +3220,7 @@ 1E950E412912A10D0051A99B /* PrivacyDashboard in Frameworks */, 37DF000529F9C056002B7D3E /* SyncDataProviders in Frameworks */, 37BA812D29B3CD690053F1A3 /* SyncUI in Frameworks */, + 4B4D60B12A0C83B900BCD287 /* NetworkProtectionUI in Frameworks */, 1E25269C28F8741A00E44DFA /* Common in Frameworks */, 98A50964294B691800D10880 /* Persistence in Frameworks */, ); @@ -3257,7 +3544,9 @@ 378B5887295CF2A4002C0CC0 /* Version.xcconfig */, 376CC8B4296EB630006B63A7 /* AppStore.xcconfig */, 376CC8B5296EBA8F006B63A7 /* AppStoreBuildNumber.xcconfig */, + 7B5291892A169BC90022E406 /* NetworkProtectionDeveloperID.xcconfig */, 378C76D8296842FD0092E949 /* App */, + 4B4D604E2A0B293C00BCD287 /* Extensions */, 378C76D92968433B0092E949 /* Tests */, 378C76DA296843460092E949 /* UITests */, ); @@ -3271,6 +3560,7 @@ 378B58CD295ECA75002C0CC0 /* DuckDuckGo.xcconfig */, 37DD516C296EAEDC00837F27 /* DuckDuckGoAppStore.xcconfig */, 378E2799296F6FDE00FCADA2 /* ManualAppStoreRelease.xcconfig */, + 4B18E3222A1D31E4005D0AAA /* NetworkProtection */, ); path = App; sourceTree = ""; @@ -3300,6 +3590,9 @@ isa = PBXGroup; children = ( 378E279D2970217400FCADA2 /* BuildToolPlugins */, + 4BE15DB22A0B0DD500898243 /* NetworkProtection */, + 4BE15DB32A0B0DD500898243 /* NetworkProtectionUI */, + 4BE15DB12A0B0DD500898243 /* PixelKit */, 378F44E229B4B7B600899924 /* SwiftUIExtensions */, 37BA812B29B3CB8A0053F1A3 /* SyncUI */, ); @@ -3455,6 +3748,28 @@ path = Preferences; sourceTree = ""; }; + 4B18E3222A1D31E4005D0AAA /* NetworkProtection */ = { + isa = PBXGroup; + children = ( + 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */, + 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */, + 4B4BEC182A11B3EA001D9AC5 /* DuckDuckGoNotifications.xcconfig */, + 4B18E3272A1D3896005D0AAA /* NetworkProtectionStartStopVPNBase.xcconfig */, + 4B18E3232A1D32B1005D0AAA /* NetworkProtectionStartVPN.xcconfig */, + 4B18E3252A1D3581005D0AAA /* NetworkProtectionStopVPN.xcconfig */, + ); + path = NetworkProtection; + sourceTree = ""; + }; + 4B18E32C2A1ECF1F005D0AAA /* NetworkProtection */ = { + isa = PBXGroup; + children = ( + 4B4D604F2A0B293C00BCD287 /* NetworkProtectionSystemExtension.xcconfig */, + 4B4D60502A0B293C00BCD287 /* NetworkProtectionAppExtension.xcconfig */, + ); + path = NetworkProtection; + sourceTree = ""; + }; 4B1AD89E25FC27E200261379 /* IntegrationTests */ = { isa = PBXGroup; children = ( @@ -3473,6 +3788,31 @@ path = IntegrationTests; sourceTree = ""; }; + 4B25375C2A11BE7500610219 /* NetworkProtectionSystemExtension */ = { + isa = PBXGroup; + children = ( + 4B25376E2A11BF8B00610219 /* Info.plist */, + 4B25376F2A11BF8B00610219 /* main.swift */, + 4B2537702A11BF8B00610219 /* NetworkProtectionIPCNotificationsPresenter.swift */, + 4B25376D2A11BF6D00610219 /* NetworkProtectionSystemExtension_Debug.entitlements */, + 4B25376C2A11BF6D00610219 /* NetworkProtectionSystemExtension_Release.entitlements */, + ); + path = NetworkProtectionSystemExtension; + sourceTree = ""; + }; + 4B2D063A2A11CFBD00DE1F49 /* DuckDuckGoAgent */ = { + isa = PBXGroup; + children = ( + 4B2D06512A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.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 = ( @@ -3501,6 +3841,160 @@ path = ViewModel; sourceTree = ""; }; + 4B4BEC312A11B509001D9AC5 /* DuckDuckGoNotifications */ = { + isa = PBXGroup; + children = ( + 7B5291882A1697680022E406 /* Info.plist */, + 4B4BEC382A11B509001D9AC5 /* DuckDuckGoNotificationsAppDelegate.swift */, + 4B4BEC322A11B509001D9AC5 /* Logging.swift */, + 4B4BEC342A11B509001D9AC5 /* Assets.xcassets */, + 4B4BEC332A11B509001D9AC5 /* DuckDuckGoNotifications.entitlements */, + ); + path = DuckDuckGoNotifications; + sourceTree = ""; + }; + 4B4D604E2A0B293C00BCD287 /* Extensions */ = { + isa = PBXGroup; + children = ( + 4B4D60512A0B293C00BCD287 /* ExtensionBase.xcconfig */, + 4B18E32C2A1ECF1F005D0AAA /* NetworkProtection */, + ); + path = Extensions; + sourceTree = ""; + }; + 4B4D60542A0B29FA00BCD287 /* NetworkProtection */ = { + isa = PBXGroup; + children = ( + 4B4D60572A0B29FA00BCD287 /* AppAndExtensionTargets */, + 4B4D60602A0B29FA00BCD287 /* AppTargets */, + 4B4D60742A0B29FA00BCD287 /* NetworkExtensionTargets */, + ); + path = NetworkProtection; + sourceTree = ""; + }; + 4B4D60572A0B29FA00BCD287 /* AppAndExtensionTargets */ = { + isa = PBXGroup; + children = ( + 4B4D60582A0B29FA00BCD287 /* AppAndExtensionTargets */, + 4B4D605D2A0B29FA00BCD287 /* AppAndExtensionAndNotificationTargets */, + ); + path = AppAndExtensionTargets; + sourceTree = ""; + }; + 4B4D60582A0B29FA00BCD287 /* AppAndExtensionTargets */ = { + isa = PBXGroup; + children = ( + 4B4D60592A0B29FA00BCD287 /* TunnelConfiguration+WgQuickConfig.swift */, + 4B4D605A2A0B29FA00BCD287 /* String+ArrayConversion.swift */, + 4B4D605C2A0B29FA00BCD287 /* NetworkProtectionSelectedServerStore.swift */, + ); + path = AppAndExtensionTargets; + sourceTree = ""; + }; + 4B4D605D2A0B29FA00BCD287 /* AppAndExtensionAndNotificationTargets */ = { + isa = PBXGroup; + children = ( + 4B4D605E2A0B29FA00BCD287 /* NetworkProtectionBundle.swift */, + 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionSharedState.swift */, + ); + path = AppAndExtensionAndNotificationTargets; + sourceTree = ""; + }; + 4B4D60602A0B29FA00BCD287 /* AppTargets */ = { + isa = PBXGroup; + children = ( + 4B4D60612A0B29FA00BCD287 /* DeveloperIDTarget */, + 4B4D60632A0B29FA00BCD287 /* BothAppTargets */, + ); + path = AppTargets; + sourceTree = ""; + }; + 4B4D60612A0B29FA00BCD287 /* DeveloperIDTarget */ = { + isa = PBXGroup; + children = ( + 4B4D60622A0B29FA00BCD287 /* SystemExtensionManager.swift */, + ); + path = DeveloperIDTarget; + sourceTree = ""; + }; + 4B4D60632A0B29FA00BCD287 /* BothAppTargets */ = { + isa = PBXGroup; + children = ( + 4B4D60642A0B29FA00BCD287 /* LoginItem.swift */, + 4B4D60652A0B29FA00BCD287 /* NetworkProtectionNavBarButtonModel.swift */, + 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */, + 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */, + 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */, + 4B4D606B2A0B29FA00BCD287 /* Invite */, + 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */, + ); + path = BothAppTargets; + sourceTree = ""; + }; + 4B4D606B2A0B29FA00BCD287 /* Invite */ = { + isa = PBXGroup; + children = ( + 4B4D606C2A0B29FA00BCD287 /* NetworkProtectionInviteDialog.swift */, + 4B4D606D2A0B29FA00BCD287 /* NetworkProtectionInviteSuccessView.swift */, + 4B4D606E2A0B29FA00BCD287 /* NetworkProtectionInviteCodeView.swift */, + 4B4D606F2A0B29FA00BCD287 /* NetworkProtectionInvitePresenter.swift */, + 4B4D60702A0B29FA00BCD287 /* NetworkProtectionInviteCodeViewModel.swift */, + ); + path = Invite; + sourceTree = ""; + }; + 4B4D60742A0B29FA00BCD287 /* NetworkExtensionTargets */ = { + isa = PBXGroup; + children = ( + 4B4D60752A0B29FA00BCD287 /* AppExtensionAndNotificationTargets */, + 4B4D60772A0B29FA00BCD287 /* SystemExtensionAndNotificationTargets */, + 4B4D607A2A0B29FA00BCD287 /* NetworkExtensionAndNotificationTargets */, + 4B4D607D2A0B29FA00BCD287 /* NetworkExtensionTargets */, + ); + path = NetworkExtensionTargets; + sourceTree = ""; + }; + 4B4D60752A0B29FA00BCD287 /* AppExtensionAndNotificationTargets */ = { + isa = PBXGroup; + children = ( + 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */, + ); + path = AppExtensionAndNotificationTargets; + sourceTree = ""; + }; + 4B4D60772A0B29FA00BCD287 /* SystemExtensionAndNotificationTargets */ = { + isa = PBXGroup; + children = ( + 4B4D60782A0B29FA00BCD287 /* NetworkProtectionExtensionMachService.swift */, + 4B4D60792A0B29FA00BCD287 /* IPCConnection.swift */, + ); + path = SystemExtensionAndNotificationTargets; + sourceTree = ""; + }; + 4B4D607A2A0B29FA00BCD287 /* NetworkExtensionAndNotificationTargets */ = { + isa = PBXGroup; + children = ( + 4B4D607B2A0B29FA00BCD287 /* NetworkProtectionNotificationsPresenter.swift */, + 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */, + ); + path = NetworkExtensionAndNotificationTargets; + sourceTree = ""; + }; + 4B4D607D2A0B29FA00BCD287 /* NetworkExtensionTargets */ = { + isa = PBXGroup; + children = ( + 4B4D607E2A0B29FA00BCD287 /* NetworkProtectionConnectionTester.swift */, + 4B4D607F2A0B29FA00BCD287 /* NetworkProtectionConnectionBandwidthAnalyzer.swift */, + 4B4D60802A0B29FA00BCD287 /* PacketTunnelProvider.swift */, + 4B4D60812A0B29FA00BCD287 /* NetworkConnectionType.swift */, + 4B4D60832A0B29FA00BCD287 /* NetworkProtectionPixelEvent.swift */, + 4B4D60842A0B29FA00BCD287 /* NetworkProtectionTunnelErrorStore.swift */, + 4B4D60872A0B29FA00BCD287 /* NetworkProtectionLatencyReporter.swift */, + 4B4D60882A0B29FA00BCD287 /* NetworkProtectionTunnelHealthStore.swift */, + ); + path = NetworkExtensionTargets; + sourceTree = ""; + }; 4B59023726B35F3600489384 /* Chromium */ = { isa = PBXGroup; children = ( @@ -3522,6 +4016,23 @@ path = Bitwarden; sourceTree = ""; }; + 4B5F14C32A145D6A0060320F /* NetworkProtectionVPNController */ = { + isa = PBXGroup; + children = ( + 4B5F14C52A145D6A0060320F /* Main.swift */, + 4B5F14C62A145D6A0060320F /* DuckDuckGo Network Protection */, + ); + path = NetworkProtectionVPNController; + sourceTree = ""; + }; + 4B5F14F72A148B230060320F /* NetworkProtectionAppExtension */ = { + isa = PBXGroup; + children = ( + 4B5F14F82A148B230060320F /* Info.plist */, + ); + path = NetworkProtectionAppExtension; + sourceTree = ""; + }; 4B6160D125B14E5E007DE5B2 /* ContentBlocker */ = { isa = PBXGroup; children = ( @@ -4106,6 +4617,7 @@ children = ( B6F7128029F681EB00594A45 /* QuickLookUI.framework */, 85AE2FF124A33A2D002D507F /* WebKit.framework */, + 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */, ); name = Frameworks; sourceTree = ""; @@ -4358,10 +4870,15 @@ 378E279C2970217400FCADA2 /* LocalPackages */, AA68C3D62490F821001B8783 /* README.md */, AA585D80248FD31100E9A3E2 /* DuckDuckGo */, + 4B4BEC312A11B509001D9AC5 /* DuckDuckGoNotifications */, AA585D93248FD31400E9A3E2 /* UnitTests */, 4B1AD89E25FC27E200261379 /* IntegrationTests */, 7B4CE8DB26F02108009134B1 /* UITests */, B6EC37E929B5DA2A001ACE79 /* tests-server */, + 4B5F14F72A148B230060320F /* NetworkProtectionAppExtension */, + 4B25375C2A11BE7500610219 /* NetworkProtectionSystemExtension */, + 4B5F14C32A145D6A0060320F /* NetworkProtectionVPNController */, + 4B2D063A2A11CFBD00DE1F49 /* DuckDuckGoAgent */, AA585D7F248FD31100E9A3E2 /* Products */, 85AE2FF024A33A2D002D507F /* Frameworks */, ); @@ -4378,6 +4895,13 @@ 3706FE99293F661700E42796 /* Unit Tests App Store.xctest */, 3706FEB2293F662100E42796 /* Integration Tests App Store.xctest */, 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 */, ); name = Products; sourceTree = ""; @@ -4414,6 +4938,7 @@ AA97BF4425135CB60014931A /* Menus */, 85378D9A274E618C007C5CBF /* MessageViews */, AA86491524D83384001BABEE /* NavigationBar */, + 4B4D60542A0B29FA00BCD287 /* NetworkProtection */, 85B7184727677A7D00B4277F /* Onboarding */, 1D074B252909A371006E4AC3 /* PasswordManager */, B64C84DB2692D6E80048FEBE /* Permissions */, @@ -4439,8 +4964,13 @@ 4B677454255DC18000025BD8 /* Bridging.h */, AAD86E502678D104005C11BE /* DuckDuckGoCI.entitlements */, AA585D8B248FD31400E9A3E2 /* DuckDuckGo.entitlements */, + 4B5F15032A1570F10060320F /* DuckDuckGoDebug.entitlements */, 37D9BBA329376EE8000B99F9 /* DuckDuckGoAppStore.entitlements */, 377E54382937B7C400780A0A /* DuckDuckGoAppStoreCI.entitlements */, + 4B4D609E2A0B2C2300BCD287 /* DuckDuckGo_NetP_Debug.entitlements */, + 4B4D609C2A0B2C2300BCD287 /* DuckDuckGo_NetP_Release.entitlements */, + 4B2D06642A132F3A00DE1F49 /* NetworkProtectionAppExtension.entitlements */, + 4B5F14C42A145D6A0060320F /* NetworkProtectionVPNController.entitlements */, AA585D8A248FD31400E9A3E2 /* Info.plist */, ); path = DuckDuckGo; @@ -4497,6 +5027,7 @@ AA585DB02490E6FA00E9A3E2 /* Main */ = { isa = PBXGroup; children = ( + 4B4D60E12A0C883A00BCD287 /* Main.swift */, AA68C3D824911D56001B8783 /* View */, ); path = Main; @@ -4707,6 +5238,7 @@ isa = PBXGroup; children = ( AA80EC53256BE3BC007083E7 /* UserText.swift */, + 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */, AA80EC8B256C49B8007083E7 /* Localizable.strings */, AA80EC91256C49BC007083E7 /* Localizable.stringsdict */, ); @@ -5869,7 +6401,7 @@ buildRules = ( ); dependencies = ( - 3799999429705E1F003318B1 /* PBXTargetDependency */, + 4B5F14FE2A1529230060320F /* PBXTargetDependency */, ); name = "DuckDuckGo Privacy Browser App Store"; packageProductDependencies = ( @@ -5957,6 +6489,146 @@ productReference = 4B1AD89D25FC27E200261379 /* Integration Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B2537662A11BE7700610219 /* Build configuration list for PBXNativeTarget "NetworkProtectionSystemExtension" */; + buildPhases = ( + 4B2537562A11BE7300610219 /* Sources */, + 4B2537572A11BE7300610219 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NetworkProtectionSystemExtension; + packageProductDependencies = ( + 4B2537742A11BFDE00610219 /* NetworkProtection */, + 4B2537762A11BFE100610219 /* PixelKit */, + 4B2D062B2A11C0E100DE1F49 /* Networking */, + 4B2D062F2A11C15900DE1F49 /* Common */, + ); + productName = NetworkProtectionSystemExtension; + productReference = 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.browser.debug.network-protection-extension.systemextension */; + productType = "com.apple.product-type.system-extension"; + }; + 4B2D06382A11CFBA00DE1F49 /* DuckDuckGoAgent */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B2D06452A11CFBE00DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoAgent" */; + buildPhases = ( + 4B2D06352A11CFBA00DE1F49 /* Sources */, + 4B2D06362A11CFBA00DE1F49 /* Frameworks */, + 4B2D06372A11CFBA00DE1F49 /* Resources */, + 4B2D065C2A11D23600DE1F49 /* Copy Assets */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DuckDuckGoAgent; + packageProductDependencies = ( + 4B2D064E2A11D0D000DE1F49 /* NetworkProtectionUI */, + ); + productName = DuckDuckGoAgent; + productReference = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo Agent.app */; + productType = "com.apple.product-type.application"; + }; + 4B2D06682A13318400DE1F49 /* DuckDuckGoAgentAppStore */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B2D06752A13318600DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoAgentAppStore" */; + buildPhases = ( + 4B2D06652A13318400DE1F49 /* Sources */, + 4B2D06662A13318400DE1F49 /* Frameworks */, + 4B2D06672A13318400DE1F49 /* Resources */, + 4B2D067D2A13341200DE1F49 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DuckDuckGoAgentAppStore; + packageProductDependencies = ( + 4B2D067E2A1334D700DE1F49 /* NetworkProtectionUI */, + ); + productName = DuckDuckGoAgentAppStore; + productReference = 4B2D06692A13318400DE1F49 /* DuckDuckGo Agent App Store.app */; + productType = "com.apple.product-type.application"; + }; + 4B4BEC1F2A11B4E2001D9AC5 /* DuckDuckGoNotifications */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B4BEC2C2A11B4E3001D9AC5 /* Build configuration list for PBXNativeTarget "DuckDuckGoNotifications" */; + buildPhases = ( + 4B4BEC1C2A11B4E2001D9AC5 /* Sources */, + 4B4BEC1D2A11B4E2001D9AC5 /* Frameworks */, + 4B4BEC1E2A11B4E2001D9AC5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 4B4BEC4A2A11B627001D9AC5 /* PBXTargetDependency */, + ); + name = DuckDuckGoNotifications; + packageProductDependencies = ( + 4B4BEC462A11B600001D9AC5 /* NetworkProtection */, + ); + productName = DuckDuckGoNotifications; + productReference = 4B4BEC202A11B4E2001D9AC5 /* DuckDuckGo Notifications.app */; + productType = "com.apple.product-type.application"; + }; + 4B4D603C2A0B290200BCD287 /* NetworkProtectionAppExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B4D604D2A0B290300BCD287 /* Build configuration list for PBXNativeTarget "NetworkProtectionAppExtension" */; + buildPhases = ( + 4B4D60392A0B290200BCD287 /* Sources */, + 4B4D603A2A0B290200BCD287 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 4B4D60532A0B29CB00BCD287 /* PBXTargetDependency */, + ); + name = NetworkProtectionAppExtension; + packageProductDependencies = ( + 4B4D60952A0B2A5800BCD287 /* NetworkProtection */, + 4B4D60972A0B2A5C00BCD287 /* PixelKit */, + 4B4D60AE2A0C837F00BCD287 /* Networking */, + 4B8F52342A169D2D00BE7131 /* Common */, + ); + productName = NetworkProtectionAppExtension; + 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"; + }; 7B4CE8D926F02108009134B1 /* UI Tests */ = { isa = PBXNativeTarget; buildConfigurationList = 7B4CE8E526F02108009134B1 /* Build configuration list for PBXNativeTarget "UI Tests" */; @@ -5985,11 +6657,16 @@ AA8EDF2824925E940071C2E8 /* Swift Lint */, AA585D7B248FD31100E9A3E2 /* Frameworks */, AA585D7C248FD31100E9A3E2 /* Resources */, + 4B2D065D2A11D2AE00DE1F49 /* Embed Login Items */, + 4B5F14F32A14823D0060320F /* Embed NetP Controller Apps */, + 4B5F14F62A14825A0060320F /* Replace VPN Controllers with Symlinks */, + 7B6469992A165AE00095095A /* Embed System Network Extension */, ); buildRules = ( ); dependencies = ( - 3799999229705E1A003318B1 /* PBXTargetDependency */, + 4B5F14FC2A15291D0060320F /* PBXTargetDependency */, + 4B2537642A11BE7600610219 /* PBXTargetDependency */, ); name = "DuckDuckGo Privacy Browser"; packageProductDependencies = ( @@ -6010,6 +6687,7 @@ 371D00E029D8509400EC8598 /* OpenSSL */, 4B2AAAF429E70DEA0026AFC0 /* Lottie */, 37DF000429F9C056002B7D3E /* SyncDataProviders */, + 4B4D60B02A0C83B900BCD287 /* NetworkProtectionUI */, ); productName = DuckDuckGo; productReference = AA585D7E248FD31100E9A3E2 /* DuckDuckGo.app */; @@ -6063,7 +6741,7 @@ AA585D76248FD31100E9A3E2 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1420; + LastSwiftUpdateCheck = 1430; LastUpgradeCheck = 1400; ORGANIZATIONNAME = DuckDuckGo; TargetAttributes = { @@ -6077,6 +6755,29 @@ CreatedOnToolsVersion = 12.4; TestTargetID = AA585D7D248FD31100E9A3E2; }; + 4B2537592A11BE7300610219 = { + CreatedOnToolsVersion = 14.3; + LastSwiftMigration = 1430; + }; + 4B2D06382A11CFBA00DE1F49 = { + CreatedOnToolsVersion = 14.3; + LastSwiftMigration = 1430; + }; + 4B2D06682A13318400DE1F49 = { + CreatedOnToolsVersion = 14.3; + }; + 4B4BEC1F2A11B4E2001D9AC5 = { + CreatedOnToolsVersion = 14.3; + }; + 4B4D603C2A0B290200BCD287 = { + CreatedOnToolsVersion = 14.3; + }; + 4B5F14CA2A14702C0060320F = { + CreatedOnToolsVersion = 14.3; + }; + 4B5F14E02A1476BC0060320F = { + CreatedOnToolsVersion = 14.3; + }; 7B4CE8D926F02108009134B1 = { CreatedOnToolsVersion = 12.5.1; TestTargetID = AA585D7D248FD31100E9A3E2; @@ -6116,13 +6817,20 @@ projectRoot = ""; targets = ( AA585D7D248FD31100E9A3E2 /* DuckDuckGo Privacy Browser */, + 7B4CE8D926F02108009134B1 /* UI Tests */, AA585D8F248FD31400E9A3E2 /* Unit Tests */, 4B1AD89C25FC27E200261379 /* Integration Tests */, - 7B4CE8D926F02108009134B1 /* UI Tests */, 3706FA6A293F65D500E42796 /* DuckDuckGo Privacy Browser App Store */, 3706FDD3293F661700E42796 /* Unit Tests App Store */, 3706FE9B293F662100E42796 /* Integration Tests App Store */, B6EC37E729B5DA2A001ACE79 /* tests-server */, + 4B4D603C2A0B290200BCD287 /* NetworkProtectionAppExtension */, + 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */, + 4B4BEC1F2A11B4E2001D9AC5 /* DuckDuckGoNotifications */, + 4B2D06382A11CFBA00DE1F49 /* DuckDuckGoAgent */, + 4B2D06682A13318400DE1F49 /* DuckDuckGoAgentAppStore */, + 4B5F14CA2A14702C0060320F /* startVPN */, + 4B5F14E02A1476BC0060320F /* stopVPN */, ); }; /* End PBXProject section */ @@ -6236,27 +6944,51 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7B4CE8D826F02108009134B1 /* Resources */ = { + 4B2D06372A11CFBA00DE1F49 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4B2D06582A11D19B00DE1F49 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - AA585D7C248FD31100E9A3E2 /* Resources */ = { + 4B2D06672A13318400DE1F49 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B02198C25E05FAC00ED7DEA /* Fireproofing.storyboard in Resources */, - AA80EC73256C46A2007083E7 /* Suggestion.storyboard in Resources */, - AA693E5E2696E5B90007BB78 /* CrashReports.storyboard in Resources */, - 9833913127AAA4B500DAF119 /* trackerData.json in Resources */, - AA7EB6ED27E880B600036718 /* dark-shield-dot-mouse-over.json in Resources */, - 8511E18425F82B34002F516B /* 01_Fire_really_small.json in Resources */, - 85B7184A27677C2D00B4277F /* Onboarding.storyboard in Resources */, - 4B0511C3262CAA5A00F6079C /* FireproofDomains.storyboard in Resources */, - EA477680272A21B700419EDA /* clickToLoadConfig.json in Resources */, - B6B1E88226D5DAC30062C350 /* Downloads.storyboard in Resources */, + 7B838C382A1DD8DD00E05A13 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B4BEC1E2A11B4E2001D9AC5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B4BEC482A11B61F001D9AC5 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B4CE8D826F02108009134B1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AA585D7C248FD31100E9A3E2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B02198C25E05FAC00ED7DEA /* Fireproofing.storyboard in Resources */, + AA80EC73256C46A2007083E7 /* Suggestion.storyboard in Resources */, + AA693E5E2696E5B90007BB78 /* CrashReports.storyboard in Resources */, + 9833913127AAA4B500DAF119 /* trackerData.json in Resources */, + AA7EB6ED27E880B600036718 /* dark-shield-dot-mouse-over.json in Resources */, + 8511E18425F82B34002F516B /* 01_Fire_really_small.json in Resources */, + 85B7184A27677C2D00B4277F /* Onboarding.storyboard in Resources */, + 4B0511C3262CAA5A00F6079C /* FireproofDomains.storyboard in Resources */, + EA477680272A21B700419EDA /* clickToLoadConfig.json in Resources */, + B6B1E88226D5DAC30062C350 /* Downloads.storyboard in Resources */, AA3439712754D4E900B241FA /* dark-shield.json in Resources */, AA7EB6EB27E880AE00036718 /* dark-shield-mouse-over.json in Resources */, B31055CB27A1BA1D001AC618 /* autoconsent-bundle.js in Resources */, @@ -6416,6 +7148,80 @@ shellPath = /bin/sh; shellScript = "if [[ \"${CONFIGURATION}\" == \"Release\" && \"${PRODUCT_NAME}\" != \"DuckDuckGo\" ]]; then\n echo \"PRODUCT_NAME must be equal to \\\"DuckDuckGo\\\" (is \\\"${PRODUCT_NAME}\\\")\"\n echo \"See ManualAppStoreRelease.xcconfig for instructions.\"\n exit 1\nfi\n"; }; + 4B2D065C2A11D23600DE1F49 /* Copy Assets */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Copy Assets"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + 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}\"/NetworkProtectionUI_NetworkProtectionUI.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; + }; + 4B2D067D2A13341200DE1F49 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + 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}\"/NetworkProtectionUI_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"; + }; + 7B6469992A165AE00095095A /* 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 = "DYLIB_PATH=$(find \"${TOOLCHAIN_DIR}/usr/lib\" -path \"*/${HOST_PLATFORM}/libswift_Concurrency.dylib\")\necho \"ditto ${DYLIB_PATH} to SysEx\"\n\nmkdir -p \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}/Contents/Frameworks\"\ncp \"${DYLIB_PATH}\" \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}/Contents/Frameworks/\" || exit 1\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"; + }; AA8EDF2824925E940071C2E8 /* Swift Lint */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -6509,10 +7315,12 @@ 3706FA9A293F65D500E42796 /* DuckPlayerURLExtension.swift in Sources */, 3706FA9D293F65D500E42796 /* PermissionState.swift in Sources */, 3707C724294B5D2900682A9F /* StringExtension.swift in Sources */, + 4B4D60C82A0C849600BCD287 /* NetworkProtectionInviteCodeView.swift in Sources */, 3706FA9F293F65D500E42796 /* FeedbackPresenter.swift in Sources */, 37197EA22942441900394917 /* Tab+Dialogs.swift in Sources */, 3706FAA0293F65D500E42796 /* UserAgent.swift in Sources */, 3706FAA1293F65D500E42796 /* NSAlert+DataImport.swift in Sources */, + 4B4D60DA2A0C875800BCD287 /* NetworkProtectionSelectedServerStore.swift in Sources */, 3706FAA2293F65D500E42796 /* MainWindow.swift in Sources */, 3707C727294B5D2900682A9F /* WKWebView+SessionState.swift in Sources */, 3706FAA3293F65D500E42796 /* CrashReportPromptViewController.swift in Sources */, @@ -6549,6 +7357,7 @@ 3706FAC3293F65D500E42796 /* AddEditFavoriteViewController.swift in Sources */, B6E1491129A5C30A00AAFBE8 /* FBProtectionTabExtension.swift in Sources */, 3706FAC4293F65D500E42796 /* PrintingUserScript.swift in Sources */, + 4B4D60B42A0C847900BCD287 /* LoginItem.swift in Sources */, 3706FEBF293F6EFF00E42796 /* BWError.swift in Sources */, 3706FAC6293F65D500E42796 /* ConnectBitwardenViewController.swift in Sources */, 3706FAC8293F65D500E42796 /* AppTrackerDataSetProvider.swift in Sources */, @@ -6628,6 +7437,7 @@ 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 */, 3706FB10293F65D500E42796 /* SuggestionTableRowView.swift in Sources */, 3706FB11293F65D500E42796 /* DownloadsPreferences.swift in Sources */, @@ -6638,6 +7448,7 @@ 3706FB16293F65D500E42796 /* StoredPermission.swift in Sources */, 3706FB17293F65D500E42796 /* FirePopoverCollectionViewHeader.swift in Sources */, 3706FB19293F65D500E42796 /* FireViewController.swift in Sources */, + 4B4D60D42A0C84F700BCD287 /* UserText+NetworkProtection.swift in Sources */, 3707C71F294B5D2900682A9F /* WKUserContentControllerExtension.swift in Sources */, 3706FB1A293F65D500E42796 /* OutlineSeparatorViewCell.swift in Sources */, 3706FB1B293F65D500E42796 /* SafariDataImporter.swift in Sources */, @@ -6682,6 +7493,7 @@ 3706FB3F293F65D500E42796 /* NSPopUpButtonView.swift in Sources */, 3706FB40293F65D500E42796 /* ContextualMenu.swift in Sources */, 3706FB41293F65D500E42796 /* NavigationBarViewController.swift in Sources */, + 4B7534CC2A1FD7EA00158A99 /* NetworkProtectionInviteDialog.swift in Sources */, 3707C71C294B5D1900682A9F /* TabExtensionsBuilder.swift in Sources */, 3706FB42293F65D500E42796 /* MainViewController.swift in Sources */, 3706FB43293F65D500E42796 /* DuckPlayer.swift in Sources */, @@ -6690,6 +7502,7 @@ 3706FB46293F65D500E42796 /* FirePopoverWrapperViewController.swift in Sources */, 3706FB47293F65D500E42796 /* NSPasteboardItemExtension.swift in Sources */, 3706FB48293F65D500E42796 /* AutofillPreferencesModel.swift in Sources */, + 4B4D60DE2A0C875E00BCD287 /* NetworkProtectionBundle.swift in Sources */, 3706FB49293F65D500E42796 /* NSException+Catch.swift in Sources */, 3706FB4A293F65D500E42796 /* PasswordManagementNoteModel.swift in Sources */, 3706FB4B293F65D500E42796 /* CookieNotificationAnimationModel.swift in Sources */, @@ -6728,6 +7541,7 @@ 3706FB6B293F65D500E42796 /* HistoryEntry.swift in Sources */, 3706FB6C293F65D500E42796 /* FaviconStore.swift in Sources */, 3706FB6D293F65D500E42796 /* SuggestionListCharacteristics.swift in Sources */, + 4B4D60C62A0C849600BCD287 /* NetworkProtectionInviteCodeViewModel.swift in Sources */, 3706FB6F293F65D500E42796 /* BookmarkListViewController.swift in Sources */, 3706FB70293F65D500E42796 /* SecureVaultLoginImporter.swift in Sources */, 3706FB71293F65D500E42796 /* AddBookmarkModalViewController.swift in Sources */, @@ -6761,6 +7575,7 @@ 3706FB87293F65D500E42796 /* ProcessExtension.swift in Sources */, 3706FB88293F65D500E42796 /* PermissionAuthorizationQuery.swift in Sources */, 3706FB89293F65D500E42796 /* BadgeAnimationView.swift in Sources */, + 4B4D60C32A0C849100BCD287 /* EventMapping+NetworkProtectionError.swift in Sources */, 3706FB8A293F65D500E42796 /* BrowserTabSelectionDelegate.swift in Sources */, 3706FB8B293F65D500E42796 /* PasswordManagementListSection.swift in Sources */, 3706FB8C293F65D500E42796 /* FaviconReferenceCache.swift in Sources */, @@ -6773,6 +7588,7 @@ 3706FB92293F65D500E42796 /* PermissionModel.swift in Sources */, 3706FB93293F65D500E42796 /* PasteboardFolder.swift in Sources */, 3706FB94293F65D500E42796 /* CookieManagedNotificationView.swift in Sources */, + 4B4D60BE2A0C848A00BCD287 /* NetworkProtection+ConvenienceInitializers.swift in Sources */, 3706FB95293F65D500E42796 /* PermissionType.swift in Sources */, 3706FB96293F65D500E42796 /* RecentlyClosedWindow.swift in Sources */, 3706FB97293F65D500E42796 /* ActionSpeech.swift in Sources */, @@ -6793,6 +7609,7 @@ 3706FBA0293F65D500E42796 /* NSTextFieldExtension.swift in Sources */, 3706FBA1293F65D500E42796 /* FireproofDomainsContainer.swift in Sources */, 3706FBA2293F65D500E42796 /* GeolocationService.swift in Sources */, + 4B4D60C42A0C849600BCD287 /* NetworkProtectionInvitePresenter.swift in Sources */, 3706FBA3293F65D500E42796 /* FireproofingURLExtensions.swift in Sources */, 3706FBA4293F65D500E42796 /* ContentOverlayPopover.swift in Sources */, 3706FBA5293F65D500E42796 /* TabShadowView.swift in Sources */, @@ -6812,6 +7629,7 @@ 3706FBB4293F65D500E42796 /* NSAlert+PasswordManager.swift in Sources */, 1D6A492129CF7A490011DF74 /* NSPopoverExtension.swift in Sources */, 3706FBB5293F65D500E42796 /* UserContentUpdating.swift in Sources */, + 4B4D60B72A0C847D00BCD287 /* NetworkProtectionNavBarButtonModel.swift in Sources */, 3706FBB6293F65D500E42796 /* ChromePreferences.swift in Sources */, 3706FBB7293F65D500E42796 /* FirePopoverViewController.swift in Sources */, 3706FBB8293F65D500E42796 /* SavePaymentMethodPopover.swift in Sources */, @@ -6853,6 +7671,7 @@ 3706FBDC293F65D500E42796 /* Permissions.xcdatamodeld in Sources */, 3706FBDD293F65D500E42796 /* PaddedImageButton.swift in Sources */, 3706FBDE293F65D500E42796 /* EncryptionKeyStoring.swift in Sources */, + 4B4D60E32A0C883A00BCD287 /* Main.swift in Sources */, 37197EA12942441700394917 /* Tab+UIDelegate.swift in Sources */, 3706FBDF293F65D500E42796 /* String+Punycode.swift in Sources */, 3706FBE0293F65D500E42796 /* NSException+Catch.m in Sources */, @@ -6887,6 +7706,7 @@ 3706FBFB293F65D500E42796 /* MoreOrLessView.swift in Sources */, 3706FBFD293F65D500E42796 /* DateExtension.swift in Sources */, 987799FA29999973005D8EB6 /* LocalBookmarkStore.swift in Sources */, + 4B4D60D52A0C873C00BCD287 /* TunnelConfiguration+WgQuickConfig.swift in Sources */, 3706FBFE293F65D500E42796 /* History.xcdatamodeld in Sources */, 3706FBFF293F65D500E42796 /* PermissionStore.swift in Sources */, 3706FC00293F65D500E42796 /* PrivacyIconViewModel.swift in Sources */, @@ -6905,6 +7725,7 @@ 3706FC09293F65D500E42796 /* SuggestionViewModel.swift in Sources */, 3706FC0A293F65D500E42796 /* BookmarkManagedObject.swift in Sources */, 3706FC0B293F65D500E42796 /* CSVLoginExporter.swift in Sources */, + 4B4D60D72A0C874E00BCD287 /* String+ArrayConversion.swift in Sources */, 37197EAC294244D600394917 /* FutureExtension.swift in Sources */, 3706FC0C293F65D500E42796 /* NSAttributedStringExtension.swift in Sources */, 3706FC0D293F65D500E42796 /* AnimationView.swift in Sources */, @@ -6955,6 +7776,7 @@ 3706FC38293F65D500E42796 /* BundleExtension.swift in Sources */, 3706FC3A293F65D500E42796 /* NSOpenPanelExtensions.swift in Sources */, 3706FC3B293F65D500E42796 /* FirePopover.swift in Sources */, + 4B4D60C12A0C848E00BCD287 /* NetworkProtectionControllerErrorStore.swift in Sources */, 3706FC3C293F65D500E42796 /* HistoryCoordinator.swift in Sources */, 3706FC3E293F65D500E42796 /* VariantManager.swift in Sources */, 3706FC3F293F65D500E42796 /* ApplicationDockMenu.swift in Sources */, @@ -6970,6 +7792,7 @@ 3706FC49293F65D500E42796 /* RoundedSelectionRowView.swift in Sources */, 3706FC4A293F65D500E42796 /* LocalStatisticsStore.swift in Sources */, 3706FC4B293F65D500E42796 /* BackForwardListItem.swift in Sources */, + 4B4D60DD2A0C875E00BCD287 /* NetworkProtectionSharedState.swift in Sources */, 3706FC4C293F65D500E42796 /* BrowserImportMoreInfoViewController.swift in Sources */, 3706FC4D293F65D500E42796 /* CookieConsentUserPermissionView.swift in Sources */, 3707C723294B5D2900682A9F /* URLSessionExtension.swift in Sources */, @@ -7037,6 +7860,7 @@ 3706FC89293F65D500E42796 /* NSWindow+Toast.swift in Sources */, 3706FC8A293F65D500E42796 /* AutoconsentUserScript.swift in Sources */, 3706FC8B293F65D500E42796 /* BookmarksExporter.swift in Sources */, + 4B4D60C52A0C849600BCD287 /* NetworkProtectionInviteSuccessView.swift in Sources */, 3706FC8C293F65D500E42796 /* FirefoxDataImporter.swift in Sources */, 3706FC8D293F65D500E42796 /* PreferencesGeneralView.swift in Sources */, 37197EA92942443D00394917 /* WebView.swift in Sources */, @@ -7344,6 +8168,113 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B2537562A11BE7300610219 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B25377A2A11C01700610219 /* UserText+NetworkProtectionExtensions.swift in Sources */, + 4B2537832A11C07600610219 /* NetworkProtectionLatencyReporter.swift in Sources */, + 4B2D06282A11C0C500DE1F49 /* NetworkProtectionSelectedServerStore.swift in Sources */, + 4B25377B2A11C01700610219 /* NetworkProtectionNotificationsPresenter.swift in Sources */, + 4B25377E2A11C07600610219 /* NetworkProtectionTunnelHealthStore.swift in Sources */, + 4B2D06262A11C0C500DE1F49 /* String+ArrayConversion.swift in Sources */, + 4B2D062D2A11C12300DE1F49 /* Logging.swift in Sources */, + 4B2537842A11C07600610219 /* PacketTunnelProvider.swift in Sources */, + 4B25377D2A11C07600610219 /* NetworkProtectionConnectionTester.swift in Sources */, + 4B2537822A11C07600610219 /* NetworkProtectionTunnelErrorStore.swift in Sources */, + 4B25377C2A11C07600610219 /* NetworkProtectionPixelEvent.swift in Sources */, + 4B2537852A11C07600610219 /* NetworkProtectionConnectionBandwidthAnalyzer.swift in Sources */, + 4B2D06272A11C0C500DE1F49 /* TunnelConfiguration+WgQuickConfig.swift in Sources */, + 4B2D062A2A11C0C900DE1F49 /* NetworkProtectionSharedState.swift in Sources */, + 4B2537732A11BF8C00610219 /* NetworkProtectionIPCNotificationsPresenter.swift in Sources */, + 4B2D06322A11C1D300DE1F49 /* NSApplicationExtension.swift in Sources */, + 4B2D06332A11C1E300DE1F49 /* OptionalExtension.swift in Sources */, + 4B2537782A11C00F00610219 /* NetworkProtectionExtensionMachService.swift in Sources */, + 4B2537792A11C00F00610219 /* IPCConnection.swift in Sources */, + 4B2537812A11C07600610219 /* NetworkConnectionType.swift in Sources */, + 4B2537722A11BF8B00610219 /* main.swift in Sources */, + 4B2D06312A11C18C00DE1F49 /* UserDefaultsWrapper.swift in Sources */, + 4B2D06292A11C0C900DE1F49 /* NetworkProtectionBundle.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B2D06352A11CFBA00DE1F49 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B2D065B2A11D1FF00DE1F49 /* Logging.swift in Sources */, + 4B2D06572A11D19B00DE1F49 /* DuckDuckGoAgentAppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B2D06652A13318400DE1F49 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B2D067C2A13340900DE1F49 /* Logging.swift in Sources */, + 4B2D067A2A1333EF00DE1F49 /* DuckDuckGoAgentAppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B4BEC1C2A11B4E2001D9AC5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B4BEC3D2A11B56B001D9AC5 /* DuckDuckGoNotificationsAppDelegate.swift in Sources */, + 4B4BEC3E2A11B56E001D9AC5 /* Logging.swift in Sources */, + 4B4BEC412A11B5BD001D9AC5 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */, + 4B4BEC432A11B5C7001D9AC5 /* NetworkProtectionBundle.swift in Sources */, + 4B4BEC442A11B5DE001D9AC5 /* NetworkProtectionNotificationsPresenter.swift in Sources */, + 4B4BEC452A11B5EE001D9AC5 /* UserText+NetworkProtectionExtensions.swift in Sources */, + 4B4BEC3F2A11B5AE001D9AC5 /* IPCConnection.swift in Sources */, + 4B4BEC422A11B5C7001D9AC5 /* NetworkProtectionSharedState.swift in Sources */, + 4B4BEC402A11B5B5001D9AC5 /* NetworkProtectionExtensionMachService.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B4D60392A0B290200BCD287 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B4D608C2A0B2A3700BCD287 /* NetworkProtectionLatencyReporter.swift in Sources */, + 4B4D609F2A0B2C7300BCD287 /* Logging.swift in Sources */, + 4B4D608B2A0B2A3700BCD287 /* NetworkProtectionTunnelErrorStore.swift in Sources */, + 4B4D60A12A0B2D6100BCD287 /* NetworkProtectionSharedState.swift in Sources */, + 4B4D60892A0B2A1C00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */, + 4B4D60A62A0B2ECC00BCD287 /* String+ArrayConversion.swift in Sources */, + 4B4D60942A0B2A3700BCD287 /* NetworkProtectionConnectionBandwidthAnalyzer.swift in Sources */, + 4B4D60A02A0B2D5B00BCD287 /* NetworkProtectionBundle.swift in Sources */, + 4B4D608D2A0B2A3700BCD287 /* NetworkProtectionConnectionTester.swift in Sources */, + 4B4D60A82A0B2F0B00BCD287 /* TunnelConfiguration+WgQuickConfig.swift in Sources */, + 4B4D60932A0B2A3700BCD287 /* NetworkProtectionPixelEvent.swift in Sources */, + 4B4D60AB2A0C7FEA00BCD287 /* UserDefaultsWrapper.swift in Sources */, + 4B4D608A2A0B2A3700BCD287 /* PacketTunnelProvider.swift in Sources */, + 4B4D60AD2A0C807300BCD287 /* NSApplicationExtension.swift in Sources */, + 4B4D60A52A0B2EC000BCD287 /* UserText+NetworkProtectionExtensions.swift in Sources */, + 4B4D60922A0B2A3700BCD287 /* NetworkConnectionType.swift in Sources */, + 4B4D608E2A0B2A3700BCD287 /* NetworkProtectionTunnelHealthStore.swift in Sources */, + 4B4D60AA2A0C7FDD00BCD287 /* NetworkProtectionNotificationsPresenter.swift in Sources */, + 4B4D60AC2A0C804B00BCD287 /* OptionalExtension.swift in Sources */, + 4B4D60A72A0B2F0600BCD287 /* NetworkProtectionSelectedServerStore.swift in Sources */, + ); + 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; + }; 7B4CE8D626F02108009134B1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -7380,6 +8311,7 @@ 4B92928F26670D1700AD2C21 /* BookmarkTableCellView.swift in Sources */, 4B9292CF2667123700AD2C21 /* BookmarkManagementSidebarViewController.swift in Sources */, 4B39AAF627D9B2C700A73FD5 /* NSStackViewExtension.swift in Sources */, + 4B4D60DC2A0C875800BCD287 /* NetworkProtectionSelectedServerStore.swift in Sources */, B637273D26CCF0C200C8CB02 /* OptionalExtension.swift in Sources */, 4BE65477271FCD41008D1D63 /* PasswordManagementLoginItemView.swift in Sources */, AA80EC54256BE3BC007083E7 /* UserText.swift in Sources */, @@ -7422,6 +8354,7 @@ 4B59024326B35F7C00489384 /* BrowserImportViewController.swift in Sources */, 4B9292D72667124000AD2C21 /* NSPopUpButtonExtension.swift in Sources */, 85D33F1225C82EB3002B91A6 /* ConfigurationManager.swift in Sources */, + 4B4D60CE2A0C849600BCD287 /* NetworkProtectionInviteCodeView.swift in Sources */, 31F28C4F28C8EEC500119F70 /* YoutubePlayerUserScript.swift in Sources */, B6A9E48426146AAB0067D1B9 /* PixelParameters.swift in Sources */, 4B7A94B429C16294000C7D4C /* ErrorWithParameters.swift in Sources */, @@ -7449,8 +8382,10 @@ 4B723E0B26B0005B00E14D75 /* FileImportViewController.swift in Sources */, 8589063C267BCDC000D23B0D /* SaveCredentialsViewController.swift in Sources */, 4BBE0AA727B9B027003B37A8 /* PopUpButton.swift in Sources */, + 4B4D60CF2A0C849600BCD287 /* NetworkProtectionInviteDialog.swift in Sources */, AABEE6A524AA0A7F0043105B /* SuggestionViewController.swift in Sources */, 85589E8027BBB8630038AD11 /* AddEditFavoriteWindow.swift in Sources */, + 4B4D60CB2A0C849600BCD287 /* NetworkProtectionInviteSuccessView.swift in Sources */, 1D6216B229069BBF00386B2C /* BWKeyStorage.swift in Sources */, AA7E919F287872EA00AB6B62 /* VisitViewModel.swift in Sources */, B69B503B2726A12500758A2B /* Atb.swift in Sources */, @@ -7481,6 +8416,7 @@ AA7E919728746BCC00AB6B62 /* HistoryMenu.swift in Sources */, F4A6198C283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift in Sources */, 85707F24276A332A00DC0649 /* OnboardingButtonStyles.swift in Sources */, + 4B4D60D82A0C875100BCD287 /* String+ArrayConversion.swift in Sources */, 4B8A4E0127C8447E005F40E8 /* SaveIdentityPopover.swift in Sources */, B637273B26CBC8AF00C8CB02 /* AuthenticationAlert.swift in Sources */, 315AA07028CA5CC800200030 /* YoutubePlayerNavigationHandler.swift in Sources */, @@ -7500,6 +8436,7 @@ B6B1E87E26D5DA0E0062C350 /* DownloadsPopover.swift in Sources */, 4B9292A026670D2A00AD2C21 /* SpacerNode.swift in Sources */, B6E61EE8263ACE16004E11AB /* UTType.swift in Sources */, + 4B2D06342A11CC4600DE1F49 /* SystemExtensionManager.swift in Sources */, 3775913629AB9A1C00E26367 /* SyncManagementDialogViewController.swift in Sources */, B6C0BB6729AEFF8100AE8E3C /* BookmarkExtension.swift in Sources */, 4BE6547F271FCD4D008D1D63 /* PasswordManagementCreditCardModel.swift in Sources */, @@ -7515,6 +8452,7 @@ 37CC53F427E8D4620028713D /* NSPathControlView.swift in Sources */, B6BF5D8929470BC4006742B1 /* HTTPSUpgradeTabExtension.swift in Sources */, 1D36E65B298ACD2900AA485D /* AppIconChanger.swift in Sources */, + 4B4D60E22A0C883A00BCD287 /* Main.swift in Sources */, 98779A0029999B64005D8EB6 /* Bookmark.xcdatamodeld in Sources */, 85589E9E27BFE4500038AD11 /* DefaultBrowserPromptView.swift in Sources */, 4B78A86B26BB3ADD0071BB16 /* BrowserImportSummaryViewController.swift in Sources */, @@ -7525,6 +8463,7 @@ 4B1E6EF227AB5E5D00F51793 /* PasswordManagementItemList.swift in Sources */, AAC5E4D025D6A709007F5990 /* Bookmark.swift in Sources */, 4BBDEE9328FC14760092FAA6 /* ConnectBitwardenViewModel.swift in Sources */, + 4B4D60D62A0C873C00BCD287 /* TunnelConfiguration+WgQuickConfig.swift in Sources */, 4B5A4F4C27F3A5AA008FBD88 /* NSNotificationName+DataImport.swift in Sources */, B64C853826944B880048FEBE /* StoredPermission.swift in Sources */, AAE246F8270A406200BEEAEE /* FirePopoverCollectionViewHeader.swift in Sources */, @@ -7592,6 +8531,7 @@ 4B0AACAE28BC6FD0001038AC /* SafariFaviconsReader.swift in Sources */, B6B3E0E12657EA7A0040E0A2 /* NSScreenExtension.swift in Sources */, B65E6BA026D9F10600095F96 /* NSBezierPathExtension.swift in Sources */, + 4B4D60E02A0C875F00BCD287 /* NetworkProtectionBundle.swift in Sources */, AA6820E425502F19005ED0D5 /* WebsiteDataStore.swift in Sources */, B64C852A26942AC90048FEBE /* PermissionContextMenu.swift in Sources */, 85D438B6256E7C9E00F3BAF8 /* ContextMenuUserScript.swift in Sources */, @@ -7656,6 +8596,7 @@ AA222CB92760F74E00321475 /* FaviconReferenceCache.swift in Sources */, 4B9292A126670D2A00AD2C21 /* BookmarkTreeController.swift in Sources */, 4B29759728281F0900187C4E /* FirefoxEncryptionKeyReader.swift in Sources */, + 4B4D60C22A0C849000BCD287 /* EventMapping+NetworkProtectionError.swift in Sources */, 4B9292D02667123700AD2C21 /* BookmarkManagementSplitViewController.swift in Sources */, 3171D6DB2889B64D0068632A /* CookieManagedNotificationContainerView.swift in Sources */, B6E61EE3263AC0C8004E11AB /* FileManagerExtension.swift in Sources */, @@ -7664,6 +8605,7 @@ B6CFAA522943725600CB6B11 /* WebKitDownloadDelegate.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 */, @@ -7690,6 +8632,7 @@ 856CADF0271710F400E79BB0 /* HoverUserScript.swift in Sources */, AA6EF9B525081B4C004754E6 /* MainMenuActions.swift in Sources */, B63D466925BEB6C200874977 /* WKWebView+SessionState.swift in Sources */, + 4B4D60C02A0C848D00BCD287 /* NetworkProtectionControllerErrorStore.swift in Sources */, 4B723E1226B0006E00E14D75 /* DataImport.swift in Sources */, B6085D092743AAB600A9C456 /* FireproofDomains.xcdatamodeld in Sources */, 3106AD76287F000600159FE5 /* CookieConsentUserPermissionViewController.swift in Sources */, @@ -7719,6 +8662,7 @@ AAE7527C263B056C00B973F8 /* HistoryStore.swift in Sources */, AAE246F32709EF3B00BEEAEE /* FirePopoverCollectionViewItem.swift in Sources */, AA61C0D22727F59B00E6B681 /* ArrayExtension.swift in Sources */, + 4B4D60CC2A0C849600BCD287 /* NetworkProtectionInviteCodeViewModel.swift in Sources */, AAC30A2C268F1ECD00D2D9CD /* CrashReportSender.swift in Sources */, 373A1AB02842C4EA00586521 /* BookmarkHTMLImporter.swift in Sources */, 31C3CE0228EDC1E70002C24A /* CustomRoundedCornersShape.swift in Sources */, @@ -7787,6 +8731,7 @@ 85707F31276A7DCA00DC0649 /* OnboardingViewModel.swift in Sources */, 85AC3B0525D6B1D800C7D2AA /* ScriptSourceProviding.swift in Sources */, 4BB99D0026FE191E001E4761 /* CoreDataBookmarkImporter.swift in Sources */, + 4B4D60B52A0C847A00BCD287 /* LoginItem.swift in Sources */, AA3F895324C18AD500628DDE /* SuggestionViewModel.swift in Sources */, 4B9292A326670D2A00AD2C21 /* BookmarkManagedObject.swift in Sources */, 4B723E1326B0007A00E14D75 /* CSVLoginExporter.swift in Sources */, @@ -7816,6 +8761,7 @@ B693954E26F04BEB0015B914 /* ProgressView.swift in Sources */, B69B503C2726A12500758A2B /* StatisticsStore.swift in Sources */, 4BBDEE9128FC14760092FAA6 /* BWInstallationService.swift in Sources */, + 4B4D60CA2A0C849600BCD287 /* NetworkProtectionInvitePresenter.swift in Sources */, B693955426F04BEC0015B914 /* ColorView.swift in Sources */, AA5C1DD3285A217F0089850C /* RecentlyClosedCacheItem.swift in Sources */, B6BBF17427475B15004F850E /* PopupBlockedPopover.swift in Sources */, @@ -7876,6 +8822,7 @@ 85B7184C27677C6500B4277F /* OnboardingViewController.swift in Sources */, 4B379C1E27BDB7FF008A968E /* DeviceAuthenticator.swift in Sources */, 1456D6E124EFCBC300775049 /* TabBarCollectionView.swift in Sources */, + 4B4D60BF2A0C848A00BCD287 /* NetworkProtection+ConvenienceInitializers.swift in Sources */, B655124829A79465009BFE1C /* NavigationActionExtension.swift in Sources */, 85308E25267FC9F2001ABD76 /* NSAlertExtension.swift in Sources */, 4B59024826B3673600489384 /* ThirdPartyBrowser.swift in Sources */, @@ -7887,6 +8834,7 @@ 4B59024126B35F3600489384 /* BraveDataImporter.swift in Sources */, B6A9E46B2614618A0067D1B9 /* OperatingSystemVersionExtension.swift in Sources */, 4BDFA4AE27BF19E500648192 /* ToggleableScrollView.swift in Sources */, + 4B4D60DF2A0C875F00BCD287 /* NetworkProtectionSharedState.swift in Sources */, 85AC3AEF25D5CE9800C7D2AA /* UserScripts.swift in Sources */, B643BF1427ABF772000BACEC /* NSWorkspaceExtension.swift in Sources */, B6C00ECB292F839D009C73A6 /* AutofillTabExtension.swift in Sources */, @@ -7939,7 +8887,9 @@ 4B92928B26670D1700AD2C21 /* BookmarksOutlineView.swift in Sources */, 4BF01C00272AE74C00884A61 /* CountryList.swift in Sources */, 37CD54CC27F2FDD100F1F7B9 /* PreferencesSection.swift in Sources */, + 4B4D60B62A0C847D00BCD287 /* NetworkProtectionNavBarButtonModel.swift in Sources */, FD23FD2D2886A81D007F6985 /* AutoconsentManagement.swift in Sources */, + 4B4D60D32A0C84F700BCD287 /* UserText+NetworkProtection.swift in Sources */, B6B2400E28083B49001B8F3A /* WebViewContainerView.swift in Sources */, AAC5E4D925D6A711007F5990 /* BookmarkStore.swift in Sources */, B6FA893F269C424500588ECD /* PrivacyDashboardViewController.swift in Sources */, @@ -8185,18 +9135,31 @@ target = 3706FA6A293F65D500E42796 /* DuckDuckGo Privacy Browser App Store */; targetProxy = 37079A94294236FA0031BB3C /* PBXContainerItemProxy */; }; - 3799999229705E1A003318B1 /* PBXTargetDependency */ = { + 4B1AD8A325FC27E200261379 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - productRef = 3799999129705E1A003318B1 /* InputFilesChecker */; + target = AA585D7D248FD31100E9A3E2 /* DuckDuckGo Privacy Browser */; + targetProxy = 4B1AD8A225FC27E200261379 /* PBXContainerItemProxy */; }; - 3799999429705E1F003318B1 /* PBXTargetDependency */ = { + 4B2537642A11BE7600610219 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - productRef = 3799999329705E1F003318B1 /* InputFilesChecker */; + target = 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */; + targetProxy = 4B2537632A11BE7600610219 /* PBXContainerItemProxy */; }; - 4B1AD8A325FC27E200261379 /* PBXTargetDependency */ = { + 4B4BEC4A2A11B627001D9AC5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = AA585D7D248FD31100E9A3E2 /* DuckDuckGo Privacy Browser */; - targetProxy = 4B1AD8A225FC27E200261379 /* PBXContainerItemProxy */; + productRef = 4B4BEC492A11B627001D9AC5 /* NetworkProtection */; + }; + 4B4D60532A0B29CB00BCD287 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = 4B4D60522A0B29CB00BCD287 /* NetworkProtection */; + }; + 4B5F14FC2A15291D0060320F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = 4B5F14FB2A15291D0060320F /* InputFilesChecker */; + }; + 4B5F14FE2A1529230060320F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = 4B5F14FD2A1529230060320F /* InputFilesChecker */; }; 7B4CE8E026F02108009134B1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -8390,6 +9353,202 @@ }; name = CI; }; + 4B2537672A11BE7700610219 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4D604F2A0B293C00BCD287 /* NetworkProtectionSystemExtension.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4B2537682A11BE7700610219 /* CI */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4D604F2A0B293C00BCD287 /* NetworkProtectionSystemExtension.xcconfig */; + buildSettings = { + }; + name = CI; + }; + 4B2537692A11BE7700610219 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4D604F2A0B293C00BCD287 /* NetworkProtectionSystemExtension.xcconfig */; + buildSettings = { + }; + name = Release; + }; + 4B25376A2A11BE7700610219 /* Review */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4D604F2A0B293C00BCD287 /* NetworkProtectionSystemExtension.xcconfig */; + buildSettings = { + }; + name = Review; + }; + 4B2D06462A11CFBE00DE1F49 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4B2D06472A11CFBE00DE1F49 /* CI */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */; + buildSettings = { + }; + name = CI; + }; + 4B2D06482A11CFBE00DE1F49 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */; + buildSettings = { + }; + name = Release; + }; + 4B2D06492A11CFBE00DE1F49 /* Review */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B2D064B2A11D04000DE1F49 /* DuckDuckGoAgent.xcconfig */; + buildSettings = { + }; + name = Review; + }; + 4B2D06762A13318600DE1F49 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4B2D06772A13318600DE1F49 /* CI */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */; + buildSettings = { + }; + name = CI; + }; + 4B2D06782A13318600DE1F49 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */; + buildSettings = { + }; + name = Release; + }; + 4B2D06792A13318600DE1F49 /* Review */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B2D064D2A11D04000DE1F49 /* DuckDuckGoAgentAppStore.xcconfig */; + buildSettings = { + }; + name = Review; + }; + 4B4BEC2D2A11B4E3001D9AC5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4BEC182A11B3EA001D9AC5 /* DuckDuckGoNotifications.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4B4BEC2E2A11B4E3001D9AC5 /* CI */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4BEC182A11B3EA001D9AC5 /* DuckDuckGoNotifications.xcconfig */; + buildSettings = { + }; + name = CI; + }; + 4B4BEC2F2A11B4E3001D9AC5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4BEC182A11B3EA001D9AC5 /* DuckDuckGoNotifications.xcconfig */; + buildSettings = { + }; + name = Release; + }; + 4B4BEC302A11B4E3001D9AC5 /* Review */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4BEC182A11B3EA001D9AC5 /* DuckDuckGoNotifications.xcconfig */; + buildSettings = { + }; + name = Review; + }; + 4B4D60492A0B290300BCD287 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4D60502A0B293C00BCD287 /* NetworkProtectionAppExtension.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4B4D604A2A0B290300BCD287 /* CI */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4D60502A0B293C00BCD287 /* NetworkProtectionAppExtension.xcconfig */; + buildSettings = { + }; + name = CI; + }; + 4B4D604B2A0B290300BCD287 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4D60502A0B293C00BCD287 /* NetworkProtectionAppExtension.xcconfig */; + buildSettings = { + }; + name = Release; + }; + 4B4D604C2A0B290300BCD287 /* Review */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B4D60502A0B293C00BCD287 /* NetworkProtectionAppExtension.xcconfig */; + buildSettings = { + }; + 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; + }; 7B4CE8E126F02108009134B1 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 378B588C295CF446002C0CC0 /* UITests.xcconfig */; @@ -8563,6 +9722,83 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4B2537662A11BE7700610219 /* Build configuration list for PBXNativeTarget "NetworkProtectionSystemExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B2537672A11BE7700610219 /* Debug */, + 4B2537682A11BE7700610219 /* CI */, + 4B2537692A11BE7700610219 /* Release */, + 4B25376A2A11BE7700610219 /* Review */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4B2D06452A11CFBE00DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoAgent" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B2D06462A11CFBE00DE1F49 /* Debug */, + 4B2D06472A11CFBE00DE1F49 /* CI */, + 4B2D06482A11CFBE00DE1F49 /* Release */, + 4B2D06492A11CFBE00DE1F49 /* Review */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4B2D06752A13318600DE1F49 /* Build configuration list for PBXNativeTarget "DuckDuckGoAgentAppStore" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B2D06762A13318600DE1F49 /* Debug */, + 4B2D06772A13318600DE1F49 /* CI */, + 4B2D06782A13318600DE1F49 /* Release */, + 4B2D06792A13318600DE1F49 /* Review */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4B4BEC2C2A11B4E3001D9AC5 /* Build configuration list for PBXNativeTarget "DuckDuckGoNotifications" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B4BEC2D2A11B4E3001D9AC5 /* Debug */, + 4B4BEC2E2A11B4E3001D9AC5 /* CI */, + 4B4BEC2F2A11B4E3001D9AC5 /* Release */, + 4B4BEC302A11B4E3001D9AC5 /* Review */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4B4D604D2A0B290300BCD287 /* Build configuration list for PBXNativeTarget "NetworkProtectionAppExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B4D60492A0B290300BCD287 /* Debug */, + 4B4D604A2A0B290300BCD287 /* CI */, + 4B4D604B2A0B290300BCD287 /* Release */, + 4B4D604C2A0B290300BCD287 /* Review */, + ); + 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; + }; 7B4CE8E526F02108009134B1 /* Build configuration list for PBXNativeTarget "UI Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -8800,14 +10036,6 @@ isa = XCSwiftPackageProductDependency; productName = SwiftUIExtensions; }; - 3799999129705E1A003318B1 /* InputFilesChecker */ = { - isa = XCSwiftPackageProductDependency; - productName = "plugin:InputFilesChecker"; - }; - 3799999329705E1F003318B1 /* InputFilesChecker */ = { - isa = XCSwiftPackageProductDependency; - productName = "plugin:InputFilesChecker"; - }; 37A5E2EF298AA1B20047046B /* Persistence */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -8836,16 +10064,84 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Navigation; }; + 4B2537742A11BFDE00610219 /* NetworkProtection */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtection; + }; + 4B2537762A11BFE100610219 /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + productName = PixelKit; + }; 4B2AAAF429E70DEA0026AFC0 /* Lottie */ = { isa = XCSwiftPackageProductDependency; package = 4B2AAAF329E70DEA0026AFC0 /* XCRemoteSwiftPackageReference "lottie-ios" */; productName = Lottie; }; + 4B2D062B2A11C0E100DE1F49 /* Networking */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Networking; + }; + 4B2D062F2A11C15900DE1F49 /* Common */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Common; + }; + 4B2D064E2A11D0D000DE1F49 /* NetworkProtectionUI */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionUI; + }; + 4B2D067E2A1334D700DE1F49 /* NetworkProtectionUI */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionUI; + }; + 4B4BEC462A11B600001D9AC5 /* NetworkProtection */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtection; + }; + 4B4BEC492A11B627001D9AC5 /* NetworkProtection */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtection; + }; + 4B4D60522A0B29CB00BCD287 /* NetworkProtection */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtection; + }; + 4B4D60952A0B2A5800BCD287 /* NetworkProtection */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtection; + }; + 4B4D60972A0B2A5C00BCD287 /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + productName = PixelKit; + }; + 4B4D60AE2A0C837F00BCD287 /* Networking */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Networking; + }; + 4B4D60B02A0C83B900BCD287 /* NetworkProtectionUI */ = { + isa = XCSwiftPackageProductDependency; + productName = NetworkProtectionUI; + }; + 4B5F14FB2A15291D0060320F /* InputFilesChecker */ = { + isa = XCSwiftPackageProductDependency; + productName = "plugin:InputFilesChecker"; + }; + 4B5F14FD2A1529230060320F /* InputFilesChecker */ = { + isa = XCSwiftPackageProductDependency; + productName = "plugin:InputFilesChecker"; + }; 4B82E9B225B69E3E00656FE7 /* TrackerRadarKit */ = { isa = XCSwiftPackageProductDependency; package = 4B82E9B125B69E3E00656FE7 /* XCRemoteSwiftPackageReference "TrackerRadarKit" */; productName = TrackerRadarKit; }; + 4B8F52342A169D2D00BE7131 /* Common */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Common; + }; 9807F644278CA16F00E1547B /* BrowserServicesKit */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8da80abef2..7a700e4399 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -125,6 +125,15 @@ "revision" : "4684440d03304e7638a2c8086895367e90987463", "version" : "1.2.1" } + }, + { + "identity" : "wireguard-apple", + "kind" : "remoteSourceControl", + "location" : "https://github.com/duckduckgo/wireguard-apple", + "state" : { + "revision" : "156abe15063b35b633363ec33fc2c040f81f9326", + "version" : "1.0.0" + } } ], "version" : 2 diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme new file mode 100644 index 0000000000..adc90361ec --- /dev/null +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoAgent.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoNotifications.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoNotifications.xcscheme new file mode 100644 index 0000000000..c5faeacd59 --- /dev/null +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGoNotifications.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/NetworkProtectionExtension.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/NetworkProtectionExtension.xcscheme new file mode 100644 index 0000000000..8587643ba8 --- /dev/null +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/NetworkProtectionExtension.xcscheme @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DuckDuckGo/AppDelegate/AppDelegate.swift b/DuckDuckGo/AppDelegate/AppDelegate.swift index a345caaa0c..ede13d6349 100644 --- a/DuckDuckGo/AppDelegate/AppDelegate.swift +++ b/DuckDuckGo/AppDelegate/AppDelegate.swift @@ -25,9 +25,13 @@ import Configuration import Networking import Bookmarks import DDGSync +import ServiceManagement import SyncDataProviders -@NSApplicationMain +#if NETWORK_PROTECTION +import NetworkProtection +#endif + @MainActor final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDelegate { @@ -201,6 +205,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel UserDefaultsWrapper.clearRemovedKeys() +#if NETWORK_PROTECTION + startupNetworkProtection() +#endif + syncStateCancellable = syncService.authStatePublisher .prepend(syncService.authState) .map { $0 == .inactive } @@ -266,6 +274,74 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel appearancePreferences.updateUserInterfaceStyle() } + // MARK: - Network Protection + +#if NETWORK_PROTECTION + + private func startupNetworkProtection() { + let networkProtectionFeatureVisibility = NetworkProtectionKeychainTokenStore() + + guard networkProtectionFeatureVisibility.isFeatureActivated else { + NetworkProtectionTunnelController.disableLoginItems() + LocalPinningManager.shared.unpin(.networkProtection) + return + } + + updateNetworkProtectionIfVersionChanged() + refreshNetworkProtectionServers() + } + + private func updateNetworkProtectionIfVersionChanged() { + let currentVersion = AppVersion.shared.versionNumber + let versionStore = NetworkProtectionLastVersionRunStore() + defer { + versionStore.lastVersionRun = currentVersion + } + + // should‘ve been run at least once with NetP enabled + guard let lastVersionRun = versionStore.lastVersionRun else { + os_log(.error, log: .networkProtection, "🔴 running netp for the first time: update not needed") + return + } + + if lastVersionRun != currentVersion { + os_log(.error, log: .networkProtection, "🟡 App updated from %{public}s to %{public}s: updating", lastVersionRun, currentVersion) + updateNetworkProtectionTunnelAndMenu() + } else { + // If login items failed to launch (e.g. because of the App bundle rename), launch using NSWorkspace + NetworkProtectionTunnelController.ensureLoginItemsAreRunning(.ifLoginItemsAreEnabled, after: 1) + } + } + + private func updateNetworkProtectionTunnelAndMenu() { + Task { + let provider = NetworkProtectionTunnelController() + + if await provider.isConnected() { + try? await provider.stop() + } + } + + NetworkProtectionTunnelController.resetLoginItems() + } + + /// Fetches a new list of Network Protection servers, and updates the existing set. + private func refreshNetworkProtectionServers() { + Task { + let serverCount: Int + do { + serverCount = try await NetworkProtectionDeviceManager.create().refreshServerList().count + } catch { + os_log("Failed to update Network Protection servers", log: .networkProtection, type: .error) + return + } + + os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount) + } + } + +#endif + private func subscribeToEmailProtectionStatusNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(emailDidSignInNotification(_:)), diff --git a/DuckDuckGo/AppDelegate/URLEventHandler.swift b/DuckDuckGo/AppDelegate/URLEventHandler.swift index 12a3233c1b..feb6d1e36a 100644 --- a/DuckDuckGo/AppDelegate/URLEventHandler.swift +++ b/DuckDuckGo/AppDelegate/URLEventHandler.swift @@ -19,6 +19,10 @@ import Common import Foundation +#if NETWORK_PROTECTION +import NetworkProtection +#endif + @MainActor final class URLEventHandler { @@ -95,7 +99,32 @@ final class URLEventHandler { } private static func openURL(_ url: URL) { +#if NETWORK_PROTECTION + if url.scheme == "networkprotection" { + handleNetworkProtectionURL(url) + } else { + WindowControllersManager.shared.show(url: url, newTab: true) + } +#else WindowControllersManager.shared.show(url: url, newTab: true) +#endif + } + +#if NETWORK_PROTECTION + + /// Handles NetP URLs + /// + private static func handleNetworkProtectionURL(_ url: URL) { + switch url { + case AppLauncher.Command.showStatus.launchURL: + Task { + await WindowControllersManager.shared.showNetworkProtectionStatus() + } + default: + return + } } +#endif + } diff --git a/DuckDuckGo/Assets.xcassets/Colors/AlertBubbleBackground.colorset/Contents.json b/DuckDuckGo/Assets.xcassets/Colors/AlertBubbleBackground.colorset/Contents.json new file mode 100644 index 0000000000..23344aa554 --- /dev/null +++ b/DuckDuckGo/Assets.xcassets/Colors/AlertBubbleBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC2", + "green" : "0xF0", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.140", + "blue" : "0x33", + "green" : "0xCC", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DuckDuckGo/Assets.xcassets/Colors/AlertRedLightDefaultText.colorset/Contents.json b/DuckDuckGo/Assets.xcassets/Colors/AlertRedLightDefaultText.colorset/Contents.json new file mode 100644 index 0000000000..d308a3492a --- /dev/null +++ b/DuckDuckGo/Assets.xcassets/Colors/AlertRedLightDefaultText.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "45", + "green" : "26", + "red" : "235" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "90", + "green" : "84", + "red" : "255" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DuckDuckGo/Assets.xcassets/Images/InviteLock.imageset/Contents.json b/DuckDuckGo/Assets.xcassets/Images/InviteLock.imageset/Contents.json new file mode 100644 index 0000000000..55f71e50e2 --- /dev/null +++ b/DuckDuckGo/Assets.xcassets/Images/InviteLock.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Invite-Lock-96.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DuckDuckGo/Assets.xcassets/Images/InviteLock.imageset/Invite-Lock-96.pdf b/DuckDuckGo/Assets.xcassets/Images/InviteLock.imageset/Invite-Lock-96.pdf new file mode 100644 index 0000000000..c826a6f338 Binary files /dev/null and b/DuckDuckGo/Assets.xcassets/Images/InviteLock.imageset/Invite-Lock-96.pdf differ diff --git a/DuckDuckGo/Assets.xcassets/Images/InviteLockSuccess.imageset/Contents.json b/DuckDuckGo/Assets.xcassets/Images/InviteLockSuccess.imageset/Contents.json new file mode 100644 index 0000000000..177239fca7 --- /dev/null +++ b/DuckDuckGo/Assets.xcassets/Images/InviteLockSuccess.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Intive-Lock-Succes-96.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DuckDuckGo/Assets.xcassets/Images/InviteLockSuccess.imageset/Intive-Lock-Succes-96.pdf b/DuckDuckGo/Assets.xcassets/Images/InviteLockSuccess.imageset/Intive-Lock-Succes-96.pdf new file mode 100644 index 0000000000..a1b44f32ef Binary files /dev/null and b/DuckDuckGo/Assets.xcassets/Images/InviteLockSuccess.imageset/Intive-Lock-Succes-96.pdf differ diff --git a/DuckDuckGo/Assets.xcassets/Images/WarningColored.imageset/Contents.json b/DuckDuckGo/Assets.xcassets/Images/WarningColored.imageset/Contents.json new file mode 100644 index 0000000000..2e3acc9375 --- /dev/null +++ b/DuckDuckGo/Assets.xcassets/Images/WarningColored.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "WarningColored.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DuckDuckGo/Assets.xcassets/Images/WarningColored.imageset/WarningColored.png b/DuckDuckGo/Assets.xcassets/Images/WarningColored.imageset/WarningColored.png new file mode 100644 index 0000000000..16c1f7482b Binary files /dev/null and b/DuckDuckGo/Assets.xcassets/Images/WarningColored.imageset/WarningColored.png differ diff --git a/DuckDuckGo/Common/Extensions/BundleExtension.swift b/DuckDuckGo/Common/Extensions/BundleExtension.swift index 8e46a93e1c..c8a08bf19f 100644 --- a/DuckDuckGo/Common/Extensions/BundleExtension.swift +++ b/DuckDuckGo/Common/Extensions/BundleExtension.swift @@ -26,6 +26,13 @@ extension Bundle { static let buildNumber = kCFBundleVersionKey as String static let versionNumber = "CFBundleShortVersionString" static let displayName = "CFBundleDisplayName" + static let vpnMenuAgentBundleId = "AGENT_BUNDLE_ID" + static let vpnMenuAgentProductName = "AGENT_PRODUCT_NAME" + +#if NETP_SYSTEM_EXTENSION + static let notificationsAgentBundleId = "NOTIFICATIONS_AGENT_BUNDLE_ID" + static let notificationsAgentProductName = "NOTIFICATIONS_AGENT_PRODUCT_NAME" +#endif } var displayName: String? { @@ -33,4 +40,38 @@ extension Bundle { object(forInfoDictionaryKey: Keys.name) as? String } + var vpnMenuAgentBundleId: String { + guard let bundleID = object(forInfoDictionaryKey: Keys.vpnMenuAgentBundleId) as? String else { + fatalError("Info.plist is missing \(Keys.vpnMenuAgentBundleId)") + } + return bundleID + } + + var loginItemsURL: URL { + bundleURL.appendingPathComponent("Contents/Library/LoginItems") + } + + var vpnMenuAgentURL: URL { + guard let productName = object(forInfoDictionaryKey: Keys.vpnMenuAgentProductName) as? String else { + fatalError("Info.plist is missing \(Keys.vpnMenuAgentProductName)") + } + return loginItemsURL.appendingPathComponent(productName + ".app") + } + +#if NETP_SYSTEM_EXTENSION + var notificationsAgentBundleId: String { + guard let bundleID = object(forInfoDictionaryKey: Keys.notificationsAgentBundleId) as? String else { + fatalError("Info.plist is missing \(Keys.notificationsAgentBundleId)") + } + return bundleID + } + + var notificationsAgentURL: URL { + guard let productName = object(forInfoDictionaryKey: Keys.notificationsAgentProductName) as? String else { + fatalError("Info.plist is missing \(Keys.notificationsAgentProductName)") + } + return loginItemsURL.appendingPathComponent(productName + ".app") + } +#endif + } diff --git a/DuckDuckGo/Common/Extensions/NSAlertExtension.swift b/DuckDuckGo/Common/Extensions/NSAlertExtension.swift index 0095e38e7f..59f2020b62 100644 --- a/DuckDuckGo/Common/Extensions/NSAlertExtension.swift +++ b/DuckDuckGo/Common/Extensions/NSAlertExtension.swift @@ -119,6 +119,35 @@ extension NSAlert { return alert } + static func resetNetworkProtectionAlert() -> NSAlert { + let alert = NSAlert() + alert.messageText = "Reset Network Protection?" + alert.informativeText = """ + This will remove your stored network configuration (including private key) and disable the VPN. + + You can re-enable the VPN from the Network Protection view. + """ + alert.alertStyle = .warning + alert.addButton(withTitle: "Reset") + alert.addButton(withTitle: UserText.cancel) + return alert + } + + static func removeSystemExtensionAndAgentsAlert() -> NSAlert { + let alert = NSAlert() +#if NETP_SYSTEM_EXTENSION + let sysExText = "System Extension and " +#else + let sysExText = "" +#endif + alert.messageText = "Uninstall \(sysExText)Login Items?" + alert.informativeText = "This will remove the Network Protection \(sysExText)Status Menu icon and disable the VPN." + alert.alertStyle = .warning + alert.addButton(withTitle: "Uninstall") + alert.addButton(withTitle: UserText.cancel) + return alert + } + static func noAccessToDownloads() -> NSAlert { let alert = NSAlert() alert.messageText = UserText.noAccessToDownloadsFolderHeader @@ -137,4 +166,12 @@ extension NSAlert { alert.addButton(withTitle: UserText.cancel) return alert } + + @discardableResult + func runModal() async -> NSApplication.ModalResponse { + await withCheckedContinuation { continuation in + continuation.resume(returning: self.runModal()) + } + } + } diff --git a/DuckDuckGo/Common/Extensions/NSApplicationExtension.swift b/DuckDuckGo/Common/Extensions/NSApplicationExtension.swift index dbc3402bfe..fb5afde1e7 100644 --- a/DuckDuckGo/Common/Extensions/NSApplicationExtension.swift +++ b/DuckDuckGo/Common/Extensions/NSApplicationExtension.swift @@ -52,9 +52,11 @@ extension NSApplication { return false } +#if !NETWORK_EXTENSION var mainMenuTyped: MainMenu { return mainMenu as! MainMenu // swiftlint:disable:this force_cast } +#endif var isCommandPressed: Bool { currentEvent?.modifierFlags.contains(.command) ?? false diff --git a/DuckDuckGo/Common/Extensions/NSImageExtensions.swift b/DuckDuckGo/Common/Extensions/NSImageExtensions.swift index 4c73c1ed39..da11e9af3d 100644 --- a/DuckDuckGo/Common/Extensions/NSImageExtensions.swift +++ b/DuckDuckGo/Common/Extensions/NSImageExtensions.swift @@ -16,7 +16,7 @@ // limitations under the License. // -import Foundation +import AppKit import CoreGraphics extension NSImage { diff --git a/DuckDuckGo/Common/Extensions/TimeIntervalExtension.swift b/DuckDuckGo/Common/Extensions/TimeIntervalExtension.swift index ffcdaea149..0e9faa4710 100644 --- a/DuckDuckGo/Common/Extensions/TimeIntervalExtension.swift +++ b/DuckDuckGo/Common/Extensions/TimeIntervalExtension.swift @@ -19,7 +19,21 @@ import Foundation extension TimeInterval { + static let day = days(1) - static let day: TimeInterval = 60 * 60 * 24 + static func seconds(_ amount: Int) -> TimeInterval { + TimeInterval(amount) + } + static func minutes(_ amount: Int) -> TimeInterval { + .seconds(60) * TimeInterval(amount) + } + + static func hours(_ amount: Int) -> TimeInterval { + .minutes(60) * TimeInterval(amount) + } + + static func days(_ amount: Int) -> TimeInterval { + .hours(24) * TimeInterval(amount) + } } diff --git a/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift b/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift new file mode 100644 index 0000000000..ca08be77ff --- /dev/null +++ b/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift @@ -0,0 +1,40 @@ +// +// UserText+NetworkProtection.swift +// +// Copyright © 2022 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 + +extension UserText { + static let networkProtectionTunnelName = NSLocalizedString("network.protection.tunnel.name", value: "DuckDuckGo Network Protection", comment: "The name of the NetP VPN that will be visible in the system to the user") + static let networkProtection = NSLocalizedString("network.protection", value: "Network Protection", comment: "Menu item for opening Network Protection") + + // MARK: - Navigation Bar + + static let networkProtectionButtonTooltip = NSLocalizedString("network.protection.status.button.tooltip", value: "Network Protection", comment: "The tooltip for NetP's nav bar button") + + // MARK: - Invite Code + + static let networkProtectionInviteDialogTitle = NSLocalizedString("network.protection.invite.dialog.title", value: "You've unlocked a beta feature!", comment: "Title for the network protection invite dialog") + static let networkProtectionInviteDialogMessage = NSLocalizedString("network.protection.invite.dialog.message", value: "Enter your invite code to get started.", comment: "Message for the network protection invite dialog") + static let networkProtectionInviteFieldPrompt = NSLocalizedString("network.protection.invite.field.prompt", value: "Code", comment: "Prompt for the network protection invite code text field") + static let networkProtectionInviteSuccessTitle = NSLocalizedString("network.protection.invite.success.title", value: "Success! You’re in.", comment: "Title for the network protection invite success view") + static let networkProtectionInviteSuccessMessage = NSLocalizedString("network.protection.invite.success.title", value: "Hide your location from websites and conceal your online activity from Internet providers and others on your network.", comment: "Message for the network protection invite success view") + + // MARK: - Navigation Bar Status View + + static let networkProtectionNavBarStatusViewShareFeedback = NSLocalizedString("network.protection.navbar.status.view.share.feedback", value: "Share Feedback...", comment: "Menu item for 'Share Feedback' in the Network Protection status view that's shown in the navigation bar") +} diff --git a/DuckDuckGo/Common/Localizables/UserText.swift b/DuckDuckGo/Common/Localizables/UserText.swift index 8c58b91e5f..3ff581302e 100644 --- a/DuckDuckGo/Common/Localizables/UserText.swift +++ b/DuckDuckGo/Common/Localizables/UserText.swift @@ -41,6 +41,7 @@ struct UserText { static let pasteAndGo = NSLocalizedString("paste.and.go", value: "Paste & Go", comment: "Paste & Go button") static let pasteAndSearch = NSLocalizedString("paste.and.search", value: "Paste & Search", comment: "Paste & Search button") static let clear = NSLocalizedString("clear", value: "Clear", comment: "Clear button") + static let `continue` = NSLocalizedString("`continue`", value: "Continue", comment: "Continue button") static func openIn(value: String) -> String { let localized = NSLocalizedString("open.in", value: "Open in %@", @@ -65,6 +66,7 @@ struct UserText { static let openSystemPreferences = NSLocalizedString("open.preferences", value: "Open System Preferences", comment: "Open System Preferences (to re-enable permission for the App) (up to and including macOS 12") static let unknownErrorMessage = NSLocalizedString("error.unknown", value: "An unknown error has occurred", comment: "Error page subtitle") + static let unknownErrorTryAgainMessage = NSLocalizedString("error.unknown.try.again", value: "An unknown error has occurred", comment: "Generic error message on a dialog for when the cause is not known.") static let moveTabToNewWindow = NSLocalizedString("options.menu.move.tab.to.new.window", value: "Move Tab to New Window", @@ -591,6 +593,9 @@ struct UserText { static let bookmarksBarContextMenuDelete = NSLocalizedString("bookmarks.bar.context-menu.delete", value: "Delete", comment: "Delete menu item for the bookmarks bar context menu") static let bookmarksBarContextMenuMoveToEnd = NSLocalizedString("bookmarks.bar.context-menu.move-to-end", value: "Move to End", comment: "Move to End menu item for the bookmarks bar context menu") + static let inviteDialogGetStartedButton = NSLocalizedString("invite.dialog.get.started.button", value: "Get Started", comment: "Get Started button on an invite dialog") + static let inviteDialogUnrecognizedCodeMessage = NSLocalizedString("invite.dialog.unrecognized.code.message", value: "We didn’t recognize this Invite Code.", comment: "Message to show after user enters an unrecognized invite code") + // MARK: - Bitwarden static let passwordManager = NSLocalizedString("password.manager", value: "Password Manager", comment: "Section header") @@ -643,6 +648,9 @@ struct UserText { static let showDownloadsShortcut = NSLocalizedString("pinning.show-downloads-shortcut", value: "Show Downloads Shortcut", comment: "Menu item for showing the downloads shortcut") static let hideDownloadsShortcut = NSLocalizedString("pinning.hide-downloads-shortcut", value: "Hide Downloads Shortcut", comment: "Menu item for hiding the downloads shortcut") + static let showNetworkProtectionShortcut = NSLocalizedString("pinning.show-netp-shortcut", value: "Show Network Protection", comment: "Menu item for showing the NetP shortcut") + static let hideNetworkProtectionShortcut = NSLocalizedString("pinning.hide-netp-shortcut", value: "Hide Network Protection", comment: "Menu item for hiding the NetP shortcut") + // MARK: - Tooltips static let autofillShortcutTooltip = NSLocalizedString("tooltip.autofill.shortcut", value: "Autofill", comment: "Tooltip for the autofill shortcut") diff --git a/DuckDuckGo/Common/Logging/Logging.swift b/DuckDuckGo/Common/Logging/Logging.swift index 5964240e2e..815cf470c3 100644 --- a/DuckDuckGo/Common/Logging/Logging.swift +++ b/DuckDuckGo/Common/Logging/Logging.swift @@ -127,10 +127,10 @@ extension OSLog.OSLogWrapper { } -func logOrAssertionFailure(_ message: StaticString, args: CVarArg...) { -#if DEBUG - assertionFailure("\(message)") +func logOrAssertionFailure(_ message: String) { +#if DEBUG && !CI + assertionFailure(message) #else - os_log("BWManager: Wrong handler", type: .error) + os_log("%{public}s", type: .error, message) #endif } diff --git a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift index dadfd7af47..f7e4d5762f 100644 --- a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift +++ b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift @@ -16,6 +16,7 @@ // limitations under the License. // +import AppKit import Foundation @propertyWrapper @@ -94,6 +95,7 @@ public struct UserDefaultsWrapper { case lastBookmarksBarUsagePixelSendDate = "bookmarks.bar.last-usage-pixel-send-date" case pinnedViews = "pinning.pinned-views" + case manuallyToggledPinnedViews = "pinning.manually-toggled-pinned-views" case lastDatabaseFactoryFailurePixelDate = "last.database.factory.failure.pixel.date" diff --git a/DuckDuckGo/DuckDuckGo.entitlements b/DuckDuckGo/DuckDuckGo.entitlements index 5686f4a42d..607a816ca4 100644 --- a/DuckDuckGo/DuckDuckGo.entitlements +++ b/DuckDuckGo/DuckDuckGo.entitlements @@ -2,6 +2,12 @@ + com.apple.developer.networking.networkextension + + packet-tunnel-provider-systemextension + + com.apple.developer.usernotifications.time-sensitive + com.apple.security.device.audio-input com.apple.security.device.camera @@ -13,6 +19,13 @@ keychain-access-groups $(AppIdentifierPrefix)com.duckduckgo.macos.browser + $(AppIdentifierPrefix)com.duckduckgo.network-protection + + com.apple.developer.system-extension.install + + com.apple.security.application-groups + + $(NETP_APP_GROUP) diff --git a/DuckDuckGo/DuckDuckGoAppStore.entitlements b/DuckDuckGo/DuckDuckGoAppStore.entitlements index fe4b78bacd..9d0255e659 100644 --- a/DuckDuckGo/DuckDuckGoAppStore.entitlements +++ b/DuckDuckGo/DuckDuckGoAppStore.entitlements @@ -2,13 +2,6 @@ - com.apple.security.temporary-exception.files.home-relative-path.read-only - - /Library/Application Support/Google/Chrome/ - /Library/Application Support/BraveSoftware/Brave-Browser/ - /Library/Application Support/Firefox/ - /Library/Application Support/Microsoft Edge/ - com.apple.security.app-sandbox com.apple.security.device.audio-input @@ -27,6 +20,13 @@ com.apple.security.print + com.apple.security.temporary-exception.files.home-relative-path.read-only + + /Library/Application Support/Google/Chrome/ + /Library/Application Support/BraveSoftware/Brave-Browser/ + /Library/Application Support/Firefox/ + /Library/Application Support/Microsoft Edge/ + keychain-access-groups $(AppIdentifierPrefix)com.duckduckgo.mobile.ios diff --git a/DuckDuckGo/DuckDuckGoAppStoreCI.entitlements b/DuckDuckGo/DuckDuckGoAppStoreCI.entitlements index 0678ae8bf4..9a0241659f 100644 --- a/DuckDuckGo/DuckDuckGoAppStoreCI.entitlements +++ b/DuckDuckGo/DuckDuckGoAppStoreCI.entitlements @@ -2,6 +2,10 @@ + com.apple.developer.networking.networkextension + + packet-tunnel-provider + com.apple.security.app-sandbox com.apple.security.device.audio-input diff --git a/DuckDuckGo/DuckDuckGoCI.entitlements b/DuckDuckGo/DuckDuckGoCI.entitlements index ceeb0892c5..d9eb347096 100644 --- a/DuckDuckGo/DuckDuckGoCI.entitlements +++ b/DuckDuckGo/DuckDuckGoCI.entitlements @@ -2,6 +2,8 @@ + com.apple.developer.usernotifications.time-sensitive + com.apple.security.device.audio-input com.apple.security.device.camera diff --git a/DuckDuckGo/DuckDuckGoDebug.entitlements b/DuckDuckGo/DuckDuckGoDebug.entitlements new file mode 100644 index 0000000000..c5cb100fc2 --- /dev/null +++ b/DuckDuckGo/DuckDuckGoDebug.entitlements @@ -0,0 +1,31 @@ + + + + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.network.client + + com.apple.security.personal-information.location + + keychain-access-groups + + $(AppIdentifierPrefix)com.duckduckgo.macos.browser + $(AppIdentifierPrefix)com.duckduckgo.network-protection + + com.apple.developer.usernotifications.time-sensitive + + com.apple.developer.networking.networkextension + + packet-tunnel-provider + + com.apple.developer.system-extension.install + + com.apple.security.application-groups + + $(NETP_APP_GROUP) + + + diff --git a/DuckDuckGo/DuckDuckGo_NetP_Debug.entitlements b/DuckDuckGo/DuckDuckGo_NetP_Debug.entitlements new file mode 100644 index 0000000000..069c866e05 --- /dev/null +++ b/DuckDuckGo/DuckDuckGo_NetP_Debug.entitlements @@ -0,0 +1,30 @@ + + + + + com.apple.developer.networking.networkextension + + packet-tunnel-provider + + com.apple.developer.system-extension.install + + com.apple.developer.usernotifications.time-sensitive + + com.apple.security.application-groups + + HKE973VLUW.com.duckduckgo.network-protection + $(NETP_APP_GROUP) + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.personal-information.location + + keychain-access-groups + + $(AppIdentifierPrefix)com.duckduckgo.macos.browser + $(AppIdentifierPrefix)com.duckduckgo.network-protection + + + diff --git a/DuckDuckGo/DuckDuckGo_NetP_Release.entitlements b/DuckDuckGo/DuckDuckGo_NetP_Release.entitlements new file mode 100644 index 0000000000..a2226d1f8d --- /dev/null +++ b/DuckDuckGo/DuckDuckGo_NetP_Release.entitlements @@ -0,0 +1,38 @@ + + + + + com.apple.developer.networking.networkextension + + packet-tunnel-provider-systemextension + + com.apple.developer.system-extension.install + + com.apple.developer.usernotifications.time-sensitive + + com.apple.security.application-groups + + $(TeamIdentifierPrefix)com.duckduckgo.macos.browser.network-protection + $(NETP_APP_GROUP) + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.personal-information.location + + keychain-access-groups + + $(AppIdentifierPrefix)com.duckduckgo.macos.browser + $(AppIdentifierPrefix)com.duckduckgo.network-protection + + com.apple.security.personal-information.location + + com.apple.developer.networking.networkextension + + packet-tunnel-provider-systemextension + + com.apple.developer.system-extension.install + + + diff --git a/DuckDuckGo/Fire/View/FirePopoverViewController.swift b/DuckDuckGo/Fire/View/FirePopoverViewController.swift index f4413c7742..6bf0005223 100644 --- a/DuckDuckGo/Fire/View/FirePopoverViewController.swift +++ b/DuckDuckGo/Fire/View/FirePopoverViewController.swift @@ -200,11 +200,9 @@ final class FirePopoverViewController: NSViewController { } private func adjustContentHeight() { - NSAnimationContext.runAnimationGroup { [weak self] context in - guard let self else { return } + NSAnimationContext.runAnimationGroup { [self, contentHeight = contentHeight()] context in context.duration = 1/3 context.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) - let contentHeight = self.contentHeight() self.contentHeightConstraint.animator().constant = contentHeight if contentHeight != Constants.minimumContentHeight { self.detailsWrapperViewHeightContraint.animator().constant = contentHeight diff --git a/DuckDuckGo/Info.plist b/DuckDuckGo/Info.plist index 10515ebcd5..10046403d3 100644 --- a/DuckDuckGo/Info.plist +++ b/DuckDuckGo/Info.plist @@ -52,6 +52,16 @@ https + + CFBundleTypeRole + Viewer + CFBundleURLName + Network Protection URLs + CFBundleURLSchemes + + networkprotection + + CFBundleVersion $(CURRENT_PROJECT_VERSION) @@ -76,8 +86,6 @@ MainMenu NSMicrophoneUsageDescription Allows you to share recordings - NSPrincipalClass - NSApplication NSSupportsAutomaticTermination NSSupportsSuddenTermination @@ -96,5 +104,15 @@ ITSAppUsesNonExemptEncryption + NOTIFICATIONS_AGENT_BUNDLE_ID + $(NOTIFICATIONS_AGENT_BUNDLE_ID) + NOTIFICATIONS_AGENT_PRODUCT_NAME + $(NOTIFICATIONS_AGENT_PRODUCT_NAME) + AGENT_BUNDLE_ID + $(AGENT_BUNDLE_ID) + AGENT_PRODUCT_NAME + $(AGENT_PRODUCT_NAME) + NETP_APP_GROUP + $(NETP_APP_GROUP) diff --git a/DuckDuckGo/Main/Main.swift b/DuckDuckGo/Main/Main.swift new file mode 100644 index 0000000000..2d022c1225 --- /dev/null +++ b/DuckDuckGo/Main/Main.swift @@ -0,0 +1,77 @@ +// +// Main.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 AppKit +import Foundation +import Common + +#if NETWORK_PROTECTION +import NetworkProtection +#endif + +extension Bundle { + static var mainURL: URL! + @objc dynamic static func nonMain() -> Bundle { + Bundle(url: mainURL)! + } +} + +@main +final class AppMain { + private enum LaunchError: Error { + case startVPNFailed(_ error: Error) + case stopVPNFailed(_ error: Error) + } + + static func main() async throws { +#if NETWORK_PROTECTION + switch (CommandLine.arguments.first! as NSString).lastPathComponent { + case "startVPN": + swizzleMainBundle() + + do { + try await NetworkProtectionTunnelController().start(enableLoginItems: false) + exit(0) + } catch { + throw LaunchError.startVPNFailed(error) + } + case "stopVPN": + swizzleMainBundle() + + do { + try await NetworkProtectionTunnelController().stop() + exit(0) + } catch { + throw LaunchError.stopVPNFailed(error) + } + default: + break + } +#endif + + _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) + } + + private static func swizzleMainBundle() { + Bundle.mainURL = Bundle(for: Self.self).bundleURL + + let m1 = class_getClassMethod(Bundle.self, #selector(getter: Bundle.main))! + let m2 = class_getClassMethod(Bundle.self, #selector(Bundle.nonMain))! + method_exchangeImplementations(m1, m2) + } +} diff --git a/DuckDuckGo/Menus/CleanThisHistoryMenuItem.swift b/DuckDuckGo/Menus/CleanThisHistoryMenuItem.swift index 0d1dbbddce..6221131fb0 100644 --- a/DuckDuckGo/Menus/CleanThisHistoryMenuItem.swift +++ b/DuckDuckGo/Menus/CleanThisHistoryMenuItem.swift @@ -16,6 +16,7 @@ // limitations under the License. // +import AppKit import Foundation final class ClearThisHistoryMenuItem: NSMenuItem { diff --git a/DuckDuckGo/Menus/MainMenu.storyboard b/DuckDuckGo/Menus/MainMenu.storyboard index 49c660ae00..d101b8d10d 100644 --- a/DuckDuckGo/Menus/MainMenu.storyboard +++ b/DuckDuckGo/Menus/MainMenu.storyboard @@ -419,6 +419,11 @@ + + + + + @@ -749,7 +754,7 @@ CQ - + @@ -777,11 +782,11 @@ CQ - + - + - + @@ -790,6 +795,85 @@ CQ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -843,6 +927,10 @@ CQ + + + + @@ -859,6 +947,7 @@ CQ + diff --git a/DuckDuckGo/Menus/MainMenu.swift b/DuckDuckGo/Menus/MainMenu.swift index 05bf853e67..bc4f907763 100644 --- a/DuckDuckGo/Menus/MainMenu.swift +++ b/DuckDuckGo/Menus/MainMenu.swift @@ -22,6 +22,10 @@ import OSLog // swiftlint:disable:this enforce_os_log_wrapper import WebKit import BrowserServicesKit +#if NETWORK_PROTECTION +import NetworkProtection +#endif + final class MainMenu: NSMenu { enum Constants { @@ -75,9 +79,12 @@ final class MainMenu: NSMenu { @IBOutlet weak var toggleAutofillShortcutMenuItem: NSMenuItem? @IBOutlet weak var toggleBookmarksShortcutMenuItem: NSMenuItem? @IBOutlet weak var toggleDownloadsShortcutMenuItem: NSMenuItem? + @IBOutlet weak var toggleNetworkProtectionShortcutMenuItem: NSMenuItem? // MARK: - Debug + @IBOutlet weak var debugMenuItem: NSMenuItem? + @IBOutlet weak var networkProtectionMenuItem: NSMenuItem? private func setupDebugMenuItem(with featureFlagger: FeatureFlagger) { guard let debugMenuItem else { @@ -96,8 +103,17 @@ final class MainMenu: NSMenu { if debugMenuItem.submenu?.items.contains(loggingMenuItem) == false { debugMenuItem.submenu!.addItem(loggingMenuItem) } + +#if !NETWORK_PROTECTION + // Hide the entire NetP debug menu when the feature is disabled: + networkProtectionMenuItem?.removeFromParent() +#endif } + @IBOutlet weak var networkProtectionPreferredServerLocationItem: NSMenuItem? + @IBOutlet weak var networkProtectionRegistrationKeyValidityMenuSeparatorItem: NSMenuItem? + @IBOutlet weak var networkProtectionRegistrationKeyValidityMenuItem: NSMenuItem? + // MARK: - Help @IBOutlet weak var helpMenuItem: NSMenuItem? @IBOutlet weak var helpSeparatorMenuItem: NSMenuItem? @@ -132,10 +148,18 @@ final class MainMenu: NSMenu { sharingMenu.title = shareMenuItem.title shareMenuItem.submenu = sharingMenu + // To be safe, hide the NetP shortcut menu item by default. + toggleNetworkProtectionShortcutMenuItem?.isHidden = true + updateBookmarksBarMenuItem() updateShortcutMenuItems() updateLoggingMenuItems() updateBurnerWindowMenuItem() + +#if NETWORK_PROTECTION + updateNetworkProtectionServerListMenuItems() + updateNetworkProtectionRegistrationKeyValidityMenuItems() +#endif } @MainActor @@ -268,8 +292,93 @@ final class MainMenu: NSMenu { toggleAutofillShortcutMenuItem?.title = LocalPinningManager.shared.toggleShortcutInterfaceTitle(for: .autofill) toggleBookmarksShortcutMenuItem?.title = LocalPinningManager.shared.toggleShortcutInterfaceTitle(for: .bookmarks) toggleDownloadsShortcutMenuItem?.title = LocalPinningManager.shared.toggleShortcutInterfaceTitle(for: .downloads) + +#if NETWORK_PROTECTION + let networkProtectionFeatureVisibility: NetworkProtectionFeatureVisibility = NetworkProtectionKeychainTokenStore() + if networkProtectionFeatureVisibility.isFeatureActivated { + toggleNetworkProtectionShortcutMenuItem?.isHidden = false + toggleNetworkProtectionShortcutMenuItem?.title = LocalPinningManager.shared.toggleShortcutInterfaceTitle(for: .networkProtection) + } else { + toggleNetworkProtectionShortcutMenuItem?.isHidden = true + } +#else + toggleNetworkProtectionShortcutMenuItem?.isHidden = true +#endif } +#if NETWORK_PROTECTION + private func updateNetworkProtectionServerListMenuItems() { + guard let submenu = networkProtectionPreferredServerLocationItem?.submenu, let automaticItem = submenu.items.first else { + assertionFailure("\(#function): Failed to get submenu") + return + } + + let networkProtectionServerStore = NetworkProtectionServerListFileSystemStore(errorEvents: nil) + let servers = (try? networkProtectionServerStore.storedNetworkProtectionServerList()) ?? [] + + if servers.isEmpty { + submenu.items = [automaticItem] + } else { + submenu.items = [automaticItem, NSMenuItem.separator()] + servers.map({ server in + let title: String + + if server.isRegistered { + title = "\(server.serverInfo.name) (\(server.serverInfo.serverLocation) – Public Key Registered)" + } else { + title = "\(server.serverInfo.name) (\(server.serverInfo.serverLocation))" + } + + return NSMenuItem(title: title, action: automaticItem.action, keyEquivalent: "") + }) + } + } + + private struct NetworkProtectionKeyValidityOption { + let title: String + let validity: TimeInterval + } + + private static let networkProtectionRegistrationKeyValidityOptions: [NetworkProtectionKeyValidityOption] = [ + .init(title: "15 seconds", validity: .seconds(15)), + .init(title: "30 seconds", validity: .seconds(30)), + .init(title: "1 minute", validity: .minutes(1)), + .init(title: "5 minutes", validity: .minutes(5)), + .init(title: "30 minutes", validity: .minutes(30)), + .init(title: "1 hour", validity: .hours(1)) + ] + + private func updateNetworkProtectionRegistrationKeyValidityMenuItems() { + #if DEBUG + guard let submenu = networkProtectionRegistrationKeyValidityMenuItem?.submenu, + let automaticItem = submenu.items.first else { + + assertionFailure("\(#function): Failed to get submenu") + return + } + + if Self.networkProtectionRegistrationKeyValidityOptions.isEmpty { + // Not likely to happen as it's hard-coded, but still... + submenu.items = [automaticItem] + } else { + submenu.items = [automaticItem, NSMenuItem.separator()] + Self.networkProtectionRegistrationKeyValidityOptions.map { option in + let menuItem = NSMenuItem(title: option.title, action: automaticItem.action, keyEquivalent: "") + menuItem.representedObject = option.validity + return menuItem + } + } + #else + guard let separator = networkProtectionRegistrationKeyValidityMenuSeparatorItem, + let validityMenu = networkProtectionRegistrationKeyValidityMenuItem else { + assertionFailure("\(#function): Failed to get submenu") + return + } + + separator.isHidden = true + validityMenu.isHidden = true + #endif + } +#endif + @MainActor private func updateBurnerWindowMenuItem() { if let appDelegate = NSApplication.shared.delegate as? AppDelegate, diff --git a/DuckDuckGo/Menus/MainMenuActions.swift b/DuckDuckGo/Menus/MainMenuActions.swift index 847b9db8a1..3b93fcd032 100644 --- a/DuckDuckGo/Menus/MainMenuActions.swift +++ b/DuckDuckGo/Menus/MainMenuActions.swift @@ -20,6 +20,10 @@ import Cocoa import BrowserServicesKit import Common +#if NETWORK_PROTECTION +import NetworkProtection +#endif + // Actions are sent to objects of responder chain // MARK: - Main Menu Actions @@ -233,6 +237,119 @@ extension AppDelegate { FireCoordinator.fireButtonAction() } + // MARK: - Network Protection Debug + + @IBAction func resetNetworkProtectionState(_ sender: Any?) { +#if NETWORK_PROTECTION + Task { @MainActor in + guard case .alertFirstButtonReturn = await NSAlert.resetNetworkProtectionAlert().runModal() else { return } + + do { + try await NetworkProtectionTunnelController.resetAllState() + } catch { + await NSAlert(error: error).runModal() + } + } +#endif + } + + @IBAction func removeNetworkProtectionSystemExtensionAndAgents(_ sender: Any?) { +#if NETWORK_PROTECTION + Task { @MainActor in + guard case .alertFirstButtonReturn = await NSAlert.removeSystemExtensionAndAgentsAlert().runModal() else { return } + + do { + try await NetworkProtectionTunnelController.removeSystemExtensionAndAgents() + } catch { + await NSAlert(error: error).runModal() + } + } +#endif + } + + @IBAction func networkProtectionPreferredServerChanged(_ sender: Any?) { +#if NETWORK_PROTECTION + guard let title = (sender as? NSMenuItem)?.title else { + assertionFailure("\(#function): Failed to cast sender to NSMenuItem") + return + } + + let selectedServer: SelectedNetworkProtectionServer + + if title == "Automatic" { + selectedServer = .automatic + } else { + let titleComponents = title.components(separatedBy: " ") + selectedServer = .endpoint(titleComponents.first!) + } + + NetworkProtectionTunnelController.setSelectedServer(selectedServer: selectedServer) +#endif + } + + @IBAction func networkProtectionExpireRegistrationKeyNow(_ sender: Any?) { +#if NETWORK_PROTECTION + Task { + try? await NetworkProtectionTunnelController.expireRegistrationKeyNow() + } +#endif + } + + @IBAction func networkProtectionSetRegistrationKeyValidity(_ sender: Any?) { +#if NETWORK_PROTECTION + guard let menuItem = sender as? NSMenuItem else { + assertionFailure("\(#function): Failed to cast sender to NSMenuItem") + return + } + + // nil means automatic + let validity = menuItem.representedObject as? TimeInterval + + Task { + do { + try await NetworkProtectionTunnelController.setRegistrationKeyValidity(validity) + } catch { + assertionFailure("Could not override the key validity due to an error: \(error.localizedDescription)") + os_log("Could not override the key validity due to an error: %{public}@", log: .networkProtection, type: .error, error.localizedDescription) + } + } +#endif + } + + @IBAction func networkProtectionSimulateControllerFailure(_ sender: Any?) { +#if NETWORK_PROTECTION + guard let menuItem = sender as? NSMenuItem else { + assertionFailure("\(#function): Failed to cast sender to NSMenuItem") + return + } + + if menuItem.state == .on { + menuItem.state = .off + } else { + menuItem.state = .on + } + + NetworkProtectionTunnelController.simulationOptions.setEnabled(menuItem.state == .on, option: .controllerFailure) +#endif + } + + @IBAction func networkProtectionSimulateTunnelFailure(_ sender: Any?) { +#if NETWORK_PROTECTION + guard let menuItem = sender as? NSMenuItem else { + assertionFailure("\(#function): Failed to cast sender to NSMenuItem") + return + } + + if menuItem.state == .on { + menuItem.state = .off + } else { + menuItem.state = .on + } + + NetworkProtectionTunnelController.simulationOptions.setEnabled(menuItem.state == .on, option: .tunnelFailure) +#endif + } + } extension MainViewController { @@ -352,6 +469,10 @@ extension MainViewController { LocalPinningManager.shared.togglePinning(for: .downloads) } + @IBAction func toggleNetworkProtectionShortcut(_ sender: Any) { + LocalPinningManager.shared.togglePinning(for: .networkProtection) + } + // MARK: - History @IBAction func back(_ sender: Any?) { @@ -687,7 +808,6 @@ extension MainViewController { @IBAction func showPageResources(_ sender: Any?) { tabCollectionViewModel.selectedTabViewModel?.tab.webView.showPageSource() } - } extension MainViewController: NSMenuItemValidation { @@ -785,11 +905,11 @@ extension MainViewController: NSMenuItemValidation { } // swiftlint:enable function_body_length // swiftlint:enable cyclomatic_complexity - } extension AppDelegate: NSMenuItemValidation { + // swiftlint:disable:next cyclomatic_complexity function_body_length func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { switch menuItem.action { case #selector(AppDelegate.closeAllWindows(_:)): @@ -811,6 +931,70 @@ extension AppDelegate: NSMenuItemValidation { case #selector(AppDelegate.openExportLogins(_:)): return areTherePasswords + case #selector(AppDelegate.networkProtectionPreferredServerChanged(_:)): +#if NETWORK_PROTECTION + let selectedServerName = NetworkProtectionTunnelController.selectedServerName() + + switch menuItem.title { + case "Automatic": + menuItem.state = selectedServerName == nil ? .on : .off + default: + guard let selectedServerName = selectedServerName else { + menuItem.state = .off + break + } + + menuItem.state = (menuItem.title.hasPrefix("\(selectedServerName) ")) ? .on : .off + } + + return true +#else + return false +#endif + + case #selector(AppDelegate.networkProtectionExpireRegistrationKeyNow(_:)): + return true + + case #selector(AppDelegate.networkProtectionSetRegistrationKeyValidity(_:)): +#if NETWORK_PROTECTION + let selectedValidity = NetworkProtectionTunnelController.registrationKeyValidity() + + switch menuItem.title { + case "Automatic": + menuItem.state = selectedValidity == nil ? .on : .off + default: + guard let selectedValidity = selectedValidity, + let menuItemValidity = menuItem.representedObject as? TimeInterval, + selectedValidity == menuItemValidity else { + + menuItem.state = .off + break + } + + menuItem.state = .on + } + + return true +#else + return false +#endif + + case #selector(AppDelegate.networkProtectionSimulateControllerFailure(_:)): +#if NETWORK_PROTECTION + menuItem.state = NetworkProtectionTunnelController.simulationOptions.isEnabled(.controllerFailure) ? .on : .off + return true +#else + return false +#endif + + case #selector(AppDelegate.networkProtectionSimulateTunnelFailure(_:)): +#if NETWORK_PROTECTION + menuItem.state = NetworkProtectionTunnelController.simulationOptions.isEnabled(.tunnelFailure) ? .on : .off + return true +#else + return false +#endif + default: return true } diff --git a/DuckDuckGo/Menus/VisitMenuItem.swift b/DuckDuckGo/Menus/VisitMenuItem.swift index a51557c2da..9beb7c5fbf 100644 --- a/DuckDuckGo/Menus/VisitMenuItem.swift +++ b/DuckDuckGo/Menus/VisitMenuItem.swift @@ -16,7 +16,7 @@ // limitations under the License. // -import Foundation +import AppKit final class VisitMenuItem: NSMenuItem { diff --git a/DuckDuckGo/NavigationBar/PinningManager.swift b/DuckDuckGo/NavigationBar/PinningManager.swift index 6ebf64c7b6..fb5456a73d 100644 --- a/DuckDuckGo/NavigationBar/PinningManager.swift +++ b/DuckDuckGo/NavigationBar/PinningManager.swift @@ -18,29 +18,51 @@ import Foundation +#if NETWORK_PROTECTION +import NetworkProtection +#endif + enum PinnableView: String { case autofill case bookmarks case downloads + case networkProtection } protocol PinningManager { func togglePinning(for view: PinnableView) func isPinned(_ view: PinnableView) -> Bool - + func wasManuallyToggled(_ view: PinnableView) -> Bool } final class LocalPinningManager: PinningManager { +#if NETWORK_PROTECTION + static let shared = LocalPinningManager(networkProtectionFeatureVisibility: NetworkProtectionKeychainTokenStore()) +#else static let shared = LocalPinningManager() +#endif static let pinnedViewChangedNotificationViewTypeKey = "pinning.pinnedViewChanged.viewType" @UserDefaultsWrapper(key: .pinnedViews, defaultValue: []) private var pinnedViewStrings: [String] + @UserDefaultsWrapper(key: .manuallyToggledPinnedViews, defaultValue: []) + private var manuallyToggledPinnedViewsStrings: [String] + +#if NETWORK_PROTECTION + private let networkProtectionFeatureVisibility: NetworkProtectionFeatureVisibility + + init(networkProtectionFeatureVisibility: NetworkProtectionFeatureVisibility) { + self.networkProtectionFeatureVisibility = networkProtectionFeatureVisibility + } +#endif + func togglePinning(for view: PinnableView) { + flagAsManuallyToggled(view) + if isPinned(view) { pinnedViewStrings.removeAll(where: { $0 == view.rawValue }) } else { @@ -52,6 +74,21 @@ final class LocalPinningManager: PinningManager { ]) } + /// Do not call this for user-initiated toggling. This is only meant to be used for scenarios in which certain conditions + /// may require a view to be unpinned. + /// + func unpin(_ view: PinnableView) { + guard isPinned(view) else { + return + } + + pinnedViewStrings.removeAll(where: { $0 == view.rawValue }) + + NotificationCenter.default.post(name: .PinnedViewsChanged, object: nil, userInfo: [ + Self.pinnedViewChangedNotificationViewTypeKey: view.rawValue + ]) + } + func isPinned(_ view: PinnableView) -> Bool { return pinnedViewStrings.contains(view.rawValue) } @@ -61,9 +98,38 @@ final class LocalPinningManager: PinningManager { case .autofill: return isPinned(.autofill) ? UserText.hideAutofillShortcut : UserText.showAutofillShortcut case .bookmarks: return isPinned(.bookmarks) ? UserText.hideBookmarksShortcut : UserText.showBookmarksShortcut case .downloads: return isPinned(.downloads) ? UserText.hideDownloadsShortcut : UserText.showDownloadsShortcut + case .networkProtection: +#if NETWORK_PROTECTION + if !networkProtectionFeatureVisibility.isFeatureActivated { + assertionFailure("Tried to toggle Network Protection when it was not activated") + } + + return isPinned(.networkProtection) ? UserText.hideNetworkProtectionShortcut : UserText.showNetworkProtectionShortcut +#else + fatalError("Tried to get Network Protection interface title when NetP was disabled") +#endif } } + // MARK: - Recording Manual Toggling + + /// This method is useful for knowing if the view was manually toggled. + /// It's particularly useful for initializing a pin to a certain value at a certain point during the execution of code, + /// only if the user hasn't explicitly specified a desired state. + /// As an example: this is used in Network Protection for pinning the icon to the navigation bar the first time the + /// feature is enabled. + /// + func wasManuallyToggled(_ view: PinnableView) -> Bool { + manuallyToggledPinnedViewsStrings.contains(view.rawValue) + } + + /// Flags a view as having been manually pinned / unpinned by the user. + /// + private func flagAsManuallyToggled(_ view: PinnableView) { + var set = Set(manuallyToggledPinnedViewsStrings) + set.insert(view.rawValue) + manuallyToggledPinnedViewsStrings = Array(set) + } } // MARK: - NSNotification diff --git a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift index 401010d566..e0b3c832aa 100644 --- a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift +++ b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift @@ -18,9 +18,12 @@ import Cocoa import Common -import WebKit import BrowserServicesKit +#if NETWORK_PROTECTION +import NetworkProtection +#endif + protocol OptionsButtonMenuDelegate: AnyObject { func optionsButtonMenuRequestedBookmarkThisPage(_ sender: NSMenuItem) @@ -31,6 +34,7 @@ protocol OptionsButtonMenuDelegate: AnyObject { func optionsButtonMenuRequestedBookmarkExportInterface(_ menu: NSMenu) func optionsButtonMenuRequestedLoginsPopover(_ menu: NSMenu, selectedCategory: SecureVaultSorting.Category) func optionsButtonMenuRequestedOpenExternalPasswordManager(_ menu: NSMenu) + func optionsButtonMenuRequestedNetworkProtectionPopover(_ menu: NSMenu) func optionsButtonMenuRequestedDownloadsPopover(_ menu: NSMenu) func optionsButtonMenuRequestedPrint(_ menu: NSMenu) func optionsButtonMenuRequestedPreferences(_ menu: NSMenu) @@ -48,10 +52,34 @@ final class MoreOptionsMenu: NSMenu { private let passwordManagerCoordinator: PasswordManagerCoordinating private let internalUserDecider: InternalUserDecider +#if NETWORK_PROTECTION + private let networkProtectionFeatureVisibility: NetworkProtectionFeatureVisibility +#endif + required init(coder: NSCoder) { fatalError("MoreOptionsMenu: Bad initializer") } +#if NETWORK_PROTECTION + init(tabCollectionViewModel: TabCollectionViewModel, + emailManager: EmailManager = EmailManager(), + passwordManagerCoordinator: PasswordManagerCoordinator, + networkProtectionFeatureVisibility: NetworkProtectionFeatureVisibility = NetworkProtectionKeychainTokenStore(), + internalUserDecider: InternalUserDecider) { + + self.tabCollectionViewModel = tabCollectionViewModel + self.emailManager = emailManager + self.passwordManagerCoordinator = passwordManagerCoordinator + self.networkProtectionFeatureVisibility = networkProtectionFeatureVisibility + self.internalUserDecider = internalUserDecider + + super.init(title: "") + + self.emailManager.requestDelegate = self + + setupMenuItems() + } +#else init(tabCollectionViewModel: TabCollectionViewModel, emailManager: EmailManager = EmailManager(), passwordManagerCoordinator: PasswordManagerCoordinator, @@ -61,12 +89,14 @@ final class MoreOptionsMenu: NSMenu { self.emailManager = emailManager self.passwordManagerCoordinator = passwordManagerCoordinator self.internalUserDecider = internalUserDecider + super.init(title: "") self.emailManager.requestDelegate = self setupMenuItems() } +#endif let zoomMenuItem = NSMenuItem(title: UserText.zoom, action: nil, keyEquivalent: "") @@ -95,6 +125,14 @@ final class MoreOptionsMenu: NSMenu { .withImage(NSImage(named: "OptionsButtonMenuEmail")) .withSubmenu(EmailOptionsButtonSubMenu(tabCollectionViewModel: tabCollectionViewModel, emailManager: emailManager)) +#if NETWORK_PROTECTION + if networkProtectionFeatureVisibility.isFeatureActivated { + addItem(withTitle: UserText.networkProtection, action: #selector(showNetworkProtectionStatus(_:)), keyEquivalent: "") + .targetting(self) + .withImage(.image(for: .vpnIcon)) + } +#endif + addItem(NSMenuItem.separator()) addPageItems() @@ -105,6 +143,10 @@ final class MoreOptionsMenu: NSMenu { addItem(preferencesItem) } + @objc func showNetworkProtectionStatus(_ sender: NSMenuItem) { + actionDelegate?.optionsButtonMenuRequestedNetworkProtectionPopover(self) + } + @objc func newTab(_ sender: NSMenuItem) { tabCollectionViewModel.appendNewTab() } diff --git a/DuckDuckGo/NavigationBar/View/NavigationBar.storyboard b/DuckDuckGo/NavigationBar/View/NavigationBar.storyboard index aca4a16d11..a73ddebd12 100644 --- a/DuckDuckGo/NavigationBar/View/NavigationBar.storyboard +++ b/DuckDuckGo/NavigationBar/View/NavigationBar.storyboard @@ -220,6 +220,32 @@ +