Skip to content

Commit

Permalink
Use separate jwt's for invoking preview and storing preview state
Browse files Browse the repository at this point in the history
  • Loading branch information
fraxachun committed Oct 30, 2024
1 parent e0dea4c commit e44e6f3
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class SitePreviewResolver {
},
})
.setProtectedHeader({ alg: "HS256" })
.setExpirationTime("1 day")
.setExpirationTime("10 seconds")
.sign(new TextEncoder().encode(this.config.secret));
}
}
30 changes: 23 additions & 7 deletions packages/site/cms-site/src/sitePreview/SitePreviewUtils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import "server-only";

import { jwtVerify } from "jose";
import { errors, jwtVerify, SignJWT } from "jose";
import { cookies, draftMode } from "next/headers";
import { redirect } from "next/navigation";
import { type NextRequest } from "next/server";
import { type NextRequest, NextResponse } from "next/server";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Scope = Record<string, any>;
Expand All @@ -21,12 +21,23 @@ export async function sitePreviewRoute(request: NextRequest, _graphQLFetch: unkn
const params = request.nextUrl.searchParams;
const jwt = params.get("jwt");
if (!jwt) {
throw new Error("Missing jwt parameter");
return NextResponse.json({ error: "JWT-Parameter is missing." });
}

const data = await verifySitePreviewJwt(jwt);
if (!data) {
return NextResponse.json({ error: "JWT-validation failed." });
}

cookies().set("__comet_preview", jwt);
const cookieJwt = await new SignJWT({
scope: data.scope,
path: data.path,
previewData: data.previewData,
})
.setProtectedHeader({ alg: "HS256" })
.setExpirationTime("1 day")
.sign(new TextEncoder().encode(process.env.SITE_PREVIEW_SECRET));
cookies().set("__comet_preview", cookieJwt, { httpOnly: true, sameSite: "lax" });

draftMode().enable();

Expand All @@ -50,10 +61,15 @@ export async function previewParams(options: { skipDraftModeCheck: boolean } = {
return null;
}

export async function verifySitePreviewJwt(jwt: string): Promise<SitePreviewParams> {
export async function verifySitePreviewJwt(jwt: string): Promise<SitePreviewParams | null> {
if (!process.env.SITE_PREVIEW_SECRET) {
throw new Error("SITE_PREVIEW_SECRET environment variable is required.");
}
const data = await jwtVerify<SitePreviewParams>(jwt, new TextEncoder().encode(process.env.SITE_PREVIEW_SECRET));
return data.payload;
try {
const data = await jwtVerify<SitePreviewParams>(jwt, new TextEncoder().encode(process.env.SITE_PREVIEW_SECRET));
return data.payload;
} catch (e) {
if (e instanceof errors.JOSEError) return null;
throw e;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ async function legacyPagesRouterSitePreviewApiHandler(
const jwt = params.jwt;

if (typeof jwt !== "string") {
throw new Error("Missing jwt parameter");
return res.end("JWT-Parameter is missing.");
}

const data = await verifySitePreviewJwt(jwt);
if (!data) {
return res.end("JWT-validation failed.");
}

res.setPreviewData(data);
res.redirect(data.path);
Expand Down

0 comments on commit e44e6f3

Please sign in to comment.