feat(MP-29): navigation core module, auth guards & shell wiring\n\n- Establish :frontend:core:navigation module with DeepLinkHandler\n- Introduce NavigationPort & CurrentUserProvider (DI)\n- Harden admin routes against AppRoles.ADMIN\n- Wire Koin in JS/JVM/Wasm shells (navigationModule)\n- Remove legacy DeepLinkHandler from shared\n- Add unit tests for guard logic\n\nRef: MP-29 (#24)
This commit is contained in:
+39
@@ -0,0 +1,39 @@
|
||||
package navigation
|
||||
|
||||
import at.mocode.clients.authfeature.AuthTokenManager
|
||||
import at.mocode.frontend.core.domain.models.User
|
||||
import at.mocode.frontend.core.navigation.CurrentUserProvider
|
||||
import at.mocode.frontend.core.navigation.DeepLinkHandler
|
||||
import at.mocode.frontend.core.navigation.NavigationPort
|
||||
import org.koin.dsl.module
|
||||
|
||||
class ShellCurrentUserProvider(
|
||||
private val authTokenManager: AuthTokenManager,
|
||||
) : CurrentUserProvider {
|
||||
override fun getCurrentUser(): User? {
|
||||
val state = authTokenManager.authState.value
|
||||
if (!state.isAuthenticated) return null
|
||||
// Roles are not yet modeled in AuthState; provide empty list for now
|
||||
return User(
|
||||
id = state.userId ?: state.username ?: "unknown",
|
||||
username = state.username ?: state.userId ?: "unknown",
|
||||
displayName = null,
|
||||
roles = emptyList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class NoopNavigationPort : NavigationPort {
|
||||
var lastRoute: String? = null
|
||||
override fun navigateTo(route: String) {
|
||||
lastRoute = route
|
||||
// Simple logging; actual routing is handled elsewhere in the shell
|
||||
println("[NavigationPort] navigateTo $route")
|
||||
}
|
||||
}
|
||||
|
||||
val navigationModule = module {
|
||||
single<CurrentUserProvider> { ShellCurrentUserProvider(get()) }
|
||||
single<NavigationPort> { NoopNavigationPort() }
|
||||
single { DeepLinkHandler(get(), get()) }
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import at.mocode.frontend.core.network.networkModule
|
||||
import at.mocode.clients.authfeature.di.authFeatureModule
|
||||
import at.mocode.frontend.core.localdb.localDbModule
|
||||
import at.mocode.frontend.core.localdb.DatabaseProvider
|
||||
import navigation.navigationModule
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.context.GlobalContext
|
||||
@@ -20,8 +21,8 @@ fun main() {
|
||||
console.log("[WebApp] main() entered")
|
||||
// Initialize DI (Koin) with shared modules + network + local DB modules
|
||||
try {
|
||||
initKoin { modules(networkModule, localDbModule, authFeatureModule) }
|
||||
console.log("[WebApp] Koin initialized with networkModule + localDbModule + authFeatureModule")
|
||||
initKoin { modules(networkModule, localDbModule, authFeatureModule, navigationModule) }
|
||||
console.log("[WebApp] Koin initialized with networkModule + localDbModule + authFeatureModule + navigationModule")
|
||||
} catch (e: dynamic) {
|
||||
console.warn("[WebApp] Koin initialization warning:", e)
|
||||
}
|
||||
|
||||
@@ -5,12 +5,13 @@ import androidx.compose.ui.unit.dp
|
||||
import at.mocode.shared.di.initKoin
|
||||
import at.mocode.frontend.core.network.networkModule
|
||||
import at.mocode.clients.authfeature.di.authFeatureModule
|
||||
import navigation.navigationModule
|
||||
|
||||
fun main() = application {
|
||||
// Initialize DI (Koin) with shared modules + network module
|
||||
try {
|
||||
initKoin { modules(networkModule, authFeatureModule) }
|
||||
println("[DesktopApp] Koin initialized with networkModule + authFeatureModule")
|
||||
initKoin { modules(networkModule, authFeatureModule, navigationModule) }
|
||||
println("[DesktopApp] Koin initialized with networkModule + authFeatureModule + navigationModule")
|
||||
} catch (e: Exception) {
|
||||
println("[DesktopApp] Koin initialization warning: ${e.message}")
|
||||
}
|
||||
|
||||
@@ -6,13 +6,14 @@ import org.w3c.dom.HTMLElement
|
||||
import at.mocode.shared.di.initKoin
|
||||
import at.mocode.frontend.core.network.networkModule
|
||||
import at.mocode.clients.authfeature.di.authFeatureModule
|
||||
import navigation.navigationModule
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun main() {
|
||||
// Initialize DI
|
||||
try {
|
||||
initKoin { modules(networkModule, authFeatureModule) }
|
||||
println("[WasmApp] Koin initialized")
|
||||
initKoin { modules(networkModule, authFeatureModule, navigationModule) }
|
||||
println("[WasmApp] Koin initialized (with navigationModule)")
|
||||
} catch (e: Exception) {
|
||||
println("[WasmApp] Koin init failed: ${e.message}")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user