Skip to content

Commit

Permalink
Remove VPN waitlist code (#2795)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/414235014887631/1207178910368620/f

macOS: duckduckgo/macos-browser#2776
BSK: duckduckgo/BrowserServicesKit#801

Description

Let's remove the VPN waitlist code from iOS.
  • Loading branch information
diegoreymendez authored May 24, 2024
1 parent 347c408 commit 47f3cc8
Show file tree
Hide file tree
Showing 37 changed files with 61 additions and 1,919 deletions.
68 changes: 8 additions & 60 deletions DuckDuckGo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/DuckDuckGo/BrowserServicesKit",
"state" : {
"revision" : "610a58a77fefe82f8541d4a7f998ef2a4609a068",
"version" : "147.0.0"
"revision" : "7c235d29fc446436734612e81dd486b7c52aa577",
"version" : "148.0.0"
}
},
{
Expand Down
75 changes: 0 additions & 75 deletions DuckDuckGo/AppDelegate+Waitlists.swift

This file was deleted.

27 changes: 1 addition & 26 deletions DuckDuckGo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,6 @@ import WebKit
AppDependencyProvider.shared.networkProtectionAccessController.refreshNetworkProtectionAccess()
#endif

if AppDependencyProvider.shared.vpnFeatureVisibility.shouldKeepVPNAccessViaWaitlist() {
clearDebugWaitlistState()
}

AppDependencyProvider.shared.toggleProtectionsCounter.sendEventsIfNeeded()

AppDependencyProvider.shared.userBehaviorMonitor.handleAction(.reopenApp)
Expand Down Expand Up @@ -457,7 +453,6 @@ import WebKit
}
}

// swiftlint:disable:next function_body_length
func applicationDidBecomeActive(_ application: UIApplication) {
guard !testing else { return }

Expand Down Expand Up @@ -502,7 +497,6 @@ import WebKit
}
}

checkWaitlists()
syncService.scheduler.notifyAppLifecycleEvent()
fireFailedCompilationsPixelIfNeeded()

Expand All @@ -529,19 +523,11 @@ import WebKit
}

private func stopTunnelAndShowThankYouMessagingIfNeeded() {

if accountManager.isUserAuthenticated {
tunnelDefaults.vpnEarlyAccessOverAlertAlreadyShown = true
return
}

if AppDependencyProvider.shared.vpnFeatureVisibility.shouldShowThankYouMessaging()
&& !tunnelDefaults.vpnEarlyAccessOverAlertAlreadyShown {
Task {
await self.stopAndRemoveVPN(with: "thank-you-dialog")
}
} else if AppDependencyProvider.shared.vpnFeatureVisibility.isPrivacyProLaunched()
&& !accountManager.isUserAuthenticated {
if AppDependencyProvider.shared.vpnFeatureVisibility.isPrivacyProLaunched() && !accountManager.isUserAuthenticated {
Task {
await self.stopAndRemoveVPN(with: "subscription-check")
}
Expand Down Expand Up @@ -1014,24 +1000,13 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
if NetworkProtectionNotificationIdentifier(rawValue: identifier) != nil {
presentNetworkProtectionStatusSettingsModal()
}

if AppDependencyProvider.shared.vpnFeatureVisibility.shouldKeepVPNAccessViaWaitlist(), identifier == VPNWaitlist.notificationIdentifier {
presentNetworkProtectionWaitlistModal()
}
#endif
}

completionHandler()
}

#if NETWORK_PROTECTION
private func presentNetworkProtectionWaitlistModal() {
if #available(iOS 15, *) {
let networkProtectionRoot = VPNWaitlistViewController(nibName: nil, bundle: nil)
presentSettings(with: networkProtectionRoot)
}
}

func presentNetworkProtectionStatusSettingsModal() {
Task {
if case .success(let hasEntitlements) = await accountManager.hasEntitlement(for: .networkProtection),
Expand Down
8 changes: 2 additions & 6 deletions DuckDuckGo/AppDependencyProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,9 @@ class AppDependencyProvider: DependencyProvider {
tokenStore: networkProtectionKeychainTokenStore)
networkProtectionAccessController = NetworkProtectionAccessController(featureFlagger: featureFlagger,
internalUserDecider: internalUserDecider,
accountManager: subscriptionManager.accountManager,
tokenStore: networkProtectionKeychainTokenStore,
networkProtectionTunnelController: networkProtectionTunnelController)
vpnFeatureVisibility = DefaultNetworkProtectionVisibility(
networkProtectionTokenStore: networkProtectionKeychainTokenStore,
networkProtectionAccessManager: networkProtectionAccessController,
featureFlagger: featureFlagger,
accountManager: accountManager)
vpnFeatureVisibility = DefaultNetworkProtectionVisibility(userDefaults: .networkProtectionGroupDefaults,
accountManager: accountManager)
}
}
46 changes: 2 additions & 44 deletions DuckDuckGo/DefaultNetworkProtectionVisibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,10 @@ import Core
import Subscription

struct DefaultNetworkProtectionVisibility: NetworkProtectionFeatureVisibility {
private let privacyConfigurationManager: PrivacyConfigurationManaging
private let networkProtectionTokenStore: NetworkProtectionTokenStore
private let networkProtectionAccessManager: NetworkProtectionAccess
private let featureFlagger: FeatureFlagger
private let userDefaults: UserDefaults
private let accountManager: AccountManaging

init(privacyConfigurationManager: PrivacyConfigurationManaging = ContentBlocking.shared.privacyConfigurationManager,
networkProtectionTokenStore: NetworkProtectionTokenStore,
networkProtectionAccessManager: NetworkProtectionAccess,
featureFlagger: FeatureFlagger,
userDefaults: UserDefaults = .networkProtectionGroupDefaults,
accountManager: AccountManaging) {

self.privacyConfigurationManager = privacyConfigurationManager
self.networkProtectionTokenStore = networkProtectionTokenStore
self.networkProtectionAccessManager = networkProtectionAccessManager
self.featureFlagger = featureFlagger
init(userDefaults: UserDefaults, accountManager: AccountManaging) {
self.userDefaults = userDefaults
self.accountManager = accountManager
}
Expand All @@ -56,26 +42,6 @@ struct DefaultNetworkProtectionVisibility: NetworkProtectionFeatureVisibility {
return nil
}

func isWaitlistBetaActive() -> Bool {
privacyConfigurationManager.privacyConfig.isSubfeatureEnabled(NetworkProtectionSubfeature.waitlistBetaActive)
}

func isWaitlistUser() -> Bool {
let hasLegacyAuthToken = {
guard let authToken = try? networkProtectionTokenStore.fetchToken(),
!authToken.hasPrefix(NetworkProtectionKeychainTokenStore.authTokenPrefix) else {
return false
}
return true
}()
let hasBeenInvited = {
let vpnAccessType = networkProtectionAccessManager.networkProtectionAccessType()
return vpnAccessType == .waitlistInvited || vpnAccessType == .inviteCodeInvited
}()

return hasLegacyAuthToken || hasBeenInvited
}

func isPrivacyProLaunched() -> Bool {
if let subscriptionOverrideEnabled = userDefaults.subscriptionOverrideEnabled {
#if ALPHA || DEBUG
Expand All @@ -92,19 +58,11 @@ struct DefaultNetworkProtectionVisibility: NetworkProtectionFeatureVisibility {
isPrivacyProLaunched()
}

func shouldShowThankYouMessaging() -> Bool {
isPrivacyProLaunched() && isWaitlistUser()
}

func shouldKeepVPNAccessViaWaitlist() -> Bool {
!isPrivacyProLaunched() && isWaitlistBetaActive() && isWaitlistUser()
}

func shouldShowVPNShortcut() -> Bool {
if isPrivacyProLaunched() {
return accountManager.isUserAuthenticated
} else {
return shouldKeepVPNAccessViaWaitlist()
return false
}
}
}
Expand Down
5 changes: 0 additions & 5 deletions DuckDuckGo/Feedback/VPNMetadataCollector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ struct VPNMetadata: Encodable {
// swiftlint:enable nesting

let enableSource: Source
let betaParticipant: Bool
let hasToken: Bool
let subscriptionActive: Bool
}
Expand Down Expand Up @@ -265,7 +264,6 @@ final class DefaultVPNMetadataCollector: VPNMetadataCollector {
}

func collectPrivacyProInfo() -> VPNMetadata.PrivacyProInfo {
let accessType = accessManager.networkProtectionAccessType()
var hasToken: Bool {
guard let token = try? tokenStore.fetchToken(),
!token.hasPrefix(NetworkProtectionKeychainTokenStore.authTokenPrefix) else {
Expand All @@ -276,7 +274,6 @@ final class DefaultVPNMetadataCollector: VPNMetadataCollector {

return .init(
enableSource: .init(from: accessManager.networkProtectionAccessType()),
betaParticipant: accessType == .waitlistInvited,
hasToken: hasToken,
subscriptionActive: AppDependencyProvider.shared.subscriptionManager.accountManager.isUserAuthenticated
)
Expand All @@ -288,8 +285,6 @@ extension VPNMetadata.PrivacyProInfo.Source {
switch accessType {
case .inviteCodeInvited:
self = .internal
case .waitlistInvited:
self = .waitlist
default:
self = .other
}
Expand Down
1 change: 0 additions & 1 deletion DuckDuckGo/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1469,7 +1469,6 @@ class MainViewController: UIViewController {
@objc
private func onNetworkProtectionAccountSignIn(_ notification: Notification) {
tunnelDefaults.resetEntitlementMessaging()
tunnelDefaults.vpnEarlyAccessOverAlertAlreadyShown = true
os_log("[NetP Subscription] Reset expired entitlement messaging", log: .networkProtection, type: .info)
}

Expand Down
45 changes: 4 additions & 41 deletions DuckDuckGo/NetworkProtectionAccessController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,6 @@ enum NetworkProtectionAccessType {
/// Used if the user does not have waitlist feature flag access
case none

/// Used if the user has waitlist feature flag access, but has not joined the waitlist
case waitlistAvailable

/// Used if the user has waitlist feature flag access, and has joined the waitlist
case waitlistJoined

/// Used if the user has been invited via the waitlist, but needs to accept the Privacy Policy and Terms of Service
case waitlistInvitedPendingTermsAcceptance

/// Used if the user has been invited via the waitlist and has accepted the Privacy Policy and Terms of Service
case waitlistInvited

/// Used if the user has been invited to test Network Protection directly
case inviteCodeInvited
}
Expand All @@ -54,12 +42,10 @@ protocol NetworkProtectionAccess {
struct NetworkProtectionAccessController: NetworkProtectionAccess {

private let networkProtectionActivation: NetworkProtectionFeatureActivation
private let networkProtectionWaitlistStorage: WaitlistStorage
private let networkProtectionTermsAndConditionsStore: NetworkProtectionTermsAndConditionsStore
private let featureFlagger: FeatureFlagger
private let internalUserDecider: InternalUserDecider
private let networkProtectionKeychainTokenStore: NetworkProtectionKeychainTokenStore
private let accountManager: AccountManaging
private let networkProtectionTunnelController: NetworkProtectionTunnelController

private var isUserLocaleAllowed: Bool {
Expand All @@ -74,18 +60,14 @@ struct NetworkProtectionAccessController: NetworkProtectionAccess {
return (regionCode ?? "US") == "US"
}

init(networkProtectionWaitlistStorage: WaitlistStorage = WaitlistKeychainStore(waitlistIdentifier: VPNWaitlist.identifier),
networkProtectionTermsAndConditionsStore: NetworkProtectionTermsAndConditionsStore = NetworkProtectionTermsAndConditionsUserDefaultsStore(),
featureFlagger: FeatureFlagger,
internalUserDecider: InternalUserDecider,
accountManager: AccountManaging,
init(networkProtectionTermsAndConditionsStore: NetworkProtectionTermsAndConditionsStore = NetworkProtectionTermsAndConditionsUserDefaultsStore(),
featureFlagger: FeatureFlagger = AppDependencyProvider.shared.featureFlagger,
internalUserDecider: InternalUserDecider = AppDependencyProvider.shared.internalUserDecider,
tokenStore: NetworkProtectionKeychainTokenStore,
networkProtectionTunnelController: NetworkProtectionTunnelController
) {
self.accountManager = accountManager
self.networkProtectionActivation = tokenStore
self.networkProtectionKeychainTokenStore = tokenStore
self.networkProtectionWaitlistStorage = networkProtectionWaitlistStorage
self.networkProtectionTermsAndConditionsStore = networkProtectionTermsAndConditionsStore
self.featureFlagger = featureFlagger
self.internalUserDecider = internalUserDecider
Expand All @@ -99,7 +81,7 @@ struct NetworkProtectionAccessController: NetworkProtectionAccess {
}

// Check for users who have activated the VPN via an invite code:
if networkProtectionActivation.isFeatureActivated && !networkProtectionWaitlistStorage.isInvited {
if networkProtectionActivation.isFeatureActivated {
return .inviteCodeInvited
}

Expand All @@ -109,25 +91,6 @@ struct NetworkProtectionAccessController: NetworkProtectionAccess {
return .none
}

// Check if a waitlist user has NetP access and whether they need to accept T&C.
if networkProtectionActivation.isFeatureActivated && networkProtectionWaitlistStorage.isInvited {
if networkProtectionTermsAndConditionsStore.networkProtectionWaitlistTermsAndConditionsAccepted {
return .waitlistInvited
} else {
return .waitlistInvitedPendingTermsAcceptance
}
}

// Check if the user has waitlist access at all and whether they've already joined.
let hasWaitlistAccess = featureFlagger.isFeatureOn(.networkProtectionWaitlistAccess)
if hasWaitlistAccess {
if networkProtectionWaitlistStorage.isOnWaitlist {
return .waitlistJoined
} else {
return .waitlistAvailable
}
}

return .none
}

Expand Down
Loading

0 comments on commit 47f3cc8

Please sign in to comment.