WIP ajustes de cuenta

This commit is contained in:
erik-everardo 2024-01-21 13:57:23 -06:00
parent 24e8ff10bb
commit a1c627ca59
11 changed files with 157 additions and 14 deletions

View File

@ -47,14 +47,6 @@ class AuthRepositoryImpl @Inject constructor(
} }
} }
override fun logout(): Flow<Boolean> = flow {
tokenStorage.removeToken()
try {
authApi.signOut().awaitResponse()
} catch(_: Exception) { }
emit(true)
}
override fun getCurrentToken(): AuthTokenDto? { override fun getCurrentToken(): AuthTokenDto? {
return tokenStorage.token return tokenStorage.token
} }

View File

@ -12,7 +12,4 @@ interface AuthApi {
@POST("LogIn") @POST("LogIn")
fun signInWithEmailAndPassword(@Header("apiClientId") clientId: String, @Header("apiClientSecret") clientSecret: String, @Body credential: Credential): Call<AuthTokenDto> fun signInWithEmailAndPassword(@Header("apiClientId") clientId: String, @Header("apiClientSecret") clientSecret: String, @Body credential: Credential): Call<AuthTokenDto>
@GET("LogIn/SignOut")
fun signOut(): Call<Nothing>
} }

View File

@ -6,7 +6,6 @@ import kotlinx.coroutines.flow.Flow
interface AuthRepository { interface AuthRepository {
fun authWithEmailAndPassword(email: String, password: String): Flow<Resource<Boolean>> fun authWithEmailAndPassword(email: String, password: String): Flow<Resource<Boolean>>
fun logout(): Flow<Boolean>
fun getCurrentToken(): AuthTokenDto? fun getCurrentToken(): AuthTokenDto?
fun getUserId(): Flow<Int?> fun getUserId(): Flow<Int?>
suspend fun setToken(sessionDto: AuthTokenDto) suspend fun setToken(sessionDto: AuthTokenDto)

View File

@ -1,8 +1,13 @@
package com.isolaatti.settings package com.isolaatti.settings
import com.isolaatti.auth.data.local.TokenStorage
import com.isolaatti.connectivity.RetrofitClient
import com.isolaatti.database.AppDatabase import com.isolaatti.database.AppDatabase
import com.isolaatti.settings.data.KeyValueDao import com.isolaatti.settings.data.KeyValueDao
import com.isolaatti.settings.data.SettingsRepositoryImpl import com.isolaatti.settings.data.SettingsRepositoryImpl
import com.isolaatti.settings.data.remote.AccountSettingsApi
import com.isolaatti.settings.data.repository.AccountSettingsRepositoryImpl
import com.isolaatti.settings.domain.AccountSettingsRepository
import com.isolaatti.settings.domain.SettingsRepository import com.isolaatti.settings.domain.SettingsRepository
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
@ -21,4 +26,14 @@ class Module {
fun provideSettingsRepository(keyValueDao: KeyValueDao): SettingsRepository { fun provideSettingsRepository(keyValueDao: KeyValueDao): SettingsRepository {
return SettingsRepositoryImpl(keyValueDao) return SettingsRepositoryImpl(keyValueDao)
} }
@Provides
fun provideAccountSettingsApi(retrofitClient: RetrofitClient): AccountSettingsApi {
return retrofitClient.client.create(AccountSettingsApi::class.java)
}
@Provides
fun provideAccountSettingsRepository(tokenStorage: TokenStorage, accountSettingsApi: AccountSettingsApi): AccountSettingsRepository {
return AccountSettingsRepositoryImpl(tokenStorage, accountSettingsApi)
}
} }

View File

@ -1,4 +1,25 @@
package com.isolaatti.settings.data.remote package com.isolaatti.settings.data.remote
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
interface AccountSettingsApi { interface AccountSettingsApi {
@GET("account/get_sessions")
fun getSessions(): Call<SessionsDto>
@POST("account/password/change")
fun changePassword(
@Body changePasswordDto: ChangePasswordDto,
@Query("signOut") signOut: Boolean,
@Query("signOutCurrent") signOutCurrent: Boolean
): Call<ChangePasswordResponseDto>
@POST("account/sign_out")
fun signOut(): Call<Any>
@POST("account/sign_out_sessions")
fun signOutSessions(@Body removeSessionsDto: RemoveSessionsDto): Call<Any>
} }

View File

@ -0,0 +1,6 @@
package com.isolaatti.settings.data.remote
data class ChangePasswordDto(
val oldPassword: String,
val newPassword: String
)

View File

@ -0,0 +1,12 @@
package com.isolaatti.settings.data.remote
data class ChangePasswordResponseDto(
val success: Boolean,
val reason: String?
) {
companion object {
const val ReasonUserDoesNotExist = "user_does_not_exist";
const val ReasonOldPasswordMismatch = "old_password_mismatch";
const val ReasonNewPasswordInvalid = "new_password_invalid";
}
}

View File

@ -0,0 +1,5 @@
package com.isolaatti.settings.data.remote
data class RemoveSessionsDto(
val ids: List<String>
)

View File

@ -0,0 +1,15 @@
package com.isolaatti.settings.data.remote
import java.time.ZonedDateTime
data class SessionsDto(
val data: List<SessionDto>
) {
data class SessionDto(
val id: String,
val date: ZonedDateTime,
val ip: String,
val userAgent: String,
val current: Boolean
)
}

View File

@ -1,6 +1,76 @@
package com.isolaatti.settings.data.repository package com.isolaatti.settings.data.repository
import com.isolaatti.auth.data.local.TokenStorage
import com.isolaatti.settings.data.remote.AccountSettingsApi
import com.isolaatti.settings.data.remote.ChangePasswordDto
import com.isolaatti.settings.data.remote.ChangePasswordResponseDto
import com.isolaatti.settings.data.remote.RemoveSessionsDto
import com.isolaatti.settings.data.remote.SessionsDto
import com.isolaatti.settings.domain.AccountSettingsRepository import com.isolaatti.settings.domain.AccountSettingsRepository
import com.isolaatti.utils.Resource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import retrofit2.awaitResponse
import javax.inject.Inject
class AccountSettingsRepositoryImpl : AccountSettingsRepository { class AccountSettingsRepositoryImpl @Inject constructor(
private val tokenStorage: TokenStorage,
private val accountSettingsApi: AccountSettingsApi
) : AccountSettingsRepository {
override fun logout(): Flow<Resource<Boolean>> = flow {
tokenStorage.removeToken()
try {
val response = accountSettingsApi.signOut().awaitResponse()
if(response.isSuccessful) {
emit(Resource.Success(true))
} else {
emit(Resource.Error(Resource.Error.mapErrorCode(response.code())))
}
} catch (exception: Exception) {
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
}
}
override fun getSessions(): Flow<Resource<List<SessionsDto.SessionDto>>> = flow {
try {
val response = accountSettingsApi.getSessions().awaitResponse()
if(response.isSuccessful) {
emit(Resource.Success(response.body()?.data))
} else {
emit(Resource.Error(Resource.Error.mapErrorCode(response.code())))
}
} catch(_: Exception) {
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
}
}
override fun signOutSessions(sessionIds: List<String>): Flow<Resource<Boolean>> = flow {
try {
val response = accountSettingsApi.signOutSessions(RemoveSessionsDto(sessionIds)).awaitResponse()
if(response.isSuccessful) {
emit(Resource.Success(true))
} else {
emit(Resource.Error(Resource.Error.mapErrorCode(response.code())))
}
} catch(_: Exception) {
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
}
}
override fun changePassword(oldPassword: String, newPassword: String, signOut: Boolean, signOutCurrent: Boolean): Flow<Resource<ChangePasswordResponseDto>> = flow {
try {
val response = accountSettingsApi.changePassword(ChangePasswordDto(oldPassword, newPassword), signOut, signOutCurrent).awaitResponse()
if(response.isSuccessful) {
emit(Resource.Success(response.body()))
} else {
emit(Resource.Error(Resource.Error.mapErrorCode(response.code())))
}
} catch(_: Exception) {
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
}
}
} }

View File

@ -1,5 +1,16 @@
package com.isolaatti.settings.domain package com.isolaatti.settings.domain
interface AccountSettingsRepository { import com.isolaatti.settings.data.remote.ChangePasswordResponseDto
import com.isolaatti.settings.data.remote.SessionsDto
import com.isolaatti.utils.Resource
import kotlinx.coroutines.flow.Flow
interface AccountSettingsRepository {
fun logout(): Flow<Resource<Boolean>>
fun getSessions(): Flow<Resource<List<SessionsDto.SessionDto>>>
fun signOutSessions(sessionIds: List<String>): Flow<Resource<Boolean>>
fun changePassword(oldPassword: String, newPassword: String, signOut: Boolean, signOutCurrent: Boolean): Flow<Resource<ChangePasswordResponseDto>>
} }