diff --git a/packages/cli/src/services/web-ui.ts b/packages/cli/src/services/web-ui.ts index ebb3d1b41ac..9a3615720a2 100644 --- a/packages/cli/src/services/web-ui.ts +++ b/packages/cli/src/services/web-ui.ts @@ -26,7 +26,7 @@ export const handler = Effect.fn("cli.web-ui.handler")(function* (options?: { re function serveUI(request: HttpServerRequest.HttpServerRequest, url: URL, assets: AssetMap) { const key = url.pathname.replace(/^\//, "") - if (key.startsWith("_assets/") && assets[key] === undefined) + if ((key.startsWith("_assets/") || key.startsWith("icons/")) && assets[key] === undefined) return Effect.succeed(HttpServerResponse.empty({ status: 404, headers: { "cache-control": "no-store" } })) const name = assets[key] !== undefined ? key : "index.html" const file = assets[name] @@ -45,7 +45,7 @@ function serveUI(request: HttpServerRequest.HttpServerRequest, url: URL, assets: } return Effect.succeed( request.method === "HEAD" - ? HttpServerResponse.empty({ headers }) + ? HttpServerResponse.empty({ status: 200, headers }) : HttpServerResponse.raw(file, { headers, contentType: headers["content-type"] }), ) } diff --git a/packages/server/src/process.ts b/packages/server/src/process.ts index bb25cbd5f3c..99f3b37f1b4 100644 --- a/packages/server/src/process.ts +++ b/packages/server/src/process.ts @@ -184,6 +184,7 @@ function dispatch( const app = yield* Ref.get(application) const ready = state.type === "ready" && Option.isSome(app) if ( + (url.pathname === "/api" || url.pathname.startsWith("/api/") || url.pathname === "/openapi.json") && (!ready || (!hasPtyConnectTicketURL(url) && !hasPersistentPtyConnectTicketURL(url))) && !(yield* authorizedRequest(request, auth)) ) diff --git a/packages/server/test/process.test.ts b/packages/server/test/process.test.ts index 96f4f92b851..0b36bcfef6f 100644 --- a/packages/server/test/process.test.ts +++ b/packages/server/test/process.test.ts @@ -114,5 +114,13 @@ it.live("allows browser preflight requests without credentials", () => expect(missing.headers.get("content-type")).toBe("text/plain") expect(missing.headers.get("vary")?.toLowerCase()).toContain("accept-encoding") expect(yield* Effect.promise(() => missing.text())).toBe(fallback) + + yield* Effect.forEach(["/api", "/api/missing", "/openapi.json"], (pathname) => + Effect.gen(function* () { + const response = yield* Effect.promise(() => fetch(new URL(pathname, HttpServer.formatAddress(server.address)))) + expect(response.status).toBe(401) + expect(yield* Effect.promise(() => response.text())).toBe("") + }), + ) }), )