60 lines
1.5 KiB
Swift
60 lines
1.5 KiB
Swift
import SwiftUI
|
|
import LabWiseKit
|
|
|
|
@Observable
|
|
final class AppState {
|
|
var isAuthenticated: Bool = false
|
|
var currentUser: AuthUser?
|
|
|
|
static let shared = AppState()
|
|
|
|
private let authClient = AuthClient()
|
|
|
|
private init() {
|
|
// Wire 401 handler
|
|
APIClient.shared.onUnauthorized = { [weak self] in
|
|
guard let self else { return }
|
|
Task { @MainActor in
|
|
self.signedOut()
|
|
}
|
|
}
|
|
|
|
// If a session cookie exists, validate it with the server on launch
|
|
let hasCookie = HTTPCookieStorage.shared.cookies?.contains {
|
|
($0.name == "__Secure-better-auth.session_token" || $0.name == "better-auth.session_token")
|
|
&& !$0.value.isEmpty
|
|
} ?? false
|
|
if hasCookie {
|
|
// Optimistically show the authenticated UI, then validate
|
|
isAuthenticated = true
|
|
Task { @MainActor [weak self] in
|
|
await self?.validateExistingSession()
|
|
}
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
private func validateExistingSession() async {
|
|
do {
|
|
let user = try await authClient.fetchCurrentUser()
|
|
currentUser = user
|
|
isAuthenticated = true
|
|
} catch {
|
|
// Cookie was stale or invalid
|
|
signedOut()
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
func signedIn(user: AuthUser) {
|
|
currentUser = user
|
|
isAuthenticated = true
|
|
}
|
|
|
|
@MainActor
|
|
func signedOut() {
|
|
currentUser = nil
|
|
isAuthenticated = false
|
|
}
|
|
}
|