Commit 4e20f726 authored by Jose Blaya's avatar Jose Blaya
Browse files

Merge branch 'release/1.1.8' into release/2.0.0

# Conflicts:
#	PIALibrary/Resources/UI/iOS/en.lproj/Welcome.strings
#	PIALibrary/Sources/Library/Client+Configuration.swift
parents 283d3554 dee3c84f
......@@ -10,7 +10,7 @@
"login.username.placeholder" = "Username (p1234567)";
"login.password.placeholder" = "Password";
"login.submit" = "LOGIN";
"login.restore.button" = "Couldn't get your plan?";
"login.restore.button" = "Didn't receive account details?";
"login.error.title" = "Log in";
"login.error.validation" = "You must enter a username and password.";
"login.error.unauthorized" = "Your username or password is incorrect.";
......
......@@ -17,6 +17,9 @@ public struct AccountInfo {
/// The currently subscribed `Plan`.
public let plan: Plan
/// The product id for the current subscription
public let productId: String?
/// Returns `true` if the account is eligible for renewal.
///
/// - Seealso: `AccountProvider.renew(...)`
......
......@@ -17,6 +17,12 @@ public enum Plan: String {
/// Plan expires/renews after one year.
case yearly
/// Plan expires/renews after one month (price before 2019).
case legacyMonthly
/// Plan expires/renews after one year (price before 2019).
case legacyYearly
/// It's a trial plan.
case trial
......
......@@ -449,14 +449,14 @@ class DefaultAccountProvider: AccountProvider, ConfigurationAccess, DatabaseAcce
case .trial:
callback?(nil, ClientError.renewingTrial)
return
case .monthly:
// callback?([.monthly, .yearly], nil)
callback?([.monthly], nil)
case .yearly:
callback?([.yearly], nil)
case .legacyMonthly:
callback?([.legacyMonthly], nil)
case .legacyYearly:
callback?([.yearly], nil)
case .other:
callback?(nil, ClientError.renewingNonRenewable)
}
......
......@@ -17,7 +17,7 @@ extension Client {
/// If `true`, expose development features.
public var isDevelopment: Bool
let publicKey: SecKey
var publicKey: SecKey?
// MARK: WebServices
......@@ -125,6 +125,10 @@ extension Client {
/// The value of the max of servers appearing in the quick connect tile.
public var maxQuickConnectServers: Int
// MARK: Access to Data PublicKey
private let accessQueue = DispatchQueue(label: "SynchronizedDataAccess",
attributes: .concurrent)
// MARK: Initialization
init() {
......@@ -134,24 +138,7 @@ extension Client {
let errorMessage = {
return "Cannot load PIA public key"
}
if let publicKey = database.secure.publicKeyEntry() {
self.publicKey = publicKey
} else {
guard let pubKeyFile = bundle.path(forResource: "PIA", ofType: "pub") else {
fatalError(errorMessage())
}
guard let pubKeyData = try? Data(contentsOf: URL(fileURLWithPath: pubKeyFile)) else {
fatalError(errorMessage())
}
guard let strippedData = pubKeyData.withStrippedASN1Header() else {
fatalError(errorMessage())
}
guard let publicKey = database.secure.setPublicKey(withData: strippedData) else {
fatalError(errorMessage())
}
self.publicKey = publicKey
}
let production = "https://www.privateinternetaccess.com"
baseUrls = [
.production: production
......@@ -208,6 +195,26 @@ extension Client {
#endif
maxQuickConnectServers = 6
if let publicKey = database.secure.publicKeyEntry() {
self.publicKey = publicKey
} else {
accessQueue.sync {
guard let pubKeyFile = bundle.path(forResource: "PIA", ofType: "pub") else {
fatalError(errorMessage())
}
guard let pubKeyData = try? Data(contentsOf: URL(fileURLWithPath: pubKeyFile)) else {
fatalError(errorMessage())
}
guard let strippedData = pubKeyData.withStrippedASN1Header() else {
fatalError(errorMessage())
}
guard let publicKey = database.secure.setPublicKey(withData: strippedData) else {
fatalError(errorMessage())
}
self.publicKey = publicKey
}
}
}
// MARK: WebServices
......
......@@ -29,11 +29,6 @@ public class IKEv2Profile: NetworkExtensionProfile {
return "IKEv2"
}
/// :nodoc:
public static var usernameAuthPrefix: String {
return "token_"
}
/// :nodoc:
public static var isTunnel: Bool {
return false
......@@ -153,9 +148,9 @@ public class IKEv2Profile: NetworkExtensionProfile {
/// :nodoc:
public func generatedProtocol(withConfiguration configuration: VPNConfiguration) -> NEVPNProtocol {
var iKEv2Username = IKEv2Profile.usernameAuthPrefix
if let username = Client.providers.accountProvider.publicUsername {
iKEv2Username += username
var iKEv2Username = ""
if let username = Client.providers.accountProvider.currentUser?.credentials.username {
iKEv2Username = username
}
let cfg = NEVPNProtocolIKEv2()
......
......@@ -14,6 +14,7 @@ class GlossAccountInfo: GlossParser {
required init?(json: JSON) {
let email: String? = "email" <~~ json
let productId: String? = "product_id" <~~ json
let plan: Plan = "plan" <~~ json ?? .other
guard let isRenewable: Bool = "renewable" <~~ json else {
return nil
......@@ -35,6 +36,7 @@ class GlossAccountInfo: GlossParser {
parsed = AccountInfo(
email: email,
plan: plan,
productId: productId,
isRenewable: isRenewable,
isRecurring: isRecurring,
expirationDate: Date(timeIntervalSince1970: expirationTime),
......@@ -49,6 +51,7 @@ extension AccountInfo: JSONEncodable {
public func toJSON() -> JSON? {
return jsonify([
"email" ~~> email,
"product_id" ~~> productId,
"plan" ~~> plan.rawValue,
"renewable" ~~> isRenewable,
"recurring" ~~> isRecurring,
......
......@@ -195,8 +195,9 @@ class PIAWebServices: WebServices, ConfigurationAccess {
callback?(nil, ClientError.malformedResponseData)
return
}
if self.accessedConfiguration.verifiesServersSignature {
guard response.verifySignature(publicKey: self.accessedConfiguration.publicKey) else {
if self.accessedConfiguration.verifiesServersSignature,
let key = self.accessedConfiguration.publicKey {
guard response.verifySignature(publicKey: key) else {
callback?(nil, ClientError.badServersSignature)
return
}
......
......@@ -53,6 +53,9 @@ public class MockAccountProvider: AccountProvider, WebServicesConsumer {
/// Fakes `AccountInfo.email`.
public var mockEmail: String = "mock@email.com"
/// Fakes `AccountInfo.product_id`.
public var mockProductId: String = "com.privateinternetaccess.ios.iap.2019.1month"
/// Fakes `AccountInfo.plan`.
public var mockPlan: Plan = .monthly
......@@ -88,6 +91,7 @@ public class MockAccountProvider: AccountProvider, WebServicesConsumer {
return AccountInfo(
email: self.mockEmail,
plan: self.mockPlan,
productId: self.mockProductId,
isRenewable: self.mockIsRenewable,
isRecurring: self.mockIsRecurring,
expirationDate: self.mockExpirationDate,
......
......@@ -158,7 +158,7 @@ internal enum L10n {
internal static let placeholder = L10n.tr("Welcome", "login.password.placeholder")
}
internal enum Restore {
/// Couldn't get your plan?
/// Didn't receive account details?
internal static let button = L10n.tr("Welcome", "login.restore.button")
}
internal enum Username {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment