fix: prevent connecting to own instance as a remote

Add shared isSelfOrigin() helper that normalizes origins before
comparing to window.location.origin. Fixes auto-connect treating
self-referencing replicatedInstances entries as remote connections,
causing duplicate friends/DMs/data. Also hides self-referencing
entries from the Connections panel UI.
This commit is contained in:
Jannis Braun
2026-04-08 01:28:20 +02:00
parent fa5dbbfd4f
commit a1c47e071e
2 changed files with 16 additions and 6 deletions
@@ -1,7 +1,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import type { InstanceInfoResponse, FederationRegistryEntry } from '@backspace/shared'; import type { InstanceInfoResponse, FederationRegistryEntry } from '@backspace/shared';
import { useInstanceStore, DifferentPasswordError } from '../../stores/instanceStore'; import { useInstanceStore, DifferentPasswordError, isSelfOrigin } from '../../stores/instanceStore';
import { useAuthStore } from '../../stores/authStore'; import { useAuthStore } from '../../stores/authStore';
import { useUIStore } from '../../stores/uiStore'; import { useUIStore } from '../../stores/uiStore';
import { isElectron } from '../../platform/platform'; import { isElectron } from '../../platform/platform';
@@ -991,8 +991,9 @@ export function ConnectedInstances() {
}); });
}; };
// Convert registry Map to array // Convert registry Map to array (hide self-referencing entry — shown as Home Instance above)
const registryEntries = Array.from(registry.values()); const registryEntries = Array.from(registry.values())
.filter(entry => !isSelfOrigin(entry.origin));
// Compute filter counts // Compute filter counts
const counts = { const counts = {
+12 -3
View File
@@ -116,6 +116,15 @@ function normalizeOrigin(url: string): string {
} }
} }
/** Check whether an origin string refers to the current (home) instance. */
export function isSelfOrigin(origin: string): boolean {
try {
return normalizeOrigin(origin) === window.location.origin;
} catch {
return false;
}
}
// ─── API client resolution ─────────────────────────────────────────────────── // ─── API client resolution ───────────────────────────────────────────────────
// ─── Registry helpers ──────────────────────────────────────────────────────── // ─── Registry helpers ────────────────────────────────────────────────────────
@@ -187,8 +196,8 @@ export const useInstanceStore = create<InstanceState>((set, get) => ({
const origin = normalizeOrigin(url); const origin = normalizeOrigin(url);
// Reject self-connection // Reject self-connection
if (origin === window.location.origin) { if (isSelfOrigin(url)) {
throw new Error('Cannot add your home instance as a remote instance'); throw new Error("You're already logged into this instance");
} }
// Reject duplicates // Reject duplicates
@@ -791,7 +800,7 @@ export const useInstanceStore = create<InstanceState>((set, get) => ({
for (const ri of currentUser.replicatedInstances) { for (const ri of currentUser.replicatedInstances) {
const origin = ri.origin || `https://${ri.domain}`; const origin = ri.origin || `https://${ri.domain}`;
// Never connect to ourselves — home WS is managed separately // Never connect to ourselves — home WS is managed separately
if (origin === window.location.origin) continue; if (isSelfOrigin(origin)) continue;
if (get().instances.some(i => i.origin === origin)) continue; // already loaded if (get().instances.some(i => i.origin === origin)) continue; // already loaded
const cachedEntry = cached[origin]; const cachedEntry = cached[origin];
const regEntry = registry.get(origin); const regEntry = registry.get(origin);