diff options
| -rw-r--r-- | ios/MullvadVPN/Account.swift | 56 | ||||
| -rw-r--r-- | ios/MullvadVPN/MullvadAPI.swift | 47 |
2 files changed, 23 insertions, 80 deletions
diff --git a/ios/MullvadVPN/Account.swift b/ios/MullvadVPN/Account.swift index 065a04d111..942b8c5a39 100644 --- a/ios/MullvadVPN/Account.swift +++ b/ios/MullvadVPN/Account.swift @@ -27,11 +27,14 @@ enum AccountError: Error { /// A enum describing the error emitted during login enum AccountLoginError: Error { case invalidAccount + case network(MullvadAPI.Error) + case communication(MullvadAPI.ResponseError) case tunnelConfiguration(TunnelManagerError) } enum CreateAccountError: Error { - case newAccountToken + case network(MullvadAPI.Error) + case communication(MullvadAPI.ResponseError) case tunnelConfiguration(TunnelManagerError) } @@ -51,12 +54,15 @@ extension AccountError: LocalizedError { var failureReason: String? { switch self { - case .createNew(.newAccountToken): + case .createNew(.network), .createNew(.communication): return NSLocalizedString("Failed to create new account", comment: "") case .login(.invalidAccount): return NSLocalizedString("Invalid account", comment: "") + case .login(.network), .login(.communication): + return NSLocalizedString("Network error", comment: "") + case .login(.tunnelConfiguration(.setAccount(let setAccountError))), .createNew(.tunnelConfiguration(.setAccount(let setAccountError))): switch setAccountError { @@ -132,10 +138,10 @@ class Account { func loginWithNewAccount() -> AnyPublisher<String, AccountError> { return apiClient.createAccount() - .mapError { _ in CreateAccountError.newAccountToken } + .mapError { CreateAccountError.network($0) } .flatMap { (response) -> AnyPublisher<(String, Date), CreateAccountError> in response.result - .mapError { _ in CreateAccountError.newAccountToken } + .mapError { CreateAccountError.communication($0) } .publisher .flatMap { (accountToken) in TunnelManager.shared.setAccount(accountToken: accountToken) @@ -154,23 +160,18 @@ class Account { /// Perform the login and save the account token along with expiry (if available) to the /// application preferences. func login(with accountToken: String) -> AnyPublisher<(), AccountError> { - return apiClient.verifyAccount(accountToken: accountToken) - .setFailureType(to: AccountLoginError.self) - .handleEvents(receiveOutput: { (accountVerification) in - if case .deferred(let error) = accountVerification { - os_log(.error, "Failed to verify the account: %{public}s", error.localizedDescription) - } - }) - .flatMap { - self.handleVerification($0).publisher - .flatMap { (expiry) in - TunnelManager.shared.setAccount(accountToken: accountToken) - .mapError { AccountLoginError.tunnelConfiguration($0) } - .map { expiry } - } - }.mapError { AccountError.login($0) } - .receive(on: DispatchQueue.main).map { (expiry) in - self.saveAccountToPreferences(accountToken: accountToken, expiry: expiry) + return apiClient.getAccountExpiry(accountToken: accountToken) + .mapError { AccountLoginError.network($0) } + .flatMap { (response) in + response.result + .mapError { AccountLoginError.communication($0) } + .publisher + }.flatMap { (expiry) in + TunnelManager.shared.setAccount(accountToken: accountToken) + .mapError { AccountLoginError.tunnelConfiguration($0) } + .map { expiry } + }.mapError { AccountError.login($0) }.receive(on: DispatchQueue.main).map { (expiry) in + self.saveAccountToPreferences(accountToken: accountToken, expiry: expiry) }.eraseToAnyPublisher() } @@ -183,18 +184,7 @@ class Account { .eraseToAnyPublisher() } - private func handleVerification(_ verification: AccountVerification) -> Result<Date?, AccountLoginError> { - switch verification { - case .deferred: - return .success(nil) - case .verified(let expiry): - return .success(expiry) - case .invalid: - return .failure(.invalidAccount) - } - } - - private func saveAccountToPreferences(accountToken: String, expiry: Date?) { + private func saveAccountToPreferences(accountToken: String, expiry: Date) { let preferences = UserDefaults.standard preferences.set(accountToken, forKey: UserDefaultsKeys.accountToken.rawValue) diff --git a/ios/MullvadVPN/MullvadAPI.swift b/ios/MullvadVPN/MullvadAPI.swift index 4fbaa1d430..95a01a27a7 100644 --- a/ios/MullvadVPN/MullvadAPI.swift +++ b/ios/MullvadVPN/MullvadAPI.swift @@ -16,28 +16,6 @@ private let kMullvadAPIURL = URL(string: "https://api.mullvad.net/rpc/")! /// Network request timeout in seconds private let kNetworkTimeout: TimeInterval = 10 -/// A type that describes the account verification result -enum AccountVerification { - /// The app should attempt to verify the account token at some point later because the network - /// may not be available at this time. - case deferred(DeferReasonError) - - /// The app successfully verified the account token with the server - case verified(Date) - - // Invalid token - case invalid -} - -/// An error type that describes why the account verification was deferred -enum DeferReasonError: Error { - /// Mullvad API communication error - case communication(MullvadAPI.Error) - - /// Mullvad API responded with an error - case server(MullvadAPI.ResponseError) -} - /// A response received when sending the AppStore receipt to the backend struct SendAppStoreReceiptResponse: Codable { let timeAdded: TimeInterval @@ -132,31 +110,6 @@ class MullvadAPI { return MullvadAPI.makeDataTaskPublisher(request: request) } - func verifyAccount(accountToken: String) -> AnyPublisher<AccountVerification, Never> { - return getAccountExpiry(accountToken: accountToken) - .map({ (response) -> AccountVerification in - switch response.result { - case .success(let expiry): - // Report .verified when expiry is successfully received - return .verified(expiry) - - case .failure(let serverError): - if case .accountDoesNotExist = serverError.code { - // Report .invalid account if the server responds with the special code - return .invalid - } else { - // Otherwise report .deferred and pass the server error along - return .deferred(.server(serverError)) - } - } - }) - .catch({ (networkError) in - // Treat all communication errors as .deferred verification - return Just(.deferred(.communication(networkError))) - }) - .eraseToAnyPublisher() - } - func pushWireguardKey(accountToken: String, publicKey: Data) -> AnyPublisher<Response<WireguardAssociatedAddresses>, MullvadAPI.Error> { let request = JsonRpcRequest(method: "push_wg_key", params: [ AnyEncodable(accountToken), |
