Skip to content

Commit

Permalink
Enable Stripe purchase flow for internal users in non-App Store target (
Browse files Browse the repository at this point in the history
#2228)

Task/Issue URL:
https://app.asana.com/0/1199230911884351/1206534283150250/f
CC: @samsymons @Bunn 

**Description**:
Enable Stripe purchase flow for internal users in non-App Store target.
Following the requirements listed in the linked task we do want to
enable the Subscription flow for users that are authenticated as
internal users and have not started waitlist interaction with VPN or
DBP.

<!--
Tagging instructions
If this PR isn't ready to be merged for whatever reason it should be
marked with the `DO NOT MERGE` label (particularly if it's a draft)
If it's pending Product Review/PFR, please add the `Pending Product
Review` label.

If at any point it isn't actively being worked on/ready for
review/otherwise moving forward (besides the above PR/PFR exception)
strongly consider closing it (or not opening it in the first place). If
you decide not to close it, make sure it's labelled to make it clear the
PRs state and comment with more information.
-->

---
###### Internal references:
[Pull Request Review
Checklist](https://app.asana.com/0/1202500774821704/1203764234894239/f)
[Software Engineering
Expectations](https://app.asana.com/0/59792373528535/199064865822552)
[Technical Design
Template](https://app.asana.com/0/59792373528535/184709971311943)
[Pull Request
Documentation](https://app.asana.com/0/1202500774821704/1204012835277482/f)

---------

Co-authored-by: Diego Rey Mendez <[email protected]>
  • Loading branch information
miasma13 and diegoreymendez authored Feb 27, 2024
1 parent abc259c commit fa0211c
Show file tree
Hide file tree
Showing 31 changed files with 353 additions and 88 deletions.
2 changes: 1 addition & 1 deletion Configuration/App/DuckDuckGo.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application
CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development
CODE_SIGN_IDENTITY[config=CI][sdk=macosx*] =

FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION SPARKLE DBP
FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION SPARKLE DBP SUBSCRIPTION STRIPE

PRODUCT_NAME_PREFIX = DuckDuckGo

Expand Down
2 changes: 1 addition & 1 deletion Configuration/App/DuckDuckGoPrivacyPro.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@

#include "DuckDuckGo.xcconfig"

FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION SPARKLE SUBSCRIPTION DBP STRIPE
FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION SPARKLE SUBSCRIPTION DBP STRIPE SUBSCRIPTION_OVERRIDE_ENABLED
PRODUCT_NAME = $(PRODUCT_NAME_PREFIX) Privacy Pro
PRODUCT_MODULE_NAME = $(PRIVACY_PRO_PRODUCT_MODULE_NAME_OVERRIDE:default=$(DEFAULT_PRODUCT_MODULE_NAME))
2 changes: 1 addition & 1 deletion Configuration/Tests/UnitTests.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES

FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION DBP
FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION DBP SUBSCRIPTION

INFOPLIST_FILE = UnitTests/Info.plist
PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.macos.browser.DuckDuckGoTests
Expand Down
35 changes: 33 additions & 2 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@
1E950E3F2912A10D0051A99B /* ContentBlocking in Frameworks */ = {isa = PBXBuildFile; productRef = 1E950E3E2912A10D0051A99B /* ContentBlocking */; };
1E950E412912A10D0051A99B /* PrivacyDashboard in Frameworks */ = {isa = PBXBuildFile; productRef = 1E950E402912A10D0051A99B /* PrivacyDashboard */; };
1E950E432912A10D0051A99B /* UserScript in Frameworks */ = {isa = PBXBuildFile; productRef = 1E950E422912A10D0051A99B /* UserScript */; };
1EA7B8D32B7E078C000330A4 /* SubscriptionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 1EA7B8D22B7E078C000330A4 /* SubscriptionUI */; };
1EA7B8D52B7E078C000330A4 /* Subscription in Frameworks */ = {isa = PBXBuildFile; productRef = 1EA7B8D42B7E078C000330A4 /* Subscription */; };
1EA7B8D82B7E1283000330A4 /* SubscriptionFeatureAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EA7B8D72B7E1283000330A4 /* SubscriptionFeatureAvailability.swift */; };
1EA7B8D92B7E1283000330A4 /* SubscriptionFeatureAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EA7B8D72B7E1283000330A4 /* SubscriptionFeatureAvailability.swift */; };
1EA7B8DA2B7E1283000330A4 /* SubscriptionFeatureAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EA7B8D72B7E1283000330A4 /* SubscriptionFeatureAvailability.swift */; };
1ED910D52B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */; };
1ED910D62B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */; };
1ED910D72B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */; };
Expand Down Expand Up @@ -3355,6 +3360,7 @@
1E7E2E8F29029A2A00C01B54 /* ContentBlockingRulesUpdateObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentBlockingRulesUpdateObserver.swift; sourceTree = "<group>"; };
1E7E2E932902AC0E00C01B54 /* PrivacyDashboardPermissionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyDashboardPermissionHandler.swift; sourceTree = "<group>"; };
1E862A882A9FC01200F84D4B /* SubscriptionUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = SubscriptionUI; sourceTree = "<group>"; };
1EA7B8D72B7E1283000330A4 /* SubscriptionFeatureAvailability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionFeatureAvailability.swift; sourceTree = "<group>"; };
1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityTheftRestorationPagesUserScript.swift; sourceTree = "<group>"; };
310E79BE294A19A8007C49E8 /* FireproofingReferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FireproofingReferenceTests.swift; sourceTree = "<group>"; };
311B262628E73E0A00FD181A /* TabShadowConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabShadowConfig.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4684,6 +4690,7 @@
buildActionMask = 2147483647;
files = (
373FB4B12B4D6C42004C88D6 /* PreferencesViews in Frameworks */,
1EA7B8D32B7E078C000330A4 /* SubscriptionUI in Frameworks */,
B6F7128129F681EB00594A45 /* QuickLookUI.framework in Frameworks */,
9DB6E7242AA0DC5800A17F3C /* LoginItems in Frameworks */,
EE7295E32A545B9A008C0991 /* NetworkProtection in Frameworks */,
Expand All @@ -4699,6 +4706,7 @@
37269EFB2B332F9E005E8E46 /* Common in Frameworks */,
4B2AAAF529E70DEA0026AFC0 /* Lottie in Frameworks */,
AA06B6B72672AF8100F541C5 /* Sparkle in Frameworks */,
1EA7B8D52B7E078C000330A4 /* Subscription in Frameworks */,
B6B77BE8297973D4001E68A1 /* Navigation in Frameworks */,
3739326729AE4B42009346AE /* DDGSync in Frameworks */,
7BA59C9B2AE18B49009A97B1 /* SystemExtensionManager in Frameworks */,
Expand Down Expand Up @@ -4908,6 +4916,14 @@
path = Services;
sourceTree = "<group>";
};
1EA7B8D62B7E124E000330A4 /* Subscription */ = {
isa = PBXGroup;
children = (
1EA7B8D72B7E1283000330A4 /* SubscriptionFeatureAvailability.swift */,
);
path = Subscription;
sourceTree = "<group>";
};
3171D6DC2889B6700068632A /* CookieManaged */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -6788,6 +6804,7 @@
4B677422255DBEB800025BD8 /* SmarterEncryption */,
B68458AE25C7E75100DC17B6 /* StateRestoration */,
B6A9E44E26142AF90067D1B9 /* Statistics */,
1EA7B8D62B7E124E000330A4 /* Subscription */,
AACB8E7224A4C8BC005F2218 /* Suggestions */,
3775913429AB99DA00E26367 /* Sync */,
AA86491B24D837DE001BABEE /* Tab */,
Expand Down Expand Up @@ -8779,6 +8796,8 @@
3722177F2B3337FE00B8E9C2 /* TestUtils */,
373FB4B02B4D6C42004C88D6 /* PreferencesViews */,
7BA076BA2B65D61400D7FB72 /* NetworkProtectionProxy */,
1EA7B8D22B7E078C000330A4 /* SubscriptionUI */,
1EA7B8D42B7E078C000330A4 /* Subscription */,
);
productName = DuckDuckGo;
productReference = AA585D7E248FD31100E9A3E2 /* DuckDuckGo.app */;
Expand Down Expand Up @@ -9979,6 +9998,7 @@
B66260E829ACD0C900E9E3EE /* DuckPlayerTabExtension.swift in Sources */,
3706FBAA293F65D500E42796 /* HoverUserScript.swift in Sources */,
3706FBAC293F65D500E42796 /* MainMenuActions.swift in Sources */,
1EA7B8D92B7E1283000330A4 /* SubscriptionFeatureAvailability.swift in Sources */,
4BF97AD92B43C5C000EB4240 /* Bundle+VPN.swift in Sources */,
3706FBAE293F65D500E42796 /* DataImport.swift in Sources */,
3706FBAF293F65D500E42796 /* FireproofDomains.xcdatamodeld in Sources */,
Expand Down Expand Up @@ -11221,6 +11241,7 @@
4B957AF12AC7AE700062CA31 /* AppStateRestorationManager.swift in Sources */,
4B957AF22AC7AE700062CA31 /* DailyPixel.swift in Sources */,
4B957AF32AC7AE700062CA31 /* NavigationHotkeyHandler.swift in Sources */,
1EA7B8DA2B7E1283000330A4 /* SubscriptionFeatureAvailability.swift in Sources */,
4B957AF42AC7AE700062CA31 /* ClickToLoadUserScript.swift in Sources */,
4B957AF52AC7AE700062CA31 /* WindowControllersManager.swift in Sources */,
4B957AF62AC7AE700062CA31 /* FireAnimationView.swift in Sources */,
Expand Down Expand Up @@ -12252,6 +12273,7 @@
4BA1A6C2258B0A1300F6F690 /* ContiguousBytesExtension.swift in Sources */,
B6A22B622B1E29D000ECD2BA /* DataImportSummaryViewModel.swift in Sources */,
37534CA8281198CD002621E7 /* AdjacentItemEnumerator.swift in Sources */,
1EA7B8D82B7E1283000330A4 /* SubscriptionFeatureAvailability.swift in Sources */,
987799F62999996B005D8EB6 /* BookmarkDatabase.swift in Sources */,
4BE53374286E39F10019DBFD /* ChromiumKeychainPrompt.swift in Sources */,
B6553692268440D700085A79 /* WKProcessPool+GeolocationProvider.swift in Sources */,
Expand Down Expand Up @@ -13507,7 +13529,7 @@
repositoryURL = "https://github.com/duckduckgo/OpenSSL-XCFramework";
requirement = {
kind = exactVersion;
version = 3.1.2000;
version = 3.1.4000;
};
};
4B2AAAF329E70DEA0026AFC0 /* XCRemoteSwiftPackageReference "lottie-ios" */ = {
Expand Down Expand Up @@ -13555,7 +13577,7 @@
repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit";
requirement = {
kind = exactVersion;
version = 111.0.2;
version = 111.1.1;
};
};
AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */ = {
Expand Down Expand Up @@ -13617,6 +13639,15 @@
package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
productName = UserScript;
};
1EA7B8D22B7E078C000330A4 /* SubscriptionUI */ = {
isa = XCSwiftPackageProductDependency;
productName = SubscriptionUI;
};
1EA7B8D42B7E078C000330A4 /* Subscription */ = {
isa = XCSwiftPackageProductDependency;
package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
productName = Subscription;
};
312978892B64131200B67619 /* DataBrokerProtection */ = {
isa = XCSwiftPackageProductDependency;
productName = DataBrokerProtection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/BrowserServicesKit",
"state" : {
"revision" : "04c35220aa94bd005171086acccadd677400e7d5",
"version" : "111.0.2"
"revision" : "e3140633373b14b3d1fca25b098869cdaa753913",
"version" : "111.1.1"
}
},
{
Expand Down Expand Up @@ -68,8 +68,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/OpenSSL-XCFramework",
"state" : {
"revision" : "bb7bfc010ef4d2e7913c343663b167e2a984ac79",
"version" : "3.1.2000"
"revision" : "b75ab2c0405860bb2616db71b9a456acb118c21a",
"version" : "3.1.4000"
}
},
{
Expand Down
7 changes: 7 additions & 0 deletions DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel

featureFlagger = DefaultFeatureFlagger(internalUserDecider: internalUserDecider,
privacyConfig: AppPrivacyFeatures.shared.contentBlocking.privacyConfigurationManager.privacyConfig)

}

func applicationWillFinishLaunching(_ notification: Notification) {
Expand Down Expand Up @@ -281,6 +282,12 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel

#if SUBSCRIPTION
Task {
var defaultEnvironment = SubscriptionPurchaseEnvironment.ServiceEnvironment.default

let currentEnvironment = UserDefaultsWrapper(key: .subscriptionEnvironment,
defaultValue: defaultEnvironment).wrappedValue
SubscriptionPurchaseEnvironment.currentServiceEnvironment = currentEnvironment

#if STRIPE
SubscriptionPurchaseEnvironment.current = .stripe
#else
Expand Down
16 changes: 16 additions & 0 deletions DuckDuckGo/Assets.xcassets/Images/ITR-Icon.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "CreditCard-16.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
Binary file not shown.
2 changes: 2 additions & 0 deletions DuckDuckGo/Common/Localizables/UserText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,8 @@ struct UserText {
// Comment: "Title for Subscription item in the options menu"
static let subscriptionOptionsMenuItem = "Privacy Pro"

static let identityTheftRestorationOptionsMenuItem = "Identity Theft Restoration"

// Key: "preferences.subscription"
// Comment: "Show subscription preferences"
static let subscription = "Privacy Pro"
Expand Down
5 changes: 5 additions & 0 deletions DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ public struct UserDefaultsWrapper<T> {
case syncDidPresentFaviconsFetcherOnboarding = "sync.did-present-favicons-fetcher-onboarding"
case syncDidMigrateToImprovedListsHandling = "sync.did-migrate-to-improved-lists-handling"
case syncDidShowSyncPausedByFeatureFlagAlert = "sync.did-show-sync-paused-by-feature-flag-alert"

// Subscription

case subscriptionInternalTesting = "subscription.internal-testing-enabled"
case subscriptionEnvironment = "subscription.environment"
}

enum RemovedKeys: String, CaseIterable {
Expand Down
13 changes: 12 additions & 1 deletion DuckDuckGo/Menus/MainMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import NetworkProtection
#endif

#if SUBSCRIPTION
import Subscription
import SubscriptionUI
#endif

Expand Down Expand Up @@ -591,7 +592,17 @@ import SubscriptionUI
NSMenuItem(title: "Trigger Fatal Error", action: #selector(MainViewController.triggerFatalError))

#if SUBSCRIPTION
SubscriptionDebugMenu(currentViewController: {
let currentEnvironmentWrapper = UserDefaultsWrapper(key: .subscriptionEnvironment, defaultValue: SubscriptionPurchaseEnvironment.ServiceEnvironment.default)
let isInternalTestingWrapper = UserDefaultsWrapper(key: .subscriptionInternalTesting, defaultValue: false)

SubscriptionDebugMenu(currentEnvironment: { currentEnvironmentWrapper.wrappedValue.rawValue },
updateEnvironment: {
guard let newEnvironment = SubscriptionPurchaseEnvironment.ServiceEnvironment(rawValue: $0) else { return }
currentEnvironmentWrapper.wrappedValue = newEnvironment
SubscriptionPurchaseEnvironment.currentServiceEnvironment = newEnvironment },
isInternalTestingEnabled: { isInternalTestingWrapper.wrappedValue },
updateInternalTestingFlag: { isInternalTestingWrapper.wrappedValue = $0 },
currentViewController: {
WindowControllersManager.shared.lastKeyMainWindowController?.mainViewController
})
#endif
Expand Down
10 changes: 6 additions & 4 deletions DuckDuckGo/NavigationBar/View/AddressBarTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -317,10 +317,12 @@ final class AddressBarTextField: NSTextField {
#endif

#if SUBSCRIPTION
if providedUrl.isChild(of: URL.subscriptionBaseURL) || providedUrl.isChild(of: URL.identityTheftRestoration) {
selectedTabViewModel.updateAddressBarStrings()
self.window?.makeFirstResponder(nil)
return
if DefaultSubscriptionFeatureAvailability().isFeatureAvailable() {
if providedUrl.isChild(of: URL.subscriptionBaseURL) || providedUrl.isChild(of: URL.identityTheftRestoration) {
selectedTabViewModel.updateAddressBarStrings()
self.window?.makeFirstResponder(nil)
return
}
}
#endif

Expand Down
25 changes: 20 additions & 5 deletions DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ protocol OptionsButtonMenuDelegate: AnyObject {
#endif
#if SUBSCRIPTION
func optionsButtonMenuRequestedSubscriptionPurchasePage(_ menu: NSMenu)
func optionsButtonMenuRequestedIdentityTheftRestoration(_ menu: NSMenu)
#endif
}

Expand Down Expand Up @@ -244,6 +245,10 @@ final class MoreOptionsMenu: NSMenu {
@objc func openSubscriptionPurchasePage(_ sender: NSMenuItem) {
actionDelegate?.optionsButtonMenuRequestedSubscriptionPurchasePage(self)
}

@objc func openIdentityTheftRestoration(_ sender: NSMenuItem) {
actionDelegate?.optionsButtonMenuRequestedIdentityTheftRestoration(self)
}
#endif

@objc func findInPage(_ sender: NSMenuItem) {
Expand Down Expand Up @@ -304,13 +309,13 @@ final class MoreOptionsMenu: NSMenu {
var items: [NSMenuItem] = []

#if SUBSCRIPTION
if AccountManager().isUserAuthenticated {
items.append(contentsOf: makeActiveSubscriptionItems())
} else if SubscriptionPurchaseEnvironment.canPurchase {
if DefaultSubscriptionFeatureAvailability().isFeatureAvailable() && !AccountManager().isUserAuthenticated {
items.append(contentsOf: makeInactiveSubscriptionItems())
} else {
items.append(contentsOf: makeActiveSubscriptionItems()) // this adds NETP and DBP only if conditionally enabled
}
#else
items.append(contentsOf: makeActiveSubscriptionItems()) // this only adds NETP and DBP (if enabled)
items.append(contentsOf: makeActiveSubscriptionItems()) // this adds NETP and DBP only if conditionally enabled
#endif

if !items.isEmpty {
Expand Down Expand Up @@ -355,9 +360,19 @@ final class MoreOptionsMenu: NSMenu {
} else {
DefaultDataBrokerProtectionFeatureVisibility().disableAndDeleteForWaitlistUsers()
}

#endif // DBP

#if SUBSCRIPTION
if AccountManager().isUserAuthenticated {
let identityTheftRestorationItem = NSMenuItem(title: UserText.identityTheftRestorationOptionsMenuItem,
action: #selector(openIdentityTheftRestoration),
keyEquivalent: "")
.targetting(self)
.withImage(NSImage(named: "ITR-Icon"))
items.append(identityTheftRestorationItem)
}
#endif

return items
}

Expand Down
18 changes: 12 additions & 6 deletions DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,14 @@ final class NavigationBarViewController: NSViewController {
}

#if SUBSCRIPTION
let accountManager = AccountManager()
let networkProtectionTokenStorage = NetworkProtectionKeychainTokenStore()
if DefaultSubscriptionFeatureAvailability().isFeatureAvailable() {
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
if accountManager.accessToken != nil && (try? networkProtectionTokenStorage.fetchToken()) == nil {
print("[NetP Subscription] Got access token but not auth token, meaning token exchange failed")
return
}
}
#endif

Expand Down Expand Up @@ -370,7 +372,7 @@ final class NavigationBarViewController: NSViewController {

#if NETWORK_PROTECTION
func listenToVPNToggleNotifications() {
vpnToggleCancellable = NotificationCenter.default.publisher(for: .ToggleNetworkProtectionInMainWindow).sink { [weak self] _ in
vpnToggleCancellable = NotificationCenter.default.publisher(for: .ToggleNetworkProtectionInMainWindow).receive(on: DispatchQueue.main).sink { [weak self] _ in
guard self?.view.window?.isKeyWindow == true else {
return
}
Expand Down Expand Up @@ -1033,6 +1035,10 @@ extension NavigationBarViewController: OptionsButtonMenuDelegate {
func optionsButtonMenuRequestedSubscriptionPurchasePage(_ menu: NSMenu) {
WindowControllersManager.shared.showTab(with: .subscription(.subscriptionPurchase))
}

func optionsButtonMenuRequestedIdentityTheftRestoration(_ menu: NSMenu) {
WindowControllersManager.shared.showTab(with: .subscription(.identityTheftRestoration))
}
#endif

}
Expand Down
Loading

0 comments on commit fa0211c

Please sign in to comment.