fix(self-host): tie the public address to a single origin (#2605)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-08 22:17:39 +02:00
1 parent 6c36d934f7
commit 8cc485cf81
17 files changed
+903 -61

No files matched your search

@@ -2,10 +2,12 @@
import {
buildUrl,
canonicalizeDomain,
type DomainConfig,
deriveDomain,
deriveEndpointsFromDomain,
normalizePublicEndpoint,
parsePublicOrigin,
} from '@fluxer/config/src/EndpointDerivation';
import {describe, expect, test} from 'vitest';
@@ -394,3 +396,103 @@ describe('normalizePublicEndpoint', () => {
expect(normalizePublicEndpoint('https://fluxer.dev/media', ' ', 8443)).toBe('https://fluxer.dev/media');
});
});
describe('canonicalizeDomain', () => {
test('lowercases, trims and drops the root dot', () => {
expect(canonicalizeDomain(' CHAT.Example.COM. ')).toBe('chat.example.com');
});
test('leaves an empty value empty', () => {
expect(canonicalizeDomain(' ')).toBe('');
});
});
describe('parsePublicOrigin', () => {
test('reads scheme, host and a non-standard port', () => {
expect(parsePublicOrigin('https://chat.example.com:8443')).toEqual({
public_scheme: 'https',
base_domain: 'chat.example.com',
public_port: 8443,
});
expect(parsePublicOrigin('http://chat.example.com:19080')).toEqual({
public_scheme: 'http',
base_domain: 'chat.example.com',
public_port: 19080,
});
});
test('fills in the standard port for a portless origin', () => {
expect(parsePublicOrigin('https://chat.example.com')).toEqual({
public_scheme: 'https',
base_domain: 'chat.example.com',
public_port: 443,
});
expect(parsePublicOrigin('http://chat.example.com')).toEqual({
public_scheme: 'http',
base_domain: 'chat.example.com',
public_port: 80,
});
});
test('normalizes an explicitly written standard port to the portless form', () => {
const origin = parsePublicOrigin('https://chat.example.com:443');
expect(origin).toEqual({public_scheme: 'https', base_domain: 'chat.example.com', public_port: 443});
expect(buildUrl(origin?.public_scheme ?? 'https', origin?.base_domain ?? '', origin?.public_port)).toBe(
'https://chat.example.com',
);
expect(parsePublicOrigin('http://chat.example.com:80')?.public_port).toBe(80);
});
test('canonicalizes the host', () => {
expect(parsePublicOrigin(' https://CHAT.Example.com.:8443 ')).toEqual({
public_scheme: 'https',
base_domain: 'chat.example.com',
public_port: 8443,
});
});
test('keeps an IPv6 literal bracketed', () => {
expect(parsePublicOrigin('http://[::1]:19080')).toEqual({
public_scheme: 'http',
base_domain: '[::1]',
public_port: 19080,
});
});
test('accepts a bare trailing slash', () => {
expect(parsePublicOrigin('https://chat.example.com:8443/')?.public_port).toBe(8443);
});
test('rejects anything that is not a bare origin', () => {
expect(parsePublicOrigin('')).toBeNull();
expect(parsePublicOrigin(' ')).toBeNull();
expect(parsePublicOrigin('not a url')).toBeNull();
expect(parsePublicOrigin('chat.example.com:8443')).toBeNull();
expect(parsePublicOrigin('wss://chat.example.com')).toBeNull();
expect(parsePublicOrigin('https://chat.example.com/media')).toBeNull();
expect(parsePublicOrigin('https://chat.example.com?a=1')).toBeNull();
expect(parsePublicOrigin('https://chat.example.com#top')).toBeNull();
expect(parsePublicOrigin('https://user:[email protected]')).toBeNull();
});
});
describe('endpoints derived from a public origin', () => {
test('an origin with a non-standard port ports every derived endpoint', () => {
const origin = parsePublicOrigin('https://chat.example.com:29080');
const endpoints = deriveEndpointsFromDomain({
base_domain: origin?.base_domain ?? '',
public_scheme: origin?.public_scheme ?? 'https',
internal_scheme: 'http',
public_port: origin?.public_port,
});
expect(endpoints.api_client).toBe('https://chat.example.com:29080/api');
expect(endpoints.app).toBe('https://chat.example.com:29080');
expect(endpoints.gateway).toBe('wss://chat.example.com:29080/gateway');
expect(endpoints.admin).toBe('https://chat.example.com:29080/admin');
});
test('an origin written with an explicit :443 derives portless endpoints', () => {
const origin = parsePublicOrigin('https://chat.example.com:443');
const endpoints = deriveEndpointsFromDomain({
base_domain: origin?.base_domain ?? '',
public_scheme: origin?.public_scheme ?? 'https',
internal_scheme: 'http',
public_port: origin?.public_port,
});
expect(endpoints.admin).toBe('https://chat.example.com/admin');
expect(endpoints.app).toBe('https://chat.example.com');
expect(endpoints.gateway).toBe('wss://chat.example.com/gateway');
});
});