blob: 6b773eb1421aadbc3ea2adaee6ec9dc5d258d07c (
plain) (
blame)
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
|
import Combine
import Foundation
@MainActor
final class SettingsViewModel: ObservableObject {
@Published private(set) var client: NjallaClient?
@Published private(set) var balance: WalletBalance?
@Published private(set) var isAuthenticated = false
@Published private(set) var isBootstrapped = false
@Published private(set) var isLoadingBalance = false
@Published var errorMessage: String?
private let keychainManager = KeychainManager()
var requiresOnboarding: Bool {
isBootstrapped && !isAuthenticated
}
func bootstrap() async {
guard !isBootstrapped else { return }
defer {
isBootstrapped = true
}
do {
guard let token = try keychainManager.readToken(), !token.isEmpty else {
isAuthenticated = false
client = nil
balance = nil
return
}
let client = NjallaClient(token: token)
self.client = client
isAuthenticated = true
try await refreshBalance()
} catch is CancellationError {
return
} catch {
if (error as? URLError)?.code == .cancelled {
return
}
errorMessage = error.localizedDescription
client = nil
balance = nil
isAuthenticated = false
}
}
func login(token: String) async throws {
let trimmedToken = token.trimmingCharacters(in: .whitespacesAndNewlines)
let client = NjallaClient(token: trimmedToken)
let balance = try await client.getBalance()
try keychainManager.saveToken(trimmedToken)
self.client = client
self.balance = balance
isAuthenticated = true
isBootstrapped = true
errorMessage = nil
}
func refreshBalance() async throws {
guard let client else { return }
isLoadingBalance = true
defer {
isLoadingBalance = false
}
do {
balance = try await client.getBalance()
errorMessage = nil
} catch is CancellationError {
throw CancellationError()
} catch {
if (error as? URLError)?.code == .cancelled {
throw error
}
errorMessage = error.localizedDescription
throw error
}
}
func logout() throws {
try keychainManager.deleteToken()
client = nil
balance = nil
isAuthenticated = false
errorMessage = nil
}
func logoutIfCurrentTokenDeleted(_ key: String) throws -> Bool {
guard let storedToken = try keychainManager.readToken(), storedToken == key else {
return false
}
try logout()
return true
}
}
|