@@ -0,0 +1,34 @@
|
||||
import { NextRequest } from "next/server";
|
||||
import { db } from "@/lib/db";
|
||||
import crypto from "crypto";
|
||||
import type { ReviewSession } from "@prisma/client";
|
||||
|
||||
export type TokenValidation =
|
||||
| { type: "ok"; session: ReviewSession }
|
||||
| { type: "invalid" }
|
||||
| { type: "requiresPassword" };
|
||||
|
||||
export function makeUnlockCookieValue(token: string): string {
|
||||
const secret = process.env.AUTH_SECRET ?? "fallback-secret";
|
||||
return crypto.createHmac("sha256", secret).update(token).digest("hex");
|
||||
}
|
||||
|
||||
export async function validateReviewToken(
|
||||
token: string,
|
||||
req: NextRequest
|
||||
): Promise<TokenValidation> {
|
||||
const session = await db.reviewSession.findUnique({ where: { token } });
|
||||
if (!session || !session.isActive) return { type: "invalid" };
|
||||
if (session.expiresAt && session.expiresAt < new Date()) return { type: "invalid" };
|
||||
|
||||
if (session.passwordHash) {
|
||||
const cookieName = `rsauth_${token}`;
|
||||
const cookieValue = req.cookies.get(cookieName)?.value;
|
||||
const expected = makeUnlockCookieValue(token);
|
||||
if (!cookieValue || cookieValue !== expected) {
|
||||
return { type: "requiresPassword" };
|
||||
}
|
||||
}
|
||||
|
||||
return { type: "ok", session };
|
||||
}
|
||||
Reference in New Issue
Block a user