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:
+1
-61
@@ -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,
|
||||
|
||||
+1
@@ -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
|
||||
|
||||
+4
-11
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -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(
|
||||
|
||||
+3
@@ -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,
|
||||
|
||||
+2
@@ -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,
|
||||
|
||||
+3
@@ -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 {
|
||||
|
||||
+1
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user