Implement logout on token/credentials corruption

This commit is contained in:
Nymos 2025-02-19 16:23:18 +03:00
parent f41e8c734d
commit f9d31d4743
11 changed files with 39 additions and 13 deletions
data/src/main/java/com/nto/data
domain/src/main/java/com/nto/domain
presentation/src/main/java/com/nto/presentation

@ -3,7 +3,6 @@ package com.nto.data.repository
import com.nto.data.models.LoginResult
import com.nto.data.models.ScanResult
import com.nto.data.models.UserDTO
import com.nto.data.models.cards.VisitCardDTO
import com.nto.data.models.cards.VisitCardWrapper
interface DataRepository {
@ -14,4 +13,5 @@ interface DataRepository {
suspend fun getInfo(): UserDTO
suspend fun getVisits(id: String?): VisitCardWrapper
suspend fun open(): ScanResult
suspend fun logout()
}

@ -2,6 +2,7 @@ package com.nto.data.repository
import android.content.Context
import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences
import com.nto.data.models.LoginResult
import com.nto.data.models.ScanResult
import com.nto.data.models.UserDTO
@ -59,4 +60,8 @@ class DataRepositoryImpl @Inject constructor(@ApplicationContext private val con
}
}
override suspend fun logout() {
context.getSharedPreferences("auth", MODE_PRIVATE).edit().remove("token").remove("login").apply()
}
}

@ -15,7 +15,7 @@ object Provider {
@Singleton
fun provideRetrofit(): RetrofitApi {
return Retrofit.Builder()
.baseUrl("https://test.com/")
.baseUrl("http://v-chat.ru/")
.addConverterFactory(GsonConverterFactory.create())
.build().create(RetrofitApi::class.java)
}

@ -12,4 +12,5 @@ interface DomainRepository {
suspend fun getInfo(): UserDTO
suspend fun getVisits(id: String): VisitCardWrapper
suspend fun open(): ScanResult
suspend fun logout()
}

@ -36,7 +36,7 @@ class DomainRepositoryImpl @Inject constructor(private val dataRepositoryImpl: D
return try {
return dataRepositoryImpl.getInfo()
} catch (e: IOException) {
UserDTO(isError = true)
UserDTO(isError = true, isUnauthorized = true) //TODO
}
}
@ -44,7 +44,7 @@ class DomainRepositoryImpl @Inject constructor(private val dataRepositoryImpl: D
return try {
dataRepositoryImpl.getVisits(id)
} catch (e: IOException) {
VisitCardWrapper(null, isUnauthorized = true)
VisitCardWrapper(null, isUnauthorized = true) //TODO
}
}
@ -52,4 +52,8 @@ class DomainRepositoryImpl @Inject constructor(private val dataRepositoryImpl: D
return dataRepositoryImpl.open()
}
override suspend fun logout() {
dataRepositoryImpl.logout()
}
}

@ -8,4 +8,7 @@ class ProfileUseCase @Inject constructor(private val domainRepositoryImpl: Domai
suspend fun getInfo(): UserDTO{
return domainRepositoryImpl.getInfo()
}
suspend fun logout(){
return domainRepositoryImpl.logout()
}
}

@ -10,6 +10,7 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb

@ -15,7 +15,7 @@ fun Navigation(navController: NavHostController, modifier: Modifier = Modifier)
NavHost(
navController = navController,
modifier = modifier,
startDestination = Destinations.Profile
startDestination = Destinations.Login
) {
composable<Destinations.Login> {
LoginScreen(navController)

@ -70,9 +70,9 @@ fun ProfileScreen(
scanOptions.setOrientationLocked(false)
scanOptions.setCaptureActivity(CustomCaptureActivity::class.java)
LaunchedEffect(Unit) {
LaunchedEffect(state.isUnauthorized) {
if (state.isUnauthorized) {
navController.navigate(Destinations.Login)
viewModel.logout(navController)
}
}

@ -18,10 +18,11 @@ data class ProfileState(
val visits: List<VisitCardDTO> = listOf()
){
fun deserialize(o: UserDTO, context: Context){
val dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
this.firstName = o.firstName
this.secondName = o.secondName
this.thirdName = o.thirdName
this.lastOpen = SimpleDateFormat.getDateInstance().format(o.lastVisit)
this.lastOpen = o.lastVisit.format(dateFormat)
this.job = translatePosition(o.position, context)
this.isUnauthorized = o.isUnauthorized
}

@ -4,19 +4,18 @@ import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController
import com.nto.data.models.Position
import com.nto.data.models.QRDTO
import com.nto.data.models.cards.VisitCardDTO
import com.nto.data.models.cards.VisitType
import com.nto.data.utils.Destinations
import com.nto.domain.usecase.ProfileUseCase
import com.nto.presentation.R
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.invoke
import kotlinx.coroutines.launch
import java.time.LocalDateTime
import javax.inject.Inject
@ -32,7 +31,15 @@ class ProfileViewModel @Inject constructor(
"Алексеевич",
"20 января 2024 20:21",
"Senior UI/UX designer",
visits = listOf(VisitCardDTO("Кабинет 207", 10020, LocalDateTime.now(), VisitType.CARD_ENTRY, qrCode = QRDTO(12032, "Кобинет 52")))
visits = listOf(
VisitCardDTO(
"Кабинет 207",
10020,
LocalDateTime.now(),
VisitType.CARD_ENTRY,
qrCode = QRDTO(12032, "Кобинет 52")
)
)
)
)
@ -42,7 +49,6 @@ class ProfileViewModel @Inject constructor(
fun updateInfo() {
viewModelScope.launch(Dispatchers.IO) {
val result = useCase.getInfo()
if (result.isError) return@launch
_state.tryEmit(ProfileState().apply { deserialize(result, context) })
}
}
@ -52,7 +58,12 @@ class ProfileViewModel @Inject constructor(
}
fun logout(navController: NavController) {
//TODO
viewModelScope.launch(Dispatchers.IO) {
useCase.logout()
Dispatchers.Main {
navController.navigate(Destinations.Login)
}
}
}
fun option(navController: NavController) {