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.dao.MessageDao
|
||||||
import de.bollwerk.app.data.db.entity.MessageEntity
|
import de.bollwerk.app.data.db.entity.MessageEntity
|
||||||
import de.bollwerk.app.data.security.E2EEKeyManager
|
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.WebSocketClient
|
||||||
import de.bollwerk.app.data.sync.WebSocketEvent
|
import de.bollwerk.app.data.sync.WebSocketEvent
|
||||||
import de.bollwerk.app.di.ApplicationScope
|
import de.bollwerk.app.di.ApplicationScope
|
||||||
|
|
@ -129,12 +131,19 @@ internal class MessageRepositoryImpl @Inject constructor(
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val serverUrl = settingsRepository.getStringOrNull(StringKey.ServerUrl)
|
val serverUrl = settingsRepository.getStringOrNull(StringKey.ServerUrl)
|
||||||
?: return@withContext Result.failure(SyncError.NotConfigured("Server-URL nicht gesetzt"))
|
?: 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"))
|
?: return@withContext Result.failure(SyncError.NotConfigured("Nicht angemeldet"))
|
||||||
try {
|
try {
|
||||||
val response = httpClient.get("${serverUrl.trimEnd('/')}/api/users") {
|
var response = httpClient.get("${serverUrl.trimEnd('/')}/api/users") {
|
||||||
header("Authorization", "Bearer $token")
|
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) {
|
if (response.status == HttpStatusCode.OK) {
|
||||||
Result.success(response.body<List<UserListItemDto>>())
|
Result.success(response.body<List<UserListItemDto>>())
|
||||||
} else {
|
} 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(
|
private suspend fun attemptSendToServer(
|
||||||
id: String,
|
id: String,
|
||||||
recipientId: String,
|
recipientId: String,
|
||||||
|
|
@ -207,14 +237,23 @@ internal class MessageRepositoryImpl @Inject constructor(
|
||||||
): Result<Unit> = withContext(Dispatchers.IO) {
|
): Result<Unit> = withContext(Dispatchers.IO) {
|
||||||
val serverUrl = settingsRepository.getStringOrNull(StringKey.ServerUrl)
|
val serverUrl = settingsRepository.getStringOrNull(StringKey.ServerUrl)
|
||||||
?: return@withContext Result.failure(SyncError.NotConfigured("Server-URL nicht gesetzt"))
|
?: 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"))
|
?: return@withContext Result.failure(SyncError.NotConfigured("Nicht angemeldet"))
|
||||||
try {
|
try {
|
||||||
val response = httpClient.post("${serverUrl.trimEnd('/')}/api/messages") {
|
var response = httpClient.post("${serverUrl.trimEnd('/')}/api/messages") {
|
||||||
header("Authorization", "Bearer $token")
|
header("Authorization", "Bearer $token")
|
||||||
contentType(ContentType.Application.Json)
|
contentType(ContentType.Application.Json)
|
||||||
setBody(SendMessageRequest(id = id, receiverId = recipientId, body = body, sentAt = sentAt))
|
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) {
|
if (response.status == HttpStatusCode.Created || response.status == HttpStatusCode.OK) {
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue