diff --git a/app/src/main/java/de/bollwerk/app/data/repository/MessageRepositoryImpl.kt b/app/src/main/java/de/bollwerk/app/data/repository/MessageRepositoryImpl.kt index bff53cb..0fd6ffa 100644 --- a/app/src/main/java/de/bollwerk/app/data/repository/MessageRepositoryImpl.kt +++ b/app/src/main/java/de/bollwerk/app/data/repository/MessageRepositoryImpl.kt @@ -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>()) } 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 = 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 {