diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 4b185eebdc..be147b4f12 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1090,6 +1090,8 @@ 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 */; }; + 4B2F565C2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2F565B2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift */; }; + 4B2F565D2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2F565B2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift */; }; 4B379C1527BD91E3008A968E /* QuartzIdleStateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C1427BD91E3008A968E /* QuartzIdleStateProvider.swift */; }; 4B379C1E27BDB7FF008A968E /* DeviceAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C1D27BDB7FF008A968E /* DeviceAuthenticator.swift */; }; 4B379C2227BDBA29008A968E /* LocalAuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C2127BDBA29008A968E /* LocalAuthenticationService.swift */; }; @@ -3393,6 +3395,7 @@ 4B2D06642A132F3A00DE1F49 /* NetworkProtectionAppExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetworkProtectionAppExtension.entitlements; sourceTree = ""; }; 4B2D06692A13318400DE1F49 /* DuckDuckGo VPN App Store.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DuckDuckGo VPN App Store.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 4B2E7D6226FF9D6500D2DB17 /* PrintingUserScript.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrintingUserScript.swift; sourceTree = ""; }; + 4B2F565B2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionSubscriptionEventHandler.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 = ""; }; 4B379C2127BDBA29008A968E /* LocalAuthenticationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAuthenticationService.swift; sourceTree = ""; }; @@ -5213,6 +5216,7 @@ children = ( 4BCF15D52ABB83D70083F6DF /* NetworkProtectionRemoteMessaging */, 7BA7CC4D2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift */, + 4B2F565B2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift */, ); path = DeveloperIDTarget; sourceTree = ""; @@ -10830,6 +10834,7 @@ 4B957B052AC7AE700062CA31 /* FindInPageModel.swift in Sources */, 4B957B062AC7AE700062CA31 /* PseudoFolder.swift in Sources */, 4B957B072AC7AE700062CA31 /* Visit.swift in Sources */, + 4B2F565D2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift in Sources */, 4B957B082AC7AE700062CA31 /* PixelDataStore.swift in Sources */, 4B957B092AC7AE700062CA31 /* WaitlistStorage.swift in Sources */, 4B957B0A2AC7AE700062CA31 /* Pixel.swift in Sources */, @@ -11243,6 +11248,7 @@ 1DFAB51D2A8982A600A0F7F6 /* SetExtension.swift in Sources */, 315AA07028CA5CC800200030 /* YoutubePlayerNavigationHandler.swift in Sources */, 37AFCE9227DB8CAD00471A10 /* PreferencesAboutView.swift in Sources */, + 4B2F565C2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift in Sources */, 9826B0A02747DF3D0092F683 /* ContentBlocking.swift in Sources */, 4B379C2227BDBA29008A968E /* LocalAuthenticationService.swift in Sources */, 37CEFCA92A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift in Sources */, @@ -13044,7 +13050,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 99.0.2; + version = 100.0.0; }; }; AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2a122ea08a..96ffc4f465 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "18043cbc24e5bb79aa1f44e01a367e0bccd2fa6e", - "version" : "99.0.2" + "revision" : "c3a482a4ca22d706207d08a68db8f23f0c262040", + "version" : "100.0.0" } }, { diff --git a/DuckDuckGo/Application/AppDelegate.swift b/DuckDuckGo/Application/AppDelegate.swift index 1d16b16cec..e85d6aaf1d 100644 --- a/DuckDuckGo/Application/AppDelegate.swift +++ b/DuckDuckGo/Application/AppDelegate.swift @@ -78,6 +78,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel private var emailCancellables = Set() let bookmarksManager = LocalBookmarkManager.shared +#if NETWORK_PROTECTION && SUBSCRIPTION + private let networkProtectionSubscriptionEventHandler = NetworkProtectionSubscriptionEventHandler() +#endif + #if DBP && SUBSCRIPTION private let dataBrokerProtectionSubscriptionEventHandler = DataBrokerProtectionSubscriptionEventHandler() #endif @@ -247,6 +251,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel UserDefaultsWrapper.clearRemovedKeys() +#if NETWORK_PROTECTION && SUBSCRIPTION + networkProtectionSubscriptionEventHandler.registerForSubscriptionAccountManagerEvents() +#endif + #if NETWORK_PROTECTION NetworkProtectionAppEvents().applicationDidFinishLaunching() UNUserNotificationCenter.current().delegate = self diff --git a/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift b/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift index 77c27d2e61..f505891891 100644 --- a/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift +++ b/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift @@ -122,7 +122,7 @@ public final class BookmarkStoreMock: BookmarkStore { } var moveObjectUUIDCalled = false - func move(objectUUIDs: [String], toIndex: Int?, withinParentFolder: DuckDuckGo_Privacy_Browser.ParentFolderType, completion: @escaping (Error?) -> Void) { + func move(objectUUIDs: [String], toIndex: Int?, withinParentFolder: ParentFolderType, completion: @escaping (Error?) -> Void) { moveObjectUUIDCalled = true } diff --git a/DuckDuckGo/MainWindow/MainViewController.swift b/DuckDuckGo/MainWindow/MainViewController.swift index f5cfe4a1ea..8d5248bff9 100644 --- a/DuckDuckGo/MainWindow/MainViewController.swift +++ b/DuckDuckGo/MainWindow/MainViewController.swift @@ -21,6 +21,10 @@ import Carbon.HIToolbox import Combine import Common +#if NETWORK_PROTECTION +import NetworkProtection +#endif + final class MainViewController: NSViewController { private let tabBarContainerView = NSView() diff --git a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift index e4b4a7b938..c4b090fa71 100644 --- a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift +++ b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift @@ -356,18 +356,6 @@ final class MoreOptionsMenu: NSMenu { #endif // DBP -#if SUBSCRIPTION - let item1 = NSMenuItem(title: "Placeholder A", action: #selector(openPreferences(_:)), keyEquivalent: "") - .targetting(self) - .withImage(.image(for: .vpnIcon)) - items.append(item1) - - let item2 = NSMenuItem(title: "Placeholder B", action: #selector(openPreferences(_:)), keyEquivalent: "") - .targetting(self) - .withImage(.image(for: .vpnIcon)) - items.append(item2) -#endif - return items } diff --git a/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift b/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift index 66f7b554a1..fb8f9bff1f 100644 --- a/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift +++ b/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift @@ -28,6 +28,7 @@ import NetworkProtectionUI #endif #if SUBSCRIPTION +import Subscription import SubscriptionUI #endif @@ -331,6 +332,16 @@ final class NavigationBarViewController: NSViewController { return } + #if SUBSCRIPTION + let accountManager = AccountManager() + let networkProtectionTokenStorage = NetworkProtectionKeychainTokenStore() + + if accountManager.accessToken != nil && (try? networkProtectionTokenStorage.fetchToken()) == nil { + print("[NetP Subscription] Got access token but not auth token, meaning token exchange failed") + return + } + #endif + // 1. If the user is on the waitlist but hasn't been invited or accepted terms and conditions, show the waitlist screen. // 2. If the user has no waitlist state but has an auth token, show the NetP popover. // 3. If the user has no state of any kind, show the waitlist screen. diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift index 7d8124b432..e9201fa310 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift @@ -70,7 +70,7 @@ extension EventMapping where Event == NetworkProtectionError { .wireGuardDnsResolution, .wireGuardSetNetworkSettings, .startWireGuardBackend, - // Needs Privacy triage for macOS Geoswitching pixels + .failedToRetrieveAuthToken, .failedToFetchLocationList, .failedToParseLocationListResponse: domainEvent = .networkProtectionUnhandledError(function: #function, line: #line, error: event) diff --git a/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionSubscriptionEventHandler.swift b/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionSubscriptionEventHandler.swift new file mode 100644 index 0000000000..7ad69d346b --- /dev/null +++ b/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionSubscriptionEventHandler.swift @@ -0,0 +1,73 @@ +// +// NetworkProtectionSubscriptionEventHandler.swift +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETWORK_PROTECTION && SUBSCRIPTION + +import Foundation +import Subscription +import NetworkProtection + +final class NetworkProtectionSubscriptionEventHandler { + + private let accountManager: AccountManaging + private let networkProtectionRedemptionCoordinator: NetworkProtectionCodeRedeeming + private let networkProtectionTokenStorage: NetworkProtectionTokenStore + private let networkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling + + init(accountManager: AccountManaging = AccountManager(), + networkProtectionRedemptionCoordinator: NetworkProtectionCodeRedeeming = NetworkProtectionCodeRedemptionCoordinator(), + networkProtectionTokenStorage: NetworkProtectionTokenStore = NetworkProtectionKeychainTokenStore(), + networkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling = NetworkProtectionFeatureDisabler()) { + self.accountManager = accountManager + self.networkProtectionRedemptionCoordinator = networkProtectionRedemptionCoordinator + self.networkProtectionTokenStorage = networkProtectionTokenStorage + self.networkProtectionFeatureDisabler = networkProtectionFeatureDisabler + } + + func registerForSubscriptionAccountManagerEvents() { + NotificationCenter.default.addObserver(self, selector: #selector(handleAccountDidSignIn), name: .accountDidSignIn, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(handleAccountDidSignOut), name: .accountDidSignOut, object: nil) + } + + @objc private func handleAccountDidSignIn() { + guard let token = accountManager.accessToken else { + assertionFailure("[NetP Subscription] AccountManager signed in but token could not be retrieved") + return + } + + Task { + do { + try await networkProtectionRedemptionCoordinator.exchange(accessToken: token) + print("[NetP Subscription] Exchanged access token for auth token successfully") + } catch { + print("[NetP Subscription] Failed to exchange access token for auth token: \(error)") + } + } + } + + @objc private func handleAccountDidSignOut() { + print("[NetP Subscription] Deleted NetP auth token after signing out from Privacy Pro") + + Task { + await networkProtectionFeatureDisabler.disable(keepAuthToken: false, uninstallSystemExtension: false) + } + } + +} + +#endif diff --git a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift index 6bc1dfa909..e2bc40319d 100644 --- a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift +++ b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift @@ -116,7 +116,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider { domainEvent = .networkProtectionNoAuthTokenFoundError case .unhandledError(function: let function, line: let line, error: let error): domainEvent = .networkProtectionUnhandledError(function: function, line: line, error: error) - case .failedToFetchLocationList, + case .failedToRetrieveAuthToken, + .failedToFetchLocationList, .failedToParseLocationListResponse: // Needs Privacy triage for macOS Geoswitching pixels return diff --git a/DuckDuckGo/Preferences/View/PreferencesAboutView.swift b/DuckDuckGo/Preferences/View/PreferencesAboutView.swift index d1acf50065..9bf013d095 100644 --- a/DuckDuckGo/Preferences/View/PreferencesAboutView.swift +++ b/DuckDuckGo/Preferences/View/PreferencesAboutView.swift @@ -52,7 +52,7 @@ extension Preferences { Text(UserText.privacySimplified).font(.privacySimplified) Text(UserText.versionLabel(version: model.appVersion.versionNumber, build: model.appVersion.buildNumber)).onTapGesture(count: 12) { -#if NETWORK_PROTECTION +#if NETWORK_PROTECTION && !SUBSCRIPTION model.displayNetPInvite() #endif } diff --git a/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift b/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift index 0db71533d6..ea9284cf51 100644 --- a/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift +++ b/LocalPackages/BuildToolPlugins/Plugins/InputFilesChecker/InputFilesChecker.swift @@ -32,6 +32,7 @@ let nonSandboxedExtraInputFiles: Set = [ .init("NetworkProtectionAppEvents.swift", .source), .init("NetworkProtectionIPCTunnelController.swift", .source), .init("NetworkProtectionNavBarPopoverManager.swift", .source), + .init("NetworkProtectionSubscriptionEventHandler.swift", .source), .init("KeychainType+ClientDefault.swift", .source), .init("DBPHomeViewController.swift", .source), .init("DataBrokerProtectionManager.swift", .source), diff --git a/LocalPackages/DataBrokerProtection/Package.swift b/LocalPackages/DataBrokerProtection/Package.swift index 367711f3cb..4794e9e768 100644 --- a/LocalPackages/DataBrokerProtection/Package.swift +++ b/LocalPackages/DataBrokerProtection/Package.swift @@ -29,7 +29,7 @@ let package = Package( targets: ["DataBrokerProtection"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), .package(path: "../PixelKit"), .package(path: "../SwiftUIExtensions"), .package(path: "../XPCHelper") diff --git a/LocalPackages/LoginItems/Package.swift b/LocalPackages/LoginItems/Package.swift index f9f32c0b06..e937cc86e2 100644 --- a/LocalPackages/LoginItems/Package.swift +++ b/LocalPackages/LoginItems/Package.swift @@ -13,7 +13,7 @@ let package = Package( ), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), ], targets: [ .target( diff --git a/LocalPackages/NetworkProtectionMac/Package.swift b/LocalPackages/NetworkProtectionMac/Package.swift index 661052b917..ae7d1f94b5 100644 --- a/LocalPackages/NetworkProtectionMac/Package.swift +++ b/LocalPackages/NetworkProtectionMac/Package.swift @@ -30,7 +30,7 @@ let package = Package( .library(name: "NetworkProtectionUI", targets: ["NetworkProtectionUI"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), .package(path: "../XPCHelper"), .package(path: "../SwiftUIExtensions") ], diff --git a/LocalPackages/PixelKit/Package.swift b/LocalPackages/PixelKit/Package.swift index f84c9c457f..fc9e1e4e96 100644 --- a/LocalPackages/PixelKit/Package.swift +++ b/LocalPackages/PixelKit/Package.swift @@ -20,7 +20,7 @@ let package = Package( ) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), ], targets: [ .target( diff --git a/LocalPackages/Subscription/Package.swift b/LocalPackages/Subscription/Package.swift index ed2768e73d..c7d45ec7a4 100644 --- a/LocalPackages/Subscription/Package.swift +++ b/LocalPackages/Subscription/Package.swift @@ -12,7 +12,7 @@ let package = Package( targets: ["Subscription"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), ], targets: [ .target( diff --git a/LocalPackages/SwiftUIExtensions/Package.swift b/LocalPackages/SwiftUIExtensions/Package.swift index c15221a974..a669a83fce 100644 --- a/LocalPackages/SwiftUIExtensions/Package.swift +++ b/LocalPackages/SwiftUIExtensions/Package.swift @@ -13,7 +13,7 @@ let package = Package( ), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), ], targets: [ .target( diff --git a/LocalPackages/SyncUI/Package.swift b/LocalPackages/SyncUI/Package.swift index dae7ebfe0d..9f7d02d9a8 100644 --- a/LocalPackages/SyncUI/Package.swift +++ b/LocalPackages/SyncUI/Package.swift @@ -13,7 +13,7 @@ let package = Package( ], dependencies: [ .package(path: "../SwiftUIExtensions"), - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), ], targets: [ .target( diff --git a/LocalPackages/SystemExtensionManager/Package.swift b/LocalPackages/SystemExtensionManager/Package.swift index f4891de858..0678143ab0 100644 --- a/LocalPackages/SystemExtensionManager/Package.swift +++ b/LocalPackages/SystemExtensionManager/Package.swift @@ -16,7 +16,7 @@ let package = Package( ), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), ], targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. diff --git a/LocalPackages/XPCHelper/Package.swift b/LocalPackages/XPCHelper/Package.swift index dcedd7be38..4a76947d8b 100644 --- a/LocalPackages/XPCHelper/Package.swift +++ b/LocalPackages/XPCHelper/Package.swift @@ -30,7 +30,7 @@ let package = Package( .library(name: "XPCHelper", targets: ["XPCHelper"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "99.0.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "100.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/UnitTests/Waitlist/Mocks/MockNetworkProtectionCodeRedeemer.swift b/UnitTests/Waitlist/Mocks/MockNetworkProtectionCodeRedeemer.swift index b9f5b7fb08..629639fd4b 100644 --- a/UnitTests/Waitlist/Mocks/MockNetworkProtectionCodeRedeemer.swift +++ b/UnitTests/Waitlist/Mocks/MockNetworkProtectionCodeRedeemer.swift @@ -27,9 +27,9 @@ final class MockNetworkProtectionCodeRedeemer: NetworkProtectionCodeRedeeming { case error } - var redeemedCode: String? var throwError: Bool = false + var redeemedCode: String? func redeem(_ code: String) async throws { if throwError { throw MockNetworkProtectionCodeRedeemerError.error @@ -38,6 +38,15 @@ final class MockNetworkProtectionCodeRedeemer: NetworkProtectionCodeRedeeming { } } + var redeemedAccessToken: String? + func exchange(accessToken: String) async throws { + if throwError { + throw MockNetworkProtectionCodeRedeemerError.error + } else { + redeemedAccessToken = accessToken + } + } + } #endif