Skip to content

Commit 405dd55

Browse files
sirtimidclaude
andauthored
feat(ocap-kernel): add allowedWsHosts param to initializeRemoteComms (#878)
## Summary - Add `allowedWsHosts` as an optional parameter to the `initializeRemoteComms` RPC method (struct, type, and handler) - Pass `allowedWsHosts` through to `RemoteCommsOptions` when provided ## Test plan - [x] Added param validation tests for `allowedWsHosts` (accepts valid array, rejects non-array, rejects non-string elements, accepts empty array) - [x] Added handler test for passing `allowedWsHosts` to hook - [x] Updated existing "all options" and "not include undefined" tests to include `allowedWsHosts` - [x] All tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Extends a networking-related RPC surface to accept and pass through an `allowedWsHosts` allowlist, which can affect what websocket targets are permitted. Risk is moderated by strict param validation and focused tests, but misconfiguration could broaden connectivity. > > **Overview** > Adds an optional `allowedWsHosts: string[]` parameter to the `initializeRemoteComms` RPC method, validating it via superstruct and passing it through to `RemoteCommsOptions` only when provided. > > Updates/expands unit tests to cover `allowedWsHosts` validation (accepts arrays including empty, rejects non-arrays and non-string elements) and to assert the handler forwards the option and omits it when undefined. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f99cce3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a2a205d commit 405dd55

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

packages/ocap-kernel/src/rpc/platform-services/initializeRemoteComms.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,42 @@ describe('initializeRemoteComms', () => {
7070
expect(is(validParams, initializeRemoteCommsSpec.params)).toBe(true);
7171
});
7272

73+
it('should accept params with allowedWsHosts', () => {
74+
const validParams = {
75+
keySeed: '0x1234567890abcdef',
76+
allowedWsHosts: ['localhost', 'example.com'],
77+
};
78+
79+
expect(is(validParams, initializeRemoteCommsSpec.params)).toBe(true);
80+
});
81+
82+
it('should accept params with empty allowedWsHosts array', () => {
83+
const validParams = {
84+
keySeed: '0x1234567890abcdef',
85+
allowedWsHosts: [],
86+
};
87+
88+
expect(is(validParams, initializeRemoteCommsSpec.params)).toBe(true);
89+
});
90+
91+
it('should reject params with non-array allowedWsHosts', () => {
92+
const invalidParams = {
93+
keySeed: '0x1234567890abcdef',
94+
allowedWsHosts: 'not-an-array',
95+
};
96+
97+
expect(is(invalidParams, initializeRemoteCommsSpec.params)).toBe(false);
98+
});
99+
100+
it('should reject params with non-string elements in allowedWsHosts', () => {
101+
const invalidParams = {
102+
keySeed: '0x1234567890abcdef',
103+
allowedWsHosts: ['localhost', 123],
104+
};
105+
106+
expect(is(invalidParams, initializeRemoteCommsSpec.params)).toBe(false);
107+
});
108+
73109
it('should accept params with incarnationId', () => {
74110
const validParams = {
75111
keySeed: '0x1234567890abcdef',
@@ -562,6 +598,31 @@ describe('initializeRemoteComms', () => {
562598
);
563599
});
564600

601+
it('should pass allowedWsHosts to hook when provided', async () => {
602+
const mockInitializeRemoteComms: InitializeRemoteComms = vi.fn(
603+
async () => null,
604+
);
605+
606+
const hooks = {
607+
initializeRemoteComms: mockInitializeRemoteComms,
608+
};
609+
610+
const params = {
611+
keySeed: '0xtestseed',
612+
allowedWsHosts: ['localhost', 'example.com'],
613+
};
614+
615+
await initializeRemoteCommsHandler.implementation(hooks, params);
616+
617+
expect(mockInitializeRemoteComms).toHaveBeenCalledWith(
618+
'0xtestseed',
619+
{
620+
allowedWsHosts: ['localhost', 'example.com'],
621+
},
622+
undefined,
623+
);
624+
});
625+
565626
it('should pass all options when all are provided', async () => {
566627
const mockInitializeRemoteComms: InitializeRemoteComms = vi.fn(
567628
async () => null,
@@ -576,6 +637,7 @@ describe('initializeRemoteComms', () => {
576637
relays: ['/dns4/relay.example/tcp/443/wss/p2p/relay'],
577638
maxRetryAttempts: 5,
578639
maxQueue: 100,
640+
allowedWsHosts: ['localhost'],
579641
};
580642

581643
await initializeRemoteCommsHandler.implementation(hooks, params);
@@ -586,6 +648,7 @@ describe('initializeRemoteComms', () => {
586648
relays: ['/dns4/relay.example/tcp/443/wss/p2p/relay'],
587649
maxRetryAttempts: 5,
588650
maxQueue: 100,
651+
allowedWsHosts: ['localhost'],
589652
},
590653
undefined,
591654
);
@@ -620,6 +683,7 @@ describe('initializeRemoteComms', () => {
620683
expect(options).not.toHaveProperty('relays');
621684
expect(options).not.toHaveProperty('maxRetryAttempts');
622685
expect(options).not.toHaveProperty('maxQueue');
686+
expect(options).not.toHaveProperty('allowedWsHosts');
623687
return null;
624688
},
625689
);
@@ -641,6 +705,7 @@ describe('initializeRemoteComms', () => {
641705
relays: ['/dns4/relay.example/tcp/443/wss/p2p/relay'],
642706
maxRetryAttempts: 5,
643707
maxQueue: 100,
708+
allowedWsHosts: ['localhost'],
644709
};
645710

646711
expect(is(validParams, initializeRemoteCommsSpec.params)).toBe(true);

packages/ocap-kernel/src/rpc/platform-services/initializeRemoteComms.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const initializeRemoteCommsParamsStruct = object({
1515
relays: optional(array(string())),
1616
maxRetryAttempts: optional(number()),
1717
maxQueue: optional(number()),
18+
allowedWsHosts: optional(array(string())),
1819
incarnationId: optional(string()),
1920
});
2021

@@ -23,6 +24,7 @@ type InitializeRemoteCommsParams = {
2324
relays?: string[];
2425
maxRetryAttempts?: number;
2526
maxQueue?: number;
27+
allowedWsHosts?: string[];
2628
incarnationId?: string;
2729
};
2830

@@ -69,6 +71,9 @@ export const initializeRemoteCommsHandler: InitializeRemoteCommsHandler = {
6971
if (params.maxQueue !== undefined) {
7072
options.maxQueue = params.maxQueue;
7173
}
74+
if (params.allowedWsHosts !== undefined) {
75+
options.allowedWsHosts = params.allowedWsHosts;
76+
}
7277
return await initializeRemoteComms(
7378
params.keySeed,
7479
options,

0 commit comments

Comments
 (0)