Skip to content

Commit a524c5e

Browse files
authored
Merge pull request #156 from SARAMALI15792/fix/run-command-exit-code
fix: runCommand returns correct success status and remove credentials…
2 parents 7c4f09e + 22a6cab commit a524c5e

4 files changed

Lines changed: 16 additions & 13 deletions

File tree

components/terminal/xterm-terminal.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,15 +357,17 @@ export function XtermTerminal({
357357
return null;
358358
}
359359

360+
// Remove credentials from URL — they are sent in the WebSocket init message instead
361+
url.searchParams.delete('authorization');
362+
360363
// Add session ID as arg parameter for ttyd-auth.sh
361-
// URL format: ?authorization=base64(user:pass)&arg=SESSION_ID
362364
url.searchParams.append('arg', terminalSessionId.current);
363365

364366
const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
365367
const wsPath = url.pathname.replace(/\/$/, '') + '/ws';
366368
const wsFullUrl = `${wsProtocol}//${url.host}${wsPath}${url.search}`;
367369

368-
console.log('[XtermTerminal] Connecting to:', wsFullUrl.replace(authorization, '***'));
370+
console.log('[XtermTerminal] Connecting to:', wsFullUrl);
369371
return { wsFullUrl, authorization };
370372
} catch (error) {
371373
console.error('[XtermTerminal] Failed to parse URL:', error);

lib/actions/sandbox.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@ export async function runCommand(
4040
const { ttyd } = await getSandboxTtydContext(sandboxId, session.user.id)
4141
const { baseUrl, accessToken, authorization } = ttyd
4242

43-
const output = await execCommand(baseUrl, accessToken, command, timeoutMs, authorization)
43+
const result = await execCommand(baseUrl, accessToken, command, timeoutMs, authorization)
4444

45-
return { success: true, output }
45+
if (result.exitCode !== 0) {
46+
return { success: false, error: `Command failed with exit code ${result.exitCode}`, output: result.output }
47+
}
48+
49+
return { success: true, output: result.output }
4650
} catch (error) {
4751
console.error('Failed to execute command in sandbox:', error)
4852
const errorMessage = error instanceof TtydExecError ? error.message : 'Unknown error'

lib/util/ttyd-exec.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,7 @@ function stripAnsiCodes(str: string): string {
167167
function buildWsUrl(
168168
ttydUrl: string,
169169
accessToken: string,
170-
sessionId?: string,
171-
authorization?: string
170+
sessionId?: string
172171
): string {
173172
const url = new URL(ttydUrl)
174173
const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
@@ -180,10 +179,7 @@ function buildWsUrl(
180179
if (sessionId) {
181180
params.append('arg', sessionId)
182181
}
183-
if (authorization) {
184-
params.append('authorization', authorization)
185-
}
186-
182+
// authorization is sent securely in the WebSocket init message — not added to URL
187183
return `${wsProtocol}//${url.host}${wsPath}?${params.toString()}`
188184
}
189185

@@ -256,7 +252,7 @@ export async function executeTtydCommand(options: TtydExecOptions): Promise<Ttyd
256252
const endMarkerPattern = new RegExp(`${END_MARKER_PREFIX}${markerId}:(\\d+)___`)
257253

258254
// Build WebSocket URL
259-
const wsUrl = buildWsUrl(ttydUrl, accessToken, sessionId, authorization)
255+
const wsUrl = buildWsUrl(ttydUrl, accessToken, sessionId)
260256

261257
// Text encoder/decoder
262258
const textEncoder = new TextEncoder()
@@ -566,7 +562,7 @@ export async function execCommand(
566562
command: string,
567563
timeoutMs?: number,
568564
authorization?: string
569-
): Promise<string> {
565+
): Promise<{ output: string; exitCode: number }> {
570566
const result = await executeTtydCommand({
571567
ttydUrl,
572568
accessToken,
@@ -579,7 +575,7 @@ export async function execCommand(
579575
throw new TtydExecError('Command timed out', TtydExecErrorCode.TIMEOUT)
580576
}
581577

582-
return result.output
578+
return { output: result.output, exitCode: result.exitCode }
583579
}
584580

585581
/**

next.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { NextConfig } from 'next'
22

33
const nextConfig: NextConfig = {
4+
turbopack: false as any,
45
reactStrictMode: true,
56
output: 'standalone',
67
compress: true,

0 commit comments

Comments
 (0)