chore(infra): Network/Auth – DoD schließen
- Entfernen/Deprecaten: `frontend/features/auth-feature/.../AuthenticatedHttpClient.kt` und alle manuellen `Authorization`‑Header‑Setzungen.
- Stattdessen: DI‑`apiClient` via Koin injizieren (`single(named("apiClient"))`) und Token‑Anreicherung über Ktor `Auth` Plugin (Bearer) verdrahten.
- Build‑Guard ergänzen: Auch Vorkommen von `HttpHeaders.Authorization` erkennen.
This commit is contained in:
@@ -61,6 +61,12 @@ kotlin {
|
||||
implementation(libs.ktor.client.logging)
|
||||
implementation(libs.ktor.client.auth)
|
||||
|
||||
// DI
|
||||
implementation(libs.koin.core)
|
||||
|
||||
// Network core (provides apiClient + TokenProvider)
|
||||
implementation(projects.frontend.core.network)
|
||||
|
||||
// Coroutines and serialization
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
|
||||
+4
-1
@@ -5,6 +5,9 @@ import io.ktor.client.call.*
|
||||
import io.ktor.client.request.forms.*
|
||||
import io.ktor.http.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import io.ktor.client.HttpClient
|
||||
import org.koin.core.context.GlobalContext
|
||||
import org.koin.core.qualifier.named
|
||||
|
||||
/**
|
||||
* Data classes for authentication API communication
|
||||
@@ -37,7 +40,7 @@ class AuthApiClient(
|
||||
// Optional: Client-Secret (nur bei vertraulichen Clients erforderlich)
|
||||
private val clientSecret: String? = null
|
||||
) {
|
||||
private val client = AuthenticatedHttpClient.createUnauthenticated()
|
||||
private val client: HttpClient by lazy { GlobalContext.get().koin.get<HttpClient>(named("apiClient")) }
|
||||
|
||||
/**
|
||||
* Authenticate user with username and password
|
||||
|
||||
+7
-7
@@ -2,9 +2,10 @@ package at.mocode.clients.authfeature
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import at.mocode.clients.authfeature.AuthenticatedHttpClient.addAuthHeader
|
||||
import at.mocode.shared.core.AppConstants
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.request.post
|
||||
import org.koin.core.context.GlobalContext
|
||||
import org.koin.core.qualifier.named
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
@@ -37,6 +38,7 @@ class LoginViewModel(
|
||||
val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()
|
||||
|
||||
private val authApiClient = AuthApiClient()
|
||||
private val apiClient: HttpClient by lazy { GlobalContext.get().koin.get<HttpClient>(named("apiClient")) }
|
||||
|
||||
fun updateUsername(username: String) {
|
||||
_uiState.value = _uiState.value.copy(
|
||||
@@ -96,10 +98,8 @@ class LoginViewModel(
|
||||
// Fire-and-forget: Trigger Backend Sync so the user exists in Members
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val client = AuthenticatedHttpClient.create()
|
||||
client.post("${AppConstants.GATEWAY_URL}/api/members/sync") {
|
||||
addAuthHeader()
|
||||
}
|
||||
// Fire-and-forget sync call; Bearer token added by Ktor Auth plugin
|
||||
apiClient.post("/api/members/sync")
|
||||
} catch (_: Exception) {
|
||||
// Non-fatal: Wir zeigen Sync-Fehler im Login nicht an
|
||||
}
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package at.mocode.clients.authfeature.di
|
||||
|
||||
import at.mocode.clients.authfeature.AuthTokenManager
|
||||
import at.mocode.frontend.core.network.TokenProvider
|
||||
import org.koin.dsl.module
|
||||
|
||||
/**
|
||||
* Koin module for auth-feature: provides AuthTokenManager and binds it as TokenProvider for apiClient.
|
||||
*/
|
||||
val authFeatureModule = module {
|
||||
// Single in-memory token manager
|
||||
single { AuthTokenManager() }
|
||||
|
||||
// Bridge to core network TokenProvider without adding a hard dependency there
|
||||
single<TokenProvider> {
|
||||
object : TokenProvider {
|
||||
override fun getAccessToken(): String? = get<AuthTokenManager>().getToken()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user