fix: enforce ws3 roles + node allowlist
This commit is contained in:
@@ -8,6 +8,11 @@ import { WebSocket } from "ws";
|
||||
|
||||
import { resolveMainSessionKeyFromConfig, type SessionEntry } from "../config/sessions.js";
|
||||
import { resetAgentRunContextForTest } from "../infra/agent-events.js";
|
||||
import {
|
||||
loadOrCreateDeviceIdentity,
|
||||
publicKeyRawBase64UrlFromPem,
|
||||
signDevicePayload,
|
||||
} from "../infra/device-identity.js";
|
||||
import { drainSystemEvents, peekSystemEvents } from "../infra/system-events.js";
|
||||
import { rawDataToString } from "../infra/ws.js";
|
||||
import { resetLogger, setLoggerOverride } from "../logging.js";
|
||||
@@ -16,6 +21,7 @@ import { getDeterministicFreePortBlock } from "../test-utils/ports.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||
|
||||
import { PROTOCOL_VERSION } from "./protocol/index.js";
|
||||
import { buildDeviceAuthPayload } from "./device-auth.js";
|
||||
import type { GatewayServerOptions } from "./server.js";
|
||||
import {
|
||||
agentCommand,
|
||||
@@ -268,10 +274,44 @@ export async function connectReq(
|
||||
caps?: string[];
|
||||
commands?: string[];
|
||||
permissions?: Record<string, boolean>;
|
||||
device?: {
|
||||
id: string;
|
||||
publicKey: string;
|
||||
signature: string;
|
||||
signedAt: number;
|
||||
};
|
||||
},
|
||||
): Promise<ConnectResponse> {
|
||||
const { randomUUID } = await import("node:crypto");
|
||||
const id = randomUUID();
|
||||
const client = opts?.client ?? {
|
||||
id: GATEWAY_CLIENT_NAMES.TEST,
|
||||
version: "1.0.0",
|
||||
platform: "test",
|
||||
mode: GATEWAY_CLIENT_MODES.TEST,
|
||||
};
|
||||
const role = opts?.role ?? "operator";
|
||||
const requestedScopes = Array.isArray(opts?.scopes) ? opts?.scopes : [];
|
||||
const device = (() => {
|
||||
if (opts?.device) return opts.device;
|
||||
const identity = loadOrCreateDeviceIdentity();
|
||||
const signedAtMs = Date.now();
|
||||
const payload = buildDeviceAuthPayload({
|
||||
deviceId: identity.deviceId,
|
||||
clientId: client.id,
|
||||
clientMode: client.mode,
|
||||
role,
|
||||
scopes: requestedScopes,
|
||||
signedAtMs,
|
||||
token: opts?.token ?? null,
|
||||
});
|
||||
return {
|
||||
id: identity.deviceId,
|
||||
publicKey: publicKeyRawBase64UrlFromPem(identity.publicKeyPem),
|
||||
signature: signDevicePayload(identity.privateKeyPem, payload),
|
||||
signedAt: signedAtMs,
|
||||
};
|
||||
})();
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: "req",
|
||||
@@ -280,16 +320,11 @@ export async function connectReq(
|
||||
params: {
|
||||
minProtocol: opts?.minProtocol ?? PROTOCOL_VERSION,
|
||||
maxProtocol: opts?.maxProtocol ?? PROTOCOL_VERSION,
|
||||
client: opts?.client ?? {
|
||||
id: GATEWAY_CLIENT_NAMES.TEST,
|
||||
version: "1.0.0",
|
||||
platform: "test",
|
||||
mode: GATEWAY_CLIENT_MODES.TEST,
|
||||
},
|
||||
client,
|
||||
caps: opts?.caps ?? [],
|
||||
commands: opts?.commands ?? [],
|
||||
permissions: opts?.permissions ?? undefined,
|
||||
role: opts?.role,
|
||||
role,
|
||||
scopes: opts?.scopes,
|
||||
auth:
|
||||
opts?.token || opts?.password
|
||||
@@ -298,6 +333,7 @@ export async function connectReq(
|
||||
password: opts?.password,
|
||||
}
|
||||
: undefined,
|
||||
device,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user