52 lines
1.7 KiB
Swift
52 lines
1.7 KiB
Swift
import Foundation
|
|
|
|
/// Authentication, session, and system info.
|
|
@MainActor
|
|
final class AuthRepository {
|
|
private let client: APIClient
|
|
private let session: SessionStore
|
|
private let config: APIConfiguration
|
|
|
|
init(client: APIClient, session: SessionStore, config: APIConfiguration) {
|
|
self.client = client
|
|
self.session = session
|
|
self.config = config
|
|
}
|
|
|
|
/// Logs in, then (optionally) selects the configured database. Auth state is
|
|
/// carried by cookies that `URLSession` stores automatically.
|
|
@discardableResult
|
|
func login(email: String, password: String) async throws -> AuthResponse {
|
|
let response: AuthResponse = try await client.send(
|
|
"POST", .authenticate,
|
|
body: AuthRequest(email: email, password: password),
|
|
wrapInData: false, // login body is sent unwrapped
|
|
as: AuthResponse.self
|
|
)
|
|
session.markAuthenticated()
|
|
if let db = config.databaseId {
|
|
try await selectDatabase(db)
|
|
}
|
|
return response
|
|
}
|
|
|
|
func selectDatabase(_ id: String) async throws {
|
|
// Body is `{ "data": "<db id>" }` — a bare string under the envelope.
|
|
let _: JSONValue = try await client.send(
|
|
"PUT", .databaseSelection,
|
|
body: id,
|
|
wrapInData: true,
|
|
as: JSONValue.self
|
|
)
|
|
}
|
|
|
|
func logout() async {
|
|
// Best effort; clear local session regardless of outcome.
|
|
_ = try? await client.action("GET", .logout, as: JSONValue.self)
|
|
session.clear()
|
|
}
|
|
|
|
func version() async throws -> VersionInfo {
|
|
try await client.get(.version, as: VersionInfo.self)
|
|
}
|
|
}
|