Нормальные токены
This commit is contained in:
@@ -2,6 +2,7 @@ package auth.data.remote.api
|
||||
|
||||
import auth.data.remote.dto.AuthRequest
|
||||
import auth.data.remote.dto.AuthResponse
|
||||
import auth.data.remote.dto.RefreshTokenRequest
|
||||
import core.domain.model.ServerConfigModel
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
@@ -10,13 +11,14 @@ import retrofit2.http.POST
|
||||
|
||||
interface AuthApi {
|
||||
@POST("auth/login")
|
||||
@Headers("Cache-Control: no-cache")
|
||||
suspend fun login(@Body request: AuthRequest): AuthResponse
|
||||
|
||||
@POST("auth/register")
|
||||
@Headers("Cache-Control: no-cache")
|
||||
suspend fun register(@Body request: AuthRequest): AuthResponse
|
||||
|
||||
@POST("auth/refresh")
|
||||
suspend fun refreshToken(@Body request: RefreshTokenRequest): AuthResponse
|
||||
|
||||
@GET("config")
|
||||
@Headers("Cache-Control: no-cache")
|
||||
suspend fun getConfig(): ServerConfigModel
|
||||
|
||||
@@ -9,6 +9,7 @@ data class AuthRequest(
|
||||
|
||||
data class AuthResponse(
|
||||
@SerializedName("accessToken") val accessToken: String?,
|
||||
@SerializedName("refreshToken") val refreshToken: String?,
|
||||
@SerializedName("user") val user: UserDto?,
|
||||
@SerializedName("userId") val userId: String?,
|
||||
@SerializedName("username") val username: String?,
|
||||
@@ -21,3 +22,7 @@ data class UserDto(
|
||||
@SerializedName("displayName") val displayName: String?,
|
||||
@SerializedName("avatarUrl") val avatarUrl: String?
|
||||
)
|
||||
|
||||
data class RefreshTokenRequest(
|
||||
@SerializedName("refreshToken") val refreshToken: String
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ package auth.data.repository
|
||||
|
||||
import auth.data.remote.api.AuthApi
|
||||
import auth.data.remote.dto.AuthRequest
|
||||
import auth.data.remote.dto.RefreshTokenRequest
|
||||
import auth.domain.model.AuthResult
|
||||
import auth.domain.repository.AuthRepository
|
||||
import core.network.ServerConfig
|
||||
@@ -25,12 +26,13 @@ class AuthRepositoryImpl @Inject constructor(
|
||||
val token = response.accessToken ?: return Result.failure(Exception("Token is null"))
|
||||
val userId = response.userId ?: ""
|
||||
|
||||
tokenManager.saveToken(token, userId)
|
||||
tokenManager.saveToken(token, userId, response.refreshToken)
|
||||
_isAuthenticated.value = true
|
||||
fetchConfig()
|
||||
Result.success(
|
||||
AuthResult(
|
||||
token = token,
|
||||
refreshToken = response.refreshToken,
|
||||
userId = userId,
|
||||
userName = response.username ?: userName,
|
||||
displayName = response.displayName ?: response.username ?: userName,
|
||||
@@ -48,12 +50,13 @@ class AuthRepositoryImpl @Inject constructor(
|
||||
val token = response.accessToken ?: return Result.failure(Exception("Token is null"))
|
||||
val userId = response.userId ?: ""
|
||||
|
||||
tokenManager.saveToken(token, userId)
|
||||
tokenManager.saveToken(token, userId, response.refreshToken)
|
||||
_isAuthenticated.value = true
|
||||
fetchConfig()
|
||||
Result.success(
|
||||
AuthResult(
|
||||
token = token,
|
||||
refreshToken = response.refreshToken,
|
||||
userId = userId,
|
||||
userName = response.username ?: userName,
|
||||
displayName = response.displayName ?: response.username ?: userName,
|
||||
@@ -95,4 +98,34 @@ class AuthRepositoryImpl @Inject constructor(
|
||||
// Silent fail
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun refreshToken(): Result<AuthResult> {
|
||||
val currentRefreshToken = tokenManager.getRefreshToken()
|
||||
if (currentRefreshToken == null) {
|
||||
return Result.failure(Exception("Refresh token is null"))
|
||||
}
|
||||
|
||||
return try {
|
||||
val response = api.refreshToken(RefreshTokenRequest(currentRefreshToken))
|
||||
val newAccessToken = response.accessToken ?: return Result.failure(Exception("New access token is null"))
|
||||
val newRefreshToken = response.refreshToken
|
||||
val userId = response.userId ?: ""
|
||||
|
||||
tokenManager.saveToken(newAccessToken, userId, newRefreshToken)
|
||||
_isAuthenticated.value = true
|
||||
|
||||
Result.success(
|
||||
AuthResult(
|
||||
token = newAccessToken,
|
||||
refreshToken = newRefreshToken,
|
||||
userId = userId,
|
||||
userName = response.username ?: "",
|
||||
displayName = response.displayName ?: "",
|
||||
avatarUrl = null
|
||||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package auth.domain.model
|
||||
|
||||
data class AuthResult(
|
||||
val token: String,
|
||||
val refreshToken: String?,
|
||||
val userId: String,
|
||||
val userName: String,
|
||||
val displayName: String,
|
||||
|
||||
@@ -10,4 +10,5 @@ interface AuthRepository {
|
||||
fun isAuthenticated(): Boolean
|
||||
fun isAuthenticatedFlow(): kotlinx.coroutines.flow.StateFlow<Boolean>
|
||||
suspend fun updatePushToken(token: String)
|
||||
suspend fun refreshToken(): Result<AuthResult>
|
||||
}
|
||||
|
||||
@@ -69,6 +69,18 @@ class AuthViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshToken() {
|
||||
viewModelScope.launch {
|
||||
repository.refreshToken()
|
||||
.onSuccess {
|
||||
// Token refreshed successfully
|
||||
}
|
||||
.onFailure {
|
||||
// Refresh failed, will trigger logout via AuthInterceptor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePushToken() {
|
||||
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
|
||||
if (task.isSuccessful) {
|
||||
|
||||
Reference in New Issue
Block a user