From 1c78ecc93dfcf4082ed7dfdaa124a15e50d1e169 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Mon, 18 Mar 2024 23:15:17 -0700 Subject: [PATCH] UpdateMonitor: Fix authentication with update monitor --- .../kordophone/backend/server/APIClient.kt | 27 ++++++++++++------- .../backend/server/UpdateMonitor.kt | 13 ++++++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/backend/src/main/java/net/buzzert/kordophone/backend/server/APIClient.kt b/backend/src/main/java/net/buzzert/kordophone/backend/server/APIClient.kt index e82973b..56b9e48 100644 --- a/backend/src/main/java/net/buzzert/kordophone/backend/server/APIClient.kt +++ b/backend/src/main/java/net/buzzert/kordophone/backend/server/APIClient.kt @@ -1,6 +1,5 @@ package net.buzzert.kordophone.backend.server -import com.google.gson.Gson import kotlinx.coroutines.runBlocking import okhttp3.Authenticator import okhttp3.HttpUrl @@ -13,14 +12,13 @@ import okhttp3.WebSocket import okhttp3.WebSocketListener import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory -import retrofit2.create import java.net.URL interface APIClient { fun getAPIInterface(): APIInterface fun getWebSocketClient( serverPath: String, - authToken: String? = null, + queryParams: Map?, listener: WebSocketListener ): WebSocket } @@ -109,24 +107,35 @@ class RetrofitAPIClient( return retrofit.create(APIInterface::class.java) } - override fun getWebSocketClient(serverPath: String, authToken: String?, listener: WebSocketListener): WebSocket { - val requestURL = baseURL.authenticatedWebSocketURL(serverPath, authToken) + override fun getWebSocketClient( + serverPath: String, + queryParams: Map?, + listener: WebSocketListener + ): WebSocket { + val params = (queryParams ?: hashMapOf()).toMutableMap() + + val authToken = tokenStore.authenticationToken + if (authToken != null) { + params["token"] = authToken + } + + val requestURL = baseURL.authenticatedWebSocketURL(serverPath, params) val request = Request.Builder() .url(requestURL) .build() - return OkHttpClient().newWebSocket(request, listener) + return client.newWebSocket(request, listener) } } -fun URL.authenticatedWebSocketURL(serverPath: String, authToken: String? = null): URL { +fun URL.authenticatedWebSocketURL(serverPath: String, params: Map): URL { val baseURI = HttpUrl.parse(this.toString())!! val requestURL = baseURI.newBuilder() .host(baseURI.host()) .addEncodedPathSegments(serverPath) - if (authToken != null) { - requestURL.addQueryParameter("token", authToken) + params.forEach { (key, value) -> + requestURL.addQueryParameter(key, value) } return URL(requestURL.build().toString()) diff --git a/backend/src/main/java/net/buzzert/kordophone/backend/server/UpdateMonitor.kt b/backend/src/main/java/net/buzzert/kordophone/backend/server/UpdateMonitor.kt index ac418c5..14bcd0c 100644 --- a/backend/src/main/java/net/buzzert/kordophone/backend/server/UpdateMonitor.kt +++ b/backend/src/main/java/net/buzzert/kordophone/backend/server/UpdateMonitor.kt @@ -17,9 +17,7 @@ import okhttp3.Response import okhttp3.WebSocket import okhttp3.WebSocketListener import okio.ByteString -import retrofit2.converter.gson.GsonConverterFactory import java.lang.reflect.Type -import kotlin.time.Duration const val UPMON_LOG: String = "UpdateMonitor" @@ -36,13 +34,18 @@ class UpdateMonitor(private val client: APIClient) : WebSocketListener() { private val updateItemsType: Type = object : TypeToken>() {}.type private var webSocket: WebSocket? = null private var needsSocketReconnect: Boolean = false + private var messageSeq: Int = -1 private val _conversationChanged: MutableSharedFlow = MutableSharedFlow() private val _messageAdded: MutableSharedFlow = MutableSharedFlow() fun beginMonitoringUpdates() { Log.d(UPMON_LOG, "Opening websocket connection") - this.webSocket = client.getWebSocketClient("/updates", null, this) + this.webSocket = client.getWebSocketClient( + serverPath = "/updates", + queryParams = mapOf("seq" to messageSeq.toString()), + listener = this + ) } fun stopMonitoringForUpdates() { @@ -65,6 +68,10 @@ class UpdateMonitor(private val client: APIClient) : WebSocketListener() { it.conversation = conversationChanged!! }) } + + if (updateItem.sequence > messageSeq) { + messageSeq = updateItem.sequence + } } }