feat(federation): normalizeOriginForCompare helper
This commit is contained in:
@@ -78,3 +78,33 @@ describe('verifyPeerSignature', () => {
|
|||||||
expect(verifyPeerSignature(body, sig, timestamp, nonce, peer)).toBe(false);
|
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}`;
|
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