Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove VPN waitlist code #2795

Merged
merged 22 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may be able to get rid of this whole class, but we can do this in a followup.


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
quanganhdo marked this conversation as resolved.
Show resolved Hide resolved
}

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