Skip to content

Commit 18aea42

Browse files
skulidropekclaude
andcommitted
feat(app): show SSH password in VS Code CF tunnel panel
When clicking VS Code, the panel now: - enables password auth on the container (via chpasswd) - returns sshPassword from POST /ssh-tunnel - displays the password with a copy button Fixes: user was prompted for password without knowing it Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 49179e6 commit 18aea42

3 files changed

Lines changed: 19 additions & 6 deletions

File tree

packages/api/src/http.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1261,12 +1261,18 @@ export const makeRouter = () => {
12611261
Effect.gen(function*(_) {
12621262
const { projectKey } = yield* _(projectKeyParams)
12631263
const project = yield* _(getProjectItemByKey(projectKey))
1264+
const sshPassword = generateSshPassword()
1265+
yield* _(
1266+
enableContainerPasswordAuth(project.containerName, sshPassword).pipe(
1267+
Effect.orElse(() => Effect.void)
1268+
)
1269+
)
12641270
const hostname = yield* _(
12651271
startSshProjectTunnel(projectKey, project.sshPort).pipe(
12661272
Effect.orElse(() => Effect.succeed(null))
12671273
)
12681274
)
1269-
return yield* _(jsonResponse({ hostname }, 200))
1275+
return yield* _(jsonResponse({ hostname, sshPassword }, 200))
12701276
}).pipe(Effect.catchAll(errorResponse))
12711277
)
12721278
)

packages/app/src/web/api-share-links.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,14 @@ export const deleteProjectShareLink = (
7272
OkResponseSchema
7373
).pipe(Effect.asVoid)
7474

75-
const SshTunnelResponseSchema = Schema.Struct({ hostname: Schema.NullOr(Schema.String) })
75+
const SshTunnelResponseSchema = Schema.Struct({
76+
hostname: Schema.NullOr(Schema.String),
77+
sshPassword: Schema.String
78+
})
7679

7780
export const startProjectSshTunnel = (
7881
projectKey: string
79-
): Effect.Effect<{ readonly hostname: string | null }, string> =>
82+
): Effect.Effect<{ readonly hostname: string | null; readonly sshPassword: string }, string> =>
8083
requestJson(
8184
"POST",
8285
`/projects/by-key/${encodeURIComponent(projectKey)}/ssh-tunnel`,

packages/app/src/web/app-ready-terminal-pane.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ const buildVsCodeAccessInfo = (project: TerminalPaneProps["project"]): VsCodeAcc
164164
type CfTunnelState =
165165
| { readonly tag: "idle" }
166166
| { readonly tag: "loading" }
167-
| { readonly tag: "ready"; readonly hostname: string }
167+
| { readonly tag: "ready"; readonly hostname: string; readonly sshPassword: string }
168168
| { readonly tag: "failed" }
169169

170170
const WILDCARD_SSH_CONFIG = `Host *.trycloudflare.com
@@ -263,6 +263,10 @@ const VsCodeAccessPanel = (
263263
<code style={vsCodePanelCodeStyle}>{cfSshCommand}</code>
264264
<button onClick={() => { copyText(cfSshCommand as string) }} style={vsCodePanelCopyBtnStyle} type="button">copy</button>
265265

266+
<div style={{ color: "#8be9fd", fontSize: "0.9em", fontWeight: "bold", marginTop: "10px" }}>SSH password</div>
267+
<code style={vsCodePanelCodeStyle}>{cfState.sshPassword}</code>
268+
<button onClick={() => { copyText(cfState.sshPassword) }} style={vsCodePanelCopyBtnStyle} type="button">copy</button>
269+
266270
{cfVscodeUri !== null && (
267271
<>
268272
<div style={{ color: "#8be9fd", fontSize: "0.9em", fontWeight: "bold", marginTop: "10px" }}>Open in VS Code</div>
@@ -371,10 +375,10 @@ const startTunnel = (
371375
startProjectSshTunnel(projectKey).pipe(
372376
Effect.match({
373377
onFailure: () => { setCfState({ tag: "failed" }) },
374-
onSuccess: ({ hostname }) => {
378+
onSuccess: ({ hostname, sshPassword }) => {
375379
setCfState(
376380
hostname !== null
377-
? { tag: "ready", hostname }
381+
? { tag: "ready", hostname, sshPassword }
378382
: { tag: "failed" }
379383
)
380384
}

0 commit comments

Comments
 (0)