fix: authenticate desktop agent websocket

This commit is contained in:
Simos Mikelatos
2026-06-19 15:52:23 +00:00
parent f150fa6b09
commit 077baee5f2
4 changed files with 19 additions and 8 deletions

View File

@@ -40,11 +40,12 @@ function toAgentWsUrl(httpUrl) {
* while desktop access is enabled. * while desktop access is enabled.
*/ */
export class ComputerAgentController { export class ComputerAgentController {
constructor({ appRoot, settingsPath, isPackaged = false, getRunningEnvironmentUrls, promptConsent, onChange }) { constructor({ appRoot, settingsPath, isPackaged = false, getRunningEnvironmentUrls, getApiKey, promptConsent, onChange }) {
this.appRoot = appRoot; this.appRoot = appRoot;
this.settingsPath = settingsPath; this.settingsPath = settingsPath;
this.isPackaged = isPackaged; this.isPackaged = isPackaged;
this.getRunningEnvironmentUrls = getRunningEnvironmentUrls; this.getRunningEnvironmentUrls = getRunningEnvironmentUrls;
this.getApiKey = getApiKey;
this.promptConsent = promptConsent; this.promptConsent = promptConsent;
this.onChange = onChange; this.onChange = onChange;
this.settings = { enabled: false, consentMode: 'ask' }; this.settings = { enabled: false, consentMode: 'ask' };
@@ -138,6 +139,7 @@ export class ComputerAgentController {
...runtime.env, ...runtime.env,
PATH: getDesktopPath(), PATH: getDesktopPath(),
CLOUDCLI_DESKTOP_AGENT_URLS: wsTargets.join(','), CLOUDCLI_DESKTOP_AGENT_URLS: wsTargets.join(','),
CLOUDCLI_DESKTOP_AGENT_API_KEY: this.getApiKey?.() || '',
CLOUDCLI_COMPUTER_USE_CONSENT_MODE: this.settings.consentMode, CLOUDCLI_COMPUTER_USE_CONSENT_MODE: this.settings.consentMode,
}, },
stdio: ['pipe', 'pipe', 'pipe'], stdio: ['pipe', 'pipe', 'pipe'],

View File

@@ -909,6 +909,7 @@ async function bootstrap() {
settingsPath: getComputerUseSettingsPath(), settingsPath: getComputerUseSettingsPath(),
isPackaged: app.isPackaged, isPackaged: app.isPackaged,
getRunningEnvironmentUrls, getRunningEnvironmentUrls,
getApiKey: () => cloud.getAccount()?.apiKey || '',
promptConsent: promptComputerUseConsent, promptConsent: promptComputerUseConsent,
onChange: syncDesktopState, onChange: syncDesktopState,
}); });

View File

@@ -42,6 +42,7 @@ const RECONNECT_MAX_MS = 30_000;
const consentMode: ConsentMode = process.env.CLOUDCLI_COMPUTER_USE_CONSENT_MODE === 'auto' ? 'auto' : 'ask'; const consentMode: ConsentMode = process.env.CLOUDCLI_COMPUTER_USE_CONSENT_MODE === 'auto' ? 'auto' : 'ask';
const agentLabel = process.env.CLOUDCLI_DESKTOP_AGENT_LABEL || 'cloudcli-desktop'; const agentLabel = process.env.CLOUDCLI_DESKTOP_AGENT_LABEL || 'cloudcli-desktop';
const desktopAgentApiKey = process.env.CLOUDCLI_DESKTOP_AGENT_API_KEY || '';
function parseTargets(): string[] { function parseTargets(): string[] {
const raw = const raw =
@@ -195,9 +196,7 @@ function connect(url: string): void {
const open = () => { const open = () => {
socket = new WebSocket(url, { socket = new WebSocket(url, {
headers: process.env.CLOUDCLI_DESKTOP_AGENT_TOKEN headers: desktopAgentApiKey ? { 'X-API-Key': desktopAgentApiKey } : undefined,
? { 'x-cloudcli-agent-token': process.env.CLOUDCLI_DESKTOP_AGENT_TOKEN }
: undefined,
}); });
socket.on('open', () => { socket.on('open', () => {

View File

@@ -15,9 +15,7 @@ export function handleDesktopAgentConnection(
ws: WebSocket, ws: WebSocket,
request: AuthenticatedWebSocketRequest request: AuthenticatedWebSocketRequest
): void { ): void {
const label = request.user?.username ? `desktop:${request.user.username}` : 'desktop-agent'; let registered = false;
console.log('[INFO] Desktop agent websocket connected:', label);
desktopAgentRelay.register(ws, label);
ws.on('message', (rawMessage) => { ws.on('message', (rawMessage) => {
const data = parseIncomingJsonObject(rawMessage); const data = parseIncomingJsonObject(rawMessage);
@@ -25,6 +23,17 @@ export function handleDesktopAgentConnection(
return; return;
} }
const kind = typeof data.kind === 'string' ? data.kind : typeof data.type === 'string' ? data.type : ''; const kind = typeof data.kind === 'string' ? data.kind : typeof data.type === 'string' ? data.type : '';
if (kind === 'register' && !registered) {
const label = typeof data.label === 'string' && data.label.trim()
? data.label.trim()
: request.user?.username
? `desktop:${request.user.username}`
: 'desktop-agent';
registered = true;
console.log('[INFO] Desktop agent websocket registered:', label);
desktopAgentRelay.register(ws, label);
return;
}
if (kind === 'computer_relay_result' && typeof data.id === 'string') { if (kind === 'computer_relay_result' && typeof data.id === 'string') {
desktopAgentRelay.handleResult( desktopAgentRelay.handleResult(
data.id, data.id,
@@ -37,6 +46,6 @@ export function handleDesktopAgentConnection(
}); });
ws.on('close', () => { ws.on('close', () => {
console.log('[INFO] Desktop agent websocket disconnected:', label); console.log('[INFO] Desktop agent websocket disconnected');
}); });
} }