// // PersistentUserSessionRegistry.swift // shortcut // // Created by Bailey Townsend on 6/25/25. // import ATProtoKit import Foundation import SwiftData @MainActor public struct PersistentUserSessionRegistry: UserSessionRegistry { private var modelContext: ModelContext init(modelContext: ModelContext) { self.modelContext = modelContext } public func register(_ id: UUID, session: UserSession) async { let model = UserSessionToModel(id, session: session) self.modelContext.insert(model) do { try self.modelContext.save() } catch { print("Error saving user session: \(error)") } } public func getSession(for id: UUID) async -> UserSession? { let descriptor = FetchDescriptor( predicate: #Predicate { $0.id == id } ) do { let models = try self.modelContext.fetch(descriptor) guard let model = models.first else { return nil } return ModelToUserSession(model) } catch { return nil } } public func containsSession(for id: UUID) async -> Bool { let descriptor = FetchDescriptor( predicate: #Predicate { $0.id == id } ) do { let count = try self.modelContext.fetchCount(descriptor) return count > 0 } catch { return false } } public func removeSession(for id: UUID) async { let descriptor = FetchDescriptor( predicate: #Predicate { $0.id == id } ) do { let models = try self.modelContext.fetch(descriptor) for model in models { self.modelContext.delete(model) } try self.modelContext.save() } catch { // Handle error silently or log as needed } } public func removeAllSessions() async { let descriptor = FetchDescriptor() do { let models = try self.modelContext.fetch(descriptor) for model in models { self.modelContext.delete(model) } try self.modelContext.save() } catch { // Handle error silently or log as needed } } public func getAllSessions() async -> [UUID: UserSession] { let descriptor = FetchDescriptor() do { let models = try self.modelContext.fetch(descriptor) var sessions: [UUID: UserSession] = [:] for model in models { let session = ModelToUserSession(model) sessions[model.id] = session } return sessions } catch { return [:] } } } private func ModelToUserSession(_ model: UserSessionModel) -> UserSession { return UserSession( handle: model.handle, sessionDID: model.sessionDID, email: model.email, isEmailConfirmed: model.isEmailConfirmed, isEmailAuthenticationFactorEnabled: model.isEmailAuthenticationFactorEnabled, // didDocument: model.didDocument, isActive: model.isActive, status: model.status, serviceEndpoint: model.serviceEndpoint, pdsURL: model.pdsURL ) } private func UserSessionToModel(_ id: UUID, session: UserSession) -> UserSessionModel { return UserSessionModel( sessionId: id, handle: session.handle, sessionDID: session.sessionDID, email: session.email, isEmailConfirmed: session.isEmailConfirmed, isEmailAuthenticationFactorEnabled: session.isEmailAuthenticationFactorEnabled, // didDocument: session.didDocument, isActive: session.isActive, status: session.status, serviceEndpoint: session.serviceEndpoint, pdsURL: session.pdsURL) }