From 7f45c9010869e204ec9509653191bff89776ae74 Mon Sep 17 00:00:00 2001 From: magnus Date: Wed, 11 Dec 2024 15:29:37 +0100 Subject: [PATCH 1/3] add e2e --- .../app/auth-interrupts/forbidden/page.tsx | 8 ++++++ .../app/auth-interrupts/unauthorized/page.tsx | 8 ++++++ examples/app-router/app/forbidden.tsx | 11 ++++++++ examples/app-router/app/unauthorized.tsx | 7 +++++ examples/app-router/next.config.ts | 3 ++ .../tests/appRouter/auth-interrupts.test.ts | 28 +++++++++++++++++++ 6 files changed, 65 insertions(+) create mode 100644 examples/app-router/app/auth-interrupts/forbidden/page.tsx create mode 100644 examples/app-router/app/auth-interrupts/unauthorized/page.tsx create mode 100644 examples/app-router/app/forbidden.tsx create mode 100644 examples/app-router/app/unauthorized.tsx create mode 100644 packages/tests-e2e/tests/appRouter/auth-interrupts.test.ts diff --git a/examples/app-router/app/auth-interrupts/forbidden/page.tsx b/examples/app-router/app/auth-interrupts/forbidden/page.tsx new file mode 100644 index 000000000..9e9a10b78 --- /dev/null +++ b/examples/app-router/app/auth-interrupts/forbidden/page.tsx @@ -0,0 +1,8 @@ +import { forbidden } from "next/navigation"; + +export default function Page() { + forbidden(); + + // this should never be rendered + return <>; +} diff --git a/examples/app-router/app/auth-interrupts/unauthorized/page.tsx b/examples/app-router/app/auth-interrupts/unauthorized/page.tsx new file mode 100644 index 000000000..d611f5250 --- /dev/null +++ b/examples/app-router/app/auth-interrupts/unauthorized/page.tsx @@ -0,0 +1,8 @@ +import { unauthorized } from "next/navigation"; + +export default function Page() { + unauthorized(); + + // this should never be rendered + return <>; +} diff --git a/examples/app-router/app/forbidden.tsx b/examples/app-router/app/forbidden.tsx new file mode 100644 index 000000000..3c2521184 --- /dev/null +++ b/examples/app-router/app/forbidden.tsx @@ -0,0 +1,11 @@ +import Link from "next/link"; + +export default function Forbidden() { + return ( +
+

Forbidden

+

You are not authorized to access this resource.

+ Return Home +
+ ); +} diff --git a/examples/app-router/app/unauthorized.tsx b/examples/app-router/app/unauthorized.tsx new file mode 100644 index 000000000..7a8bbc3dd --- /dev/null +++ b/examples/app-router/app/unauthorized.tsx @@ -0,0 +1,7 @@ +export default function Unauthorized() { + return ( +
+

Unauthorized

+
+ ); +} diff --git a/examples/app-router/next.config.ts b/examples/app-router/next.config.ts index 8a85d80a7..8ad1b21df 100644 --- a/examples/app-router/next.config.ts +++ b/examples/app-router/next.config.ts @@ -17,6 +17,9 @@ const nextConfig: NextConfig = { }, ], }, + experimental: { + authInterrupts: true, + }, redirects: async () => { return [ { diff --git a/packages/tests-e2e/tests/appRouter/auth-interrupts.test.ts b/packages/tests-e2e/tests/appRouter/auth-interrupts.test.ts new file mode 100644 index 000000000..004f0b5d0 --- /dev/null +++ b/packages/tests-e2e/tests/appRouter/auth-interrupts.test.ts @@ -0,0 +1,28 @@ +import { expect, test } from "@playwright/test"; + +const NO_CACHE_HEADER = + "private, no-cache, no-store, max-age=0, must-revalidate"; + +test("test forbidden", async ({ page }) => { + const result = await page.goto("/auth-interrupts/forbidden"); + expect(result).toBeDefined(); + expect(result?.status()).toBe(403); + + const headers = result?.headers(); + expect(headers?.["cache-control"]).toBe(NO_CACHE_HEADER); + + const heading = page.getByText("Forbidden"); + await expect(heading).toBeVisible(); +}); + +test("test unauthorized", async ({ page }) => { + const result = await page.goto("/auth-interrupts/unauthorized"); + expect(result).toBeDefined(); + expect(result?.status()).toBe(401); + + const headers = result?.headers(); + expect(headers?.["cache-control"]).toBe(NO_CACHE_HEADER); + + const heading = page.getByText("Unauthorized"); + await expect(heading).toBeVisible(); +}); From a4044480aa5a632a6e210212cc93c24704a88d86 Mon Sep 17 00:00:00 2001 From: magnus Date: Wed, 11 Dec 2024 15:30:22 +0100 Subject: [PATCH 2/3] add 403 and 401 to fixHeadersForError --- packages/open-next/src/http/openNextResponse.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/open-next/src/http/openNextResponse.ts b/packages/open-next/src/http/openNextResponse.ts index 5db512ebf..40e10b24d 100644 --- a/packages/open-next/src/http/openNextResponse.ts +++ b/packages/open-next/src/http/openNextResponse.ts @@ -14,6 +14,7 @@ import { parseCookies, parseHeaders } from "./util"; const SET_COOKIE_HEADER = "set-cookie"; const CANNOT_BE_USED = "This cannot be used in OpenNext"; +const ERROR_CODES = [404, 500, 403, 401]; // We only need to implement the methods that are used by next.js export class OpenNextNodeResponse extends Transform implements ServerResponse { @@ -375,15 +376,15 @@ export class OpenNextNodeResponse extends Transform implements ServerResponse { return this; } - // For some reason, next returns the 500 error page with some cache-control headers + // For some reason, next returns the error pages with some cache-control headers // We need to fix that private fixHeadersForError() { if (process.env.OPEN_NEXT_DANGEROUSLY_SET_ERROR_HEADERS === "true") { return; } - // We only check for 404 and 500 errors + // We only check for 401, 403, 404 and 500 errors // The rest should be errors that are handled by the user and they should set the cache headers themselves - if (this.statusCode === 404 || this.statusCode === 500) { + if (ERROR_CODES.includes(this.statusCode)) { // For some reason calling this.setHeader("Cache-Control", "no-cache, no-store, must-revalidate") does not work here // The function is not even called, i'm probably missing something obvious this.headers["cache-control"] = From ae48e5c2cec00bbc78e97a98a30542c837ffe440 Mon Sep 17 00:00:00 2001 From: magnus Date: Wed, 11 Dec 2024 15:37:02 +0100 Subject: [PATCH 3/3] ascending --- packages/open-next/src/http/openNextResponse.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/open-next/src/http/openNextResponse.ts b/packages/open-next/src/http/openNextResponse.ts index 40e10b24d..14f81d91a 100644 --- a/packages/open-next/src/http/openNextResponse.ts +++ b/packages/open-next/src/http/openNextResponse.ts @@ -14,7 +14,7 @@ import { parseCookies, parseHeaders } from "./util"; const SET_COOKIE_HEADER = "set-cookie"; const CANNOT_BE_USED = "This cannot be used in OpenNext"; -const ERROR_CODES = [404, 500, 403, 401]; +const ERROR_CODES = [401, 403, 404, 500]; // We only need to implement the methods that are used by next.js export class OpenNextNodeResponse extends Transform implements ServerResponse {