mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-21 18:26:09 +00:00
fix(server): allow authenticated CORS preflight (#38026)
This commit is contained in:
@@ -10,6 +10,7 @@ import { HttpMiddleware, HttpRouter, HttpServer, HttpServerRequest, HttpServerRe
|
||||
import { randomUUID } from "node:crypto"
|
||||
import { createServer } from "node:http"
|
||||
import { ServerAuth } from "./auth"
|
||||
import { isAllowedCorsOrigin } from "./cors"
|
||||
import { authorizedRequest } from "./middleware/authorization"
|
||||
import { withoutParentSpan } from "./request-tracing"
|
||||
import { createRoutes } from "./routes"
|
||||
@@ -48,7 +49,12 @@ export const start = Effect.fn("ServerProcess.start")(function* <E, R>(
|
||||
const application = yield* Ref.make(Option.none<App>())
|
||||
// Request fibers may continue inbound trace context, but must not inherit the server startup parent.
|
||||
yield* bound.http
|
||||
.serve(dispatch(password, status, application, shutdown), HttpMiddleware.logger)
|
||||
.serve(
|
||||
dispatch(password, status, application, shutdown).pipe(
|
||||
HttpMiddleware.cors({ allowedOrigins: isAllowedCorsOrigin, maxAge: 86_400 }),
|
||||
),
|
||||
HttpMiddleware.logger,
|
||||
)
|
||||
.pipe(withoutParentSpan)
|
||||
if (lifecycle)
|
||||
yield* lifecycle.onListen(bound.http.address, Deferred.succeed(shutdown, undefined).pipe(Effect.asVoid)).pipe(
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { HttpServer } from "effect/unstable/http"
|
||||
import { it } from "../../core/test/lib/effect"
|
||||
import { ServerProcess } from "../src/process"
|
||||
|
||||
it.live("allows browser preflight requests without credentials", () =>
|
||||
Effect.gen(function* () {
|
||||
const server = yield* ServerProcess.start<never, never>({
|
||||
hostname: "127.0.0.1",
|
||||
port: 0,
|
||||
password: "secret",
|
||||
database: { path: ":memory:" },
|
||||
})
|
||||
const response = yield* Effect.promise(() =>
|
||||
fetch(new URL("/api/health", HttpServer.formatAddress(server.address)), {
|
||||
method: "OPTIONS",
|
||||
headers: {
|
||||
origin: "http://localhost:3000",
|
||||
"access-control-request-method": "GET",
|
||||
"access-control-request-headers": "authorization",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
expect(response.status).toBe(204)
|
||||
expect(response.headers.get("access-control-allow-origin")).toBe("http://localhost:3000")
|
||||
expect(response.headers.get("access-control-allow-headers")).toBe("authorization")
|
||||
|
||||
const health = yield* Effect.promise(() =>
|
||||
fetch(new URL("/api/health", HttpServer.formatAddress(server.address)), {
|
||||
headers: {
|
||||
authorization: `Basic ${btoa("opencode:secret")}`,
|
||||
origin: "http://localhost:3000",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
expect(health.status).toBe(200)
|
||||
expect(health.headers.get("access-control-allow-origin")).toBe("http://localhost:3000")
|
||||
}),
|
||||
)
|
||||
Reference in New Issue
Block a user