Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.

Subscription oauth v2 #3480

Closed
wants to merge 65 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
cc16889
builds
federicocappelli Oct 16, 2024
8b07ea5
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Oct 16, 2024
79faa6b
auth and first purchase improved
federicocappelli Oct 21, 2024
44e00ee
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Oct 21, 2024
c6c2bef
purchase flow fixed
federicocappelli Oct 22, 2024
c640a91
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Oct 22, 2024
018751a
purchase fixed
federicocappelli Oct 23, 2024
de81314
token fixes
federicocappelli Oct 23, 2024
b4c661e
loggers improved and restore fixed
federicocappelli Oct 24, 2024
d123038
subscription refresh improved
federicocappelli Oct 25, 2024
9d90ccf
v1 to v2 auth migration
federicocappelli Oct 25, 2024
457922c
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Oct 25, 2024
60d4012
lint ad restore commented code
federicocappelli Oct 25, 2024
07e2cc0
review suggestions applied
federicocappelli Oct 29, 2024
bd5bb1b
tests and logs
federicocappelli Oct 30, 2024
e92d0db
vpn fixed
federicocappelli Oct 31, 2024
1406315
debug menu improved
federicocappelli Oct 31, 2024
eebbc48
unit tests and lint
federicocappelli Oct 31, 2024
8ea3254
unit tests and improvements
federicocappelli Nov 1, 2024
c78a9c2
signout as async
federicocappelli Nov 1, 2024
c021b95
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Nov 4, 2024
0f426a1
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Nov 4, 2024
f06370b
lint
federicocappelli Nov 5, 2024
5f69e54
BSK points to branch now
federicocappelli Nov 5, 2024
929e12d
bsk updated
federicocappelli Nov 5, 2024
386fd70
Merge branch 'main' of https://github.com/duckduckgo/iOS into fcappel…
federicocappelli Nov 6, 2024
b018cce
bsk local
federicocappelli Nov 7, 2024
00e55c5
Merge branch 'main' of https://github.com/duckduckgo/iOS into fcappel…
federicocappelli Nov 7, 2024
a955a78
BSK
federicocappelli Nov 7, 2024
b67e5d4
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Nov 7, 2024
47ac372
BSK update
federicocappelli Nov 8, 2024
80be4fe
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Nov 14, 2024
bd51e3f
DI improved
federicocappelli Nov 19, 2024
7327d2d
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Nov 19, 2024
67d5d50
token v1/v2 exchange fixed, token providing improved
federicocappelli Nov 22, 2024
d0c8344
updates after mac integration
federicocappelli Nov 27, 2024
60bad87
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Nov 27, 2024
170ed9e
merge
federicocappelli Nov 27, 2024
32e5de6
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Nov 27, 2024
87455ba
local bsk
federicocappelli Nov 27, 2024
0191b02
project fix
federicocappelli Nov 27, 2024
bd5cb7c
unit tests builds
federicocappelli Nov 28, 2024
f229b65
main merge
federicocappelli Nov 29, 2024
e4fbf00
BSK > branch
federicocappelli Nov 29, 2024
f8eabd5
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Nov 29, 2024
a745b49
packages
federicocappelli Nov 29, 2024
b3482bd
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Dec 2, 2024
464e598
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Dec 2, 2024
ba4cbad
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Dec 12, 2024
edf1bfa
updates from mac and unit tests fixed
federicocappelli Dec 12, 2024
88cd2d9
testing comments fixed
federicocappelli Jan 6, 2025
7b93366
BSK updated
federicocappelli Jan 7, 2025
e4dfc38
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Jan 8, 2025
0053c73
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Jan 9, 2025
62bd2da
BSK updated, some flows updated
federicocappelli Jan 10, 2025
b72a122
subscription manager load initial data improved, pixels added
federicocappelli Jan 12, 2025
4e887d4
BSK update with subscription cache bug fix
federicocappelli Jan 13, 2025
6f3a7ad
settings and init improvements
federicocappelli Jan 16, 2025
7a0e848
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Jan 16, 2025
ef81d09
Subscription stuff renamed
federicocappelli Jan 20, 2025
b4196db
BSK updated
federicocappelli Jan 20, 2025
bc33fcf
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Jan 20, 2025
5660c74
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Jan 20, 2025
5f574f3
Merge branch 'main' into fcappelli/subscription_oauth_api_v2
federicocappelli Jan 21, 2025
d045cce
pr suggestions
federicocappelli Jan 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
lint ad restore commented code
  • Loading branch information
federicocappelli committed Oct 25, 2024
commit 60d401232ac43a642d1958a59c32bc7b67ebe9f4
4 changes: 0 additions & 4 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
1E4F4A5A297193DE00625985 /* MainViewController+CookiesManaged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4F4A59297193DE00625985 /* MainViewController+CookiesManaged.swift */; };
1E4FAA6427D8DFB900ADC5B3 /* OngoingDownloadRowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4FAA6327D8DFB900ADC5B3 /* OngoingDownloadRowViewModel.swift */; };
1E4FAA6627D8DFC800ADC5B3 /* CompleteDownloadRowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4FAA6527D8DFC800ADC5B3 /* CompleteDownloadRowViewModel.swift */; };
1E53508F2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E53508E2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift */; };
1E5918472CA422A7008ED2B3 /* Navigation in Frameworks */ = {isa = PBXBuildFile; productRef = 1E5918462CA422A7008ED2B3 /* Navigation */; };
1E60989B290009C700A508F9 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 1E7060BD28F88EE200E4CCDB /* Common */; };
1E60989D290011E600A508F9 /* ContentBlocking in Frameworks */ = {isa = PBXBuildFile; productRef = 1E60989C290011E600A508F9 /* ContentBlocking */; };
Expand Down Expand Up @@ -1377,7 +1376,6 @@
1E4F4A59297193DE00625985 /* MainViewController+CookiesManaged.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainViewController+CookiesManaged.swift"; sourceTree = "<group>"; };
1E4FAA6327D8DFB900ADC5B3 /* OngoingDownloadRowViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OngoingDownloadRowViewModel.swift; sourceTree = "<group>"; };
1E4FAA6527D8DFC800ADC5B3 /* CompleteDownloadRowViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompleteDownloadRowViewModel.swift; sourceTree = "<group>"; };
1E53508E2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift"; sourceTree = "<group>"; };
1E61BC2927074BED00B2854D /* TextSizeUserScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextSizeUserScript.swift; sourceTree = "<group>"; };
1E6A4D682984208800A371D3 /* LocaleExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocaleExtension.swift; sourceTree = "<group>"; };
1E7A71162934EB6400B7EA19 /* OmniBarNotificationAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OmniBarNotificationAnimator.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5331,7 +5329,6 @@
BDE91CD42C6292BF0005CB74 /* Feedback */,
F1FDC92F2BF4E0B3006B1435 /* SubscriptionEnvironment+Default.swift */,
D60170BB2BA32DD6001911B5 /* Subscription.swift */,
1E53508E2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift */,
D6D95CE42B6DA3F200960317 /* AsyncHeadlessWebview */,
D664C7932B289AA000CBFA76 /* ViewModel */,
D664C7AC2B289AA000CBFA76 /* Views */,
Expand Down Expand Up @@ -7754,7 +7751,6 @@
9820EAF522613CD30089094D /* WebProgressWorker.swift in Sources */,
1EEF387D285B1A1100383393 /* TrackerImageCache.swift in Sources */,
3151F0EC27357FEE00226F58 /* VoiceSearchFeedbackViewModel.swift in Sources */,
1E53508F2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift in Sources */,
1DDF402D2BA09482006850D9 /* SettingsMainSettingsView.swift in Sources */,
85010502292FB1000033978F /* FireproofFaviconUpdater.swift in Sources */,
F1C4A70E1E57725800A6CA1B /* OmniBar.swift in Sources */,
Expand Down
11 changes: 5 additions & 6 deletions DuckDuckGo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -558,12 +558,11 @@ import os.log
}
}

// TODO: restore but limit the number of parallel subscription fetches
// AppDependencyProvider.shared.subscriptionManager.refreshCachedSubscription { isSubscriptionActive in
// if isSubscriptionActive {
// DailyPixel.fire(pixel: .privacyProSubscriptionActive)
// }
// }
AppDependencyProvider.shared.subscriptionManager.refreshCachedSubscription { isSubscriptionActive in
if isSubscriptionActive {
DailyPixel.fire(pixel: .privacyProSubscriptionActive)
}
}

let importPasswordsStatusHandler = ImportPasswordsStatusHandler(syncService: syncService)
importPasswordsStatusHandler.checkSyncSuccessStatus()
Expand Down
11 changes: 0 additions & 11 deletions DuckDuckGo/AppDependencyProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,6 @@ final class AppDependencyProvider: DependencyProvider {
let subscriptionEnvironment = DefaultSubscriptionManager.getSavedOrDefaultEnvironment(userDefaults: subscriptionUserDefaults)
vpnSettings.alignTo(subscriptionEnvironment: subscriptionEnvironment)

// let entitlementsCache = UserDefaultsCache<[Entitlement]>(userDefaults: subscriptionUserDefaults,
// key: UserDefaultsCacheKey.subscriptionEntitlements,
// settings: UserDefaultsCacheSettings(defaultExpirationInterval: .minutes(20)))
// let accessTokenStorage = SubscriptionTokenKeychainStorage(keychainType: .dataProtection(.named(subscriptionAppGroup)))
// let subscriptionService = DefaultSubscriptionEndpointService(currentServiceEnvironment: subscriptionEnvironment.serviceEnvironment)
// let authService = DefaultAuthEndpointService(currentServiceEnvironment: subscriptionEnvironment.serviceEnvironment)
// let accountManager = DefaultAccountManager(accessTokenStorage: accessTokenStorage,
// entitlementsCache: entitlementsCache,
// subscriptionEndpointService: subscriptionService,
// authEndpointService: authService)

let configuration = URLSessionConfiguration.default
configuration.httpCookieStorage = nil
configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,8 @@ import Networking

// struct NetworkProtectionVisibilityForTunnelProvider: NetworkProtectionFeatureVisibility {
//
// private let oAuthClient: any OAuthClient
//
// init(oAuthClient: any OAuthClient) {
// self.oAuthClient = oAuthClient
// }
//
// func isPrivacyProLaunched() -> Bool {
// let tokensContainer = oAuthClient.getStoredTokens()
// return tokensContainer?.accessToken != nil
// return true
// }
//
// func shouldMonitorEntitlement() -> Bool {
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/RemoteMessagingConfigMatcherProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ final class RemoteMessagingConfigMatcherProvider: RemoteMessagingConfigMatcherPr

let surveyActionMapper: DefaultRemoteMessagingSurveyURLBuilder

if let subscription = try? await subscriptionManager.currentSubscription(refresh: false) { // TODO: mmmm, review errors handling
if let subscription = try? await subscriptionManager.currentSubscription(refresh: false) {
privacyProDaysSinceSubscribed = Calendar.current.numberOfDaysBetween(subscription.startedAt, and: Date()) ?? -1
privacyProDaysUntilExpiry = Calendar.current.numberOfDaysBetween(Date(), and: subscription.expiresOrRenewsAt) ?? -1
privacyProPurchasePlatform = subscription.platform.rawValue
Expand Down
10 changes: 0 additions & 10 deletions DuckDuckGo/SettingsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -723,18 +723,8 @@ extension SettingsViewModel {
state.subscription.platform = subscription.platform
state.subscription.hasActiveSubscription = subscription.isActive

// TODO: check the logic here
// Check entitlements and update state
state.subscription.entitlements = subscriptionManager.entitlements

/*var currentEntitlements: [Entitlement.ProductName] = []
let entitlementsToCheck: [Entitlement.ProductName] = [.networkProtection, .dataBrokerProtection, .identityTheftRestoration]
for entitlement in entitlementsToCheck {
if case .success(true) = await subscriptionManager.accountManager.hasEntitlement(forProductName: entitlement) {
currentEntitlements.append(entitlement)
}
}
self.state.subscription.entitlements = currentEntitlements*/
} catch SubscriptionEndpointServiceError.noData {
// Auth successful but no Subscription is available
Logger.subscription.log("Subscription not present")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider {
private static var vpnLogger = VPNLogger()
private static let persistentPixel: PersistentPixelFiring = PersistentPixel()
private var cancellables = Set<AnyCancellable>()
// private let accountManager: AccountManager
private let subscriptionManager: any SubscriptionManager

private let configurationStore = ConfigurationStore()
private let configurationManager: ConfigurationManager
Expand Down Expand Up @@ -440,32 +440,50 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider {
}

// MARK: - Configure Subscription
// let entitlementsCache = UserDefaultsCache<[Entitlement]>(userDefaults: UserDefaults.standard,
// key: UserDefaultsCacheKey.subscriptionEntitlements,
// settings: UserDefaultsCacheSettings(defaultExpirationInterval: .minutes(20)))

let subscriptionAppGroup = Bundle.main.appGroup(bundle: .subs)
// let accessTokenStorage = SubscriptionTokenKeychainStorage(keychainType: .dataProtection(.named(subscriptionAppGroup)))
// let subscriptionService = DefaultSubscriptionEndpointService(currentServiceEnvironment: subscriptionEnvironment.serviceEnvironment)
// let authService = DefaultAuthEndpointService(currentServiceEnvironment: subscriptionEnvironment.serviceEnvironment)
// let accountManager = DefaultAccountManager(accessTokenStorage: accessTokenStorage,
// entitlementsCache: entitlementsCache,
// subscriptionEndpointService: subscriptionService,
// authEndpointService: authService)
// self.accountManager = accountManager

// let featureVisibility = NetworkProtectionVisibilityForTunnelProvider(oAuthClient: <#T##any OAuthClient#>)
let configuration = URLSessionConfiguration.default
configuration.httpCookieStorage = nil
configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
let urlSession = URLSession(configuration: configuration,
delegate: SessionDelegate(),
delegateQueue: nil)
let apiService = DefaultAPIService(urlSession: urlSession)
let authEnvironment: OAuthEnvironment = subscriptionEnvironment.serviceEnvironment == .production ? .production : .staging

let authService = DefaultOAuthService(baseURL: authEnvironment.url, apiService: apiService)
let keychainManager = SubscriptionKeychainManager()
let legacyAccountStorage = AccountKeychainStorage()
let authClient = DefaultOAuthClient(tokensStorage: keychainManager,
legacyTokenStorage: legacyAccountStorage,
authService: authService)

apiService.authorizationRefresherCallback = { _ in
guard let tokensContainer = keychainManager.tokensContainer else {
throw OAuthClientError.internalError("Missing refresh token")
}

if tokensContainer.decodedAccessToken.isExpired() {
Logger.OAuth.debug("Refreshing tokens")
let tokens = try await authClient.refreshTokens()
return tokens.accessToken
} else {
Logger.general.debug("Trying to refresh valid token, using the old one")
return tokensContainer.accessToken
}
}
let storePurchaseManager = DefaultStorePurchaseManager()
let subscriptionEndpointService = DefaultSubscriptionEndpointService(apiService: apiService,
baseURL: subscriptionEnvironment.serviceEnvironment.url)
let subscriptionManager = DefaultSubscriptionManager(storePurchaseManager: storePurchaseManager,
oAuthClient: authClient,
subscriptionEndpointService: subscriptionEndpointService,
subscriptionEnvironment: subscriptionEnvironment)
self.subscriptionManager = subscriptionManager
let accessTokenProvider: () -> String? = {
// if featureVisibility.shouldMonitorEntitlement() {
return {
// accountManager.accessToken
"" // TODO: :(
}
// }
return { nil }
return {
authClient.currentTokensContainer?.accessToken
}
}()
let tokenStore = NetworkProtectionKeychainTokenStore(accessTokenProvider: accessTokenProvider)

let errorStore = NetworkProtectionTunnelErrorStore()
let notificationsPresenter = NetworkProtectionUNNotificationPresenter()

Expand All @@ -475,6 +493,7 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider {
wrappee: notificationsPresenter
)
notificationsPresenter.requestAuthorization()

super.init(notificationsPresenter: notificationsPresenterDecorator,
tunnelHealthStore: NetworkProtectionTunnelHealthStore(),
controllerErrorStore: errorStore,
Expand All @@ -486,10 +505,12 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider {
providerEvents: Self.packetTunnelProviderEvents,
settings: settings,
defaults: .networkProtectionGroupDefaults,
entitlementCheck: { return await Self.entitlementCheck() }
entitlementCheck: {
let hasEntitlement = subscriptionManager.entitlements.contains(.networkProtection)
return .success(hasEntitlement)
}
)

// accountManager.delegate = self
startMonitoringMemoryPressureEvents()
observeServerChanges()
APIRequest.Headers.setUserAgent(DefaultUserAgentManager.duckDuckGoUserAgent)
Expand Down Expand Up @@ -537,19 +558,9 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider {
WidgetCenter.shared.reloadTimelines(ofKind: "VPNStatusWidget")
}

private static func entitlementCheck() async -> Result<Bool, Error> {
return .success(true) // TODO: WTF?
// guard NetworkProtectionVisibilityForTunnelProvider(accountManager: accountManager).shouldMonitorEntitlement() else {
// return .success(true)
// }
//
// let result = await accountManager.hasEntitlement(forProductName: .networkProtection)
// switch result {
// case .success(let hasEntitlement):
// return .success(hasEntitlement)
// case .failure(let error):
// return .failure(error)
// }
private func entitlementCheck() async -> Result<Bool, Error> {
let hasEntitlement = subscriptionManager.entitlements.contains(.networkProtection)
return .success(hasEntitlement)
}
}

Expand Down