Lock network settings for builds >= 3000
This commit is contained in:
parent
320513dd38
commit
2565b9f3d0
|
@ -126,7 +126,7 @@
|
||||||
<EnvironmentVariables>
|
<EnvironmentVariables>
|
||||||
<EnvironmentVariable
|
<EnvironmentVariable
|
||||||
key = "APP_TYPE"
|
key = "APP_TYPE"
|
||||||
value = "2"
|
value = "0"
|
||||||
isEnabled = "YES">
|
isEnabled = "YES">
|
||||||
</EnvironmentVariable>
|
</EnvironmentVariable>
|
||||||
<EnvironmentVariable
|
<EnvironmentVariable
|
||||||
|
|
|
@ -114,7 +114,8 @@ class AppContext {
|
||||||
|
|
||||||
productManager = ProductManager(.init(
|
productManager = ProductManager(.init(
|
||||||
appType: Constants.InApp.appType,
|
appType: Constants.InApp.appType,
|
||||||
lastFullVersionBuild: Constants.InApp.lastFullVersionBuild
|
lastFullVersionBuild: Constants.InApp.lastFullVersionBuild,
|
||||||
|
lastNetworkSettingsBuild: Constants.InApp.lastNetworkSettingsBuild
|
||||||
))
|
))
|
||||||
intentsManager = IntentsManager()
|
intentsManager = IntentsManager()
|
||||||
reviewer = Reviewer()
|
reviewer = Reviewer()
|
||||||
|
@ -163,6 +164,15 @@ class AppContext {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eligibility: ignore network settings if ineligible
|
||||||
|
private func isEligibleForNetworkSettings() -> Bool {
|
||||||
|
guard productManager.isEligible(forFeature: .networkSettings) else {
|
||||||
|
pp_log.warning("Ignore network settings, not eligible")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// eligibility: reset on-demand rules if no trusted networks
|
// eligibility: reset on-demand rules if no trusted networks
|
||||||
private func isEligibleForOnDemandRules() -> Bool {
|
private func isEligibleForOnDemandRules() -> Bool {
|
||||||
guard productManager.isEligible(forFeature: .trustedNetworks) else {
|
guard productManager.isEligible(forFeature: .trustedNetworks) else {
|
||||||
|
|
|
@ -75,6 +75,8 @@ extension Constants {
|
||||||
#else
|
#else
|
||||||
static let lastFullVersionBuild: (Int, LocalProduct) = (0, .fullVersion_macOS)
|
static let lastFullVersionBuild: (Int, LocalProduct) = (0, .fullVersion_macOS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static let lastNetworkSettingsBuild = 2999
|
||||||
|
|
||||||
private static var isBeta: Bool {
|
private static var isBeta: Bool {
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
|
|
|
@ -68,6 +68,8 @@ struct LocalProduct: RawRepresentable, Equatable, Hashable {
|
||||||
// MARK: Features
|
// MARK: Features
|
||||||
|
|
||||||
static let allProviders = LocalProduct(featureId: "all_providers")
|
static let allProviders = LocalProduct(featureId: "all_providers")
|
||||||
|
|
||||||
|
static let networkSettings = LocalProduct(featureId: "network_settings")
|
||||||
|
|
||||||
static let trustedNetworks = LocalProduct(featureId: "trusted_networks")
|
static let trustedNetworks = LocalProduct(featureId: "trusted_networks")
|
||||||
|
|
||||||
|
@ -81,6 +83,7 @@ struct LocalProduct: RawRepresentable, Equatable, Hashable {
|
||||||
|
|
||||||
static let allFeatures: [LocalProduct] = [
|
static let allFeatures: [LocalProduct] = [
|
||||||
.allProviders,
|
.allProviders,
|
||||||
|
.networkSettings,
|
||||||
.trustedNetworks,
|
.trustedNetworks,
|
||||||
.siriShortcuts,
|
.siriShortcuts,
|
||||||
.fullVersion_iOS,
|
.fullVersion_iOS,
|
||||||
|
|
|
@ -49,12 +49,16 @@ class ProductManager: NSObject, ObservableObject {
|
||||||
|
|
||||||
let lastFullVersionBuild: (Int, LocalProduct)
|
let lastFullVersionBuild: (Int, LocalProduct)
|
||||||
|
|
||||||
|
let lastNetworkSettingsBuild: Int
|
||||||
|
|
||||||
init(
|
init(
|
||||||
appType: AppType,
|
appType: AppType,
|
||||||
lastFullVersionBuild: (Int, LocalProduct)
|
lastFullVersionBuild: (Int, LocalProduct),
|
||||||
|
lastNetworkSettingsBuild: Int
|
||||||
) {
|
) {
|
||||||
self.appType = appType
|
self.appType = appType
|
||||||
self.lastFullVersionBuild = lastFullVersionBuild
|
self.lastFullVersionBuild = lastFullVersionBuild
|
||||||
|
self.lastNetworkSettingsBuild = lastNetworkSettingsBuild
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +197,11 @@ class ProductManager: NSObject, ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEligible(forFeature feature: LocalProduct) -> Bool {
|
func isEligible(forFeature feature: LocalProduct) -> Bool {
|
||||||
|
if let purchasedAppBuild = purchasedAppBuild {
|
||||||
|
if feature == .networkSettings && purchasedAppBuild <= cfg.lastNetworkSettingsBuild {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
return isFullVersion() || purchasedFeatures.contains(feature)
|
return isFullVersion() || purchasedFeatures.contains(feature)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -34,6 +34,10 @@ extension ProfileView {
|
||||||
|
|
||||||
@Binding private var modalType: ModalType?
|
@Binding private var modalType: ModalType?
|
||||||
|
|
||||||
|
private var isEligibleForNetworkSettings: Bool {
|
||||||
|
productManager.isEligible(forFeature: .networkSettings)
|
||||||
|
}
|
||||||
|
|
||||||
private var isEligibleForTrustedNetworks: Bool {
|
private var isEligibleForTrustedNetworks: Bool {
|
||||||
productManager.isEligible(forFeature: .trustedNetworks)
|
productManager.isEligible(forFeature: .trustedNetworks)
|
||||||
}
|
}
|
||||||
|
@ -75,10 +79,20 @@ extension ProfileView {
|
||||||
Label(L10n.Account.title, systemImage: themeAccountImage)
|
Label(L10n.Account.title, systemImage: themeAccountImage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NavigationLink {
|
|
||||||
NetworkSettingsView(currentProfile: currentProfile)
|
// eligibility: enter network settings or present paywall
|
||||||
} label: {
|
if isEligibleForNetworkSettings {
|
||||||
Label(L10n.NetworkSettings.title, systemImage: themeNetworkSettingsImage)
|
NavigationLink {
|
||||||
|
NetworkSettingsView(currentProfile: currentProfile)
|
||||||
|
} label: {
|
||||||
|
networkSettingsRow
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Button {
|
||||||
|
modalType = .paywallNetworkSettings
|
||||||
|
} label: {
|
||||||
|
networkSettingsRow
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eligibility: enter trusted networks or present paywall
|
// eligibility: enter trusted networks or present paywall
|
||||||
|
@ -97,6 +111,10 @@ extension ProfileView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var networkSettingsRow: some View {
|
||||||
|
Label(L10n.NetworkSettings.title, systemImage: themeNetworkSettingsImage)
|
||||||
|
}
|
||||||
|
|
||||||
private var onDemandRow: some View {
|
private var onDemandRow: some View {
|
||||||
Label(L10n.OnDemand.title, systemImage: themeOnDemandImage)
|
Label(L10n.OnDemand.title, systemImage: themeOnDemandImage)
|
||||||
|
|
|
@ -31,6 +31,8 @@ struct ProfileView: View {
|
||||||
enum ModalType: Int, Identifiable {
|
enum ModalType: Int, Identifiable {
|
||||||
case rename
|
case rename
|
||||||
|
|
||||||
|
case paywallNetworkSettings
|
||||||
|
|
||||||
case paywallTrustedNetworks
|
case paywallTrustedNetworks
|
||||||
|
|
||||||
var id: Int {
|
var id: Int {
|
||||||
|
@ -123,6 +125,14 @@ struct ProfileView: View {
|
||||||
RenameView(currentProfile: profileManager.currentProfile)
|
RenameView(currentProfile: profileManager.currentProfile)
|
||||||
}.themeGlobal()
|
}.themeGlobal()
|
||||||
|
|
||||||
|
case .paywallNetworkSettings:
|
||||||
|
NavigationView {
|
||||||
|
PaywallView(
|
||||||
|
modalType: $modalType,
|
||||||
|
feature: .networkSettings
|
||||||
|
)
|
||||||
|
}.themeGlobal()
|
||||||
|
|
||||||
case .paywallTrustedNetworks:
|
case .paywallTrustedNetworks:
|
||||||
NavigationView {
|
NavigationView {
|
||||||
PaywallView(
|
PaywallView(
|
||||||
|
|
|
@ -41,10 +41,12 @@ extension Profile.OpenVPNSettings: VPNConfigurationProviding {
|
||||||
}
|
}
|
||||||
|
|
||||||
// network settings
|
// network settings
|
||||||
customBuilder.applyGateway(from: parameters.networkSettings.gateway)
|
if parameters.withNetworkSettings {
|
||||||
customBuilder.applyDNS(from: parameters.networkSettings.dns)
|
customBuilder.applyGateway(from: parameters.networkSettings.gateway)
|
||||||
customBuilder.applyProxy(from: parameters.networkSettings.proxy)
|
customBuilder.applyDNS(from: parameters.networkSettings.dns)
|
||||||
customBuilder.applyMTU(from: parameters.networkSettings.mtu)
|
customBuilder.applyProxy(from: parameters.networkSettings.proxy)
|
||||||
|
customBuilder.applyMTU(from: parameters.networkSettings.mtu)
|
||||||
|
}
|
||||||
|
|
||||||
let customConfiguration = customBuilder.build()
|
let customConfiguration = customBuilder.build()
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,11 @@ extension Profile.WireGuardSettings: VPNConfigurationProviding {
|
||||||
var customBuilder = configuration.builder()
|
var customBuilder = configuration.builder()
|
||||||
|
|
||||||
// network settings
|
// network settings
|
||||||
customBuilder.applyGateway(from: parameters.networkSettings.gateway)
|
if parameters.withNetworkSettings {
|
||||||
customBuilder.applyDNS(from: parameters.networkSettings.dns)
|
customBuilder.applyGateway(from: parameters.networkSettings.gateway)
|
||||||
customBuilder.applyMTU(from: parameters.networkSettings.mtu)
|
customBuilder.applyDNS(from: parameters.networkSettings.dns)
|
||||||
|
customBuilder.applyMTU(from: parameters.networkSettings.mtu)
|
||||||
|
}
|
||||||
|
|
||||||
let customConfiguration = customBuilder.build()
|
let customConfiguration = customBuilder.build()
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ extension VPNManager {
|
||||||
appGroup: profileManager.appGroup,
|
appGroup: profileManager.appGroup,
|
||||||
preferences: appManager.preferences,
|
preferences: appManager.preferences,
|
||||||
passwordReference: profileManager.passwordReference(forProfile: profile),
|
passwordReference: profileManager.passwordReference(forProfile: profile),
|
||||||
|
withNetworkSettings: isNetworkSettingsSupported(),
|
||||||
withCustomRules: isOnDemandRulesSupported()
|
withCustomRules: isOnDemandRulesSupported()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@ public class VPNManager: ObservableObject, RateLimited {
|
||||||
|
|
||||||
private let strategy: VPNManagerStrategy
|
private let strategy: VPNManagerStrategy
|
||||||
|
|
||||||
|
public var isNetworkSettingsSupported: () -> Bool
|
||||||
|
|
||||||
public var isOnDemandRulesSupported: () -> Bool
|
public var isOnDemandRulesSupported: () -> Bool
|
||||||
|
|
||||||
// MARK: State
|
// MARK: State
|
||||||
|
@ -72,6 +74,7 @@ public class VPNManager: ObservableObject, RateLimited {
|
||||||
self.profileManager = profileManager
|
self.profileManager = profileManager
|
||||||
self.providerManager = providerManager
|
self.providerManager = providerManager
|
||||||
self.strategy = strategy
|
self.strategy = strategy
|
||||||
|
isNetworkSettingsSupported = { true }
|
||||||
isOnDemandRulesSupported = { true }
|
isOnDemandRulesSupported = { true }
|
||||||
|
|
||||||
currentState = ObservableState()
|
currentState = ObservableState()
|
||||||
|
|
|
@ -47,6 +47,8 @@ struct VPNConfigurationParameters {
|
||||||
|
|
||||||
let passwordReference: Data?
|
let passwordReference: Data?
|
||||||
|
|
||||||
|
let withNetworkSettings: Bool
|
||||||
|
|
||||||
let onDemandRules: [NEOnDemandRule]
|
let onDemandRules: [NEOnDemandRule]
|
||||||
|
|
||||||
init(
|
init(
|
||||||
|
@ -54,6 +56,7 @@ struct VPNConfigurationParameters {
|
||||||
appGroup: String,
|
appGroup: String,
|
||||||
preferences: AppPreferences,
|
preferences: AppPreferences,
|
||||||
passwordReference: Data?,
|
passwordReference: Data?,
|
||||||
|
withNetworkSettings: Bool,
|
||||||
withCustomRules: Bool
|
withCustomRules: Bool
|
||||||
) {
|
) {
|
||||||
title = profile.header.name
|
title = profile.header.name
|
||||||
|
@ -62,6 +65,7 @@ struct VPNConfigurationParameters {
|
||||||
networkSettings = profile.networkSettings
|
networkSettings = profile.networkSettings
|
||||||
username = !profile.account.username.isEmpty ? profile.account.username : nil
|
username = !profile.account.username.isEmpty ? profile.account.username : nil
|
||||||
self.passwordReference = passwordReference
|
self.passwordReference = passwordReference
|
||||||
|
self.withNetworkSettings = withNetworkSettings
|
||||||
onDemandRules = profile.onDemand.rules(withCustomRules: withCustomRules)
|
onDemandRules = profile.onDemand.rules(withCustomRules: withCustomRules)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue