feat(federation): resolveOriginFromHostname helper
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { getDb } from '../db/index.js';
|
||||
import * as schema from '../db/schema.js';
|
||||
import { getOurOrigin } from './federationAuth.js';
|
||||
import { validateOrigin } from '../routes/federation.js';
|
||||
|
||||
/**
|
||||
* Resolve a typed hostname (e.g., the part after `@` in `alice@orbit.test`)
|
||||
* into a full peer origin URL suitable for ensurePeered() / fetch().
|
||||
*
|
||||
* Resolution order:
|
||||
* 1. If a federation_peers row exists whose URL host matches (case-insensitive),
|
||||
* return that peer's stored origin verbatim. (Authoritative for any peer the
|
||||
* admin has explicitly configured.)
|
||||
* 2. Otherwise, mirror getOurOrigin()'s scheme:
|
||||
* - https://... → https://${hostname}
|
||||
* - http://... → http://${hostname} (covers dev: localhost:3006)
|
||||
* Validate via validateOrigin (which rejects http for non-localhost).
|
||||
*
|
||||
* Returns null if the result fails validation (e.g., http for a public domain
|
||||
* when our scheme is http — caller should surface as 'invalid target').
|
||||
*
|
||||
* Stale-scheme edge case: if a stored peer row points at the wrong scheme
|
||||
* (peer migrated http↔https since the row was written), ensurePeered will
|
||||
* surface a connectivity failure via the standard 'unreachable' path. Scheme
|
||||
* migration of an existing peer is an admin operation outside this code's
|
||||
* scope (delete + re-peer).
|
||||
*/
|
||||
export function resolveOriginFromHostname(hostnameOrHostPort: string): string | null {
|
||||
if (!hostnameOrHostPort) return null;
|
||||
const target = hostnameOrHostPort.trim().toLowerCase();
|
||||
if (!target) return null;
|
||||
|
||||
const db = getDb();
|
||||
const peers = db
|
||||
.select({ origin: schema.federationPeers.origin })
|
||||
.from(schema.federationPeers)
|
||||
.all();
|
||||
|
||||
for (const p of peers) {
|
||||
try {
|
||||
const u = new URL(p.origin);
|
||||
if (u.host.toLowerCase() === target) return p.origin;
|
||||
} catch {
|
||||
// skip malformed origin
|
||||
}
|
||||
}
|
||||
|
||||
const ourScheme = getOurOrigin().startsWith('https://') ? 'https://' : 'http://';
|
||||
const candidate = `${ourScheme}${target}`;
|
||||
return validateOrigin(candidate);
|
||||
}
|
||||
Reference in New Issue
Block a user