fix: 401 token refresh in MessageRepositoryImpl
fetchUsers() and attemptSendToServer() had no retry logic on 401. SyncServiceImpl already had this pattern (auto-refresh on 401). Add private refreshAccessToken(serverUrl) and retry once on 401 in both methods.
This commit is contained in:
parent
ea02029dbe
commit
a14c40d756
1 changed files with 43 additions and 4 deletions
|
|
@ -4,6 +4,8 @@ import android.util.Log
|
|||
import de.bollwerk.app.data.db.dao.MessageDao
|
||||
import de.bollwerk.app.data.db.entity.MessageEntity
|
||||
import de.bollwerk.app.data.security.E2EEKeyManager
|
||||
import de.bollwerk.app.data.sync.LoginResponse
|
||||
import de.bollwerk.app.data.sync.RefreshRequest
|
||||
import de.bollwerk.app.data.sync.WebSocketClient
|
||||
import de.bollwerk.app.data.sync.WebSocketEvent
|
||||
import de.bollwerk.app.di.ApplicationScope
|
||||
|
|
@ -129,12 +131,19 @@ internal class MessageRepositoryImpl @Inject constructor(
|
|||
withContext(Dispatchers.IO) {
|
||||
val serverUrl = settingsRepository.getStringOrNull(StringKey.ServerUrl)
|
||||
?: return@withContext Result.failure(SyncError.NotConfigured("Server-URL nicht gesetzt"))
|
||||
val token = settingsRepository.getStringOrNull(StringKey.AuthAccessToken)
|
||||
var token = settingsRepository.getStringOrNull(StringKey.AuthAccessToken)
|
||||
?: return@withContext Result.failure(SyncError.NotConfigured("Nicht angemeldet"))
|
||||
try {
|
||||
val response = httpClient.get("${serverUrl.trimEnd('/')}/api/users") {
|
||||
var response = httpClient.get("${serverUrl.trimEnd('/')}/api/users") {
|
||||
header("Authorization", "Bearer $token")
|
||||
}
|
||||
if (response.status == HttpStatusCode.Unauthorized && refreshAccessToken(serverUrl)) {
|
||||
token = settingsRepository.getStringOrNull(StringKey.AuthAccessToken)
|
||||
?: return@withContext Result.failure(SyncError.NotConfigured("Nicht angemeldet"))
|
||||
response = httpClient.get("${serverUrl.trimEnd('/')}/api/users") {
|
||||
header("Authorization", "Bearer $token")
|
||||
}
|
||||
}
|
||||
if (response.status == HttpStatusCode.OK) {
|
||||
Result.success(response.body<List<UserListItemDto>>())
|
||||
} else {
|
||||
|
|
@ -199,6 +208,27 @@ internal class MessageRepositoryImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun refreshAccessToken(serverUrl: String): Boolean {
|
||||
val refreshToken = settingsRepository.getStringOrNull(StringKey.AuthRefreshToken)
|
||||
?.takeIf { it.isNotBlank() } ?: return false
|
||||
return try {
|
||||
val response = httpClient.post("${serverUrl.trimEnd('/')}/api/auth/refresh") {
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(RefreshRequest(refreshToken))
|
||||
}
|
||||
if (response.status == HttpStatusCode.OK) {
|
||||
val loginResponse: LoginResponse = response.body()
|
||||
settingsRepository.setString(StringKey.AuthAccessToken, loginResponse.accessToken)
|
||||
settingsRepository.setString(StringKey.AuthRefreshToken, loginResponse.refreshToken)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun attemptSendToServer(
|
||||
id: String,
|
||||
recipientId: String,
|
||||
|
|
@ -207,14 +237,23 @@ internal class MessageRepositoryImpl @Inject constructor(
|
|||
): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val serverUrl = settingsRepository.getStringOrNull(StringKey.ServerUrl)
|
||||
?: return@withContext Result.failure(SyncError.NotConfigured("Server-URL nicht gesetzt"))
|
||||
val token = settingsRepository.getStringOrNull(StringKey.AuthAccessToken)
|
||||
var token = settingsRepository.getStringOrNull(StringKey.AuthAccessToken)
|
||||
?: return@withContext Result.failure(SyncError.NotConfigured("Nicht angemeldet"))
|
||||
try {
|
||||
val response = httpClient.post("${serverUrl.trimEnd('/')}/api/messages") {
|
||||
var response = httpClient.post("${serverUrl.trimEnd('/')}/api/messages") {
|
||||
header("Authorization", "Bearer $token")
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(SendMessageRequest(id = id, receiverId = recipientId, body = body, sentAt = sentAt))
|
||||
}
|
||||
if (response.status == HttpStatusCode.Unauthorized && refreshAccessToken(serverUrl)) {
|
||||
token = settingsRepository.getStringOrNull(StringKey.AuthAccessToken)
|
||||
?: return@withContext Result.failure(SyncError.NotConfigured("Nicht angemeldet"))
|
||||
response = httpClient.post("${serverUrl.trimEnd('/')}/api/messages") {
|
||||
header("Authorization", "Bearer $token")
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(SendMessageRequest(id = id, receiverId = recipientId, body = body, sentAt = sentAt))
|
||||
}
|
||||
}
|
||||
if (response.status == HttpStatusCode.Created || response.status == HttpStatusCode.OK) {
|
||||
Result.success(Unit)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue