From 41a7c91893065248ec8ff7f862a8a3fcc9f1b0d7 Mon Sep 17 00:00:00 2001 From: silberengel Date: Thu, 21 Aug 2025 00:02:27 +0200 Subject: [PATCH] Made localhost relays off by default, with localstorage checkbox to turn it on. --- src/lib/components/RelayStatus.svelte | 29 ++++++++++++++++++++++++-- src/lib/ndk.ts | 11 ++++++++++ src/lib/stores/userStore.ts | 30 +++++++++++++++++++++++++++ src/lib/utils/relay_management.ts | 28 ++++++++++++++++++++++++- 4 files changed, 95 insertions(+), 3 deletions(-) diff --git a/src/lib/components/RelayStatus.svelte b/src/lib/components/RelayStatus.svelte index cf4d069..9afbe91 100644 --- a/src/lib/components/RelayStatus.svelte +++ b/src/lib/components/RelayStatus.svelte @@ -1,5 +1,5 @@
@@ -124,6 +138,17 @@
+
+ + +
+ {#if !$ndkSignedIn} Anonymous Mode diff --git a/src/lib/ndk.ts b/src/lib/ndk.ts index d5d0d69..f724969 100644 --- a/src/lib/ndk.ts +++ b/src/lib/ndk.ts @@ -12,6 +12,7 @@ import { buildCompleteRelaySet, deduplicateRelayUrls, testRelayConnection, + setLocalhostPreferenceChangeCallback, } from "./utils/relay_management.ts"; import { userStore } from "./stores/userStore.ts"; @@ -52,6 +53,16 @@ let relaySetLastUpdated: number = 0; const RELAY_SET_CACHE_DURATION = 5 * 60 * 1000; // 5 minutes const RELAY_SET_STORAGE_KEY = "alexandria/relay_set_cache"; +// AI-NOTE: 2025-01-24 - Function to invalidate relay cache when localhost preference changes +function invalidateRelayCache() { + persistentRelaySet = null; + relaySetLastUpdated = 0; + console.debug("[NDK.ts] Relay cache invalidated due to localhost preference change"); +} + +// Set up callback for localhost preference changes +setLocalhostPreferenceChangeCallback(invalidateRelayCache); + /** * Load persistent relay set from localStorage */ diff --git a/src/lib/stores/userStore.ts b/src/lib/stores/userStore.ts index a2551e0..4f84cf8 100644 --- a/src/lib/stores/userStore.ts +++ b/src/lib/stores/userStore.ts @@ -39,6 +39,36 @@ export const userStore = writable({ signedIn: false, }); +// AI-NOTE: 2025-01-24 - User preference for localhost relay inclusion +// This allows users to disable localhost relays for security reasons +const LOCALHOST_RELAYS_STORAGE_KEY = "alexandria/preferences/include_localhost_relays"; + +// Initialize from localStorage if available +let initialLocalhostPreference = false; +if (typeof window !== "undefined") { + try { + const stored = localStorage.getItem(LOCALHOST_RELAYS_STORAGE_KEY); + if (stored !== null) { + initialLocalhostPreference = JSON.parse(stored); + } + } catch (error) { + console.warn("Failed to load localhost relay preference from localStorage:", error); + } +} + +export const includeLocalhostRelays = writable(initialLocalhostPreference); + +// Subscribe to changes and persist to localStorage +if (typeof window !== "undefined") { + includeLocalhostRelays.subscribe((value) => { + try { + localStorage.setItem(LOCALHOST_RELAYS_STORAGE_KEY, JSON.stringify(value)); + } catch (error) { + console.warn("Failed to save localhost relay preference to localStorage:", error); + } + }); +} + // Helper functions for relay management function getRelayStorageKey(user: NDKUser, type: "inbox" | "outbox"): string { return `${loginStorageKey}/${user.pubkey}/${type}`; diff --git a/src/lib/utils/relay_management.ts b/src/lib/utils/relay_management.ts index 32c21b8..ac779ec 100644 --- a/src/lib/utils/relay_management.ts +++ b/src/lib/utils/relay_management.ts @@ -8,6 +8,7 @@ import { } from "../consts.ts"; import { getRelaySetForNetworkCondition } from "./network_detection.ts"; import { networkCondition } from "../stores/networkStore.ts"; +import { includeLocalhostRelays } from "../stores/userStore.ts"; import { get } from "svelte/store"; /** @@ -349,6 +350,23 @@ async function testLocalRelays( } } +// AI-NOTE: 2025-01-24 - Cache invalidation for localhost preference changes +// This allows the relay management system to react to user preference changes +let localhostPreferenceChangeCallback: (() => void) | null = null; + +export function setLocalhostPreferenceChangeCallback(callback: () => void) { + localhostPreferenceChangeCallback = callback; +} + +// Subscribe to localhost preference changes and trigger relay updates +if (typeof window !== "undefined") { + includeLocalhostRelays.subscribe(() => { + if (localhostPreferenceChangeCallback) { + localhostPreferenceChangeCallback(); + } + }); +} + /** * Discovers local relays by testing common localhost URLs * @param ndk NDK instance @@ -356,6 +374,13 @@ async function testLocalRelays( */ export async function discoverLocalRelays(ndk: NDK): Promise { try { + // Check if user has disabled localhost relays + const shouldIncludeLocalhost = get(includeLocalhostRelays); + if (!shouldIncludeLocalhost) { + console.debug("[relay_management.ts] Localhost relays disabled by user preference"); + return []; + } + // If no local relays are configured, return empty array if (localRelays.length === 0) { console.debug("[relay_management.ts] No local relays configured"); @@ -686,7 +711,8 @@ export async function buildCompleteRelaySet( user?.pubkey || "null", ); - // Discover local relays first + // AI-NOTE: 2025-01-24 - Local relay discovery respects user preference + // The discoverLocalRelays function will return empty array if user has disabled localhost relays const discoveredLocalRelays = await discoverLocalRelays(ndk); console.debug( "[relay_management.ts] buildCompleteRelaySet: Discovered local relays:",