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 5 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
66 changes: 8 additions & 58 deletions DuckDuckGo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,6 @@
"version" : "3.0.0"
}
},
{
"identity" : "browserserviceskit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/DuckDuckGo/BrowserServicesKit",
"state" : {
"revision" : "b1501e60d245625d4a5d42a61b329364134f0879",
"version" : "140.0.1"
}
},
{
"identity" : "content-scope-scripts",
"kind" : "remoteSourceControl",
Expand Down
75 changes: 0 additions & 75 deletions DuckDuckGo/AppDelegate+Waitlists.swift

This file was deleted.

23 changes: 1 addition & 22 deletions DuckDuckGo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

setupSubscriptionsEnvironment()

if vpnFeatureVisibility.shouldKeepVPNAccessViaWaitlist() {
clearDebugWaitlistState()
}

AppDependencyProvider.shared.toggleProtectionsCounter.sendEventsIfNeeded()
AppDependencyProvider.shared.userBehaviorMonitor.handleAction(.reopenApp)

Expand Down Expand Up @@ -453,7 +449,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
}

checkWaitlists()
syncService.scheduler.notifyAppLifecycleEvent()
fireFailedCompilationsPixelIfNeeded()
refreshShortcuts()
Expand All @@ -475,15 +470,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

private func stopTunnelAndShowThankYouMessagingIfNeeded() {
if AccountManager().isUserAuthenticated {
tunnelDefaults.vpnEarlyAccessOverAlertAlreadyShown = true
return
}

if vpnFeatureVisibility.shouldShowThankYouMessaging() && !tunnelDefaults.vpnEarlyAccessOverAlertAlreadyShown {
Task {
await self.stopAndRemoveVPN(with: "thank-you-dialog")
}
} else if vpnFeatureVisibility.isPrivacyProLaunched() && !AccountManager().isUserAuthenticated {
if vpnFeatureVisibility.isPrivacyProLaunched() && !AccountManager().isUserAuthenticated {
Task {
await self.stopAndRemoveVPN(with: "subscription-check")
}
Expand Down Expand Up @@ -934,24 +924,13 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
}
}
}

if 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() {
if #available(iOS 15, *) {
let networkProtectionRoot = NetworkProtectionRootViewController()
Expand Down
24 changes: 0 additions & 24 deletions DuckDuckGo/DefaultNetworkProtectionVisibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,6 @@ struct DefaultNetworkProtectionVisibility: NetworkProtectionFeatureVisibility {
DefaultNetworkProtectionVisibility(networkProtectionTokenStore: nil, networkProtectionAccessManager: nil)
}

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

func isWaitlistUser() -> Bool {
guard let networkProtectionTokenStore, let networkProtectionAccessManager else {
preconditionFailure("networkProtectionTokenStore and networkProtectionAccessManager must be non-nil")
}

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 Down
5 changes: 0 additions & 5 deletions DuckDuckGo/Feedback/VPNMetadataCollector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ struct VPNMetadata: Encodable {
// swiftlint:enable nesting

let enableSource: Source
let betaParticipant: Bool
let hasToken: Bool
let subscriptionActive: Bool
}
Expand Down Expand Up @@ -289,7 +288,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 @@ -300,7 +298,6 @@ final class DefaultVPNMetadataCollector: VPNMetadataCollector {

return .init(
enableSource: .init(from: accessManager.networkProtectionAccessType()),
betaParticipant: accessType == .waitlistInvited,
hasToken: hasToken,
subscriptionActive: AccountManager(subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs)).isUserAuthenticated
)
Expand All @@ -312,8 +309,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 @@ -1430,7 +1430,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
36 changes: 1 addition & 35 deletions DuckDuckGo/NetworkProtectionAccessController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,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 @@ -53,7 +41,6 @@ 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
Expand All @@ -72,13 +59,11 @@ struct NetworkProtectionAccessController: NetworkProtectionAccess {

init(
networkProtectionActivation: NetworkProtectionFeatureActivation = NetworkProtectionKeychainTokenStore(),
networkProtectionWaitlistStorage: WaitlistStorage = WaitlistKeychainStore(waitlistIdentifier: VPNWaitlist.identifier),
networkProtectionTermsAndConditionsStore: NetworkProtectionTermsAndConditionsStore = NetworkProtectionTermsAndConditionsUserDefaultsStore(),
featureFlagger: FeatureFlagger = AppDependencyProvider.shared.featureFlagger,
internalUserDecider: InternalUserDecider = AppDependencyProvider.shared.internalUserDecider
) {
self.networkProtectionActivation = networkProtectionActivation
self.networkProtectionWaitlistStorage = networkProtectionWaitlistStorage
self.networkProtectionTermsAndConditionsStore = networkProtectionTermsAndConditionsStore
self.featureFlagger = featureFlagger
self.internalUserDecider = internalUserDecider
Expand All @@ -91,7 +76,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 @@ -101,25 +86,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
9 changes: 0 additions & 9 deletions DuckDuckGo/NetworkProtectionDebugViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ final class NetworkProtectionDebugViewController: UITableViewController {
case shutDown
case showEntitlementMessaging
case resetEntitlementMessaging
case resetThankYouMessaging
}

enum NetworkPathRows: Int, CaseIterable {
Expand Down Expand Up @@ -389,8 +388,6 @@ final class NetworkProtectionDebugViewController: UITableViewController {
cell.textLabel?.text = "Show Entitlement Messaging"
case .resetEntitlementMessaging:
cell.textLabel?.text = "Reset Entitlement Messaging"
case .resetThankYouMessaging:
cell.textLabel?.text = "Reset Thank You Messaging"
case .none:
break
}
Expand All @@ -410,8 +407,6 @@ final class NetworkProtectionDebugViewController: UITableViewController {
UserDefaults.networkProtectionGroupDefaults.enableEntitlementMessaging()
case .resetEntitlementMessaging:
UserDefaults.networkProtectionGroupDefaults.resetEntitlementMessaging()
case .resetThankYouMessaging:
UserDefaults.networkProtectionGroupDefaults.resetThankYouMessaging()
case .none:
break
}
Expand Down Expand Up @@ -649,11 +644,7 @@ final class NetworkProtectionDebugViewController: UITableViewController {
Endpoint: \(VPNSettings(defaults: .networkProtectionGroupDefaults).selectedEnvironment.endpointURL.absoluteString)

isPrivacyProLaunched: \(vpnVisibility.isPrivacyProLaunched() ? "YES" : "NO")
isWaitlistBetaActive: \(vpnVisibility.isWaitlistBetaActive() ? "YES" : "NO")
isWaitlistUser: \(vpnVisibility.isWaitlistUser() ? "YES" : "NO")

shouldShowThankYouMessaging: \(vpnVisibility.shouldShowThankYouMessaging() ? "YES" : "NO")
shouldKeepVPNAccessViaWaitlist: \(vpnVisibility.shouldKeepVPNAccessViaWaitlist() ? "YES" : "NO")
shouldMonitorEntitlement: \(vpnVisibility.shouldMonitorEntitlement() ? "YES" : "NO")
shouldShowVPNShortcut: \(vpnVisibility.shouldShowVPNShortcut() ? "YES" : "NO")
"""
Expand Down
27 changes: 5 additions & 22 deletions DuckDuckGo/NetworkProtectionFeatureVisibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,8 @@ import Foundation
import Subscription

public protocol NetworkProtectionFeatureVisibility {
func isWaitlistBetaActive() -> Bool
func isWaitlistUser() -> Bool
func isPrivacyProLaunched() -> Bool

/// Whether to show the thank-you messaging for current waitlist users
func shouldShowThankYouMessaging() -> Bool

/// Whether to let the user continues to use the VPN via the waitlist
/// This should only before 100% roll out
func shouldKeepVPNAccessViaWaitlist() -> Bool

/// Whether to enforce entitlement check and show entitlement-related messaging
/// This should always happen after 100% roll out
/// N.B. Backend will independently check for valid entitlement regardless of this value
Expand All @@ -42,20 +33,12 @@ public protocol NetworkProtectionFeatureVisibility {
}

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

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

func shouldShowVPNShortcut() -> Bool {
if isPrivacyProLaunched() {
let accountManager = AccountManager()
return accountManager.isUserAuthenticated
} else {
return shouldKeepVPNAccessViaWaitlist()
guard isPrivacyProLaunched() else {
return false
}

let accountManager = AccountManager()
return accountManager.isUserAuthenticated
}
}