local mode stored into local database
This commit is contained in:
@@ -4,19 +4,22 @@ import com.vaultdrop.mobile.data.remote.ApiClient
|
|||||||
import com.vaultdrop.mobile.data.remote.dto.LoginResponseDto
|
import com.vaultdrop.mobile.data.remote.dto.LoginResponseDto
|
||||||
import com.vaultdrop.mobile.domain.ActiveUserStore
|
import com.vaultdrop.mobile.domain.ActiveUserStore
|
||||||
import com.vaultdrop.mobile.domain.DeviceIdentity
|
import com.vaultdrop.mobile.domain.DeviceIdentity
|
||||||
|
import com.vaultdrop.mobile.domain.LocalModeStore
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orchestration de la session (restauration/sauvegarde/purge) : relie le store
|
* Orchestration de la session (restauration/sauvegarde/purge) : relie le store
|
||||||
* sécurisé, le miroir `active_user_id` et le token en mémoire lu par
|
* sécurisé, le miroir `active_user_id` et le token en mémoire lu par
|
||||||
* `AuthInterceptor`.
|
* `AuthInterceptor`. Le drapeau « mode local » est persisté à part
|
||||||
|
* ([LocalModeStore]) pour survivre aux redémarrages.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
class SessionManager @Inject constructor(
|
class SessionManager @Inject constructor(
|
||||||
private val secureTokenStore: SecureTokenStore,
|
private val secureTokenStore: SecureTokenStore,
|
||||||
private val activeUserStore: ActiveUserStore,
|
private val activeUserStore: ActiveUserStore,
|
||||||
private val tokenProvider: TokenProvider,
|
private val tokenProvider: TokenProvider,
|
||||||
|
private val localModeStore: LocalModeStore,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/** Restaure la session persistée (si présente), sinon null. */
|
/** Restaure la session persistée (si présente), sinon null. */
|
||||||
@@ -30,6 +33,7 @@ class SessionManager @Inject constructor(
|
|||||||
suspend fun save(token: String, user: com.vaultdrop.mobile.data.remote.dto.UserDto) {
|
suspend fun save(token: String, user: com.vaultdrop.mobile.data.remote.dto.UserDto) {
|
||||||
secureTokenStore.save(token, user)
|
secureTokenStore.save(token, user)
|
||||||
activeUserStore.set(user.id)
|
activeUserStore.set(user.id)
|
||||||
|
localModeStore.clear()
|
||||||
tokenProvider.current = token
|
tokenProvider.current = token
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +42,12 @@ class SessionManager @Inject constructor(
|
|||||||
activeUserStore.clear()
|
activeUserStore.clear()
|
||||||
tokenProvider.current = null
|
tokenProvider.current = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun isLocalMode(): Boolean = localModeStore.get()
|
||||||
|
|
||||||
|
suspend fun setLocalMode() = localModeStore.set()
|
||||||
|
|
||||||
|
suspend fun clearLocalMode() = localModeStore.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
data class AuthSession(
|
data class AuthSession(
|
||||||
|
|||||||
+2
-1
@@ -7,7 +7,8 @@ import androidx.room.PrimaryKey
|
|||||||
/**
|
/**
|
||||||
* Miroir de la table `user_preferences` JS (`key`/`value`/`updated_at`).
|
* Miroir de la table `user_preferences` JS (`key`/`value`/`updated_at`).
|
||||||
* Clés connues : `device_user_id` (32-hex, généré une fois), `sync_mode`,
|
* Clés connues : `device_user_id` (32-hex, généré une fois), `sync_mode`,
|
||||||
* `active_user_id` (miroir non-sensible du compte connecté).
|
* `active_user_id` (miroir non-sensible du compte connecté), `local_mode`
|
||||||
|
* (app utilisée sans compte).
|
||||||
*/
|
*/
|
||||||
@Entity(tableName = "user_preferences")
|
@Entity(tableName = "user_preferences")
|
||||||
data class UserPreferenceEntity(
|
data class UserPreferenceEntity(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package com.vaultdrop.mobile.domain
|
|||||||
object PrefKeys {
|
object PrefKeys {
|
||||||
const val DEVICE_USER_ID = "device_user_id"
|
const val DEVICE_USER_ID = "device_user_id"
|
||||||
const val ACTIVE_USER_ID = "active_user_id"
|
const val ACTIVE_USER_ID = "active_user_id"
|
||||||
|
const val LOCAL_MODE = "local_mode"
|
||||||
const val SYNC_MODE = "sync_mode"
|
const val SYNC_MODE = "sync_mode"
|
||||||
const val THEME = "theme"
|
const val THEME = "theme"
|
||||||
const val SERVER_URL = "server_url"
|
const val SERVER_URL = "server_url"
|
||||||
|
|||||||
@@ -37,8 +37,11 @@ class AuthViewModel @Inject constructor(
|
|||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val session = sessionManager.restore()
|
val session = sessionManager.restore()
|
||||||
_authState.value =
|
_authState.value = when {
|
||||||
if (session != null) AuthState.SignedIn(session.user) else AuthState.SignedOut
|
session != null -> AuthState.SignedIn(session.user)
|
||||||
|
sessionManager.isLocalMode() -> AuthState.Local
|
||||||
|
else -> AuthState.SignedOut
|
||||||
|
}
|
||||||
authRepository.registerDevice()
|
authRepository.registerDevice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +70,10 @@ class AuthViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun continueWithoutAccount() {
|
fun continueWithoutAccount() {
|
||||||
_authState.value = AuthState.Local
|
viewModelScope.launch {
|
||||||
|
sessionManager.setLocalMode()
|
||||||
|
_authState.value = AuthState.Local
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Purge la session et revient en mode local (sans repasser par le login). */
|
/** Purge la session et revient en mode local (sans repasser par le login). */
|
||||||
@@ -76,6 +82,7 @@ class AuthViewModel @Inject constructor(
|
|||||||
Timber.d("auth: session purgée (mode local)")
|
Timber.d("auth: session purgée (mode local)")
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
sessionManager.clear()
|
sessionManager.clear()
|
||||||
|
sessionManager.setLocalMode()
|
||||||
}
|
}
|
||||||
_authState.value = AuthState.Local
|
_authState.value = AuthState.Local
|
||||||
}
|
}
|
||||||
@@ -86,6 +93,7 @@ class AuthViewModel @Inject constructor(
|
|||||||
Timber.d("auth: session purgée (signOut)")
|
Timber.d("auth: session purgée (signOut)")
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
sessionManager.clear()
|
sessionManager.clear()
|
||||||
|
sessionManager.clearLocalMode()
|
||||||
}
|
}
|
||||||
_authState.value = AuthState.SignedOut
|
_authState.value = AuthState.SignedOut
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user