Add AuthManager OSLog tracing and fix URL construction in APIEndpoints
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import KeychainAccess
|
import KeychainAccess
|
||||||
|
import OSLog
|
||||||
|
|
||||||
|
private let logger = Logger(subsystem: "com.timetracker.app", category: "AuthManager")
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
final class AuthManager: ObservableObject {
|
final class AuthManager: ObservableObject {
|
||||||
@@ -29,19 +32,23 @@ final class AuthManager: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkAuthState() async {
|
func checkAuthState() async {
|
||||||
guard accessToken != nil else {
|
guard let token = accessToken else {
|
||||||
|
logger.info("checkAuthState — no token in keychain, not authenticated")
|
||||||
isAuthenticated = false
|
isAuthenticated = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
logger.info("checkAuthState — token found (first 20 chars: \(token.prefix(20))…), calling /auth/me")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let user: User = try await apiClient.request(
|
let user: User = try await apiClient.request(
|
||||||
endpoint: APIEndpoint.me,
|
endpoint: APIEndpoint.me,
|
||||||
authenticated: true
|
authenticated: true
|
||||||
)
|
)
|
||||||
|
logger.info("checkAuthState — /auth/me OK, user: \(user.id)")
|
||||||
currentUser = user
|
currentUser = user
|
||||||
isAuthenticated = true
|
isAuthenticated = true
|
||||||
} catch {
|
} catch {
|
||||||
|
logger.error("checkAuthState — /auth/me failed: \(error.localizedDescription) — clearing auth")
|
||||||
clearAuth()
|
clearAuth()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,15 +74,18 @@ final class AuthManager: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func clearAuth() {
|
func clearAuth() {
|
||||||
|
logger.info("clearAuth — wiping token and user")
|
||||||
accessToken = nil
|
accessToken = nil
|
||||||
currentUser = nil
|
currentUser = nil
|
||||||
isAuthenticated = false
|
isAuthenticated = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleTokenResponse(_ response: TokenResponse) async {
|
func handleTokenResponse(_ response: TokenResponse) async {
|
||||||
|
logger.info("handleTokenResponse — storing JWT for user \(response.user.id)")
|
||||||
accessToken = response.accessToken
|
accessToken = response.accessToken
|
||||||
currentUser = response.user
|
currentUser = response.user
|
||||||
isAuthenticated = true
|
isAuthenticated = true
|
||||||
|
logger.info("handleTokenResponse — isAuthenticated = true, token stored: \(self.accessToken != nil)")
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginURL: URL {
|
var loginURL: URL {
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ enum APIEndpoint {
|
|||||||
|
|
||||||
struct APIEndpoints {
|
struct APIEndpoints {
|
||||||
static func url(for endpoint: String) -> URL {
|
static func url(for endpoint: String) -> URL {
|
||||||
AppConfig.apiBaseURL.appendingPathComponent(endpoint)
|
// Use URL(string:relativeTo:) rather than appendingPathComponent so that
|
||||||
|
// leading slashes in endpoint strings are handled correctly and don't
|
||||||
|
// accidentally replace or duplicate the base URL path.
|
||||||
|
let base = AppConfig.apiBaseURL.absoluteString.hasSuffix("/")
|
||||||
|
? AppConfig.apiBaseURL
|
||||||
|
: URL(string: AppConfig.apiBaseURL.absoluteString + "/")!
|
||||||
|
let relative = endpoint.hasPrefix("/") ? String(endpoint.dropFirst()) : endpoint
|
||||||
|
return URL(string: relative, relativeTo: base)!.absoluteURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user