feat: ignore untrusted relay list and onion relays

This commit is contained in:
codytseng
2025-05-19 22:35:53 +08:00
parent 8d23c49908
commit c85892d6cd
3 changed files with 27 additions and 16 deletions

View File

@@ -13,6 +13,7 @@ import {
tagNameEquals tagNameEquals
} from './tag' } from './tag'
import { isWebsocketUrl, normalizeHttpUrl, normalizeUrl } from './url' import { isWebsocketUrl, normalizeHttpUrl, normalizeUrl } from './url'
import { isTorBrowser } from './utils'
const EVENT_EMBEDDED_EVENT_IDS_CACHE = new LRUCache<string, string[]>({ max: 10000 }) const EVENT_EMBEDDED_EVENT_IDS_CACHE = new LRUCache<string, string[]>({ max: 10000 })
const EVENT_IS_REPLY_NOTE_CACHE = new LRUCache<string, boolean>({ max: 10000 }) const EVENT_IS_REPLY_NOTE_CACHE = new LRUCache<string, boolean>({ max: 10000 })
@@ -137,30 +138,35 @@ export function getRelayListFromRelayListEvent(event?: Event) {
return { write: BIG_RELAY_URLS, read: BIG_RELAY_URLS, originalRelays: [] } return { write: BIG_RELAY_URLS, read: BIG_RELAY_URLS, originalRelays: [] }
} }
const torBrowserDetected = isTorBrowser()
const relayList = { write: [], read: [], originalRelays: [] } as TRelayList const relayList = { write: [], read: [], originalRelays: [] } as TRelayList
event.tags.filter(tagNameEquals('r')).forEach(([, url, type]) => { event.tags.filter(tagNameEquals('r')).forEach(([, url, type]) => {
if (!url || !isWebsocketUrl(url)) return if (!url || !isWebsocketUrl(url)) return
const normalizedUrl = normalizeUrl(url) const normalizedUrl = normalizeUrl(url)
if (!normalizedUrl) return if (!normalizedUrl) return
switch (type) {
case 'write': const scope = type === 'read' ? 'read' : type === 'write' ? 'write' : 'both'
relayList.write.push(normalizedUrl) relayList.originalRelays.push({ url: normalizedUrl, scope })
relayList.originalRelays.push({ url: normalizedUrl, scope: 'write' })
break // Filter out .onion URLs if not using Tor browser
case 'read': if (normalizedUrl.endsWith('.onion/') && !torBrowserDetected) return
relayList.read.push(normalizedUrl)
relayList.originalRelays.push({ url: normalizedUrl, scope: 'read' }) if (type === 'write') {
break relayList.write.push(normalizedUrl)
default: } else if (type === 'read') {
relayList.write.push(normalizedUrl) relayList.read.push(normalizedUrl)
relayList.read.push(normalizedUrl) } else {
relayList.originalRelays.push({ url: normalizedUrl, scope: 'both' }) relayList.write.push(normalizedUrl)
relayList.read.push(normalizedUrl)
} }
}) })
// If there are too many relays, use the default BIG_RELAY_URLS
// Because they don't know anything about relays, their settings cannot be trusted
return { return {
write: relayList.write.length ? relayList.write : BIG_RELAY_URLS, write: relayList.write.length && relayList.write.length <= 8 ? relayList.write : BIG_RELAY_URLS,
read: relayList.read.length ? relayList.read : BIG_RELAY_URLS, read: relayList.read.length && relayList.write.length <= 8 ? relayList.read : BIG_RELAY_URLS,
originalRelays: relayList.originalRelays originalRelays: relayList.originalRelays
} }
} }

View File

@@ -18,6 +18,12 @@ export function isAndroid() {
return /android/i.test(ua) return /android/i.test(ua)
} }
export function isTorBrowser() {
if (typeof window === 'undefined' || !window.navigator) return false
const ua = window.navigator.userAgent
return /torbrowser/i.test(ua)
}
export function isInViewport(el: HTMLElement) { export function isInViewport(el: HTMLElement) {
const rect = el.getBoundingClientRect() const rect = el.getBoundingClientRect()
return ( return (

View File

@@ -54,7 +54,6 @@ const ProfilePage = forwardRef(({ id, index }: { id?: string; index?: number },
if (!topContainer) return if (!topContainer) return
const checkHeight = () => { const checkHeight = () => {
console.log('checkHeight', topContainer.scrollHeight)
setTopContainerHeight(topContainer.scrollHeight) setTopContainerHeight(topContainer.scrollHeight)
} }