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:",