fix(connection): keep LAN serving working under the /api browser-trust fence
Markerless requests pass on any Host (a non-browser sender is the principal and forges headers anyway); browser Host matching gains port-less entries and WHATWG normalization; dsh derives LAN IP-literal authorities for an all-interfaces bind and web grows --trusted-host for named ones.
This commit is contained in:
@@ -35,6 +35,9 @@ describe('parseDshArgs', () => {
|
||||
// at boot); the adapter only coerces the port string to a number.
|
||||
expect(parse(['web', '--host', '0.0.0.0', '--port', '8080', '--dev', '--workspace-root', '/w']))
|
||||
.toEqual({ mode: 'web', host: '0.0.0.0', port: 8080, dev: true, workspaceRoot: '/w' })
|
||||
// --trusted-host is variadic and repeatable; authorities pass through unvalidated.
|
||||
expect(parse(['web', '--trusted-host', 'harness.internal:3080', 'lab.internal', '--trusted-host', '10.0.0.9']))
|
||||
.toEqual({ mode: 'web', dev: false, trustedHosts: ['harness.internal:3080', 'lab.internal', '10.0.0.9'] })
|
||||
})
|
||||
|
||||
it('exits nonzero instead of silently starting fresh or dropping inputs', () => {
|
||||
|
||||
40
apps/cli/tests/trusted-hosts.spec.ts
Normal file
40
apps/cli/tests/trusted-hosts.spec.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/** LAN-authority derivation for the /api browser-trust fence (`resolveTrustedHosts`). */
|
||||
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { lanIPv4Addresses, resolveTrustedHosts } from '../src/app-cli-entry.ts'
|
||||
|
||||
vi.mock('node:os', () => ({
|
||||
networkInterfaces: () => ({
|
||||
lo0: [
|
||||
{ family: 'IPv4', internal: true, address: '127.0.0.1' },
|
||||
],
|
||||
en0: [
|
||||
{ family: 'IPv6', internal: false, address: 'fe80::1' },
|
||||
{ family: 'IPv4', internal: false, address: '192.168.1.5' },
|
||||
],
|
||||
en1: [
|
||||
{ family: 'IPv4', internal: false, address: '10.0.0.7' },
|
||||
],
|
||||
utun0: undefined,
|
||||
}),
|
||||
}))
|
||||
|
||||
afterEach(() => { vi.restoreAllMocks() })
|
||||
|
||||
describe('lanIPv4Addresses', () => {
|
||||
it('returns only non-internal IPv4 addresses, in interface order', () => {
|
||||
expect(lanIPv4Addresses()).toEqual(['192.168.1.5', '10.0.0.7'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('resolveTrustedHosts', () => {
|
||||
it('derives port-less LAN IP literals for an all-interfaces bind, ahead of the extras', () => {
|
||||
expect(resolveTrustedHosts('0.0.0.0', ['harness.internal:3080']))
|
||||
.toEqual(['192.168.1.5', '10.0.0.7', 'harness.internal:3080'])
|
||||
})
|
||||
|
||||
it('derives nothing for a loopback or unresolved bind — extras alone stand', () => {
|
||||
expect(resolveTrustedHosts('127.0.0.1', [])).toEqual([])
|
||||
expect(resolveTrustedHosts(undefined, ['lab.internal'])).toEqual(['lab.internal'])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user