// // 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 } }