diff --git a/.changeset/red-crabs-tickle.md b/.changeset/red-crabs-tickle.md new file mode 100644 index 0000000..a538e84 --- /dev/null +++ b/.changeset/red-crabs-tickle.md @@ -0,0 +1,7 @@ +--- +"e2e": patch +"@next-safe/middleware": patch +--- + +fix(middleware): Added forgotten redirect/notFound fields into gsspWithNonce function. +fix(e2e): Aadded test pages to test redirect/notFound fields in gsspWithNonce. diff --git a/apps/e2e/components/InternalTestLinks.tsx b/apps/e2e/components/InternalTestLinks.tsx new file mode 100644 index 0000000..e5736e6 --- /dev/null +++ b/apps/e2e/components/InternalTestLinks.tsx @@ -0,0 +1,26 @@ +export const InternalTestLinks = () => { + return ( + + ); +}; + +export default InternalTestLinks; diff --git a/apps/e2e/components/TestNavigation.tsx b/apps/e2e/components/TestNavigation.tsx new file mode 100644 index 0000000..1e339f7 --- /dev/null +++ b/apps/e2e/components/TestNavigation.tsx @@ -0,0 +1,12 @@ +import { InternalTestLinks } from './InternalTestLinks'; + +export const TestNavigation = () => { + return ( + <> +

Internal navigation to other pages

+ + + ); +}; + +export default TestNavigation; diff --git a/apps/e2e/pages/gssp-not-found/index.tsx b/apps/e2e/pages/gssp-not-found/index.tsx new file mode 100644 index 0000000..e83efcb --- /dev/null +++ b/apps/e2e/pages/gssp-not-found/index.tsx @@ -0,0 +1,18 @@ +import Layout from 'components/Layout'; +import { gsspWithNonce } from '@next-safe/middleware/dist/document'; + +export const getServerSideProps = gsspWithNonce(async (ctx) => { + return { + notFound: true, + }; +}); + +const Page = () => { + return ( + + Page should show 404 error + + ); +}; + +export default Page; diff --git a/apps/e2e/pages/gssp-redirect/index.tsx b/apps/e2e/pages/gssp-redirect/index.tsx new file mode 100644 index 0000000..ad44605 --- /dev/null +++ b/apps/e2e/pages/gssp-redirect/index.tsx @@ -0,0 +1,21 @@ +import Layout from 'components/Layout'; +import { gsspWithNonce } from '@next-safe/middleware/dist/document'; + +export const getServerSideProps = gsspWithNonce(async (ctx) => { + return { + redirect: { + destination: '/gssp-redirect/redirected', + permanent: false, + }, + }; +}); + +const Page = () => { + return ( + + Page should redirect to /gssp-redirected + + ); +}; + +export default Page; diff --git a/apps/e2e/pages/gssp-redirect/redirected.tsx b/apps/e2e/pages/gssp-redirect/redirected.tsx new file mode 100644 index 0000000..b88afa4 --- /dev/null +++ b/apps/e2e/pages/gssp-redirect/redirected.tsx @@ -0,0 +1,46 @@ +import "twin.macro"; +import { gsspWithNonce } from "@next-safe/middleware/dist/document"; +import Prose from '../../components/Prose'; +import Hydrated from '../../components/Hydrated'; +import StyleElem from '../../components/StyleElem'; +import StyleAttr from '../../components/StyleAttr'; +import TestNavigation from '../../components/TestNavigation'; +import Layout from '../../components/Layout'; + +export const getServerSideProps = gsspWithNonce(async (ctx) => { + return { + props: {}, + }; +}); + +const Page = () => { + + return ( + + +

A Page with getServerSideProps (redirected)

+ +

+ It get's prerendered per request and has access to request and + response data +

+

+ That's why it can use Nonce-based CSP, it has the chance to set a + fresh nonce as attribute to scripts on each request. +

+

Inline Styles

+ + Hi, i am styled with by an inline style tag. If I am teal, I am + trusted by CSP + + + Hi, i am styled with by an inline style attribute, If I am blue + , I am trusted by CSP + + +
+
+ ); +}; + +export default Page; diff --git a/apps/e2e/pages/gssp/index.tsx b/apps/e2e/pages/gssp/index.tsx index 2e3f009..5a8837d 100644 --- a/apps/e2e/pages/gssp/index.tsx +++ b/apps/e2e/pages/gssp/index.tsx @@ -5,6 +5,7 @@ import Hydrated from "components/Hydrated"; import StyleElem from "components/StyleElem"; import StyleAttr from "components/StyleAttr"; import { gsspWithNonce } from "@next-safe/middleware/dist/document"; +import TestNavigation from "../../components/TestNavigation"; export const getServerSideProps = gsspWithNonce(async (ctx) => { return { @@ -35,19 +36,7 @@ const Page = () => { Hi, i am styled with by an inline style attribute, If I am blue , I am trusted by CSP -

Internal navigation to other pages

- + ); diff --git a/apps/e2e/pages/index.tsx b/apps/e2e/pages/index.tsx index 12d9ce9..d1c0f93 100644 --- a/apps/e2e/pages/index.tsx +++ b/apps/e2e/pages/index.tsx @@ -1,6 +1,7 @@ -import Prose from "components/Prose"; -import Container from "components/Container"; -import Hydrated from "components/Hydrated"; +import Prose from 'components/Prose'; +import Container from 'components/Container'; +import Hydrated from 'components/Hydrated'; +import InternalTestLinks from '../components/InternalTestLinks'; // pages without a data fetching function are static pages and must use a Hash-based CSP. const Page = () => { @@ -18,20 +19,7 @@ const Page = () => {

Prerendering strategies:

This page has no data fetching method

- +

With Mantine:

  • diff --git a/apps/e2e/pages/isr/[slug].tsx b/apps/e2e/pages/isr/[slug].tsx index c6f29b4..97ae1f7 100644 --- a/apps/e2e/pages/isr/[slug].tsx +++ b/apps/e2e/pages/isr/[slug].tsx @@ -1,9 +1,9 @@ -import Link from "next/link"; -import Prose from "components/Prose"; -import Layout from "components/Layout"; -import Hydrated from "components/Hydrated"; -import StyleElem from "components/StyleElem"; -import StyleAttr from "components/StyleAttr"; +import Prose from 'components/Prose'; +import Layout from 'components/Layout'; +import Hydrated from 'components/Hydrated'; +import StyleElem from 'components/StyleElem'; +import StyleAttr from 'components/StyleAttr'; +import TestNavigation from '../../components/TestNavigation'; export const getStaticPaths = async () => { // as long as we build-time prerender at least one path, it will work with Hash-based strict CSP. @@ -63,15 +63,7 @@ const Page = ({ random, revalidate }) => { Hi, i am styled with by an inline style attribute, If I am{" "} fuchsia, I am trusted by CSP -

    Internal navigation to other pages:

    -
      -
    • - Page with getStaticProps -
    • -
    • - Page with getServerSideProps -
    • -
    + ); diff --git a/packages/next-safe-middleware/src/document/NextPageContext/index.ts b/packages/next-safe-middleware/src/document/NextPageContext/index.ts index 8297afb..118085c 100644 --- a/packages/next-safe-middleware/src/document/NextPageContext/index.ts +++ b/packages/next-safe-middleware/src/document/NextPageContext/index.ts @@ -11,10 +11,18 @@ export function gsspWithNonce< ): GetServerSideProps

    { return async (ctx) => { const gsspResult = await getServerSideProps(ctx); + const nonce = getCreateCtxNonceIdempotent(ctx); + if ("notFound" in gsspResult) { + const notFound = await gsspResult.notFound; + return { props: { nonce }, notFound: notFound }; + } + if ("redirect" in gsspResult) { + const redirect = await gsspResult.redirect; + return { props: { nonce }, redirect: redirect }; + } if ("props" in gsspResult) { - const nonce = getCreateCtxNonceIdempotent(ctx); const props = await gsspResult.props; - return { props: { ...props, nonce } }; + return { props: { ...props, nonce }}; } }; }