From 94cb8ba6d1ee4e14204fe4f13cffe13161339b41 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Wed, 18 Dec 2024 15:37:08 +0100 Subject: [PATCH 01/19] Ensure migration has occurred before accessing vault --- .../CredentialProviderViewController.swift | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift index 35f730611e..149447f243 100644 --- a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift +++ b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift @@ -22,6 +22,7 @@ import SwiftUI import BrowserServicesKit import Core import Common +import os.log class CredentialProviderViewController: ASCredentialProviderViewController { @@ -110,7 +111,9 @@ class CredentialProviderViewController: ASCredentialProviderViewController { installChildViewController(hostingController) Task { - await credentialIdentityStoreManager.populateCredentialStore() + if let self = self, self.findKeychainItemsWithV4() { + await credentialIdentityStoreManager.populateCredentialStore() + } } Pixel.fire(pixel: .autofillExtensionEnabled) @@ -203,4 +206,31 @@ class CredentialProviderViewController: ASCredentialProviderViewController { } } } + + private func findKeychainItemsWithV4() -> Bool { + var itemsWithV4: [String] = [] + + let query: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecReturnAttributes as String: kCFBooleanTrue!, + kSecMatchLimit as String: kSecMatchLimitAll + ] + + var result: AnyObject? + + let status = SecItemCopyMatching(query as CFDictionary, &result) + + if status == errSecSuccess, let items = result as? [[String: Any]] { + for item in items { + if let service = item[kSecAttrService as String] as? String, + service.contains("v4") { + itemsWithV4.append(service) + } + } + } else { + Logger.autofill.debug("No items found or error: \(status)") + } + + return !itemsWithV4.isEmpty + } } From 7bb73173badcd7f7f84d65841f9de459f03d5ad8 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Wed, 18 Dec 2024 15:37:35 +0100 Subject: [PATCH 02/19] Update to target main app --- .../xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme index 02ee5661e7..7708563eda 100644 --- a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme @@ -46,7 +46,7 @@ shouldAutocreateTestPlan = "YES"> Date: Wed, 18 Dec 2024 15:39:13 +0100 Subject: [PATCH 03/19] Populate credential store if user has enabled before launching app --- DuckDuckGo/AutofillUsageMonitor.swift | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/DuckDuckGo/AutofillUsageMonitor.swift b/DuckDuckGo/AutofillUsageMonitor.swift index 5c9f9bf87f..6123c43180 100644 --- a/DuckDuckGo/AutofillUsageMonitor.swift +++ b/DuckDuckGo/AutofillUsageMonitor.swift @@ -19,19 +19,34 @@ import Core import AuthenticationServices +import BrowserServicesKit final class AutofillUsageMonitor { + private lazy var credentialIdentityStoreManager: AutofillCredentialIdentityStoreManager? = { + guard let vault = try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter()) else { + return nil + } + + return AutofillCredentialIdentityStoreManager(vault: vault, + tld: AppDependencyProvider.shared.storageCache.tld) + }() + init() { NotificationCenter.default.addObserver(self, selector: #selector(didReceiveSaveEvent), name: .autofillSaveEvent, object: nil) - ASCredentialIdentityStore.shared.getState({ state in + ASCredentialIdentityStore.shared.getState({ [weak self] state in if state.isEnabled { - self.autofillExtensionEnabled = true + if self?.autofillExtensionEnabled == nil { + Task { + await self?.credentialIdentityStoreManager?.populateCredentialStore() + } + } + self?.autofillExtensionEnabled = true } else { - if self.autofillExtensionEnabled != nil { + if self?.autofillExtensionEnabled != nil { Pixel.fire(pixel: .autofillExtensionDisabled) - self.autofillExtensionEnabled = false + self?.autofillExtensionEnabled = false } } }) From f391cce59bd35a12b9f5c763c8de2211946f7b4c Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Wed, 18 Dec 2024 15:52:34 +0100 Subject: [PATCH 04/19] Ensure migration has occurred before accessing vault --- .../CredentialProvider/CredentialProviderViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift index 149447f243..3017132267 100644 --- a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift +++ b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift @@ -111,7 +111,7 @@ class CredentialProviderViewController: ASCredentialProviderViewController { installChildViewController(hostingController) Task { - if let self = self, self.findKeychainItemsWithV4() { + if findKeychainItemsWithV4() { await credentialIdentityStoreManager.populateCredentialStore() } } From da651c8ed27fd9f622389b8778300e2619a911d1 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Wed, 18 Dec 2024 17:04:06 +0100 Subject: [PATCH 05/19] An additional protective in case users try to access the passwords list via the extension, before launching the app --- .../CredentialProviderViewController.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift index 3017132267..557b7292e7 100644 --- a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift +++ b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift @@ -38,7 +38,11 @@ class CredentialProviderViewController: ASCredentialProviderViewController { tld: tld) private lazy var secureVault: (any AutofillSecureVault)? = { - try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter()) + if findKeychainItemsWithV4() { + return try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter()) + } else { + return nil + } }() private lazy var tld: TLD = TLD() From 1e0fa7a1c667176e72edcb1553975035f284dca6 Mon Sep 17 00:00:00 2001 From: amddg44 Date: Wed, 18 Dec 2024 19:35:27 +0100 Subject: [PATCH 06/19] Release 7.149.1-0 (#3740) --- Configuration/Version.xcconfig | 2 +- DuckDuckGo.xcodeproj/project.pbxproj | 64 ++++++++++----------- DuckDuckGo/Settings.bundle/Root.plist | 2 +- fastlane/metadata/default/release_notes.txt | 2 +- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Configuration/Version.xcconfig b/Configuration/Version.xcconfig index 9ef4c72f39..fde561fa40 100644 --- a/Configuration/Version.xcconfig +++ b/Configuration/Version.xcconfig @@ -1 +1 @@ -MARKETING_VERSION = 7.149.0 +MARKETING_VERSION = 7.149.1 diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index fbe80bb961..2d0f1997f1 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -9670,7 +9670,7 @@ CODE_SIGN_ENTITLEMENTS = PacketTunnelProvider/PacketTunnelProvider.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -9707,7 +9707,7 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -9797,7 +9797,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ShareExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -9824,7 +9824,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -9972,7 +9972,7 @@ CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGo.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -9998,7 +9998,7 @@ CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGo.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; INFOPLIST_FILE = DuckDuckGo/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -10065,7 +10065,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEAD_CODE_STRIPPING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Widgets/Info.plist; @@ -10099,7 +10099,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -10132,7 +10132,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = OpenAction/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -10162,7 +10162,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -10493,7 +10493,7 @@ CODE_SIGN_ENTITLEMENTS = AutofillCredentialProvider/AutofillCredentialProvider.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = HKE973VLUW; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -10531,7 +10531,7 @@ CODE_SIGN_ENTITLEMENTS = AutofillCredentialProvider/AutofillCredentialProviderAlpha.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = HKE973VLUW; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -10568,7 +10568,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -10607,7 +10607,7 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -10705,7 +10705,7 @@ CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGoAlpha.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -10736,7 +10736,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ShareExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -10764,7 +10764,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = OpenAction/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -10797,7 +10797,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEAD_CODE_STRIPPING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Widgets/Info.plist; @@ -10827,7 +10827,7 @@ CODE_SIGN_ENTITLEMENTS = PacketTunnelProvider/PacketTunnelProviderAlpha.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -10860,11 +10860,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 3; + DYLIB_CURRENT_VERSION = 0; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Core/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -11096,7 +11096,7 @@ CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGoAlpha.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -11124,7 +11124,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -11156,7 +11156,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -11193,7 +11193,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -11228,7 +11228,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -11263,11 +11263,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 3; + DYLIB_CURRENT_VERSION = 0; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Core/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -11439,11 +11439,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 3; + DYLIB_CURRENT_VERSION = 0; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Core/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -11472,10 +11472,10 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 0; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 3; + DYLIB_CURRENT_VERSION = 0; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Core/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; diff --git a/DuckDuckGo/Settings.bundle/Root.plist b/DuckDuckGo/Settings.bundle/Root.plist index 740cfbe9a5..5b6f693ce0 100644 --- a/DuckDuckGo/Settings.bundle/Root.plist +++ b/DuckDuckGo/Settings.bundle/Root.plist @@ -6,7 +6,7 @@ DefaultValue - 7.149.0 + 7.149.1 Key version Title diff --git a/fastlane/metadata/default/release_notes.txt b/fastlane/metadata/default/release_notes.txt index 66b16c0810..58bb2b4a63 100644 --- a/fastlane/metadata/default/release_notes.txt +++ b/fastlane/metadata/default/release_notes.txt @@ -1 +1 @@ -- Bug fixes and other improvements \ No newline at end of file + - If you use dark mode, you'll notice the app icon has an improved look, whether you've stuck with the classic orange or picked a custom icon color. \ No newline at end of file From 079e995dc8674920758dbd3c7a919ef6ce9006b4 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Wed, 18 Dec 2024 15:37:08 +0100 Subject: [PATCH 07/19] Ensure migration has occurred before accessing vault --- .../CredentialProviderViewController.swift | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift index 35f730611e..149447f243 100644 --- a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift +++ b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift @@ -22,6 +22,7 @@ import SwiftUI import BrowserServicesKit import Core import Common +import os.log class CredentialProviderViewController: ASCredentialProviderViewController { @@ -110,7 +111,9 @@ class CredentialProviderViewController: ASCredentialProviderViewController { installChildViewController(hostingController) Task { - await credentialIdentityStoreManager.populateCredentialStore() + if let self = self, self.findKeychainItemsWithV4() { + await credentialIdentityStoreManager.populateCredentialStore() + } } Pixel.fire(pixel: .autofillExtensionEnabled) @@ -203,4 +206,31 @@ class CredentialProviderViewController: ASCredentialProviderViewController { } } } + + private func findKeychainItemsWithV4() -> Bool { + var itemsWithV4: [String] = [] + + let query: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecReturnAttributes as String: kCFBooleanTrue!, + kSecMatchLimit as String: kSecMatchLimitAll + ] + + var result: AnyObject? + + let status = SecItemCopyMatching(query as CFDictionary, &result) + + if status == errSecSuccess, let items = result as? [[String: Any]] { + for item in items { + if let service = item[kSecAttrService as String] as? String, + service.contains("v4") { + itemsWithV4.append(service) + } + } + } else { + Logger.autofill.debug("No items found or error: \(status)") + } + + return !itemsWithV4.isEmpty + } } From 1e4ecf0bcce25d5a4063be71c5cb22eceb023dc4 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Wed, 18 Dec 2024 15:37:35 +0100 Subject: [PATCH 08/19] Update to target main app --- .../xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme index 02ee5661e7..7708563eda 100644 --- a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/AutofillCredentialProvider.xcscheme @@ -46,7 +46,7 @@ shouldAutocreateTestPlan = "YES"> Date: Wed, 18 Dec 2024 15:39:13 +0100 Subject: [PATCH 09/19] Populate credential store if user has enabled before launching app --- DuckDuckGo/AutofillUsageMonitor.swift | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/DuckDuckGo/AutofillUsageMonitor.swift b/DuckDuckGo/AutofillUsageMonitor.swift index 5c9f9bf87f..6123c43180 100644 --- a/DuckDuckGo/AutofillUsageMonitor.swift +++ b/DuckDuckGo/AutofillUsageMonitor.swift @@ -19,19 +19,34 @@ import Core import AuthenticationServices +import BrowserServicesKit final class AutofillUsageMonitor { + private lazy var credentialIdentityStoreManager: AutofillCredentialIdentityStoreManager? = { + guard let vault = try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter()) else { + return nil + } + + return AutofillCredentialIdentityStoreManager(vault: vault, + tld: AppDependencyProvider.shared.storageCache.tld) + }() + init() { NotificationCenter.default.addObserver(self, selector: #selector(didReceiveSaveEvent), name: .autofillSaveEvent, object: nil) - ASCredentialIdentityStore.shared.getState({ state in + ASCredentialIdentityStore.shared.getState({ [weak self] state in if state.isEnabled { - self.autofillExtensionEnabled = true + if self?.autofillExtensionEnabled == nil { + Task { + await self?.credentialIdentityStoreManager?.populateCredentialStore() + } + } + self?.autofillExtensionEnabled = true } else { - if self.autofillExtensionEnabled != nil { + if self?.autofillExtensionEnabled != nil { Pixel.fire(pixel: .autofillExtensionDisabled) - self.autofillExtensionEnabled = false + self?.autofillExtensionEnabled = false } } }) From 3c2509bb8ef525ad1b026207dc874aa97f056974 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Wed, 18 Dec 2024 15:52:34 +0100 Subject: [PATCH 10/19] Ensure migration has occurred before accessing vault --- .../CredentialProvider/CredentialProviderViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift index 149447f243..3017132267 100644 --- a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift +++ b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift @@ -111,7 +111,7 @@ class CredentialProviderViewController: ASCredentialProviderViewController { installChildViewController(hostingController) Task { - if let self = self, self.findKeychainItemsWithV4() { + if findKeychainItemsWithV4() { await credentialIdentityStoreManager.populateCredentialStore() } } From 3372bc8329ef8c72d9ee8418e4b32d7dd69a43a8 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Wed, 18 Dec 2024 17:04:06 +0100 Subject: [PATCH 11/19] An additional protective in case users try to access the passwords list via the extension, before launching the app --- .../CredentialProviderViewController.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift index 3017132267..557b7292e7 100644 --- a/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift +++ b/AutofillCredentialProvider/CredentialProvider/CredentialProviderViewController.swift @@ -38,7 +38,11 @@ class CredentialProviderViewController: ASCredentialProviderViewController { tld: tld) private lazy var secureVault: (any AutofillSecureVault)? = { - try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter()) + if findKeychainItemsWithV4() { + return try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter()) + } else { + return nil + } }() private lazy var tld: TLD = TLD() From 577e08caf8fc90fdeea344909d45660949ded8e4 Mon Sep 17 00:00:00 2001 From: amddg44 Date: Wed, 18 Dec 2024 22:02:01 +0100 Subject: [PATCH 12/19] Release 7.150.0-1 (#3742) --- DuckDuckGo.xcodeproj/project.pbxproj | 64 ++++++++++++++-------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 4ff434240a..c655af07ad 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -9670,7 +9670,7 @@ CODE_SIGN_ENTITLEMENTS = PacketTunnelProvider/PacketTunnelProvider.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -9707,7 +9707,7 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -9797,7 +9797,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ShareExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -9824,7 +9824,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -9972,7 +9972,7 @@ CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGo.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -9998,7 +9998,7 @@ CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGo.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; INFOPLIST_FILE = DuckDuckGo/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -10065,7 +10065,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Widgets/Info.plist; @@ -10099,7 +10099,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -10132,7 +10132,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = OpenAction/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -10162,7 +10162,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -10493,7 +10493,7 @@ CODE_SIGN_ENTITLEMENTS = AutofillCredentialProvider/AutofillCredentialProvider.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = HKE973VLUW; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -10531,7 +10531,7 @@ CODE_SIGN_ENTITLEMENTS = AutofillCredentialProvider/AutofillCredentialProviderAlpha.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = HKE973VLUW; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -10568,7 +10568,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -10607,7 +10607,7 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -10705,7 +10705,7 @@ CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGoAlpha.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -10736,7 +10736,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ShareExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -10764,7 +10764,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = OpenAction/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -10797,7 +10797,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Widgets/Info.plist; @@ -10827,7 +10827,7 @@ CODE_SIGN_ENTITLEMENTS = PacketTunnelProvider/PacketTunnelProviderAlpha.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -10860,11 +10860,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 0; + DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Core/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -11096,7 +11096,7 @@ CODE_SIGN_ENTITLEMENTS = DuckDuckGo/DuckDuckGoAlpha.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -11124,7 +11124,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -11156,7 +11156,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -11193,7 +11193,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; @@ -11228,7 +11228,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HKE973VLUW; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -11263,11 +11263,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 0; + DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Core/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -11439,11 +11439,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 0; + DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Core/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -11472,10 +11472,10 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 0; + DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Core/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; From 6d1fefb7a98e404f45db6579cfa5655ee3863d4a Mon Sep 17 00:00:00 2001 From: Sam Symons Date: Wed, 18 Dec 2024 13:02:10 -0800 Subject: [PATCH 13/19] Remove ESLint config files (#3739) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task/Issue URL: https://app.asana.com/0/0/1208971717942902/f Tech Design URL: CC: **Description**: This PR cleans up unused ESLint configuration files. **Steps to test this PR**: 1. Check that I haven't missed removing any other ESLint files **Definition of Done (Internal Only)**: * [ ] Does this PR satisfy our [Definition of Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)? **Device Testing**: * [ ] iPhone SE (1st Gen) * [ ] iPhone 8 * [ ] iPhone X * [ ] iPhone 14 Pro * [ ] iPad **OS Testing**: * [ ] iOS 15 * [ ] iOS 16 * [ ] iOS 17 **Theme Testing**: * [ ] Light theme * [ ] Dark theme --- ###### Internal references: [Software Engineering Expectations](https://app.asana.com/0/59792373528535/199064865822552) [Technical Design Template](https://app.asana.com/0/59792373528535/184709971311943) --- .eslintignore | 1 - .eslintrc | 25 ------------------------- 2 files changed, 26 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 539b4cdd5c..0000000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -submodules/ diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 3b909f8fd4..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,25 +0,0 @@ -{ - "env": { - "browser": true, - "es2017": true - }, - "extends": [ - "standard" - ], - "globals": { - "__firefox__": "readonly", - "SECURITY_TOKEN": "readonly", - "$FEATURE_SETTINGS$": "readonly", - "$GPC_ENABLED$": "readonly", - "$BLOCKING_ENABLED$": "readonly", - "$TRACKER_DATA$": "readonly", - "$IS_DEBUG$": "readonly", - "webkit": "readonly" - }, - "parserOptions": { - "ecmaVersion": 7 - }, - "rules": { - "indent": ["error", 4] - } -} From cdeddbadab176bbd3d9ed63c091d0ff942017070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20=C5=9Apiewak?= Date: Thu, 19 Dec 2024 10:15:05 +0100 Subject: [PATCH 14/19] Fix BrowsingMenu layout (#3712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task/Issue URL: https://app.asana.com/0/414709148257752/1208946169184139/f Tech Design URL: CC: **Description**: Adjusts layout for `BrowsingMenuButton` so that it expands along with the label inside. Additionally `BrowsingMenuViewController` got a new constraint preventing the menu view from going outside view bounds. **Steps to test this PR**: 1. Enable link conditioner with a bad/slow connection profile. 2. Try to load any site, stop before it finishes loading. 3. Open menu, check if button titles are visible. 4. Load site again (without link conditioner). 5. Check browsing menu sizing and layout is as expected. 6. Go to System Settings -> Developer -> View (simulator) or Display & Brightness -> Display Zoom (physical device) and set display zoom to "Larger text". 7. Repeat testing steps. **Definition of Done (Internal Only)**: * [ ] Does this PR satisfy our [Definition of Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)? **Orientation Testing**: * [ ] Portrait * [ ] Landscape **Device Testing**: * [x] iPhone SE (1st Gen) * [x] iPhone 8 * [ ] iPhone X * [x] iPhone 14 Pro * [x] iPad **OS Testing**: * [ ] iOS 15 * [ ] iOS 16 * [ ] iOS 17 --- ###### Internal references: [Software Engineering Expectations](https://app.asana.com/0/59792373528535/199064865822552) [Technical Design Template](https://app.asana.com/0/59792373528535/184709971311943) --- .../BrowsingMenu/BrowsingMenuButton.xib | 39 ++++++------ .../BrowsingMenuViewController.storyboard | 60 +++++++++---------- ...bViewControllerBrowsingMenuExtension.swift | 5 +- 3 files changed, 55 insertions(+), 49 deletions(-) diff --git a/DuckDuckGo/BrowsingMenu/BrowsingMenuButton.xib b/DuckDuckGo/BrowsingMenu/BrowsingMenuButton.xib index 6936ad96a9..358b28ef66 100644 --- a/DuckDuckGo/BrowsingMenu/BrowsingMenuButton.xib +++ b/DuckDuckGo/BrowsingMenu/BrowsingMenuButton.xib @@ -1,39 +1,36 @@ - + - + - - + + - + - + - diff --git a/DuckDuckGo/BrowsingMenu/BrowsingMenuViewController.storyboard b/DuckDuckGo/BrowsingMenu/BrowsingMenuViewController.storyboard index c15ecff942..9b439b5901 100644 --- a/DuckDuckGo/BrowsingMenu/BrowsingMenuViewController.storyboard +++ b/DuckDuckGo/BrowsingMenu/BrowsingMenuViewController.storyboard @@ -1,9 +1,10 @@ - + - + + @@ -12,10 +13,6 @@ - - - - @@ -28,10 +25,10 @@ - + - + @@ -39,43 +36,44 @@ - + - + - - + + - - + + + - + - + - + - + - + @@ -87,7 +85,7 @@ - + @@ -133,20 +131,20 @@ - + - + - + - + @@ -196,18 +194,20 @@ + - + - + + - + - - + + diff --git a/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift b/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift index fe6b117e86..4dc0613771 100644 --- a/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift +++ b/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift @@ -128,7 +128,10 @@ extension TabViewController { })) } - entries.append(.separator) + // Do not add separator if there are no entries so far + if entries.count > 0 { + entries.append(.separator) + } let shortcutsEntries = buildShortcutsEntries(includeBookmarks: false) entries.append(contentsOf: shortcutsEntries) From 8a8f641298aff53fccfd06d3e3d939260a2a2055 Mon Sep 17 00:00:00 2001 From: Daniel Bernal Date: Thu, 19 Dec 2024 18:22:49 +0100 Subject: [PATCH 15/19] =?UTF-8?q?DuckPlayer:=20Don=E2=80=99t=20open=20new?= =?UTF-8?q?=20tabs=20or=20DuckPlayer=20at=20launch=20when=20in=20alwaysAsk?= =?UTF-8?q?=20mode=20(#3738)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task/Issue URL: https://app.asana.com/0/1204099484721401/1208896356321073/f Tech Design URL: CC: **Description**: Bugfix: When launching the app after a crash or force close with DuckPlayer in 'Ask' mode, the app automatically opened `youtube.com/watch` pages (videos) in DuckPlayer when it shouldn't. This was caused by DuckPlayer's 'open in new tab' feature. When the app was first launched, a new tab opened for every `youtube.com/watch` page, which triggered DuckPlayer by default. --- DuckDuckGo/DuckPlayer/DuckPlayerNavigationHandler.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo/DuckPlayer/DuckPlayerNavigationHandler.swift b/DuckDuckGo/DuckPlayer/DuckPlayerNavigationHandler.swift index 13afd90eb0..8ea855cfca 100644 --- a/DuckDuckGo/DuckPlayer/DuckPlayerNavigationHandler.swift +++ b/DuckDuckGo/DuckPlayer/DuckPlayerNavigationHandler.swift @@ -954,7 +954,7 @@ extension DuckPlayerNavigationHandler: DuckPlayerNavigationHandling { // Redirect to Youtube + DuckPlayer Overlay if Ask Mode if url.isYoutubeWatch && duckPlayerMode == .alwaysAsk && !isDuckPlayerRedirect(url: url) { - redirectToYouTubeVideo(url: url, webView: webView, allowFirstVideo: false) + redirectToYouTubeVideo(url: url, webView: webView, allowFirstVideo: false, disableNewTab: true) return true } From df948c9c2a7e1a9004b36bc15dcdc7ccdf8eec60 Mon Sep 17 00:00:00 2001 From: amddg44 Date: Thu, 19 Dec 2024 20:28:00 +0100 Subject: [PATCH 16/19] Fix sharing via the Share & Action extensions on iOS 18 (#3745) Task/Issue URL: https://app.asana.com/0/414709148257752/1208991975879543/f Tech Design URL: CC: **Description**: Fixes sharing to the DDG app from the share + action extensions on iOS 18 --- OpenAction/ActionViewController.swift | 13 ++++++++++--- ShareExtension/ShareViewController.swift | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/OpenAction/ActionViewController.swift b/OpenAction/ActionViewController.swift index 2a4c493ebf..afe78b94a4 100644 --- a/OpenAction/ActionViewController.swift +++ b/OpenAction/ActionViewController.swift @@ -64,9 +64,16 @@ class ActionViewController: UIViewController { var responder = self as UIResponder? let selectorOpenURL = sel_registerName("openURL:") while let current = responder { - if current.responds(to: selectorOpenURL) { - current.perform(selectorOpenURL, with: url, afterDelay: 0) - break + if #available(iOS 18.0, *) { + if let application = current as? UIApplication { + application.open(url, options: [:], completionHandler: nil) + break + } + } else { + if current.responds(to: selectorOpenURL) { + current.perform(selectorOpenURL, with: url, afterDelay: 0) + break + } } responder = current.next } diff --git a/ShareExtension/ShareViewController.swift b/ShareExtension/ShareViewController.swift index 98829b4cbe..5afada430c 100644 --- a/ShareExtension/ShareViewController.swift +++ b/ShareExtension/ShareViewController.swift @@ -84,9 +84,16 @@ class ShareViewController: SLComposeServiceViewController { let deepLink = URL(string: AppDeepLinkSchemes.quickLink.appending(url.absoluteString))! var responder = self as UIResponder? while responder != nil { - if responder!.responds(to: selector) { - _ = responder?.perform(selector, with: deepLink, with: {}) - break + if #available(iOS 18.0, *) { + if let application = responder as? UIApplication { + application.open(deepLink, options: [:], completionHandler: nil) + break + } + } else { + if responder!.responds(to: selector) { + _ = responder?.perform(selector, with: deepLink, with: {}) + break + } } responder = responder!.next } From 8ce3815b51b25209cdef74eddc5e99d7e7b73dc3 Mon Sep 17 00:00:00 2001 From: Jonathan Jackson Date: Thu, 19 Dec 2024 16:25:37 -0500 Subject: [PATCH 17/19] Crash report cohort ID support for iOS (#3692) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task/Issue URL: https://app.asana.com/0/1208592102886666/1208759541597499/f Tech Design URL: https://app.asana.com/0/1208592102886666/1208660326715650/f **Description**: DO NOT MERGE - this is a draft for input, not ready to go live yet. iOS client support for CRCID send/receive (primarily supported in BSK, with changes under review in [BSK #1116](https://github.com/duckduckgo/BrowserServicesKit/pull/1116)). This is pretty straightforward, just conforming to CrashCollection’s new init signature, and clearing CRCIDs when the user opts out of crash reporting. BSK handles everything else. **Steps to test this PR**: Note: Must be tested on a physical device, as the simulator does not produce crash logs (and thus doesn’t find and upload them either). To cause and report a crash: 1. Launch the app and force a crash, which can be done from Settings → All Debug Options → Crash (fatal error) or similar. Note that Crash (CPU/Memory) does not appear to produce a crash log, and thus won’t trigger crash uploading. 2. Launch the app again (easiest with a debugger) 1. For the first crash of an app install: You will be prompted to opt in or out of crash reporting when the app is launched. Opt in and watch logs for “crcid” and you should see logs from CrashReportSender:56, and CrashCollection:95-109. 2. On subsequent crashes, when opted in, you should see statements confirming the received crcid was sent, and that the server returned either the same matching one, or a new one (in which case the new one should be stored and used on subsequent crash reports) To test clearing of the crcid when opting out: 1. Navigate to Settings → About and switch “Send Crash Reports” off, then back on again (this step should clear the crcid) 2. Follow steps from “To cause and report a crash” above, and confirm that the crash is submitted without an initial crcid, and that the server assigns one and it is stored (causing and uploading a second crash should confirm this new value is used on send). --- Core/PixelEvent.swift | 5 +++ DuckDuckGo.xcodeproj/project.pbxproj | 6 ++- .../xcshareddata/swiftpm/Package.resolved | 4 +- DuckDuckGo/AppDelegate.swift | 4 +- DuckDuckGo/AppUserDefaults.swift | 2 +- DuckDuckGo/CrashCollectionOnboarding.swift | 3 ++ .../CrashCollectionOnboardingViewModel.swift | 6 +++ DuckDuckGo/CrashReportSenderExtensions.swift | 40 +++++++++++++++++++ DuckDuckGo/SettingsViewModel.swift | 5 +++ DuckDuckGoTests/AppSettingsMock.swift | 1 - 10 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 DuckDuckGo/CrashReportSenderExtensions.swift diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index 18c6b0b761..0adf763dec 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -526,6 +526,9 @@ extension Pixel { case dbCrashDetectedDaily case crashOnCrashHandlersSetUp + case crashReportCRCIDMissing + case crashReportingSubmissionFailed + case dbMigrationError case dbRemovalError case dbDestroyError @@ -1456,6 +1459,8 @@ extension Pixel.Event { case .dbCrashDetected: return "m_d_crash" case .dbCrashDetectedDaily: return "m_d_crash_daily" + case .crashReportCRCIDMissing: return "m_crashreporting_crcid-missing" + case .crashReportingSubmissionFailed: return "m_crashreporting_submission-failed" case .crashOnCrashHandlersSetUp: return "m_d_crash_on_handlers_setup" case .dbMigrationError: return "m_d_dbme" case .dbRemovalError: return "m_d_dbre" diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index ed776495b7..91b6c160d0 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -225,6 +225,7 @@ 37FCAABC2992F592000E420A /* MultilineScrollableTextFix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FCAABB2992F592000E420A /* MultilineScrollableTextFix.swift */; }; 37FCAAC029930E26000E420A /* FailedAssertionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FCAABF29930E26000E420A /* FailedAssertionView.swift */; }; 37FD780F2A29E28B00B36DB1 /* SyncErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD780E2A29E28B00B36DB1 /* SyncErrorHandler.swift */; }; + 46DD3D5A2D0A29F600F33D49 /* CrashReportSenderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46DD3D592D0A29F400F33D49 /* CrashReportSenderExtensions.swift */; }; 4B0295192537BC6700E00CEF /* ConfigurationDebugViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0295182537BC6700E00CEF /* ConfigurationDebugViewController.swift */; }; 4B0F3F502B9BFF2100392892 /* NetworkProtectionFAQView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F3F4F2B9BFF2100392892 /* NetworkProtectionFAQView.swift */; }; 4B274F602AFEAECC003F0745 /* NetworkProtectionWidgetRefreshModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B274F5F2AFEAECC003F0745 /* NetworkProtectionWidgetRefreshModel.swift */; }; @@ -1597,6 +1598,7 @@ 37FCAABF29930E26000E420A /* FailedAssertionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FailedAssertionView.swift; sourceTree = ""; }; 37FCAACB2993149A000E420A /* Waitlist */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Waitlist; sourceTree = ""; }; 37FD780E2A29E28B00B36DB1 /* SyncErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncErrorHandler.swift; sourceTree = ""; }; + 46DD3D592D0A29F400F33D49 /* CrashReportSenderExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportSenderExtensions.swift; sourceTree = ""; }; 4B0295182537BC6700E00CEF /* ConfigurationDebugViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationDebugViewController.swift; sourceTree = ""; }; 4B0F3F4F2B9BFF2100392892 /* NetworkProtectionFAQView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionFAQView.swift; sourceTree = ""; }; 4B274F5F2AFEAECC003F0745 /* NetworkProtectionWidgetRefreshModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionWidgetRefreshModel.swift; sourceTree = ""; }; @@ -3888,6 +3890,7 @@ 37CF915E2BB4735F00BADCAE /* Crashes */ = { isa = PBXGroup; children = ( + 46DD3D592D0A29F400F33D49 /* CrashReportSenderExtensions.swift */, 37CF915F2BB4737300BADCAE /* CrashCollectionOnboarding.swift */, 37CF91612BB474AA00BADCAE /* CrashCollectionOnboardingView.swift */, 37CF91632BB4A82A00BADCAE /* CrashCollectionOnboardingViewModel.swift */, @@ -8235,6 +8238,7 @@ BDF8D0022C1B87F4003E3B27 /* NetworkProtectionDNSSettingsViewModel.swift in Sources */, 9838059F2228208E00385F1A /* PositiveFeedbackViewController.swift in Sources */, 8590CB67268A2E520089F6BF /* RootDebugViewController.swift in Sources */, + 46DD3D5A2D0A29F600F33D49 /* CrashReportSenderExtensions.swift in Sources */, 1DEAADEA2BA4539800E25A97 /* SettingsAppearanceView.swift in Sources */, B623C1C22862CA9E0043013E /* DownloadSession.swift in Sources */, 317CA3432CFF82E100F88848 /* SettingsAIChatView.swift in Sources */, @@ -11719,7 +11723,7 @@ repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 221.3.0; + version = 222.1.0; }; }; 9F8FE9472BAE50E50071E372 /* XCRemoteSwiftPackageReference "lottie-spm" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4eaad818db..5f7e2bbb19 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { - "revision" : "b71ed70ce9b0ef3ce51d4f96da0193ab70493944", - "version" : "221.3.0" + "revision" : "5704d77e3b4c77c7387518d796d31a35f7a1ffcf", + "version" : "222.1.0" } }, { diff --git a/DuckDuckGo/AppDelegate.swift b/DuckDuckGo/AppDelegate.swift index 38ff685038..c176b05ae0 100644 --- a/DuckDuckGo/AppDelegate.swift +++ b/DuckDuckGo/AppDelegate.swift @@ -83,7 +83,9 @@ import os.log private var syncStateCancellable: AnyCancellable? private var isSyncInProgressCancellable: AnyCancellable? - private let crashCollection = CrashCollection(platform: .iOS) + private let crashCollection = CrashCollection(crashReportSender: CrashReportSender(platform: .iOS, + pixelEvents: CrashReportSender.pixelEvents), + crashCollectionStorage: UserDefaults()) private var crashReportUploaderOnboarding: CrashCollectionOnboarding? private var autofillPixelReporter: AutofillPixelReporter? diff --git a/DuckDuckGo/AppUserDefaults.swift b/DuckDuckGo/AppUserDefaults.swift index 2c17e2ac1e..df880d42d6 100644 --- a/DuckDuckGo/AppUserDefaults.swift +++ b/DuckDuckGo/AppUserDefaults.swift @@ -76,7 +76,7 @@ public class AppUserDefaults: AppSettings { static let crashCollectionOptInStatus = "com.duckduckgo.ios.crashCollectionOptInStatus" static let crashCollectionShouldRevertOptedInStatusTrigger = "com.duckduckgo.ios.crashCollectionShouldRevertOptedInStatusTrigger" - + static let duckPlayerMode = "com.duckduckgo.ios.duckPlayerMode" static let duckPlayerAskModeOverlayHidden = "com.duckduckgo.ios.duckPlayerAskModeOverlayHidden" static let duckPlayerOpenInNewTab = "com.duckduckgo.ios.duckPlayerOpenInNewTab" diff --git a/DuckDuckGo/CrashCollectionOnboarding.swift b/DuckDuckGo/CrashCollectionOnboarding.swift index dd9e54af7c..7dac3c6265 100644 --- a/DuckDuckGo/CrashCollectionOnboarding.swift +++ b/DuckDuckGo/CrashCollectionOnboarding.swift @@ -55,9 +55,12 @@ final class CrashCollectionOnboarding: NSObject { func presentOnboardingIfNeeded(for payloads: [Data], from viewController: UIViewController, sendReport: @escaping () -> Void) { let isCurrentlyPresenting = viewController.presentedViewController != nil + // Note: DO NOT TURN THIS ON until updated screens for the opt-in prompt and screen for reviewing the kinds of data + // we collect are updated (project coming soon) if featureFlagger.isFeatureOn(.crashReportOptInStatusResetting) { if appSettings.crashCollectionOptInStatus == .optedIn && appSettings.crashCollectionShouldRevertOptedInStatusTrigger < crashCollectionShouldRevertOptedInStatusTriggerTargetValue { + appSettings.crashCollectionOptInStatus = .undetermined appSettings.crashCollectionShouldRevertOptedInStatusTrigger = crashCollectionShouldRevertOptedInStatusTriggerTargetValue } diff --git a/DuckDuckGo/CrashCollectionOnboardingViewModel.swift b/DuckDuckGo/CrashCollectionOnboardingViewModel.swift index bd641f257b..5badf39bee 100644 --- a/DuckDuckGo/CrashCollectionOnboardingViewModel.swift +++ b/DuckDuckGo/CrashCollectionOnboardingViewModel.swift @@ -19,6 +19,7 @@ import Foundation import SwiftUI +import Crashes final class CrashCollectionOnboardingViewModel: ObservableObject { @@ -106,6 +107,11 @@ final class CrashCollectionOnboardingViewModel: ObservableObject { } set { appSettings.crashCollectionOptInStatus = newValue + if appSettings.crashCollectionOptInStatus == .optedOut { + let crashCollection = CrashCollection.init(crashReportSender: CrashReportSender(platform: .iOS, + pixelEvents: CrashReportSender.pixelEvents)) + crashCollection.clearCRCID() + } } } } diff --git a/DuckDuckGo/CrashReportSenderExtensions.swift b/DuckDuckGo/CrashReportSenderExtensions.swift new file mode 100644 index 0000000000..a90e8d54da --- /dev/null +++ b/DuckDuckGo/CrashReportSenderExtensions.swift @@ -0,0 +1,40 @@ +// +// CrashReportSenderExtensions.swift +// DuckDuckGo +// +// Copyright © 2024 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 Crashes +import Common +import Core + +extension CrashReportSender { + + static let pixelEvents: EventMapping = .init { event, _, _, _ in + switch event { + case CrashReportSenderError.crcidMissing: + Pixel.fire(pixel: .crashReportCRCIDMissing) + + case CrashReportSenderError.submissionFailed(let error): + if let error { + Pixel.fire(pixel: .crashReportingSubmissionFailed, + withAdditionalParameters: ["HTTPStatusCode": "\(error.statusCode)"]) + } else { + Pixel.fire(pixel: .crashReportingSubmissionFailed) + } + } + } +} diff --git a/DuckDuckGo/SettingsViewModel.swift b/DuckDuckGo/SettingsViewModel.swift index cfdc9ae43c..224f880c2c 100644 --- a/DuckDuckGo/SettingsViewModel.swift +++ b/DuckDuckGo/SettingsViewModel.swift @@ -25,6 +25,7 @@ import Common import Combine import SyncUI import DuckPlayer +import Crashes import Subscription import NetworkProtection @@ -377,6 +378,10 @@ final class SettingsViewModel: ObservableObject { Binding( get: { self.state.crashCollectionOptInStatus == .optedIn }, set: { + if self.appSettings.crashCollectionOptInStatus == .optedIn && $0 == false { + let crashCollection = CrashCollection(crashReportSender: CrashReportSender(platform: .iOS, pixelEvents: CrashReportSender.pixelEvents)) + crashCollection.clearCRCID() + } self.appSettings.crashCollectionOptInStatus = $0 ? .optedIn : .optedOut self.state.crashCollectionOptInStatus = $0 ? .optedIn : .optedOut } diff --git a/DuckDuckGoTests/AppSettingsMock.swift b/DuckDuckGoTests/AppSettingsMock.swift index 13ced3eb65..bfd5fff474 100644 --- a/DuckDuckGoTests/AppSettingsMock.swift +++ b/DuckDuckGoTests/AppSettingsMock.swift @@ -82,7 +82,6 @@ class AppSettingsMock: AppSettings { var autoconsentEnabled = true var crashCollectionOptInStatus: CrashCollectionOptInStatus = .undetermined - var crashCollectionShouldRevertOptedInStatusTrigger: Int = 0 var newTabPageSectionsEnabled: Bool = false From 9415d44f84d49f76b3123a12467b95fd58abbef2 Mon Sep 17 00:00:00 2001 From: Sam Symons Date: Thu, 19 Dec 2024 15:24:22 -0800 Subject: [PATCH 18/19] Upgrade to Xcode 16.2 (#3743) Task/Issue URL: https://app.asana.com/0/1199230911884351/1209011361031638/f Tech Design URL: CC: Description: This PR upgrades CI to Xcode 16.2. --- .xcode-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.xcode-version b/.xcode-version index c32b0ec5ab..f6eb05e3c6 100644 --- a/.xcode-version +++ b/.xcode-version @@ -1 +1 @@ -16.1 +16.2 From 26699bebc4c4072ad19c5afda7e7813169c7a494 Mon Sep 17 00:00:00 2001 From: bwaresiak Date: Fri, 20 Dec 2024 08:28:02 +0100 Subject: [PATCH 19/19] Delegate new tab creation to WebView (#3746) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task/Issue URL: https://app.asana.com/0/856498667320406/1208699273169079/f Tech Design URL: CC: **Description**: Delegate new tab creation to WebView. **Steps to test this PR**: 1. Navigate to https://privacy-test-pages.site/privacy-protections/referrer-trimming/ 2. Check for referrer and how tabs behave. **Definition of Done (Internal Only)**: * [ ] Does this PR satisfy our [Definition of Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)? **Device Testing**: * [ ] iPhone * [ ] iPad **OS Testing**: * [ ] iOS 15 * [ ] iOS 16 * [ ] iOS 17 * [ ] iOS 18 --- ###### Internal references: [Software Engineering Expectations](https://app.asana.com/0/59792373528535/199064865822552) [Technical Design Template](https://app.asana.com/0/59792373528535/184709971311943) --- DuckDuckGo/TabViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift index 19bb29eeec..031dd5ea55 100644 --- a/DuckDuckGo/TabViewController.swift +++ b/DuckDuckGo/TabViewController.swift @@ -2032,8 +2032,8 @@ extension TabViewController: WKNavigationDelegate { } if isNewTargetBlankRequest(navigationAction: navigationAction) { - delegate?.tab(self, didRequestNewTabForUrl: url, openedByPage: true, inheritingAttribution: adClickAttributionLogic.state) - completion(.cancel) + // This will fallback to native WebView handling through webView(_:createWebViewWith:for:windowFeatures:) + completion(allowPolicy) return }