mirror of
https://github.com/passepartoutvpn/passepartout-apple.git
synced 2025-01-31 21:12:10 +00:00
Merge pull request #65 from passepartoutvpn/integrate-nordvpn
Integrate NordVPN
This commit is contained in:
commit
7a4ec7364f
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- NordVPN provider. [#65](https://github.com/passepartoutvpn/passepartout-ios/pull/65)
|
||||
|
||||
### Fixed
|
||||
|
||||
- VPN status cell doesn't always enter active profile. [#63](https://github.com/passepartoutvpn/passepartout-ios/issues/63)
|
||||
|
@ -282,6 +282,7 @@ internal enum Asset {
|
||||
}
|
||||
internal enum Providers {
|
||||
internal static let mullvad = ImageAsset(name: "mullvad")
|
||||
internal static let nordvpn = ImageAsset(name: "nordvpn")
|
||||
internal static let pia = ImageAsset(name: "pia")
|
||||
internal static let protonvpn = ImageAsset(name: "protonvpn")
|
||||
internal static let tunnelbear = ImageAsset(name: "tunnelbear")
|
||||
|
22
Passepartout-iOS/Providers.xcassets/nordvpn.imageset/Contents.json
vendored
Normal file
22
Passepartout-iOS/Providers.xcassets/nordvpn.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "nordvpn@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "nordvpn@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
BIN
Passepartout-iOS/Providers.xcassets/nordvpn.imageset/nordvpn@2x.png
vendored
Normal file
BIN
Passepartout-iOS/Providers.xcassets/nordvpn.imageset/nordvpn@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
Passepartout-iOS/Providers.xcassets/nordvpn.imageset/nordvpn@3x.png
vendored
Normal file
BIN
Passepartout-iOS/Providers.xcassets/nordvpn.imageset/nordvpn@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
@ -65,6 +65,9 @@ class AccountViewController: UIViewController, TableModelHost {
|
||||
case .mullvad:
|
||||
return V.mullvad(name.rawValue)
|
||||
|
||||
case .nordVPN:
|
||||
return V.nordvpn(name.rawValue)
|
||||
|
||||
case .pia:
|
||||
return V.pia(name.rawValue)
|
||||
|
||||
|
@ -861,6 +861,7 @@
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Passepartout-iOS/Pods-Passepartout-iOS-frameworks.sh",
|
||||
"${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework",
|
||||
"${PODS_ROOT}/OpenSSL-Apple/frameworks/iPhone/openssl.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/TunnelKit/TunnelKit.framework",
|
||||
);
|
||||
@ -870,6 +871,7 @@
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TunnelKit.framework",
|
||||
);
|
||||
@ -954,6 +956,7 @@
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Passepartout-CoreTests/Pods-Passepartout-CoreTests-frameworks.sh",
|
||||
"${PODS_ROOT}/OpenSSL-Apple/frameworks/iPhone/openssl.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/TunnelKit/TunnelKit.framework",
|
||||
);
|
||||
@ -962,6 +965,7 @@
|
||||
);
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TunnelKit.framework",
|
||||
);
|
||||
|
1
Passepartout/Resources/Web/net/nordvpn.json
Normal file
1
Passepartout/Resources/Web/net/nordvpn.json
Normal file
File diff suppressed because one or more lines are too long
@ -139,6 +139,7 @@
|
||||
|
||||
"account.sections.credentials.header" = "Credentials";
|
||||
"account.sections.guidance.footer.infrastructure.mullvad" = "Use your %@ website account number and password \"m\".";
|
||||
"account.sections.guidance.footer.infrastructure.nordvpn" = "Use your %@ website credentials. Your username is usually your e-mail.";
|
||||
"account.sections.guidance.footer.infrastructure.pia" = "Use your %@ website credentials. Your username is usually numeric with a \"p\" prefix.";
|
||||
"account.sections.guidance.footer.infrastructure.protonvpn" = "Find your %@ credentials in the \"Account > OpenVPN / IKEv2 Username\" section of the website.";
|
||||
"account.sections.guidance.footer.infrastructure.tunnelbear" = "Use your %@ website credentials. Your username is usually your e-mail.";
|
||||
|
@ -197,13 +197,16 @@ public class AppConstants {
|
||||
|
||||
public static let referrals: [Infrastructure.Name: String] = [
|
||||
.mullvad: "https://mullvad.net/en/account/create/",
|
||||
.nordVPN: "https://join.nordvpn.com/order/",
|
||||
.pia: "https://www.privateinternetaccess.com/pages/buy-vpn/",
|
||||
.protonVPN: "https://protonvpn.net/?aid=keeshux",
|
||||
.tunnelBear: "https://click.tunnelbear.com/aff_c?offer_id=2&aff_id=7464",
|
||||
.windscribe: "https://secure.link/kCsD0prd"
|
||||
]
|
||||
|
||||
public static let externalResources: [Infrastructure.Name: String] = [:]
|
||||
public static let externalResources: [Infrastructure.Name: String] = [
|
||||
.nordVPN: "https://downloads.nordcdn.com/configs/archives/certificates/servers.zip" // 9MB
|
||||
]
|
||||
}
|
||||
|
||||
public class Repos {
|
||||
@ -253,6 +256,11 @@ public class AppConstants {
|
||||
"MIT",
|
||||
"https://raw.githubusercontent.com/pia-foss/tunnel-apple/master/LICENSE"
|
||||
),
|
||||
License(
|
||||
"SSZipArchive",
|
||||
"MIT",
|
||||
"https://raw.githubusercontent.com/samsoffes/ssziparchive/master/LICENSE"
|
||||
),
|
||||
License(
|
||||
"SwiftGen",
|
||||
"MIT",
|
||||
|
@ -271,8 +271,8 @@ public class ConnectionService: Codable {
|
||||
}
|
||||
|
||||
// fix renamed pool, fall back to default
|
||||
if providerProfile.pool == nil {
|
||||
providerProfile.poolId = providerProfile.infrastructure.defaults.pool
|
||||
if providerProfile.pool == nil, let fallbackPool = providerProfile.infrastructure.defaultPool() {
|
||||
providerProfile.poolId = fallbackPool.id
|
||||
}
|
||||
|
||||
profile = providerProfile
|
||||
|
@ -40,7 +40,7 @@ public class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable {
|
||||
}
|
||||
|
||||
public var pool: Pool? {
|
||||
return infrastructure.pool(for: poolId) ?? infrastructure.pool(for: infrastructure.defaults.pool)
|
||||
return infrastructure.pool(for: poolId)
|
||||
}
|
||||
|
||||
public var presetId: String {
|
||||
@ -68,7 +68,7 @@ public class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable {
|
||||
|
||||
username = nil
|
||||
|
||||
poolId = infrastructure.defaults.pool
|
||||
poolId = infrastructure.defaultPool()?.id ?? infrastructure.defaults.pool
|
||||
presetId = infrastructure.defaults.preset
|
||||
}
|
||||
|
||||
|
@ -24,12 +24,14 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import TunnelKit
|
||||
import SSZipArchive
|
||||
|
||||
public struct Infrastructure: Codable {
|
||||
public enum Name: String, Codable, Comparable {
|
||||
case mullvad = "Mullvad"
|
||||
|
||||
case nordVPN = "NordVPN"
|
||||
|
||||
case pia = "PIA"
|
||||
|
||||
case protonVPN = "ProtonVPN"
|
||||
@ -62,10 +64,18 @@ public struct Infrastructure: Codable {
|
||||
return try JSONDecoder().decode(Infrastructure.self, from: json)
|
||||
}
|
||||
|
||||
public func defaultPool() -> Pool? {
|
||||
return pool(withPrefix: defaults.pool)
|
||||
}
|
||||
|
||||
public func pool(for identifier: String) -> Pool? {
|
||||
return pools.first { $0.id == identifier }
|
||||
}
|
||||
|
||||
public func pool(withPrefix prefix: String) -> Pool? {
|
||||
return pools.first { $0.id.hasPrefix(prefix) }
|
||||
}
|
||||
|
||||
public func preset(for identifier: String) -> InfrastructurePreset? {
|
||||
return presets.first { $0.id == identifier }
|
||||
}
|
||||
@ -87,10 +97,17 @@ extension Infrastructure.Name {
|
||||
}
|
||||
|
||||
public func importExternalResources(from url: URL, completionHandler: @escaping () -> Void) {
|
||||
var task: () -> Void
|
||||
switch self {
|
||||
case .nordVPN:
|
||||
task = {
|
||||
SSZipArchive.unzipFile(atPath: url.path, toDestination: self.externalURL.path)
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
task = {}
|
||||
}
|
||||
execute(task: task, completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
private func execute(task: @escaping () -> Void, completionHandler: @escaping () -> Void) {
|
||||
|
@ -58,6 +58,7 @@ public class InfrastructureFactory {
|
||||
// manually pre-sorted
|
||||
public let allNames: [Infrastructure.Name] = [
|
||||
.mullvad,
|
||||
.nordVPN,
|
||||
.pia,
|
||||
.protonVPN,
|
||||
.tunnelBear,
|
||||
|
@ -77,9 +77,12 @@ public struct Pool: Codable, Hashable, CustomStringConvertible {
|
||||
|
||||
public let hostname: String?
|
||||
|
||||
public let numericAddresses: [UInt32]
|
||||
public let numericAddresses: [UInt32]?
|
||||
|
||||
public func hasAddress(_ address: String) -> Bool {
|
||||
guard let numericAddresses = numericAddresses else {
|
||||
return false
|
||||
}
|
||||
guard let ipv4 = DNSResolver.ipv4(fromString: address) else {
|
||||
return false
|
||||
}
|
||||
@ -88,7 +91,7 @@ public struct Pool: Codable, Hashable, CustomStringConvertible {
|
||||
|
||||
// XXX: inefficient, can't easily use lazy on struct
|
||||
public func addresses() -> [String] {
|
||||
var addrs = numericAddresses.map { DNSResolver.string(fromIPv4: $0) }
|
||||
var addrs = numericAddresses?.map { DNSResolver.string(fromIPv4: $0) } ?? []
|
||||
if let hostname = hostname {
|
||||
addrs.insert(hostname, at: 0)
|
||||
}
|
||||
|
@ -102,6 +102,10 @@ public enum L10n {
|
||||
public static func mullvad(_ p1: String) -> String {
|
||||
return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.mullvad", p1)
|
||||
}
|
||||
/// Use your %@ website credentials. Your username is usually your e-mail.
|
||||
public static func nordvpn(_ p1: String) -> String {
|
||||
return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.nordvpn", p1)
|
||||
}
|
||||
/// Use your %@ website credentials. Your username is usually numeric with a "p" prefix.
|
||||
public static func pia(_ p1: String) -> String {
|
||||
return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.pia", p1)
|
||||
|
1
Podfile
1
Podfile
@ -9,6 +9,7 @@ def shared_pods
|
||||
pod 'TunnelKit/LZO', :git => 'https://github.com/keeshux/tunnelkit', :commit => '4af8305'
|
||||
#pod 'TunnelKit', :path => '../../personal/tunnelkit'
|
||||
#pod 'TunnelKit/LZO', :path => '../../personal/tunnelkit'
|
||||
pod 'SSZipArchive'
|
||||
end
|
||||
|
||||
target 'Passepartout-Core' do
|
||||
|
@ -1,6 +1,7 @@
|
||||
PODS:
|
||||
- MBProgressHUD (1.1.0)
|
||||
- OpenSSL-Apple (1.1.0i.2)
|
||||
- SSZipArchive (2.1.4)
|
||||
- SwiftyBeaver (1.7.0)
|
||||
- TunnelKit (1.6.2):
|
||||
- TunnelKit/AppExtension (= 1.6.2)
|
||||
@ -15,6 +16,7 @@ PODS:
|
||||
|
||||
DEPENDENCIES:
|
||||
- MBProgressHUD
|
||||
- SSZipArchive
|
||||
- TunnelKit (from `https://github.com/keeshux/tunnelkit`, commit `4af8305`)
|
||||
- TunnelKit/LZO (from `https://github.com/keeshux/tunnelkit`, commit `4af8305`)
|
||||
|
||||
@ -22,6 +24,7 @@ SPEC REPOS:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
- MBProgressHUD
|
||||
- OpenSSL-Apple
|
||||
- SSZipArchive
|
||||
- SwiftyBeaver
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
@ -37,9 +40,10 @@ CHECKOUT OPTIONS:
|
||||
SPEC CHECKSUMS:
|
||||
MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9
|
||||
OpenSSL-Apple: 37a8c0b04df4bb8971deef4671cc29222861319c
|
||||
SSZipArchive: 41455d4b8d2b6ab93990820b50dc697c2554a322
|
||||
SwiftyBeaver: 4cc0080d2e23f980652e28978db11a5c9da39165
|
||||
TunnelKit: 6be99150922d3f14187dc29732032712dd4400e3
|
||||
|
||||
PODFILE CHECKSUM: 2447c6354060c9edf9e9c5e1f1cf276750540090
|
||||
PODFILE CHECKSUM: 3eb482b1422e230476ee092236e7b47d3ac13025
|
||||
|
||||
COCOAPODS: 1.6.1
|
||||
|
@ -56,6 +56,7 @@ Passepartout is a VPN client and does absolutely nothing else without your conse
|
||||
Passepartout can connect to a few well-known VPN providers with an existing account:
|
||||
|
||||
- [Mullvad][app-net-mullvad]
|
||||
- [NordVPN][app-net-nordvpn]
|
||||
- [Private Internet Access][app-net-pia]
|
||||
- [ProtonVPN][app-net-protonvpn]
|
||||
- [TunnelBear][app-net-tunnelbear]
|
||||
@ -124,6 +125,7 @@ The country flags are taken from: <https://github.com/lipis/flag-icon-css/>
|
||||
|
||||
- MBProgressHUD - © 2009-2016 Matej Bukovinski
|
||||
- PIATunnel - © 2018-Present Private Internet Access
|
||||
- SSZipArchive - © 2010-2012 Sam Soffes
|
||||
- SwiftGen - © 2018 SwiftGen
|
||||
- SwiftyBeaver - © 2015 Sebastian Kreutzberger
|
||||
- lzo - © 1996-2017 Markus F.X.J. Oberhumer
|
||||
@ -146,6 +148,7 @@ Website: [passepartoutvpn.app][about-website]
|
||||
|
||||
[app-api]: https://github.com/passepartoutvpn/passepartout-api
|
||||
[app-net-mullvad]: https://mullvad.net/en/account/create/
|
||||
[app-net-nordvpn]: https://join.nordvpn.com/order/
|
||||
[app-net-pia]: https://www.privateinternetaccess.com/pages/buy-vpn/
|
||||
[app-net-protonvpn]: https://protonvpn.net/?aid=keeshux
|
||||
[app-net-tunnelbear]: https://click.tunnelbear.com/aff_c?offer_id=2&aff_id=7464
|
||||
|
@ -17,6 +17,7 @@ FEATURES
|
||||
|
||||
- Convenient presets for major VPN networks:
|
||||
- Mullvad
|
||||
- NordVPN
|
||||
- Private Internet Access
|
||||
- ProtonVPN
|
||||
- TunnelBear
|
||||
|
Loading…
Reference in New Issue
Block a user