-
Notifications
You must be signed in to change notification settings - Fork 4
/
ExternalOAuthPresenter.swift
115 lines (102 loc) · 3.83 KB
/
ExternalOAuthPresenter.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//
// ExternalOAuthPresenter.swift
// AptoSDK
//
// Created by Ivan Oliver Martínez on 03/06/2018.
//
//
import Foundation
import AptoSDK
class ExternalOAuthPresenter: ExternalOAuthPresenterProtocol {
let config: ExternalOAuthModuleConfig
// swiftlint:disable implicitly_unwrapped_optional
var interactor: ExternalOAuthInteractorProtocol!
weak var router: ExternalOAuthRouterProtocol!
// swiftlint:enable implicitly_unwrapped_optional
let viewModel = ExternalOAuthViewModel()
var analyticsManager: AnalyticsServiceProtocol?
private var custodianType: String?
init(config: ExternalOAuthModuleConfig) {
self.config = config
}
func viewLoaded() {
viewModel.title.send(config.title)
viewModel.explanation.send(config.explanation)
viewModel.callToAction.send(config.callToAction)
viewModel.newUserAction.send(config.newUserAction)
viewModel.allowedBalanceTypes.send(config.allowedBalanceTypes)
viewModel.assetUrl.send(config.assetUrl)
analyticsManager?.track(event: Event.selectBalanceStoreLogin)
}
func balanceTypeTapped(_ balanceType: AllowedBalanceType) {
router.showLoadingView()
custodianType = balanceType.type
interactor.balanceTypeSelected(balanceType)
analyticsManager?.track(event: Event.selectBalanceStoreLoginConnectTap)
}
func closeTapped() {
router.backInExternalOAuth(true)
}
func show(error: NSError) {
viewModel.error.send(error)
}
func show(url: URL) {
router.hideLoadingView()
router.show(url: url) { [weak self] in
self?.router.showLoadingView()
self?.interactor.verifyOauthAttemptStatus() { [weak self] result in
self?.router.hideLoadingView()
guard let self = self else { return }
self.handleOauthAttemptVerificationResult(result: result)
}
}
}
func newUserTapped(url: URL) {
router.show(url: url) {}
}
private func handleOauthAttemptVerificationResult(result: Result<OauthAttempt, NSError>) {
guard let custodianType = self.custodianType else { return }
switch (result) {
case .failure(let error):
self.show(error: error)
case .success(let attempt):
switch (attempt.status) {
case .passed:
guard let credentials = attempt.credentials else { return }
let custodian = Custodian(custodianType: custodianType, name: custodianType)
custodian.externalCredentials = .oauth(credentials)
self.router.oauthSucceeded(custodian)
case .failed:
let error = NSError(
domain: "com.aptopayments.error",
code: 1,
userInfo: [NSLocalizedDescriptionKey: attempt.errorMessage(errorMessageKeys: config.oauthErrorMessageKeys) ?? ""])
self.show(error: error)
case .pending:
// Nothing to do here
break
}
}
}
}
extension OauthAttempt {
private var defaultErrorMessageKeys: [String] { return [
"select_balance_store.login.error_oauth_invalid_request.message",
"select_balance_store.login.error_oauth_unauthorised_client.message",
"select_balance_store.login.error_oauth_access_denied.message",
"select_balance_store.login.error_oauth_unsupported_response_type.message",
"select_balance_store.login.error_oauth_invalid_scope.message",
"select_balance_store.login.error_oauth_server_error.message",
"select_balance_store.login.error_oauth_temporarily_unavailable.message"
]
}
func errorMessage(errorMessageKeys: [String]? = nil) -> String? {
guard let error = self.error else { return nil }
let errorKeys = (errorMessageKeys ?? []) + defaultErrorMessageKeys
var errorKey = errorKeys.first(where: { $0.endsWith("\(error).message") })
if (errorKey == nil) {
errorKey = errorKeys.first(where: { $0.endsWith("\(error).unknown.message") })
}
return errorKey?.podLocalized().replace(["<<ERROR_MESSAGE>>": self.errorMessage ?? ""])
}
}