Skip to content

Commit 1251a87

Browse files
fix(opencode): strip transfer-encoding in UI proxy and allow public manifest assets (#25698)
Co-authored-by: Kit Langton <[email protected]>
1 parent 67047fa commit 1251a87

5 files changed

Lines changed: 18 additions & 1 deletion

File tree

packages/app/src/components/terminal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ export const Terminal = (props: TerminalProps) => {
482482
const connectToken = async () => {
483483
const result = await client.pty
484484
.connectToken(
485-
{ ptyID: id },
485+
{ ptyID: id, directory },
486486
{
487487
throwOnError: false,
488488
headers: { "x-opencode-ticket": "1" },

packages/opencode/src/server/middleware.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { compress } from "hono/compress"
1313
import * as ServerBackend from "./backend"
1414
import { isAllowedCorsOrigin, type CorsOptions } from "./cors"
1515
import { isPtyConnectPath, PTY_CONNECT_TICKET_QUERY } from "./shared/pty-ticket"
16+
import { isPublicUIPath } from "./shared/public-ui"
1617

1718
const log = Log.create({ service: "server" })
1819

@@ -45,6 +46,7 @@ export const AuthMiddleware: MiddlewareHandler = (c, next) => {
4546
if (c.req.method === "OPTIONS") return next()
4647
const password = Flag.OPENCODE_SERVER_PASSWORD
4748
if (!password) return next()
49+
if (isPublicUIPath(c.req.method, c.req.path)) return next()
4850
if (isPtyConnectPath(c.req.path) && c.req.query(PTY_CONNECT_TICKET_QUERY)) return next()
4951
const username = Flag.OPENCODE_SERVER_USERNAME ?? "opencode"
5052

packages/opencode/src/server/routes/instance/httpapi/middleware/authorization.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Effect, Encoding, Layer, Redacted } from "effect"
33
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
44
import { HttpApiError, HttpApiMiddleware } from "effect/unstable/httpapi"
55
import { hasPtyConnectTicketURL } from "@/server/shared/pty-ticket"
6+
import { isPublicUIPath } from "@/server/shared/public-ui"
67

78
const AUTH_TOKEN_QUERY = "auth_token"
89
const UNAUTHORIZED = 401
@@ -92,6 +93,7 @@ export const authorizationRouterMiddleware = HttpRouter.middleware()(
9293
Effect.gen(function* () {
9394
const request = yield* HttpServerRequest.HttpServerRequest
9495
const url = new URL(request.url, "http://localhost")
96+
if (isPublicUIPath(request.method, url.pathname)) return yield* effect
9597
if (hasPtyConnectTicketURL(url)) return yield* effect
9698
return yield* credentialFromURL(url, request).pipe(
9799
Effect.flatMap((credential) => validateRawCredential(effect, credential, config)),
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Static UI assets the browser fetches without app-managed credentials, e.g.
2+
// the manifest link in <head>. These bypass auth so the page can install/render
3+
// the manifest icons even when a server password is configured.
4+
export const PUBLIC_UI_PATHS = new Set<string>([
5+
"/site.webmanifest",
6+
"/web-app-manifest-192x192.png",
7+
"/web-app-manifest-512x512.png",
8+
])
9+
10+
export function isPublicUIPath(method: string, pathname: string) {
11+
return method === "GET" && PUBLIC_UI_PATHS.has(pathname)
12+
}

packages/opencode/src/server/shared/ui.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function proxyResponseHeaders(headers: Record<string, string>) {
3333
// transfer metadata makes browsers decode already-decoded assets again.
3434
result.delete("content-encoding")
3535
result.delete("content-length")
36+
result.delete("transfer-encoding")
3637
return result
3738
}
3839

0 commit comments

Comments
 (0)