75 lines
2.1 KiB
Swift
75 lines
2.1 KiB
Swift
//
|
|
// Inception.swift
|
|
// PrivadoVPN
|
|
//
|
|
// Created by Juraldinio on 8/18/20.
|
|
// Copyright © 2020 Privado LLC. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
final class Inception {
|
|
|
|
|
|
private enum Constants {
|
|
|
|
// Hosts launching the app with url
|
|
static let auth = "auth"
|
|
static let purchaseList = "purchase_list"
|
|
}
|
|
|
|
// Credentials passed from url
|
|
private struct Credentials: Decodable {
|
|
let user: String
|
|
let pass: String
|
|
}
|
|
|
|
static func handle(url: URL) -> Route? {
|
|
|
|
guard let scheme = url.scheme,
|
|
scheme.localizedCaseInsensitiveCompare(PrivadoConstants.Application.urlScheme) == .orderedSame,
|
|
let host = url.host else { return nil }
|
|
|
|
switch host {
|
|
case Constants.auth:
|
|
if let token = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.first?.name {
|
|
return Self.authenticate(urlToken: token)
|
|
}
|
|
case Constants.purchaseList:
|
|
return .preference(tab: .upgrade)
|
|
default:
|
|
break
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
static func authenticate(urlToken: String) -> Route? {
|
|
|
|
let token = urlToken
|
|
.replacingOccurrences(of: "-", with: "+")
|
|
.replacingOccurrences(of: "_", with: "/")
|
|
|
|
guard let encrToken = Data(base64Encoded: String(token.suffix(token.count - 5)))
|
|
, let key = PrivadoConstants.Session.key.data(using: .utf8) else {
|
|
return nil
|
|
}
|
|
|
|
let blockSize = 16
|
|
let iv = encrToken.prefix(upTo: blockSize)
|
|
let message = encrToken.suffix(encrToken.count - blockSize)
|
|
|
|
guard let decrToken = CryptoAES(key: key, iv: iv).decrypt(data: message) else {
|
|
return nil
|
|
}
|
|
|
|
let credentials = decrToken.split(separator: ":").map { String($0) }
|
|
if credentials.count == 2
|
|
, let username = credentials.first
|
|
, let password = credentials.last {
|
|
return .login(type: .authenticate(username, password))
|
|
}
|
|
return nil
|
|
}
|
|
}
|