slice-machine icon indicating copy to clipboard operation
slice-machine copied to clipboard

feat(adapter-next): support `secret` in `/slice-simulator` route

Open angeloashmore opened this issue 1 year ago • 1 comments

Resolves: N/A

Description

This PR adds support for a more secure /slice-simulator route in Next.js websites. Both the App Router and Pages Router are supported.

This PR includes the following updates:

  • Adds a secret property to the public SliceSimulatorParams type.
  • Adds server-side runtime checking for the SLICE_SIMULATOR_SECRET environment variable.
  • Upserts slice library index files on project:init. Without this change, /slice-simulator throws an error on fresh projects after running @slicemachine/init.

See this draft documentation for details:

Secure your simulator

We recommend securing your app’s /slice-simulator route when deploying to production. You can require a secret to access the simulator route.

  1. Add a SLICE_SIMULATOR_SECRET environment variable. The value should be unique and unguessable.

  2. Rebuild and deploy your app.

  3. Once deployed, update the live preview URL in the Prismic Page Builder to include ?secret=<your-secret>.

    Example: https://example.com/slice-simulator?secret=abc123

Apps bootstrapped using a Prismic starter include support for the SLICE_SIMULATOR_SECRET environment variable.

If your app’s simulator route was created manually, update the route to check the secret on the server:

// app/slice-simulator/page.tsx

import { SliceSimulatorParams } from "@slicemachine/adapter-next/simulator";
import { redirect } from "next/navigation";

export default function SliceSimulatorPage({
  searchParams,
}: SliceSimulatorParams & { searchParams: { secret?: string } }) {
  if (
    process.env.SLICE_SIMULATOR_SECRET &&
    searchParams.secret !== process.env.SLICE_SIMULATOR_SECRET
  ) {
    redirect("/");
  }

  // ...
}
// pages/slice-simulator.tsx

import { GetServerSidePropsContext } from "next";

// ...

export function getServerSideProps(context: GetServerSidePropsContext) {
  if (
    process.env.SLICE_SIMULATOR_SECRET &&
    context.query.secret !== process.env.SLICE_SIMULATOR_SECRET
  ) {
    return { redirect: { destination: "/", permanent: false } };
  }

  return { props: {} };
}

Now, the /slice-simulator route verifies the secret before rendering. If the secret is incorrect, the request is redirected to /.

Checklist

  • [x] If my changes require tests, I added them.
  • [ ] If my changes affect backward compatibility, it has been discussed.
  • [ ] If my changes require an update to the CONTRIBUTING.md guide, I updated it.

Preview

See the above documentation and updated test snapshots.

How to QA [^1]

  1. Bootstrap a new Next.js app:

    npx create-next-app@latest nextjs-slice-simulator-secret
    cd nextjs-slice-simulator-secret
    npx @slicemachine/[email protected]
    npm run dev
    
  2. Verify http://localhost:3000/slice-simulator loads.

  3. Stop the server and add a SLICE_SIMULATOR_SECRET environment variable:

    echo "SLICE_SIMULATOR_SECRET=foo" > .env.local
    
  4. Start the server and verify the secret works:

    1. Verify http://localhost:3000/slice-simulator redirects to /
    2. Verify http://localhost:3000/slice-simulator?secret=foo loads.
  5. Verify the src/app/slice-simulator/page.tsx file looks correct and contains no TypeScript errors.

[^1]: Please use these labels when submitting a review: :question: #ask: Ask a question. :bulb: #idea: Suggest an idea. :warning: #issue: Strongly suggest a change. :tada: #nice: Share a compliment.

angeloashmore avatar Jun 28 '24 23:06 angeloashmore

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
slice-machine ✅ Ready (Inspect) Visit Preview Jun 29, 2024 0:18am

vercel[bot] avatar Jun 28 '24 23:06 vercel[bot]

Closing until we have a strong internal decision about this.

xrutayisire avatar Nov 28 '24 10:11 xrutayisire