Skip to content

Commit

Permalink
Merge branch 'main' into sam/remove-cgnat
Browse files Browse the repository at this point in the history
# By Anh Do
# Via GitHub
* main:
  Add preliminary support for subscription keychain sharing (#2538)

# Conflicts:
#	DuckDuckGo.xcodeproj/project.pbxproj
#	DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  • Loading branch information
samsymons committed Mar 6, 2024
2 parents cf262c8 + 21ce049 commit 78f1beb
Show file tree
Hide file tree
Showing 15 changed files with 141 additions and 13 deletions.
3 changes: 3 additions & 0 deletions Configuration/Configuration-Alpha.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ APP_ID = com.duckduckgo.mobile.ios.alpha

// A prefix for group ids. Must start with "group.".
GROUP_ID_PREFIX = group.com.duckduckgo.alpha

// The keychain access group for subscriptions
SUBSCRIPTION_APP_GROUP = com.duckduckgo.subscriptions.alpha
3 changes: 3 additions & 0 deletions Configuration/DuckDuckGoDeveloper.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ CODE_SIGN_STYLE = Manual

// The manually specified provisioning profile
PROVISIONING_PROFILE_SPECIFIER = Development - App

// The keychain access group for subscriptions
SUBSCRIPTION_APP_GROUP = com.duckduckgo.subscriptions
31 changes: 31 additions & 0 deletions Core/AccountManagerExtension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// AccountManagerExtension.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#if SUBSCRIPTION

import Foundation
import Subscription

public extension AccountManager {
convenience init() {
self.init(subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs))
}
}

#endif
40 changes: 40 additions & 0 deletions Core/BundleExtension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// BundleExtension.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

extension Bundle {
public func appGroup(bundle: BundleGroup) -> String {
var appGroupName: String

switch bundle {
case .subs:
appGroupName = "SUBSCRIPTION_APP_GROUP"
}

guard let appGroup = object(forInfoDictionaryKey: appGroupName) as? String else {
fatalError("Info.plist is missing \(appGroupName)")
}
return appGroup
}
}

public enum BundleGroup {
case subs
}
24 changes: 22 additions & 2 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -695,11 +695,15 @@
B6BA95C528894A28004ABA20 /* BrowsingMenuViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6BA95C428894A28004ABA20 /* BrowsingMenuViewController.storyboard */; };
B6BA95E828924730004ABA20 /* JSAlertController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6BA95E728924730004ABA20 /* JSAlertController.storyboard */; };
B6CB93E5286445AB0090FEB4 /* Base64DownloadSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */; };
BD15DB852B959CFD00821457 /* BundleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD15DB842B959CFD00821457 /* BundleExtension.swift */; };
BD862E032B30DA170073E2EE /* VPNFeedbackFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E022B30DA170073E2EE /* VPNFeedbackFormViewModel.swift */; };
BD862E052B30DB250073E2EE /* VPNFeedbackCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E042B30DB250073E2EE /* VPNFeedbackCategory.swift */; };
BD862E072B30F5E30073E2EE /* VPNFeedbackSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E062B30F5E30073E2EE /* VPNFeedbackSender.swift */; };
BD862E092B30F63E0073E2EE /* VPNMetadataCollector.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E082B30F63E0073E2EE /* VPNMetadataCollector.swift */; };
BD862E0B2B30F9300073E2EE /* VPNFeedbackFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD862E0A2B30F9300073E2EE /* VPNFeedbackFormView.swift */; };
BDA583872B98B6C700732FDC /* AccountManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA583862B98B6C700732FDC /* AccountManagerExtension.swift */; };
BDA583882B98B92F00732FDC /* AccountManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA583862B98B6C700732FDC /* AccountManagerExtension.swift */; };
BDA583892B98BA7600732FDC /* AccountManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA583862B98B6C700732FDC /* AccountManagerExtension.swift */; };
BDC234F72B27F51100D3C798 /* UniquePixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDC234F62B27F51100D3C798 /* UniquePixel.swift */; };
C10CB5F32A1A5BDF0048E503 /* AutofillViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = C10CB5F22A1A5BDF0048E503 /* AutofillViews.swift */; };
C111B26927F579EF006558B1 /* BookmarkOrFolderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C111B26827F579EF006558B1 /* BookmarkOrFolderTests.swift */; };
Expand Down Expand Up @@ -2344,11 +2348,13 @@
B6BA95C428894A28004ABA20 /* BrowsingMenuViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = BrowsingMenuViewController.storyboard; sourceTree = "<group>"; };
B6BA95E728924730004ABA20 /* JSAlertController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = JSAlertController.storyboard; sourceTree = "<group>"; };
B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64DownloadSession.swift; sourceTree = "<group>"; };
BD15DB842B959CFD00821457 /* BundleExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleExtension.swift; sourceTree = "<group>"; };
BD862E022B30DA170073E2EE /* VPNFeedbackFormViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackFormViewModel.swift; sourceTree = "<group>"; };
BD862E042B30DB250073E2EE /* VPNFeedbackCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackCategory.swift; sourceTree = "<group>"; };
BD862E062B30F5E30073E2EE /* VPNFeedbackSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackSender.swift; sourceTree = "<group>"; };
BD862E082B30F63E0073E2EE /* VPNMetadataCollector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNMetadataCollector.swift; sourceTree = "<group>"; };
BD862E0A2B30F9300073E2EE /* VPNFeedbackFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackFormView.swift; sourceTree = "<group>"; };
BDA583862B98B6C700732FDC /* AccountManagerExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountManagerExtension.swift; sourceTree = "<group>"; };
BDC234F62B27F51100D3C798 /* UniquePixel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UniquePixel.swift; sourceTree = "<group>"; };
C10CB5F22A1A5BDF0048E503 /* AutofillViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillViews.swift; sourceTree = "<group>"; };
C111B26827F579EF006558B1 /* BookmarkOrFolderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkOrFolderTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4412,6 +4418,15 @@
path = Feedback;
sourceTree = "<group>";
};
BDA583852B98B69C00732FDC /* Subscription */ = {
isa = PBXGroup;
children = (
BD15DB842B959CFD00821457 /* BundleExtension.swift */,
BDA583862B98B6C700732FDC /* AccountManagerExtension.swift */,
);
name = Subscription;
sourceTree = "<group>";
};
C14882D627F2010700D59F0C /* ImportExport */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -5104,6 +5119,7 @@
F143C2E51E4A4CD400CFDE3A /* Core */ = {
isa = PBXGroup;
children = (
BDA583852B98B69C00732FDC /* Subscription */,
858479C72B8792C900D156C1 /* History */,
EE7A92852AC6DE2500832A36 /* NetworkProtection */,
4B470ED4299C484B0086EBDC /* AppTrackingProtection */,
Expand Down Expand Up @@ -6465,6 +6481,7 @@
02025AD42988229800E694E7 /* ProxySocket.swift in Sources */,
02025AD62988229800E694E7 /* SocketProtocol.swift in Sources */,
02025AD82988229800E694E7 /* Tunnel.swift in Sources */,
BDA583892B98BA7600732FDC /* AccountManagerExtension.swift in Sources */,
02025ADA2988229800E694E7 /* Port.swift in Sources */,
02025ADB2988229800E694E7 /* HTTPStreamScanner.swift in Sources */,
02025ADC2988229800E694E7 /* UInt128.swift in Sources */,
Expand Down Expand Up @@ -6895,6 +6912,7 @@
85F98F92296F32BD00742F4A /* SyncSettingsViewController.swift in Sources */,
84E341961E2F7EFB00BDBA6F /* AppDelegate.swift in Sources */,
310D091D2799F57200DC0060 /* Download.swift in Sources */,
BDA583882B98B92F00732FDC /* AccountManagerExtension.swift in Sources */,
C13F3F6C2B7F88470083BE40 /* AuthConfirmationPromptViewModel.swift in Sources */,
1EEF124E2850EADE003DDE57 /* PrivacyIconView.swift in Sources */,
37FCAAAB29911BF1000E420A /* WaitlistExtensions.swift in Sources */,
Expand Down Expand Up @@ -7251,6 +7269,7 @@
98F6EA472863124100720957 /* ContentBlockerRulesLists.swift in Sources */,
F1134EB01F40AC6300B73467 /* AtbParser.swift in Sources */,
EE50052E29C369D300AE0773 /* FeatureFlag.swift in Sources */,
BD15DB852B959CFD00821457 /* BundleExtension.swift in Sources */,
37DF000F29F9D635002B7D3E /* SyncBookmarksAdapter.swift in Sources */,
B652DF10287C2C1600C12A9C /* ContentBlocking.swift in Sources */,
4BE2756827304F57006B20B0 /* URLRequestExtension.swift in Sources */,
Expand Down Expand Up @@ -7291,6 +7310,7 @@
B652DF0D287C2A6300C12A9C /* PrivacyFeatures.swift in Sources */,
F10E522D1E946F8800CE1253 /* NSAttributedStringExtension.swift in Sources */,
9887DC252354D2AA005C85F5 /* Database.swift in Sources */,
BDA583872B98B6C700732FDC /* AccountManagerExtension.swift in Sources */,
F143C3171E4A99D200CFDE3A /* AppURLs.swift in Sources */,
C1963863283794A000298D4D /* BookmarksCachingSearch.swift in Sources */,
);
Expand Down Expand Up @@ -9996,8 +10016,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit";
requirement = {
branch = "sam/remove-cgnat";
kind = branch;
kind = exactVersion;
version = 116.0.0;
};
};
B6F997C22B8F374300476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/DuckDuckGo/BrowserServicesKit",
"state" : {
"branch" : "sam/remove-cgnat",
"revision" : "413c313fae6ef35fad6f0bd20b4303ac7f1ed024"
"revision" : "5a6c7b62f84e7c2a4ffa7803392284a055229aef",
"version" : "116.0.0"
}
},
{
Expand Down Expand Up @@ -165,7 +165,7 @@
{
"identity" : "trackerradarkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/TrackerRadarKit",
"location" : "https://github.com/duckduckgo/TrackerRadarKit.git",
"state" : {
"revision" : "a6b7ba151d9dc6684484f3785293875ec01cc1ff",
"version" : "1.2.2"
Expand Down
9 changes: 7 additions & 2 deletions DuckDuckGo/DuckDuckGo.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.web-browser</key>
<true/>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>packet-tunnel-provider</string>
</array>
<key>com.apple.developer.web-browser</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>$(GROUP_ID_PREFIX).bookmarks</string>
Expand All @@ -17,5 +17,10 @@
<string>$(GROUP_ID_PREFIX).apptp</string>
<string>$(GROUP_ID_PREFIX).netp</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)$(APP_ID)</string>
<string>$(AppIdentifierPrefix)$(SUBSCRIPTION_APP_GROUP)</string>
</array>
</dict>
</plist>
5 changes: 5 additions & 0 deletions DuckDuckGo/DuckDuckGoAlpha.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,10 @@
<string>group.com.duckduckgo.alpha.netp</string>
<string>group.com.duckduckgo.alpha.statistics</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)$(APP_ID)</string>
<string>$(AppIdentifierPrefix)$(SUBSCRIPTION_APP_GROUP)</string>
</array>
</dict>
</plist>
2 changes: 2 additions & 0 deletions DuckDuckGo/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@
</array>
<key>UIStatusBarHidden</key>
<true/>
<key>SUBSCRIPTION_APP_GROUP</key>
<string>$(AppIdentifierPrefix)$(SUBSCRIPTION_APP_GROUP)</string>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations~ipad</key>
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/SettingsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ extension SettingsViewModel {
@available(iOS 15.0, *)
func restoreAccountPurchase() async {
DispatchQueue.main.async { self.isRestoringSubscription = true }
let result = await AppStoreRestoreFlow.restoreAccountFromPastPurchase()
let result = await AppStoreRestoreFlow.restoreAccountFromPastPurchase(subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs))
switch result {
case .success:
DispatchQueue.main.async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,12 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature, ObservableObjec
let emailAccessToken = try? EmailManager().getToken()
let purchaseTransactionJWS: String

switch await AppStorePurchaseFlow.purchaseSubscription(with: subscriptionSelection.id, emailAccessToken: emailAccessToken) {
switch await AppStorePurchaseFlow.purchaseSubscription(with: subscriptionSelection.id,
emailAccessToken: emailAccessToken,
subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs)) {
case .success(let transactionJWS):
purchaseTransactionJWS = transactionJWS

case .failure(let error):

switch error {
Expand All @@ -224,7 +227,8 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature, ObservableObjec
}

setTransactionStatus(.polling)
switch await AppStorePurchaseFlow.completeSubscriptionPurchase(with: purchaseTransactionJWS) {
switch await AppStorePurchaseFlow.completeSubscriptionPurchase(with: purchaseTransactionJWS,
subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs)) {
case .success(let purchaseUpdate):
await pushPurchaseUpdate(originalMessage: message, purchaseUpdate: purchaseUpdate)
case .failure:
Expand Down Expand Up @@ -323,7 +327,7 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature, ObservableObjec
func restoreAccountFromAppStorePurchase() async throws {
setTransactionStatus(.restoring)

let result = await AppStoreRestoreFlow.restoreAccountFromPastPurchase()
let result = await AppStoreRestoreFlow.restoreAccountFromPastPurchase(subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs))
switch result {
case .success:
setTransactionStatus(.idle)
Expand Down Expand Up @@ -356,7 +360,6 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature, ObservableObjec
}

}

// swiftlint:enable type_body_length

#endif
2 changes: 2 additions & 0 deletions PacketTunnelProvider/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<dict>
<key>DuckDuckGoGroupIdentifierPrefix</key>
<string>$(GROUP_ID_PREFIX)</string>
<key>SUBSCRIPTION_APP_GROUP</key>
<string>$(AppIdentifierPrefix)$(SUBSCRIPTION_APP_GROUP)</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,11 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider {
}

private static func entitlementCheck() async -> Result<Bool, Error> {
let result = await AccountManager().hasEntitlement(for: .networkProtection)
#if ALPHA
SubscriptionPurchaseEnvironment.currentServiceEnvironment = .staging
#endif

let result = await AccountManager(subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs)).hasEntitlement(for: .networkProtection)
switch result {
case .success(let hasEntitlement):
return .success(hasEntitlement)
Expand Down
5 changes: 5 additions & 0 deletions PacketTunnelProvider/PacketTunnelProvider.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@
<string>$(GROUP_ID_PREFIX).apptp</string>
<string>$(GROUP_ID_PREFIX).netp</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)$(APP_ID)</string>
<string>$(AppIdentifierPrefix)$(SUBSCRIPTION_APP_GROUP)</string>
</array>
</dict>
</plist>
5 changes: 5 additions & 0 deletions PacketTunnelProvider/PacketTunnelProviderAlpha.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@
<string>group.com.duckduckgo.alpha.apptp</string>
<string>group.com.duckduckgo.alpha.netp</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)$(APP_ID)</string>
<string>$(AppIdentifierPrefix)$(SUBSCRIPTION_APP_GROUP)</string>
</array>
</dict>
</plist>

0 comments on commit 78f1beb

Please sign in to comment.