Browse Source

fix(opencode): strip transfer-encoding in UI proxy and allow public manifest assets (#25698)

Co-authored-by: Kit Langton <kit.langton@gmail.com>
OpeOginni 3 tháng trước cách đây
mục cha
commit
1251a870cb

+ 1 - 1
packages/app/src/components/terminal.tsx

@@ -482,7 +482,7 @@ export const Terminal = (props: TerminalProps) => {
       const connectToken = async () => {
         const result = await client.pty
           .connectToken(
-            { ptyID: id },
+            { ptyID: id, directory },
             {
               throwOnError: false,
               headers: { "x-opencode-ticket": "1" },

+ 2 - 0
packages/opencode/src/server/middleware.ts

@@ -13,6 +13,7 @@ import { compress } from "hono/compress"
 import * as ServerBackend from "./backend"
 import { isAllowedCorsOrigin, type CorsOptions } from "./cors"
 import { isPtyConnectPath, PTY_CONNECT_TICKET_QUERY } from "./shared/pty-ticket"
+import { isPublicUIPath } from "./shared/public-ui"
 
 const log = Log.create({ service: "server" })
 
@@ -45,6 +46,7 @@ export const AuthMiddleware: MiddlewareHandler = (c, next) => {
   if (c.req.method === "OPTIONS") return next()
   const password = Flag.OPENCODE_SERVER_PASSWORD
   if (!password) return next()
+  if (isPublicUIPath(c.req.method, c.req.path)) return next()
   if (isPtyConnectPath(c.req.path) && c.req.query(PTY_CONNECT_TICKET_QUERY)) return next()
   const username = Flag.OPENCODE_SERVER_USERNAME ?? "opencode"
 

+ 2 - 0
packages/opencode/src/server/routes/instance/httpapi/middleware/authorization.ts

@@ -3,6 +3,7 @@ import { Effect, Encoding, Layer, Redacted } from "effect"
 import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
 import { HttpApiError, HttpApiMiddleware } from "effect/unstable/httpapi"
 import { hasPtyConnectTicketURL } from "@/server/shared/pty-ticket"
+import { isPublicUIPath } from "@/server/shared/public-ui"
 
 const AUTH_TOKEN_QUERY = "auth_token"
 const UNAUTHORIZED = 401
@@ -92,6 +93,7 @@ export const authorizationRouterMiddleware = HttpRouter.middleware()(
       Effect.gen(function* () {
         const request = yield* HttpServerRequest.HttpServerRequest
         const url = new URL(request.url, "http://localhost")
+        if (isPublicUIPath(request.method, url.pathname)) return yield* effect
         if (hasPtyConnectTicketURL(url)) return yield* effect
         return yield* credentialFromURL(url, request).pipe(
           Effect.flatMap((credential) => validateRawCredential(effect, credential, config)),

+ 12 - 0
packages/opencode/src/server/shared/public-ui.ts

@@ -0,0 +1,12 @@
+// Static UI assets the browser fetches without app-managed credentials, e.g.
+// the manifest link in <head>. These bypass auth so the page can install/render
+// the manifest icons even when a server password is configured.
+export const PUBLIC_UI_PATHS = new Set<string>([
+  "/site.webmanifest",
+  "/web-app-manifest-192x192.png",
+  "/web-app-manifest-512x512.png",
+])
+
+export function isPublicUIPath(method: string, pathname: string) {
+  return method === "GET" && PUBLIC_UI_PATHS.has(pathname)
+}

+ 1 - 0
packages/opencode/src/server/shared/ui.ts

@@ -33,6 +33,7 @@ function proxyResponseHeaders(headers: Record<string, string>) {
   // transfer metadata makes browsers decode already-decoded assets again.
   result.delete("content-encoding")
   result.delete("content-length")
+  result.delete("transfer-encoding")
   return result
 }