From d086c050cf9cd5e4300c63f769af26b68ec1e047 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 4 Jan 2026 08:58:28 -0500 Subject: [PATCH] Custom headers to DAO --- .../main/java/io/heckel/ntfy/db/Database.kt | 5 +-- .../main/java/io/heckel/ntfy/db/Repository.kt | 6 +-- .../java/io/heckel/ntfy/msg/ApiService.kt | 37 ++++++++----------- .../heckel/ntfy/service/SubscriberService.kt | 3 +- .../io/heckel/ntfy/service/WsConnection.kt | 4 +- 5 files changed, 22 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/io/heckel/ntfy/db/Database.kt b/app/src/main/java/io/heckel/ntfy/db/Database.kt index 38ebd5bc..b28d6696 100644 --- a/app/src/main/java/io/heckel/ntfy/db/Database.kt +++ b/app/src/main/java/io/heckel/ntfy/db/Database.kt @@ -532,10 +532,7 @@ interface CustomHeaderDao { suspend fun list(): List @Query("SELECT * FROM CustomHeader WHERE baseUrl = :baseUrl ORDER BY name") - suspend fun getForServer(baseUrl: String): List - - @Query("SELECT * FROM CustomHeader WHERE baseUrl = :baseUrl ORDER BY name") - fun getForServerSync(baseUrl: String): List + suspend fun get(baseUrl: String): List @Insert suspend fun insert(header: CustomHeader) diff --git a/app/src/main/java/io/heckel/ntfy/db/Repository.kt b/app/src/main/java/io/heckel/ntfy/db/Repository.kt index 6497d24b..d042fc56 100644 --- a/app/src/main/java/io/heckel/ntfy/db/Repository.kt +++ b/app/src/main/java/io/heckel/ntfy/db/Repository.kt @@ -402,11 +402,7 @@ class Repository(private val sharedPrefs: SharedPreferences, database: Database) } suspend fun getCustomHeaders(baseUrl: String): List { - return customHeaderDao.getForServer(baseUrl) - } - - fun getCustomHeadersSync(baseUrl: String): List { - return customHeaderDao.getForServerSync(baseUrl) + return customHeaderDao.get(baseUrl) } suspend fun addCustomHeader(header: CustomHeader) { diff --git a/app/src/main/java/io/heckel/ntfy/msg/ApiService.kt b/app/src/main/java/io/heckel/ntfy/msg/ApiService.kt index 75467cf9..f2ef456b 100644 --- a/app/src/main/java/io/heckel/ntfy/msg/ApiService.kt +++ b/app/src/main/java/io/heckel/ntfy/msg/ApiService.kt @@ -4,6 +4,7 @@ import android.content.Context import android.os.Build import com.google.gson.Gson import io.heckel.ntfy.BuildConfig +import io.heckel.ntfy.db.CustomHeader import io.heckel.ntfy.db.Notification import io.heckel.ntfy.db.Repository import io.heckel.ntfy.db.User @@ -37,7 +38,7 @@ class ApiService(context: Context) { .build() private val parser = NotificationParser() - fun publish( + suspend fun publish( baseUrl: String, topic: String, user: User? = null, @@ -95,7 +96,8 @@ class ApiService(context: Context) { } else { url } - val request = requestBuilder(urlWithQuery, user, repository) + val customHeaders = repository.getCustomHeaders(baseUrl) + val request = requestBuilder(urlWithQuery, user, customHeaders) .put(body ?: message.toRequestBody()) .build() Log.d(TAG, "Publishing to $request") @@ -123,12 +125,13 @@ class ApiService(context: Context) { } } - fun poll(subscriptionId: Long, baseUrl: String, topic: String, user: User?, since: String? = null): List { + suspend fun poll(subscriptionId: Long, baseUrl: String, topic: String, user: User?, since: String? = null): List { val sinceVal = since ?: "all" val url = topicUrlJsonPoll(baseUrl, topic, sinceVal) Log.d(TAG, "Polling topic $url") - val request = requestBuilder(url, user, repository).build() + val customHeaders = repository.getCustomHeaders(baseUrl) + val request = requestBuilder(url, user, customHeaders).build() client.newCall(request).execute().use { response -> if (!response.isSuccessful) { throw Exception("Unexpected response ${response.code} when polling topic $url") @@ -144,7 +147,7 @@ class ApiService(context: Context) { } } - fun subscribe( + suspend fun subscribe( baseUrl: String, topics: String, since: String?, @@ -155,7 +158,8 @@ class ApiService(context: Context) { val sinceVal = since ?: "all" val url = topicUrlJson(baseUrl, topics, sinceVal) Log.d(TAG, "Opening subscription connection to $url") - val request = requestBuilder(url, user, repository).build() + val customHeaders = repository.getCustomHeaders(baseUrl) + val request = requestBuilder(url, user, customHeaders).build() val call = subscriberClient.newCall(request) call.enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { @@ -184,14 +188,15 @@ class ApiService(context: Context) { return call } - fun checkAuth(baseUrl: String, topic: String, user: User?): Boolean { + suspend fun checkAuth(baseUrl: String, topic: String, user: User?): Boolean { if (user == null) { Log.d(TAG, "Checking anonymous read against ${topicUrl(baseUrl, topic)}") } else { Log.d(TAG, "Checking read access for user ${user.username} against ${topicUrl(baseUrl, topic)}") } val url = topicUrlAuth(baseUrl, topic) - val request = requestBuilder(url, user, repository).build() + val customHeaders = repository.getCustomHeaders(baseUrl) + val request = requestBuilder(url, user, customHeaders).build() client.newCall(request).execute().use { response -> if (response.isSuccessful) { return true @@ -224,27 +229,17 @@ class ApiService(context: Context) { const val EVENT_KEEPALIVE = "keepalive" const val EVENT_POLL_REQUEST = "poll_request" - fun requestBuilder(url: String, user: User?, repository: Repository? = null): Request.Builder { + fun requestBuilder(url: String, user: User?, customHeaders: List = emptyList()): Request.Builder { val builder = Request.Builder() .url(url) .addHeader("User-Agent", USER_AGENT) if (user != null) { builder.addHeader("Authorization", Credentials.basic(user.username, user.password, UTF_8)) } - if (repository != null) { - val baseUrl = extractBaseUrl(url) - repository.getCustomHeadersSync(baseUrl).forEach { header -> - builder.addHeader(header.name, header.value) - } + customHeaders.forEach { header -> + builder.addHeader(header.name, header.value) } return builder } - - private fun extractBaseUrl(url: String): String { - val httpUrl = url.toHttpUrlOrNull() ?: return "" - val schemeAndHost = "${httpUrl.scheme}://${httpUrl.host}" - val maybePort = if (httpUrl.port != 80 && httpUrl.port != 443) ":${httpUrl.port}" else "" - return schemeAndHost + maybePort - } } } diff --git a/app/src/main/java/io/heckel/ntfy/service/SubscriberService.kt b/app/src/main/java/io/heckel/ntfy/service/SubscriberService.kt index 484673d1..bfda891d 100644 --- a/app/src/main/java/io/heckel/ntfy/service/SubscriberService.kt +++ b/app/src/main/java/io/heckel/ntfy/service/SubscriberService.kt @@ -254,9 +254,10 @@ class SubscriberService : Service() { val since = sinceByBaseUrl[connectionId.baseUrl] ?: "none" val serviceActive = { isServiceStarted } val user = repository.getUser(connectionId.baseUrl) + val customHeaders = repository.getCustomHeaders(connectionId.baseUrl) val connection = if (connectionId.connectionProtocol == Repository.CONNECTION_PROTOCOL_WS) { val alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager - WsConnection(connectionId, repository, user, since, ::onStateChanged, ::onNotificationReceived, alarmManager) + WsConnection(connectionId, repository, user, customHeaders, since, ::onStateChanged, ::onNotificationReceived, alarmManager) } else { JsonConnection(connectionId, scope, repository, api, user, since, ::onStateChanged, ::onNotificationReceived, serviceActive) } diff --git a/app/src/main/java/io/heckel/ntfy/service/WsConnection.kt b/app/src/main/java/io/heckel/ntfy/service/WsConnection.kt index 703a2713..f72b6951 100644 --- a/app/src/main/java/io/heckel/ntfy/service/WsConnection.kt +++ b/app/src/main/java/io/heckel/ntfy/service/WsConnection.kt @@ -3,7 +3,6 @@ package io.heckel.ntfy.service import android.app.AlarmManager import android.os.Build import io.heckel.ntfy.db.* -import io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.msg.ApiService.Companion.requestBuilder import io.heckel.ntfy.msg.NotificationParser import io.heckel.ntfy.util.Log @@ -33,6 +32,7 @@ class WsConnection( private val connectionId: ConnectionId, private val repository: Repository, private val user: User?, + private val customHeaders: List, private val sinceId: String?, private val stateChangeListener: (Collection, ConnectionState) -> Unit, private val notificationListener: (Subscription, Notification) -> Unit, @@ -77,7 +77,7 @@ class WsConnection( val sinceId = since.get() val sinceVal = sinceId ?: "all" val urlWithSince = topicUrlWs(baseUrl, topicsStr, sinceVal) - val request = requestBuilder(urlWithSince, user, repository).build() + val request = requestBuilder(urlWithSince, user, customHeaders).build() Log.d(TAG, "$shortUrl (gid=$globalId): Opening $urlWithSince with listener ID $nextListenerId ...") webSocket = client.newWebSocket(request, Listener(nextListenerId)) }