From 254730588e9907f4bb23c7453433dd998a9dac19 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 19 Nov 2024 16:30:38 -0700 Subject: [PATCH] fix(nosecone-next): Avoid overriding original headers --- .../app/api/arcjet/route.ts | 7 +++++ examples/nextjs-bot-categories/middleware.ts | 8 +++++ nosecone-next/index.ts | 30 ++++--------------- 3 files changed, 21 insertions(+), 24 deletions(-) create mode 100644 examples/nextjs-bot-categories/middleware.ts diff --git a/examples/nextjs-bot-categories/app/api/arcjet/route.ts b/examples/nextjs-bot-categories/app/api/arcjet/route.ts index b117f0bae..88b4a4a89 100644 --- a/examples/nextjs-bot-categories/app/api/arcjet/route.ts +++ b/examples/nextjs-bot-categories/app/api/arcjet/route.ts @@ -26,6 +26,13 @@ const aj = arcjet({ export async function GET(req: Request) { const decision = await aj.protect(req); + if (decision.isErrored()) { + return NextResponse.json( + { error: decision.reason.message }, + { status: 500, statusText: "Internal Server Error" }, + ) + } + const headers = new Headers(); if (decision.reason.isBot()) { // WARNING: This is illustrative! Don't share this metadata with users; diff --git a/examples/nextjs-bot-categories/middleware.ts b/examples/nextjs-bot-categories/middleware.ts new file mode 100644 index 000000000..28c473b10 --- /dev/null +++ b/examples/nextjs-bot-categories/middleware.ts @@ -0,0 +1,8 @@ +import { createMiddleware } from "@nosecone/next"; + +export const config = { + // matcher tells Next.js which routes to run the middleware on + matcher: ["/(.*)"], +}; + +export default createMiddleware(); diff --git a/nosecone-next/index.ts b/nosecone-next/index.ts index 67b6d8bfe..03f830dd9 100644 --- a/nosecone-next/index.ts +++ b/nosecone-next/index.ts @@ -66,29 +66,6 @@ function applyNextDefaults(options: NoseconeOptions): NoseconeOptions { }; } -// Setting specific headers is the way that Next.js implements middleware -// See: https://github.com/vercel/next.js/blob/5c45d58cd058a9683e435fd3a1a9b8fede8376c3/packages/next/src/server/web/spec-extension/response.ts#L148 -function nextMiddlewareHeaders( - headers: Record, -): Record { - const forwardedHeaders: Record = { - "x-middleware-next": "1", - }; - - // This applies the logic to forward headers from Next.js middleware - // https://github.com/vercel/next.js/blob/5c45d58cd058a9683e435fd3a1a9b8fede8376c3/packages/next/src/server/web/spec-extension/response.ts#L22-L27 - for (const [headerName, headerValue] of Object.entries(headers)) { - if (typeof headerValue !== "string") { - throw new Error(`impossible: missing value for ${headerName}`); - } - forwardedHeaders[`x-middleware-request-${headerName}`] = headerValue; - } - forwardedHeaders["x-middleware-override-headers"] = - Object.keys(headers).join(","); - - return forwardedHeaders; -} - /** * Create Next.js middleware that sets secure headers on every request. * @@ -103,7 +80,12 @@ export function createMiddleware(options: NoseconeOptions = defaults) { return new Response(null, { headers: { ...headers, - ...nextMiddlewareHeaders(headers), + // Setting this specific header is the way that Next.js implements + // middleware. See: + // https://github.com/vercel/next.js/blob/5c45d58cd058a9683e435fd3a1a9b8fede8376c3/packages/next/src/server/web/spec-extension/response.ts#L148 + // Note: we don't create the `x-middleware-override-headers` header so + // the original headers pass through + "x-middleware-next": "1", }, }); };