From bf791f43a1f3656efbe477b7c7a27add989be9cc Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Mon, 9 Mar 2026 14:05:02 -0300 Subject: [PATCH] Improve NIP-42 relay authentication permissions by using hostnames - Update `IntentMultiEventHomeScreen`, `BunkerMultiEventHomeScreen`, `IntentSingleEventHomeScreen`, and `BunkerSingleEventHomeScreen` to extract the hostname from relay URLs when processing Kind 22242 events. This ensures permissions are stored and checked against the relay host rather than the full URL. - Broaden `getWildcardRelayPermission` in `ApplicationDao` to match permissions where the relay is `*`, an empty string, or `NULL`, improving fallback logic for global relay permissions. --- .../nostrsigner/database/ApplicationDao.kt | 2 +- .../components/BunkerMultiEventHomeScreen.kt | 28 +++++++++++++++++-- .../components/BunkerSingleEventHomeScreen.kt | 10 +++++-- .../components/IntentMultiEventHomeScreen.kt | 14 +++++++++- .../components/IntentSingleEventHomeScreen.kt | 10 +++++-- 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/database/ApplicationDao.kt b/app/src/main/java/com/greenart7c3/nostrsigner/database/ApplicationDao.kt index d776994b..d752b6ee 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/database/ApplicationDao.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/database/ApplicationDao.kt @@ -80,7 +80,7 @@ interface ApplicationDao { relay: String, ): ApplicationPermissionsEntity? - @Query("SELECT * FROM applicationPermission WHERE pkKey = :key AND type = :type AND kind = :kind AND relay = '*' LIMIT 1") + @Query("SELECT * FROM applicationPermission WHERE pkKey = :key AND type = :type AND kind = :kind AND (relay = '*' OR relay = '' OR relay IS NULL) LIMIT 1") fun getWildcardRelayPermission( key: String, type: String, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerMultiEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerMultiEventHomeScreen.kt index ee4a79f7..dfb4eb35 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerMultiEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerMultiEventHomeScreen.kt @@ -328,7 +328,19 @@ fun BunkerMultiEventHomeScreen( if (request.rememberType.value != RememberType.NEVER && request.checked.value) { val rejectKind = if (request.request is BunkerRequestSign) request.request.event.kind else null val rejectRelay = if (request.request is BunkerRequestSign && request.request.event.kind == 22242) { - if (relayAuthScope == RelayAuthScope.ALL) "*" else (AmberEvent.relay(request.request.event) ?: "") + if (relayAuthScope == RelayAuthScope.ALL) { + "*" + } else { + ( + AmberEvent.relay(request.request.event)?.let { url -> + try { + java.net.URI(url).host ?: url + } catch (e: Exception) { + url + } + } ?: "" + ) + } } else { "" } @@ -416,7 +428,19 @@ fun BunkerMultiEventHomeScreen( if (request.rememberType.value != RememberType.NEVER && request.checked.value) { val signRelay = if (localEvent.kind == 22242) { - if (relayAuthScope == RelayAuthScope.ALL) "*" else (AmberEvent.relay(localEvent) ?: "") + if (relayAuthScope == RelayAuthScope.ALL) { + "*" + } else { + ( + AmberEvent.relay(localEvent)?.let { url -> + try { + java.net.URI(url).host ?: url + } catch (e: Exception) { + url + } + } ?: "" + ) + } } else { "" } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerSingleEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerSingleEventHomeScreen.kt index 40e8c13f..884cdc92 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerSingleEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerSingleEventHomeScreen.kt @@ -619,8 +619,14 @@ fun BunkerSingleEventHomeScreen( } } else if (event.kind == 22242) { // Kind 22242 = relay client authentication (NIP-42) - // Permission is per-relay URL extracted from the event's "relay" tag - val relayUrl = AmberEvent.relay(event) ?: "" + // Permission is per-relay hostname extracted from the event's "relay" tag + val relayUrl = AmberEvent.relay(event)?.let { url -> + try { + java.net.URI(url).host ?: url + } catch (e: Exception) { + url + } + } ?: "" // Check for a relay-specific permission first, then wildcard "*" (all relays) val permission = applicationEntity?.permissions?.firstOrNull { diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentMultiEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentMultiEventHomeScreen.kt index a1ef1671..6548ff01 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentMultiEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentMultiEventHomeScreen.kt @@ -332,7 +332,19 @@ fun IntentMultiEventHomeScreen( if (intentData.rememberType.value != RememberType.NEVER && intentData.checked.value) { val rejectKind = if (intentData.type == SignerType.SIGN_EVENT) intentData.event?.kind else null val rejectRelay = if (intentData.type == SignerType.SIGN_EVENT && intentData.event?.kind == 22242) { - if (relayAuthScope == RelayAuthScope.ALL) "*" else (intentData.event?.let { AmberEvent.relay(it) } ?: "") + if (relayAuthScope == RelayAuthScope.ALL) { + "*" + } else { + ( + AmberEvent.relay(intentData.event)?.let { url -> + try { + java.net.URI(url).host ?: url + } catch (e: Exception) { + url + } + } ?: "" + ) + } } else { "" } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentSingleEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentSingleEventHomeScreen.kt index 164eedbe..2c8151bb 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentSingleEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentSingleEventHomeScreen.kt @@ -245,8 +245,14 @@ fun IntentSingleEventHomeScreen( } } else if (event.kind == 22242) { // Kind 22242 = relay client authentication (NIP-42) - // Permission is per-relay URL extracted from the event's "relay" tag - val relayUrl = AmberEvent.relay(event) ?: "" + // Permission is per-relay hostname extracted from the event's "relay" tag + val relayUrl = AmberEvent.relay(event)?.let { url -> + try { + java.net.URI(url).host ?: url + } catch (e: Exception) { + url + } + } ?: "" // Check for relay-specific permission first, then wildcard "*" (all relays) val permission = applicationEntity?.permissions?.firstOrNull {