feat(desktop-onboarding): neue Onboarding-UI implementiert, Backup- und Rollenmanagement hinzugefügt
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Failing after 3m10s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 6m37s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 5m59s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Has been cancelled
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Failing after 3m10s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 6m37s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 5m59s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Has been cancelled
- Einbindung eines komplett überarbeiteten Onboarding-Screens mit validierten Eingaben für Gerätename, Sicherheitsschlüssel und Backup-Pfad. - `SettingsManager` eingeführt zur Speicherung der Onboarding-Daten in `settings.json`. - Navigation verbessert: Onboarding-Workflow startet, wenn Konfiguration fehlt; neues "Setup"-Icon in der Navigationsleiste hinzugefügt. - Backend: Geräte-API und `DeviceSecurityFilter` für Authentifizierung per Sicherheitsschlüssel implementiert. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
package at.mocode.identity.domain.model
|
||||
|
||||
import kotlinx.datetime.Instant
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Repräsentiert eine registrierte Desktop-Instanz ("Gerät").
|
||||
* Die Identität wird während des Onboarding-Prozesses festgelegt.
|
||||
*/
|
||||
data class Device(
|
||||
val id: UUID = UUID.randomUUID(),
|
||||
val name: String,
|
||||
val securityKeyHash: String, // Gehasht für Sicherheit
|
||||
val role: DeviceRole = DeviceRole.CLIENT,
|
||||
val lastSyncAt: Instant? = null,
|
||||
val createdAt: Instant
|
||||
)
|
||||
|
||||
enum class DeviceRole {
|
||||
MASTER, CLIENT
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package at.mocode.identity.domain.repository
|
||||
|
||||
import at.mocode.identity.domain.model.Device
|
||||
import kotlinx.datetime.Instant
|
||||
import java.util.*
|
||||
|
||||
interface DeviceRepository {
|
||||
suspend fun findById(id: UUID): Device?
|
||||
suspend fun findByName(name: String): Device?
|
||||
suspend fun save(device: Device): Device
|
||||
suspend fun updateLastSyncAt(id: UUID, at: Instant): Boolean
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package at.mocode.identity.domain.service
|
||||
|
||||
import at.mocode.identity.domain.model.Device
|
||||
import at.mocode.identity.domain.model.DeviceRole
|
||||
import at.mocode.identity.domain.repository.DeviceRepository
|
||||
import java.util.*
|
||||
import kotlin.time.Clock
|
||||
|
||||
class DeviceService(
|
||||
private val deviceRepository: DeviceRepository
|
||||
) {
|
||||
suspend fun registerDevice(name: String, securityKeyHash: String, role: DeviceRole): Device {
|
||||
val existing = deviceRepository.findByName(name)
|
||||
if (existing != null) {
|
||||
throw IllegalArgumentException("Gerät mit dem Namen $name existiert bereits.")
|
||||
}
|
||||
|
||||
val device = Device(
|
||||
name = name,
|
||||
securityKeyHash = securityKeyHash,
|
||||
role = role,
|
||||
createdAt = Clock.System.now()
|
||||
)
|
||||
return deviceRepository.save(device)
|
||||
}
|
||||
|
||||
suspend fun validateDeviceKey(name: String, securityKeyHash: String): Boolean {
|
||||
val device = deviceRepository.findByName(name) ?: return false
|
||||
return device.securityKeyHash == securityKeyHash
|
||||
}
|
||||
|
||||
suspend fun getDeviceByName(name: String): Device? {
|
||||
return deviceRepository.findByName(name)
|
||||
}
|
||||
|
||||
suspend fun updateSyncTime(deviceId: UUID): Boolean {
|
||||
return deviceRepository.updateLastSyncAt(deviceId, Clock.System.now())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user