This commit is contained in:
Peter Steinberger 2025-06-24 22:36:59 +02:00
parent 971e1f1b11
commit 15eea702ab
4 changed files with 20 additions and 23 deletions

View file

@ -192,7 +192,7 @@ final class AuthenticationService: ObservableObject {
/// Get token for query parameters (used for SSE) /// Get token for query parameters (used for SSE)
func getTokenForQuery() -> String? { func getTokenForQuery() -> String? {
return authToken authToken
} }
// MARK: - Private Methods // MARK: - Private Methods
@ -203,7 +203,6 @@ final class AuthenticationService: ObservableObject {
let userDataJson = try? KeychainService.loadPassword(for: userDataKey), let userDataJson = try? KeychainService.loadPassword(for: userDataKey),
let userDataData = userDataJson.data(using: .utf8), let userDataData = userDataJson.data(using: .utf8),
let userData = try? JSONDecoder().decode(UserData.self, from: userDataData) { let userData = try? JSONDecoder().decode(UserData.self, from: userDataData) {
// Check if token is less than 24 hours old // Check if token is less than 24 hours old
let tokenAge = Date().timeIntervalSince(userData.loginTime) let tokenAge = Date().timeIntervalSince(userData.loginTime)
if tokenAge < 24 * 60 * 60 { // 24 hours if tokenAge < 24 * 60 * 60 { // 24 hours
@ -231,10 +230,10 @@ final class AuthenticationService: ObservableObject {
extension APIError { extension APIError {
static func authenticationFailed(_ message: String) -> APIError { static func authenticationFailed(_ message: String) -> APIError {
return APIError.serverError(500, message) APIError.serverError(500, message)
} }
static var dataEncodingFailed: APIError { static var dataEncodingFailed: APIError {
return APIError.serverError(500, "Failed to encode authentication data") APIError.serverError(500, "Failed to encode authentication data")
} }
} }

View file

@ -98,12 +98,11 @@ struct ConnectionView: View {
LoginView( LoginView(
isPresented: $viewModel.showLoginView, isPresented: $viewModel.showLoginView,
serverConfig: config, serverConfig: config,
authenticationService: authService, authenticationService: authService
onSuccess: { ) {
// Authentication successful, mark as connected // Authentication successful, mark as connected
connectionManager.isConnected = true connectionManager.isConnected = true
} }
)
} }
} }
} }

View file

@ -217,9 +217,8 @@ struct LoginView_Previews: PreviewProvider {
authenticationService: AuthenticationService( authenticationService: AuthenticationService(
apiClient: APIClient.shared, apiClient: APIClient.shared,
serverConfig: ServerConfig(host: "localhost", port: 3000) serverConfig: ServerConfig(host: "localhost", port: 3000)
), )
onSuccess: {} ) {}
)
} }
} }
#endif #endif

View file

@ -6,29 +6,29 @@ extension Process {
func configureForParentTermination() { func configureForParentTermination() {
// Set quality of service to tie lifecycle to parent // Set quality of service to tie lifecycle to parent
self.qualityOfService = .userInitiated self.qualityOfService = .userInitiated
// On macOS, we can use process groups to ensure child termination // On macOS, we can use process groups to ensure child termination
// When the parent dies, all processes in the same process group receive SIGHUP // When the parent dies, all processes in the same process group receive SIGHUP
#if os(macOS) #if os(macOS)
// This will be called just before the process launches // This will be called just before the process launches
// We'll use posix_spawn attributes to set up the process group // We'll use posix_spawn attributes to set up the process group
if #available(macOS 10.15, *) { if #available(macOS 10.15, *) {
// Modern approach: let the system handle it // Modern approach: let the system handle it
// NSTask/Process on modern macOS automatically handles parent death // NSTask/Process on modern macOS automatically handles parent death
// when qualityOfService is set // when qualityOfService is set
} }
#endif #endif
} }
/// Enhanced run method that ensures proper process group setup /// Enhanced run method that ensures proper process group setup
func runWithParentTermination() throws { func runWithParentTermination() throws {
configureForParentTermination() configureForParentTermination()
try run() try run()
} }
/// Async version of runWithParentTermination /// Async version of runWithParentTermination
func runWithParentTerminationAsync() async throws { func runWithParentTerminationAsync() async throws {
configureForParentTermination() configureForParentTermination()
try await runAsync() try await runAsync()
} }
} }