From 59d430b80ac104bff0c437d58d073b7e9db04b26 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 14 Oct 2024 14:09:10 +1300 Subject: [PATCH] ensure cors middleware also affects error responses --- .changeset/calm-rivers-reply.md | 5 ++ .../platform/src/internal/httpMiddleware.ts | 51 ++++++++++++------- 2 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 .changeset/calm-rivers-reply.md diff --git a/.changeset/calm-rivers-reply.md b/.changeset/calm-rivers-reply.md new file mode 100644 index 00000000000..a61a1a9dbf2 --- /dev/null +++ b/.changeset/calm-rivers-reply.md @@ -0,0 +1,5 @@ +--- +"@effect/platform": patch +--- + +ensure cors middleware also affects error responses diff --git a/packages/platform/src/internal/httpMiddleware.ts b/packages/platform/src/internal/httpMiddleware.ts index 00282e0dae3..8518b6e2e3a 100644 --- a/packages/platform/src/internal/httpMiddleware.ts +++ b/packages/platform/src/internal/httpMiddleware.ts @@ -1,4 +1,4 @@ -import type { HttpApp } from "@effect/platform" +import { HttpApp } from "@effect/platform" import * as Context from "effect/Context" import * as Effect from "effect/Effect" import * as FiberRef from "effect/FiberRef" @@ -276,28 +276,41 @@ export const cors = (options?: { ? { "access-control-max-age": opts.maxAge.toString() } : undefined + const headersFromRequest = (request: ServerRequest.HttpServerRequest) => { + const origin = request.headers["origin"] + return Headers.unsafeFromRecord({ + ...allowOrigin(origin), + ...allowCredentials, + ...exposeHeaders + }) + } + + const headersFromRequestOptions = (request: ServerRequest.HttpServerRequest) => { + const origin = request.headers["origin"] + const accessControlRequestHeaders = request.headers["access-control-request-headers"] + return Headers.unsafeFromRecord({ + ...allowOrigin(origin), + ...allowCredentials, + ...exposeHeaders, + ...allowMethods, + ...allowHeaders(accessControlRequestHeaders), + ...maxAge + }) + } + + const preResponseHandler = (request: ServerRequest.HttpServerRequest, response: HttpServerResponse) => + Effect.succeed(ServerResponse.setHeaders(response, headersFromRequest(request))) + return (httpApp: HttpApp.Default): HttpApp.Default => Effect.withFiberRuntime((fiber) => { const context = fiber.getFiberRef(FiberRef.currentContext) - const request = Context.unsafeGet( - context, - ServerRequest.HttpServerRequest - ) - const origin = request.headers["origin"] - const accessControlRequestHeaders = request.headers["access-control-request-headers"] - const corsHeaders = Headers.unsafeFromRecord({ - ...allowOrigin(origin), - ...allowCredentials, - ...exposeHeaders - }) + const request = Context.unsafeGet(context, ServerRequest.HttpServerRequest) if (request.method === "OPTIONS") { - Object.assign(corsHeaders, { - ...allowMethods, - ...allowHeaders(accessControlRequestHeaders), - ...maxAge - }) - return Effect.succeed(ServerResponse.empty({ status: 204, headers: corsHeaders })) + return Effect.succeed(ServerResponse.empty({ + status: 204, + headers: headersFromRequestOptions(request) + })) } - return Effect.map(httpApp, ServerResponse.setHeaders(corsHeaders)) + return Effect.zipRight(HttpApp.appendPreResponseHandler(preResponseHandler), httpApp) }) }