diff --git a/Library/Package.resolved b/Library/Package.resolved index 9ec767f9..36489554 100644 --- a/Library/Package.resolved +++ b/Library/Package.resolved @@ -41,7 +41,7 @@ "kind" : "remoteSourceControl", "location" : "git@github.com:passepartoutvpn/passepartoutkit-source", "state" : { - "revision" : "aa85d745f8419def59ef630501d71a491a32829e" + "revision" : "cfbcfd7106ee21781cb637eef8e15ed9a1463bce" } }, { diff --git a/Library/Package.swift b/Library/Package.swift index f0b88400..21b9d820 100644 --- a/Library/Package.swift +++ b/Library/Package.swift @@ -52,7 +52,7 @@ let package = Package( ], dependencies: [ // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", from: "0.12.0"), - .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "aa85d745f8419def59ef630501d71a491a32829e"), + .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "cfbcfd7106ee21781cb637eef8e15ed9a1463bce"), // .package(path: "../../passepartoutkit-source"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.9.1"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"), diff --git a/Library/Sources/CommonAPI/API/v5/providers/index.json b/Library/Sources/CommonAPI/API/v5/providers/index.json index 2c574331..b865c5af 100644 --- a/Library/Sources/CommonAPI/API/v5/providers/index.json +++ b/Library/Sources/CommonAPI/API/v5/providers/index.json @@ -18,7 +18,12 @@ "fullName": "Mullvad", "vpn": ["ovpn"], "configurations": { - "OpenVPN": {} + "OpenVPN": { + "credentials": { + "purpose": "web", + "options": ["noPassword"] + } + } } }, { "name": "nordvpn", diff --git a/Library/Sources/UILibrary/Views/Modules/OpenVPNView+Credentials.swift b/Library/Sources/UILibrary/Views/Modules/OpenVPNView+Credentials.swift index c61acbaa..37908eec 100644 --- a/Library/Sources/UILibrary/Views/Modules/OpenVPNView+Credentials.swift +++ b/Library/Sources/UILibrary/Views/Modules/OpenVPNView+Credentials.swift @@ -58,6 +58,9 @@ public struct OpenVPNCredentialsView: View { @State private var builder = OpenVPN.Credentials.Builder() + @State + private var providerConfiguration: OpenVPN.Credentials.ProviderConfiguration? + @State private var paywallReason: PaywallReason? @@ -89,29 +92,8 @@ public struct OpenVPNCredentialsView: View { } .themeManualInput() .modifier(PaywallModifier(reason: $paywallReason)) - .onLoad { - builder = credentials?.builder() ?? OpenVPN.Credentials.Builder() - builder.otp = nil - if isAuthenticating { - switch builder.otpMethod { - case .none: - focusedField = .username - - default: - focusedField = .otp - } - } - } - .onChange(of: builder) { - var copy = $0 - if isEligibleForInteractiveLogin { - copy.otp = copy.otp ?? "" - } else { - copy.otpMethod = .none - copy.otp = nil - } - credentials = copy.build() - } + .onLoad(perform: onLoad) + .onChange(of: builder, perform: onChange) } } @@ -151,7 +133,9 @@ private extension OpenVPNCredentialsView { Group { if !isAuthenticating || builder.otpMethod == .none { usernameField - passwordField + if !ignoresPassword { + passwordField + } } if isEligibleForInteractiveLogin, isAuthenticating, builder.otpMethod != .none { otpField @@ -162,7 +146,7 @@ private extension OpenVPNCredentialsView { @ViewBuilder var guidanceSection: some View { - if case .specific(let url) = providerPurpose, let url { + if let url = providerConfiguration?.url { Link(Strings.Modules.Openvpn.Credentials.Guidance.link, destination: url) } } @@ -171,11 +155,10 @@ private extension OpenVPNCredentialsView { if isAuthenticating { return builder.otpMethod.localizedDescription(style: .approachDescription) .nilIfEmpty - } else if let providerPurpose { - switch providerPurpose { + } else if let providerConfiguration { + switch providerConfiguration.purpose { case .web: return Strings.Modules.Openvpn.Credentials.Guidance.web - case .specific: return Strings.Modules.Openvpn.Credentials.Guidance.specific } @@ -229,11 +212,39 @@ private extension OpenVPNCredentialsView { [.none, .append, .encode] } - var providerPurpose: OpenVPN.Credentials.ProviderPurpose? { - guard let providerId, let metadata = providerManager.provider(withId: providerId) else { - return nil + var ignoresPassword: Bool { + providerConfiguration?.options?.contains(.noPassword) ?? false + } + + func onLoad() { + if let providerId, let metadata = providerManager.provider(withId: providerId) { + providerConfiguration = OpenVPN.Credentials.configuration(forProvider: metadata) } - return OpenVPN.Credentials.purpose(forProvider: metadata) + builder = credentials?.builder() ?? OpenVPN.Credentials.Builder() + if ignoresPassword { + builder.password = "" + } + builder.otp = nil + if isAuthenticating { + switch builder.otpMethod { + case .none: + focusedField = .username + + default: + focusedField = .otp + } + } + } + + func onChange(_ builder: OpenVPN.Credentials.Builder) { + var copy = builder + if isEligibleForInteractiveLogin { + copy.otp = copy.otp ?? "" + } else { + copy.otpMethod = .none + copy.otp = nil + } + credentials = copy.build() } }