206 lines
5.7 KiB
Swift
206 lines
5.7 KiB
Swift
//
|
|
// Customer.swift
|
|
// PrivadoVPN
|
|
//
|
|
// Created by Zhandos Bolatbekov on 01.02.2021.
|
|
// Copyright © 2021 Privado LLC. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
struct Customer: Decodable {
|
|
enum Plan: Decodable {
|
|
case freemium
|
|
case overquota
|
|
case premium(value: String)
|
|
case unrecognized(value: String)
|
|
|
|
init(from decoder: Decoder) throws {
|
|
let container = try decoder.singleValueContainer()
|
|
let plan = try container.decode(String.self)
|
|
switch plan {
|
|
case "FREE": self = .freemium
|
|
case "OVERQUOTA": self = .overquota
|
|
case _ where plan.hasPrefix("PREMIUM"): self = .premium(value: plan)
|
|
default: self = .unrecognized(value: plan)
|
|
}
|
|
}
|
|
}
|
|
|
|
let plan: Plan?
|
|
let email: String
|
|
let endDate: String
|
|
let username: String
|
|
let isPremium: Bool
|
|
let startDate: String
|
|
let premiumDate: String?
|
|
let serverGroup: String
|
|
let trafficLeft: UInt64?
|
|
let trafficTotal: UInt64?
|
|
let speedLimit: Int
|
|
let connectionsLimit: Int?
|
|
let loginUrl: String?
|
|
let isVPNActive: Bool?
|
|
let localIp: String?
|
|
let protocols: Protocols?
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case plan = "sku"
|
|
case email
|
|
case endDate = "end_date"
|
|
case username
|
|
case isPremium = "is_premium"
|
|
case startDate = "start_date"
|
|
case premiumDate = "premium_date"
|
|
case serverGroup = "server_group"
|
|
case trafficLeft = "traffic_left_mb"
|
|
case trafficTotal = "traffic_total_mb"
|
|
case speedLimit = "speed_limit_mbps"
|
|
case connectionsLimit = "connections_limit"
|
|
case loginUrl = "login_url"
|
|
case isVPNActive = "active_vpn"
|
|
case localIp = "local_ip"
|
|
case protocols
|
|
}
|
|
|
|
struct Response: Decodable {
|
|
let data: Customer?
|
|
}
|
|
struct Protocols: Decodable {
|
|
let ios: [ConnectionPriorityType]?
|
|
}
|
|
internal func isEmpty() -> Bool { self.username.isEmpty }
|
|
}
|
|
|
|
extension Customer.Plan: Equatable {
|
|
static func == (lhs: Self, rhs: Self) -> Bool {
|
|
switch (lhs, rhs) {
|
|
case (.freemium, .freemium),
|
|
(.overquota, .overquota):
|
|
return true
|
|
case let (.premium(lvalue), .premium(rvalue)),
|
|
let (.unrecognized(lvalue), .unrecognized(rvalue)):
|
|
return lvalue == rvalue
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Customer: Equatable {
|
|
|
|
static func == (lhs: Self, rhs: Self) -> Bool {
|
|
|
|
return lhs.plan == rhs.plan
|
|
&& lhs.email == rhs.email
|
|
&& lhs.username == rhs.username
|
|
&& lhs.endDate == rhs.endDate
|
|
&& lhs.isPremium == rhs.isPremium
|
|
&& lhs.startDate == rhs.startDate
|
|
&& lhs.premiumDate == rhs.premiumDate
|
|
&& lhs.serverGroup == rhs.serverGroup
|
|
&& lhs.trafficLeft == rhs.trafficLeft
|
|
&& lhs.trafficTotal == rhs.trafficTotal
|
|
&& lhs.speedLimit == rhs.speedLimit
|
|
&& lhs.connectionsLimit == rhs.connectionsLimit
|
|
&& lhs.loginUrl == rhs.loginUrl
|
|
&& lhs.isVPNActive == rhs.isVPNActive
|
|
}
|
|
}
|
|
|
|
enum ConnectionPriorityType: RawRepresentable, Decodable {
|
|
enum Constant {
|
|
static let prefix = "OPENVPN"
|
|
}
|
|
|
|
init?(rawValue: String) {
|
|
let rawValue = rawValue.uppercased()
|
|
if rawValue.hasPrefix(Constant.prefix) {
|
|
let strArray = rawValue.split(separator: "/")
|
|
let proto = OvpnProtocolType(rawValue: String(strArray[safe: 1] ?? "")) ?? .udp
|
|
let port = OvpnPortType(rawValue: String(strArray[safe: 2] ?? "")) ?? .p1194
|
|
self = .ovpn(proto: proto, port: port)
|
|
return
|
|
}
|
|
switch rawValue {
|
|
case "IKEV2": self = .ikev2
|
|
case "WIREGUARD": self = .wireguard
|
|
default: self = .ikev2
|
|
}
|
|
}
|
|
|
|
var rawValue: String {
|
|
switch self {
|
|
case .ikev2: return "IKEV2"
|
|
case .wireguard: return "WIREGUARD"
|
|
case .ovpn(proto: let proto, port: let port):
|
|
let protoStr = !proto.rawValue.isEmpty ? "/\(proto.rawValue)" : ""
|
|
let portStr = port.rawValue != 0 ? "/\(port.rawValue)" : ""
|
|
return "OPENVPN" + protoStr + portStr
|
|
}
|
|
}
|
|
|
|
typealias RawValue = String
|
|
|
|
case ikev2
|
|
case ovpn(proto: OvpnProtocolType, port: OvpnPortType)
|
|
case wireguard
|
|
|
|
static let defaultPriority: [ConnectionPriorityType] = [.ikev2 , .ovpn(proto: .udp, port: .p1194)]
|
|
|
|
public func ovpnSettings() -> (proto: OvpnProtocolType, port: OvpnPortType)? {
|
|
switch self {
|
|
case .ovpn(proto: let proto, port: let port): return (proto: proto, port: port)
|
|
default: return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
enum OvpnProtocolType: RawRepresentable {
|
|
typealias RawValue = String
|
|
|
|
var rawValue: String {
|
|
switch self {
|
|
case .udp: return "UDP"
|
|
case .tcp: return "TCP"
|
|
}
|
|
}
|
|
|
|
init?(rawValue: String) {
|
|
switch rawValue.uppercased() {
|
|
case "UDP": self = .udp
|
|
case "TCP": self = .tcp
|
|
default: self = .udp
|
|
}
|
|
}
|
|
case udp
|
|
case tcp
|
|
}
|
|
|
|
enum OvpnPortType: RawRepresentable, Decodable {
|
|
typealias RawValue = Int16
|
|
|
|
var rawValue: Int16 {
|
|
switch self {
|
|
case .p1194: return 1194
|
|
case .none: return 0
|
|
}
|
|
}
|
|
|
|
init?(rawValue: Int16) {
|
|
switch rawValue {
|
|
case 0: self = .none
|
|
case 1194: self = .p1194
|
|
default: self = .p1194
|
|
}
|
|
}
|
|
init?(rawValue: String) {
|
|
switch rawValue {
|
|
case "1194": self = .p1194
|
|
default: self = .p1194
|
|
}
|
|
}
|
|
case none
|
|
case p1194
|
|
}
|