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.
This commit is contained in:
2026-01-23 01:36:46 +01:00
parent d7cf8200e1
commit ec97b62afa
10 changed files with 18 additions and 106 deletions
@@ -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<KeycloakTokenResponse>()
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,
@@ -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
@@ -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)
}
}
@@ -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(
@@ -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,
@@ -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,
@@ -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 {
@@ -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
@@ -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.
}
@@ -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