feat(server): pty websocket auth tickets (#25660)

This commit is contained in:
Kit Langton
2026-05-03 22:56:14 -04:00
committed by GitHub
parent ce89bcb8e2
commit 7bc26dafae
19 changed files with 545 additions and 30 deletions

View File

@@ -479,6 +479,21 @@ export const Terminal = (props: TerminalProps) => {
return false
})
const connectToken = async () => {
const result = await client.pty.connectToken(
{ ptyID: id },
{
throwOnError: false,
headers: { "x-opencode-ticket": "1" },
},
)
if (result.response.status === 200 && result.data?.ticket) return result.data.ticket
if ((result.response.status === 404 || result.response.status === 405) && password) return
if (result.response.status === 403)
throw new Error("PTY connect ticket rejected by origin or CSRF checks. Check the server CORS config.")
throw new Error(`PTY connect ticket failed with ${result.response.status}`)
}
const retry = (err: unknown) => {
if (disposed) return
if (reconn !== undefined) return
@@ -498,16 +513,24 @@ export const Terminal = (props: TerminalProps) => {
}, ms)
}
const open = () => {
const open = async () => {
if (disposed) return
drop?.()
const ticket = await connectToken().catch((err) => {
fail(err)
return undefined
})
if (once.value) return
if (disposed) return
const socket = new WebSocket(
terminalWebSocketURL({
url,
id,
directory,
cursor: seek,
ticket,
sameOrigin,
username,
password,

View File

@@ -5,8 +5,9 @@ export function terminalWebSocketURL(input: {
id: string
directory: string
cursor: number
sameOrigin: boolean
username: string
ticket?: string
sameOrigin?: boolean
username?: string
password?: string
authToken?: boolean
}) {
@@ -14,6 +15,10 @@ export function terminalWebSocketURL(input: {
next.searchParams.set("directory", input.directory)
next.searchParams.set("cursor", String(input.cursor))
next.protocol = next.protocol === "https:" ? "wss:" : "ws:"
if (input.ticket) {
next.searchParams.set("ticket", input.ticket)
return next
}
if (input.password && (!input.sameOrigin || input.authToken))
next.searchParams.set(
"auth_token",