From ec97b62afafdee843884df200541439a87fb1c6e Mon Sep 17 00:00:00 2001 From: StefanMoCoAt Date: Fri, 23 Jan 2026 01:36:46 +0100 Subject: [PATCH] refactor(auth, design-system): remove unused methods and annotations for cleanup - Deleted obsolete methods such as `exchangeAuthorizationCode` and `logout` from the Auth module. - Removed unused browser PKCE utilities and associated constants. - Annotated unused components across the Design System with `@Suppress("unused")` for clarity. - Simplified `LoginViewModel` to handle logout by clearing UI state directly. --- .../frontend/core/auth/data/AuthApiClient.kt | 62 +------------------ .../core/auth/data/AuthTokenManager.kt | 1 + .../core/auth/presentation/LoginViewModel.kt | 15 ++--- .../designsystem/components/AppScaffold.kt | 1 + .../components/LoadingIndicator.kt | 3 + .../components/MeldestelleButton.kt | 2 + .../components/MeldestelleTextField.kt | 3 + .../core/designsystem/theme/AppTheme.kt | 1 + .../at/mocode/shared/core/AppConstants.kt | 31 +--------- .../src/commonMain/kotlin/MainApp.kt | 5 -- 10 files changed, 18 insertions(+), 106 deletions(-) diff --git a/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/data/AuthApiClient.kt b/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/data/AuthApiClient.kt index a77b7b55..ff6d88c9 100644 --- a/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/data/AuthApiClient.kt +++ b/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/data/AuthApiClient.kt @@ -3,19 +3,11 @@ package at.mocode.frontend.core.auth.data import at.mocode.shared.core.AppConstants import io.ktor.client.* import io.ktor.client.call.* +import io.ktor.client.request.* import io.ktor.client.request.forms.* import io.ktor.http.* import kotlinx.serialization.Serializable -/** - * Data classes for authentication API communication - */ -@Serializable -data class LoginRequest( - val username: String, - val password: String -) - @Serializable data class LoginResponse( val success: Boolean, @@ -85,49 +77,6 @@ class AuthApiClient( } } - /** - * Exchange an authorization code (PKCE) for tokens - */ - suspend fun exchangeAuthorizationCode(code: String, codeVerifier: String, redirectUri: String): LoginResponse { - val tokenEndpoint = "$keycloakBaseUrl/realms/$realm/protocol/openid-connect/token" - return try { - val response = httpClient.submitForm( - url = tokenEndpoint, - formParameters = Parameters.build { - append("grant_type", "authorization_code") - append("client_id", clientId) - if (!clientSecret.isNullOrBlank()) { - append("client_secret", clientSecret) - } - append("code", code) - append("code_verifier", codeVerifier) - append("redirect_uri", redirectUri) - } - ) { - contentType(ContentType.Application.FormUrlEncoded) - } - - if (response.status.isSuccess()) { - val kc = response.body() - LoginResponse( - success = true, - token = kc.access_token, - message = null - ) - } else { - LoginResponse( - success = false, - message = "Code-Exchange fehlgeschlagen: HTTP ${'$'}{response.status.value}" - ) - } - } catch (e: Exception) { - LoginResponse( - success = false, - message = "Code-Exchange Fehler: ${'$'}{e.message}" - ) - } - } - /** * Refresh authentication token */ @@ -169,15 +118,6 @@ class AuthApiClient( } } - /** - * Logout and invalidate token - */ - suspend fun logout(token: String): Boolean { - // Empfehlung: Frontend-seitig Token lokal verwerfen. - // Optional könnten hier Keycloak-Endpoints für Token-Revocation aufgerufen werden. - return true - } - @Serializable private data class KeycloakTokenResponse( val access_token: String, diff --git a/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/data/AuthTokenManager.kt b/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/data/AuthTokenManager.kt index ccf6a1e7..f9ff5b6c 100644 --- a/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/data/AuthTokenManager.kt +++ b/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/data/AuthTokenManager.kt @@ -70,6 +70,7 @@ data class AuthState( * to prevent XSS attacks. The token is lost when the browser tab is closed * or refreshed, requiring re-authentication. */ +@Suppress("unused") class AuthTokenManager { private var currentToken: String? = null diff --git a/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/presentation/LoginViewModel.kt b/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/presentation/LoginViewModel.kt index 3838f917..f91db027 100644 --- a/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/presentation/LoginViewModel.kt +++ b/frontend/core/auth/src/commonMain/kotlin/at/mocode/frontend/core/auth/presentation/LoginViewModel.kt @@ -46,6 +46,10 @@ class LoginViewModel( _uiState.value = _uiState.value.copy( isAuthenticated = authState.isAuthenticated ) + // If logged out, clear credentials + if (!authState.isAuthenticated) { + _uiState.value = LoginUiState() + } } } } @@ -129,15 +133,4 @@ class LoginViewModel( } } } - - fun logout() { - authTokenManager.clearToken() - // Reset UI state (clear username/password) - _uiState.value = LoginUiState() - } - - fun checkAuthenticationStatus() { - val isAuthenticated = authTokenManager.hasValidToken() - _uiState.value = _uiState.value.copy(isAuthenticated = isAuthenticated) - } } diff --git a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/AppScaffold.kt b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/AppScaffold.kt index 6d74c8d2..b73c63e0 100644 --- a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/AppScaffold.kt +++ b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/AppScaffold.kt @@ -7,6 +7,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +@Suppress("unused") @OptIn(ExperimentalMaterial3Api::class) @Composable fun AppScaffold( diff --git a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/LoadingIndicator.kt b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/LoadingIndicator.kt index d0136834..6ad1106f 100644 --- a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/LoadingIndicator.kt +++ b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/LoadingIndicator.kt @@ -51,6 +51,7 @@ fun LoadingIndicator( } } +@Suppress("unused") @Composable fun FullScreenLoading( message: String = "Loading...", @@ -67,6 +68,7 @@ fun FullScreenLoading( } } +@Suppress("unused") @Composable fun InlineLoading( message: String? = null, @@ -84,6 +86,7 @@ fun InlineLoading( } } +@Suppress("unused") @Composable fun LinearLoadingIndicator( modifier: Modifier = Modifier, diff --git a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MeldestelleButton.kt b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MeldestelleButton.kt index ff6c853c..91cbac63 100644 --- a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MeldestelleButton.kt +++ b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MeldestelleButton.kt @@ -87,6 +87,7 @@ private fun ButtonContent( } } +@Suppress("unused") @Composable fun PrimaryButton( text: String, @@ -105,6 +106,7 @@ fun PrimaryButton( fullWidth = fullWidth ) +@Suppress("unused") @Composable fun SecondaryButton( text: String, diff --git a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MeldestelleTextField.kt b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MeldestelleTextField.kt index edfcb103..f6d76bee 100644 --- a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MeldestelleTextField.kt +++ b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MeldestelleTextField.kt @@ -92,6 +92,7 @@ fun MeldestelleTextField( } } +@Suppress("unused") @Composable fun MeldestellePasswordField( value: String, @@ -136,6 +137,7 @@ fun MeldestellePasswordField( ) } +@Suppress("unused") @Composable fun MeldestelleEmailField( value: String, @@ -169,6 +171,7 @@ fun MeldestelleEmailField( /** * Form validation utilities */ +@Suppress("unused") object FormValidation { fun validateEmail(email: String): String? { return when { diff --git a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/theme/AppTheme.kt b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/theme/AppTheme.kt index 2c327445..fd538b09 100644 --- a/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/theme/AppTheme.kt +++ b/frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/theme/AppTheme.kt @@ -35,6 +35,7 @@ private val DarkColorScheme = darkColorScheme( onSurface = Color(0xFFE0E0E0) ) +@Suppress("unused") @Composable fun AppTheme( darkTheme: Boolean = false, // For now, we'll default to light theme diff --git a/frontend/shared/src/commonMain/kotlin/at/mocode/shared/core/AppConstants.kt b/frontend/shared/src/commonMain/kotlin/at/mocode/shared/core/AppConstants.kt index cbe40c6c..75375cc8 100644 --- a/frontend/shared/src/commonMain/kotlin/at/mocode/shared/core/AppConstants.kt +++ b/frontend/shared/src/commonMain/kotlin/at/mocode/shared/core/AppConstants.kt @@ -6,6 +6,7 @@ package at.mocode.shared.core */ object AppConstants { // Gateway base URL (reverse proxy / API gateway) + // Used by NetworkConfig via PlatformConfig const val GATEWAY_URL: String = "http://localhost:8081" // Keycloak configuration @@ -21,33 +22,5 @@ object AppConstants { // For the Desktop App Pilot, we use this to simulate a secure client. const val KEYCLOAK_CLIENT_SECRET: String = "postman-secret-123" - // Default redirect URI for web PKCE flow (served by Nginx in web image) - // We use the root path so Keycloak can redirect back to /?code=... - fun webRedirectUri(): String = "http://localhost:4000/" - - fun registerUrl(): String = - "$KEYCLOAK_URL/realms/$KEYCLOAK_REALM/protocol/openid-connect/registrations?client_id=web-app&response_type=code&redirect_uri=${ - encode( - webRedirectUri() - ) - }" - - fun loginUrl(): String = - "$KEYCLOAK_URL/realms/$KEYCLOAK_REALM/protocol/openid-connect/auth?client_id=web-app&response_type=code&redirect_uri=${ - encode( - webRedirectUri() - ) - }" - - fun authorizeEndpoint(): String = - "$KEYCLOAK_URL/realms/$KEYCLOAK_REALM/protocol/openid-connect/auth" - - fun tokenEndpoint(): String = - "$KEYCLOAK_URL/realms/$KEYCLOAK_REALM/protocol/openid-connect/token" - - fun desktopDownloadUrl(): String = "http://localhost:4000/downloads/" - - // Helper to URL-encode values (very small percent-encoding sufficient for URIs here) - private fun encode(value: String): String = - value.replace("://", ":%2F%2F").replace("/", "%2F").replace(":", "%3A") + // Removed unused browser flow URLs (registerUrl, loginUrl, etc.) as we focus on Desktop App. } diff --git a/frontend/shells/meldestelle-portal/src/commonMain/kotlin/MainApp.kt b/frontend/shells/meldestelle-portal/src/commonMain/kotlin/MainApp.kt index c3c7b229..c549f02e 100644 --- a/frontend/shells/meldestelle-portal/src/commonMain/kotlin/MainApp.kt +++ b/frontend/shells/meldestelle-portal/src/commonMain/kotlin/MainApp.kt @@ -4,20 +4,15 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.unit.dp import androidx.compose.runtime.collectAsState import at.mocode.clients.shared.navigation.AppScreen import at.mocode.frontend.core.auth.data.AuthTokenManager -import at.mocode.frontend.core.auth.data.AuthApiClient import at.mocode.frontend.core.auth.presentation.LoginScreen import at.mocode.frontend.core.auth.presentation.LoginViewModel import at.mocode.ping.feature.presentation.PingScreen import at.mocode.ping.feature.presentation.PingViewModel -import at.mocode.shared.core.AppConstants import at.mocode.frontend.core.designsystem.components.AppFooter -import kotlinx.coroutines.launch -import androidx.compose.runtime.rememberCoroutineScope import org.koin.compose.koinInject import org.koin.compose.viewmodel.koinViewModel