Improve claim/access detection

This commit is contained in:
Jon Staab
2025-11-04 15:36:20 -08:00
parent fe626218ea
commit 6429f82829
4 changed files with 47 additions and 28 deletions
+7 -6
View File
@@ -107,6 +107,7 @@ import {
getSetting, getSetting,
userInboxRelays, userInboxRelays,
userGroupSelections, userGroupSelections,
shouldIgnoreError,
} from "@app/core/state" } from "@app/core/state"
import {loadAlertStatuses} from "@app/core/requests" import {loadAlertStatuses} from "@app/core/requests"
import {platform, platformName, getPushInfo} from "@app/util/push" import {platform, platformName, getPushInfo} from "@app/util/push"
@@ -288,14 +289,14 @@ export const attemptRelayAccess = async (url: string, claim = "") => {
const thunk = publishJoinRequest({url, claim}) const thunk = publishJoinRequest({url, claim})
const error = await waitForThunkError(thunk) const error = await waitForThunkError(thunk)
// Ignore messages about the relay ignoring our messages if (shouldIgnoreError(error)) return
if (error?.startsWith("mute: ")) return
// If it's a strict NIP 29 relay don't worry about requesting access if (claim) {
// TODO: remove this if relay29 ever gets less strict const ignoreClaimError =
if (error?.includes("missing group (`h`) tag")) return error.includes("invalid invite code size") || error.includes("failed to validate invite code")
return claim ? error?.replace(/^\w+: /, "") : "" if (!ignoreClaimError) return error?.replace(/^\w+: /, "")
}
} }
// Deletions // Deletions
+9 -10
View File
@@ -961,6 +961,14 @@ export const deriveTimeout = (timeout: number) => {
return derived(store, identity) return derived(store, identity)
} }
export const shouldIgnoreError = (error: string) => {
const isIgnored = error.startsWith("mute: ")
const isAborted = error.includes("Signing was aborted")
const isStrictNip29Relay = error.includes("missing group (`h`) tag")
return isIgnored || isAborted || isStrictNip29Relay
}
export const deriveRelayAuthError = (url: string, claim = "") => { export const deriveRelayAuthError = (url: string, claim = "") => {
const stripPrefix = (m: string) => m.replace(/^\w+: /, "") const stripPrefix = (m: string) => m.replace(/^\w+: /, "")
@@ -987,18 +995,9 @@ export const deriveRelayAuthError = (url: string, claim = "") => {
const error = getThunkError(thunk) const error = getThunkError(thunk)
if (error) { if (error) {
const isIgnored = error.startsWith("mute: ")
const isAborted = error.includes("Signing was aborted")
const isEmptyInvite = !claim && error.includes("invite code") const isEmptyInvite = !claim && error.includes("invite code")
const isStrictNip29Relay = error.includes("missing group (`h`) tag")
if ( if (!shouldIgnoreError(error) && !isEmptyInvite) {
!isStrictNip29Relay &&
!isIgnored &&
!isAborted &&
!isEmptyInvite &&
!isStrictNip29Relay
) {
return stripPrefix(error) || "join request rejected" return stripPrefix(error) || "join request rejected"
} }
} }
+2 -1
View File
@@ -18,6 +18,7 @@ import {
RELAY_ADD_MEMBER, RELAY_ADD_MEMBER,
RELAY_REMOVE_MEMBER, RELAY_REMOVE_MEMBER,
isSignedEvent, isSignedEvent,
unionFilters,
} from "@welshman/util" } from "@welshman/util"
import type {Filter, TrustedEvent} from "@welshman/util" import type {Filter, TrustedEvent} from "@welshman/util"
import {request, load, pull} from "@welshman/net" import {request, load, pull} from "@welshman/net"
@@ -96,7 +97,7 @@ const pullAndListen = ({relays, filters, signal}: PullOpts) => {
request({ request({
relays, relays,
signal, signal,
filters: filters.map(assoc("limit", 0)), filters: unionFilters(filters).map(assoc("limit", 0)),
}) })
} }
+29 -11
View File
@@ -6,9 +6,12 @@ import {
isRelayEvent, isRelayEvent,
isRelayOk, isRelayOk,
isRelayClosed, isRelayClosed,
isRelayNegErr,
isClientReq, isClientReq,
isClientEvent, isClientEvent,
isClientClose, isClientClose,
isClientNegOpen,
isClientNegClose,
} from "@welshman/net" } from "@welshman/net"
import {sign} from "@welshman/app" import {sign} from "@welshman/app"
import { import {
@@ -59,10 +62,11 @@ export const mostlyRestrictedPolicy = (socket: Socket) => {
const pending = new Set<string>() const pending = new Set<string>()
const updateStatus = () => const updateStatus = () => {
relaysMostlyRestricted.update( relaysMostlyRestricted.update(
restricted > total / 2 ? assoc(socket.url, error) : dissoc(socket.url), restricted > total / 2 ? assoc(socket.url, error) : dissoc(socket.url),
) )
}
const unsubscribers = [ const unsubscribers = [
on(socket, SocketEvent.Receive, (message: RelayMessage) => { on(socket, SocketEvent.Receive, (message: RelayMessage) => {
@@ -72,20 +76,32 @@ export const mostlyRestrictedPolicy = (socket: Socket) => {
if (pending.has(id)) { if (pending.has(id)) {
pending.delete(id) pending.delete(id)
if (!ok && details.startsWith("restricted: ")) { if (!ok) {
restricted++ if (details.startsWith("auth-required: ")) {
error = details total--
updateStatus() updateStatus()
}
if (details.startsWith("restricted: ")) {
restricted++
error = details
updateStatus()
}
} }
} }
} }
if (isRelayClosed(message)) { if (isRelayClosed(message) || isRelayNegErr(message)) {
const [_, id, details = ""] = message const [_, id, details = ""] = message
if (pending.has(id)) { if (pending.has(id)) {
pending.delete(id) pending.delete(id)
if (details.startsWith("auth-required: ")) {
total--
updateStatus()
}
if (details.startsWith("restricted: ")) { if (details.startsWith("restricted: ")) {
restricted++ restricted++
error = details error = details
@@ -95,10 +111,12 @@ export const mostlyRestrictedPolicy = (socket: Socket) => {
} }
}), }),
on(socket, SocketEvent.Send, (message: ClientMessage) => { on(socket, SocketEvent.Send, (message: ClientMessage) => {
if (isClientReq(message)) { if (isClientReq(message) || isClientNegOpen(message)) {
total++ if (!pending.has(message[1])) {
pending.add(message[1]) total++
updateStatus() pending.add(message[1])
updateStatus()
}
} }
if (isClientEvent(message)) { if (isClientEvent(message)) {
@@ -107,7 +125,7 @@ export const mostlyRestrictedPolicy = (socket: Socket) => {
updateStatus() updateStatus()
} }
if (isClientClose(message)) { if (isClientClose(message) || isClientNegClose(message)) {
pending.delete(message[1]) pending.delete(message[1])
} }
}), }),