feat(federation): normalizeOriginForCompare helper
This commit is contained in:
@@ -78,3 +78,33 @@ describe('verifyPeerSignature', () => {
|
||||
expect(verifyPeerSignature(body, sig, timestamp, nonce, peer)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
import { normalizeOriginForCompare } from './federationAuth.js';
|
||||
|
||||
describe('normalizeOriginForCompare', () => {
|
||||
it('canonicalizes a bare host', () => {
|
||||
expect(normalizeOriginForCompare('nova.ddns.net')).toBe('nova.ddns.net');
|
||||
});
|
||||
it('strips https:// scheme', () => {
|
||||
expect(normalizeOriginForCompare('https://nova.ddns.net')).toBe('nova.ddns.net');
|
||||
});
|
||||
it('strips http:// scheme', () => {
|
||||
expect(normalizeOriginForCompare('http://localhost:3005')).toBe('localhost:3005');
|
||||
});
|
||||
it('strips trailing slash', () => {
|
||||
expect(normalizeOriginForCompare('https://nova.ddns.net/')).toBe('nova.ddns.net');
|
||||
});
|
||||
it('lowercases the host', () => {
|
||||
expect(normalizeOriginForCompare('HTTPS://Nova.DDNS.net')).toBe('nova.ddns.net');
|
||||
});
|
||||
it('returns null for null input', () => {
|
||||
expect(normalizeOriginForCompare(null)).toBeNull();
|
||||
});
|
||||
it('returns null for empty string', () => {
|
||||
expect(normalizeOriginForCompare('')).toBeNull();
|
||||
});
|
||||
it('treats bare and full-URL forms as equal', () => {
|
||||
expect(normalizeOriginForCompare('nova.ddns.net'))
|
||||
.toBe(normalizeOriginForCompare('https://nova.ddns.net'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -182,3 +182,31 @@ export function getOurOrigin(): string {
|
||||
}
|
||||
return `http://localhost:${config.port}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Canonicalize a homeInstance / origin value for comparison.
|
||||
*
|
||||
* The homeInstance column is stored in two shapes depending on the code path
|
||||
* that wrote it:
|
||||
* - `auth.ts` registration writes the bare host the client sent (e.g. `nova.ddns.net`).
|
||||
* - `resolveOrCreateReplicatedUser` writes the bare host (`extractDomain(...)`).
|
||||
* - `getOurOrigin()` returns the full URL (`https://nova.ddns.net`).
|
||||
*
|
||||
* All federation authority / self-friend comparisons must route through this
|
||||
* helper to avoid false-fires across the dual storage convention. Returns the
|
||||
* lowercased host (with optional :port), no scheme, no trailing slash.
|
||||
*
|
||||
* NOTE: A federation-wide audit + canonical-storage migration is tracked
|
||||
* separately. This helper papers over the inconsistency at comparison sites.
|
||||
*/
|
||||
export function normalizeOriginForCompare(value: string | null | undefined): string | null {
|
||||
if (!value) return null;
|
||||
let s = value.trim();
|
||||
if (!s) return null;
|
||||
// Strip scheme if present
|
||||
s = s.replace(/^https?:\/\//i, '');
|
||||
// Strip trailing slashes
|
||||
s = s.replace(/\/+$/, '');
|
||||
if (!s) return null;
|
||||
return s.toLowerCase();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user