diff --git a/src/lib/openswarm/openswarm.test.ts b/src/lib/openswarm/openswarm.test.ts index b85645b..5397a03 100644 --- a/src/lib/openswarm/openswarm.test.ts +++ b/src/lib/openswarm/openswarm.test.ts @@ -246,3 +246,21 @@ describe('the README renderer', () => { expect(escapeHtml(`<&>"'`)).toBe('<&>"''); }); }); + +describe('the hub record', () => { + it('advertises the public base, not whatever origin the proxy handed it', async () => { + // Behind Railway the request origin is internal, and a record built from + // it told every client to call back on localhost. + const { publicOrigin } = await import('./service'); + const previous = process.env.NEXT_PUBLIC_APP_URL; + + process.env.NEXT_PUBLIC_APP_URL = 'https://bittorrented.com/'; + expect(publicOrigin('https://localhost:3000')).toBe('https://bittorrented.com'); + + delete process.env.NEXT_PUBLIC_APP_URL; + expect(publicOrigin('http://localhost:3000')).toBe('http://localhost:3000'); + + if (previous === undefined) delete process.env.NEXT_PUBLIC_APP_URL; + else process.env.NEXT_PUBLIC_APP_URL = previous; + }); +}); diff --git a/src/lib/openswarm/service.ts b/src/lib/openswarm/service.ts index 15e2315..2760dd2 100644 --- a/src/lib/openswarm/service.ts +++ b/src/lib/openswarm/service.ts @@ -890,8 +890,21 @@ export function hubKey(): string { return isKey(key) ? key : 'ed25519:0000000000000000000000000000000000000000000000000000000000000000'; } +/** + * The public base a client should call back on. + * + * Behind Railway's proxy the request's own origin is the internal one, so a + * record built from it told everybody to talk to localhost. The configured app + * URL wins, exactly as the seedbox and IPTV rails already do it, and the + * request origin is only the fallback for a local run. + */ +export function publicOrigin(fallbackOrigin?: string): string { + return (process.env.NEXT_PUBLIC_APP_URL || fallbackOrigin || 'https://bittorrented.com').replace(/\/+$/, ''); +} + /** `GET /.well-known/openswarm-hub.json` (ippay §5.1, pay2seed §6.1). */ -export function hubRecord(origin: string): Record { +export function hubRecord(requestOrigin: string): Record { + const origin = publicOrigin(requestOrigin); return { openswarm: OPENSWARM_VERSION, type: 'ippay.hub',