feat(server): validate OPENCHAMBER_OPENCODE_HOSTNAME bind hostname
The env var was already read and passed to the managed OpenCode server spawn, but any non-empty string was accepted. Reject values that are not a valid IP (IPv4/IPv6, brackets allowed) or DNS-style hostname with a clear [config] error and fall back to the secure loopback default so a typo can never silently bind a non-loopback address. Refs OPE-231
This commit is contained in:
@@ -50,7 +50,7 @@ const createMockChild = () => {
|
||||
return child;
|
||||
};
|
||||
|
||||
const createRuntime = (overrides = {}, stateOverrides = {}) => {
|
||||
const createRuntime = (overrides = {}, stateOverrides = {}, envOverrides = {}) => {
|
||||
const state = {
|
||||
openCodeWorkingDirectory: '/tmp/project',
|
||||
openCodeProcess: null,
|
||||
@@ -83,6 +83,7 @@ const createRuntime = (overrides = {}, stateOverrides = {}) => {
|
||||
ENV_EFFECTIVE_PORT: 3001,
|
||||
ENV_CONFIGURED_OPENCODE_HOSTNAME: '127.0.0.1',
|
||||
ENV_SKIP_OPENCODE_START: false,
|
||||
...envOverrides,
|
||||
},
|
||||
syncToHmrState: vi.fn(),
|
||||
syncFromHmrState: vi.fn(),
|
||||
@@ -312,6 +313,27 @@ describe('OpenCode lifecycle', () => {
|
||||
expect(server.signalCode).toBe('SIGTERM');
|
||||
});
|
||||
|
||||
it('launches managed OpenCode on the configured bind hostname', async () => {
|
||||
delete process.env.OPENCODE_BINARY;
|
||||
const child = createMockChild();
|
||||
spawnMock.mockImplementationOnce(() => {
|
||||
queueMicrotask(() => {
|
||||
child.stdout.emit('data', 'opencode server listening on http://0.0.0.0:45678\n');
|
||||
});
|
||||
return child;
|
||||
});
|
||||
|
||||
const runtime = createRuntime({}, {}, { ENV_CONFIGURED_OPENCODE_HOSTNAME: '0.0.0.0' });
|
||||
const server = await runtime.startOpenCode();
|
||||
const [binary, args] = spawnMock.mock.calls[0];
|
||||
|
||||
expect(binary).toBe('opencode');
|
||||
expect(args).toEqual(['serve', '--hostname', '0.0.0.0', '--port', '45678']);
|
||||
|
||||
await server.close();
|
||||
expect(server.signalCode).toBe('SIGTERM');
|
||||
});
|
||||
|
||||
it('strips AppImage ARGV0 from managed OpenCode launch env', async () => {
|
||||
delete process.env.OPENCODE_BINARY;
|
||||
const previousArgv0 = process.env.ARGV0;
|
||||
|
||||
Reference in New Issue
Block a user