Skip to content

Commit 7eb3f74

Browse files
author
Miriad
committed
fix: use @sanity/webhook for distribute webhook signature validation
Replace custom HMAC crypto with @sanity/webhook's isValidSignature(). Matches the sanity-content webhook route. Fixes 401 errors blocking the distribution pipeline (video_gen → published).
1 parent c8e7e75 commit 7eb3f74

File tree

1 file changed

+11
-23
lines changed
  • app/api/webhooks/sanity-distribute

1 file changed

+11
-23
lines changed

app/api/webhooks/sanity-distribute/route.ts

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,12 @@
11
import { type NextRequest, NextResponse } from "next/server";
2-
import * as crypto from "node:crypto";
2+
import { isValidSignature, SIGNATURE_HEADER_NAME } from "@sanity/webhook";
33
import { writeClient } from "@/lib/sanity-write-client";
44
import { generateWithGemini } from "@/lib/gemini";
55
import { uploadVideo, uploadShort, generateShortsMetadata } from "@/lib/youtube-upload";
66
import { notifySubscribers } from "@/lib/resend-notify";
77
import { postVideoAnnouncement } from "@/lib/x-social";
88

9-
// ---------------------------------------------------------------------------
10-
// Webhook signature validation
11-
// ---------------------------------------------------------------------------
12-
13-
function isValidSignature(body: string, signature: string | null): boolean {
14-
const secret = process.env.SANITY_WEBHOOK_SECRET;
15-
if (!secret) {
16-
console.warn("[sanity-distribute] SANITY_WEBHOOK_SECRET not set");
17-
return true;
18-
}
19-
if (!signature) return false;
20-
const hmac = crypto.createHmac("sha256", secret);
21-
hmac.update(body);
22-
const digest = hmac.digest("base64");
23-
try {
24-
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
25-
} catch {
26-
return false;
27-
}
28-
}
9+
const WEBHOOK_SECRET = process.env.SANITY_WEBHOOK_SECRET;
2910

3011
// ---------------------------------------------------------------------------
3112
// Types
@@ -122,8 +103,15 @@ async function updateStatus(docId: string, status: string, extra: Record<string,
122103

123104
export async function POST(req: NextRequest): Promise<NextResponse> {
124105
const rawBody = await req.text();
125-
const signature = req.headers.get("sanity-webhook-signature");
126-
if (!isValidSignature(rawBody, signature)) {
106+
const signature = req.headers.get(SIGNATURE_HEADER_NAME);
107+
108+
if (!WEBHOOK_SECRET) {
109+
console.error("[sanity-distribute] Missing SANITY_WEBHOOK_SECRET");
110+
return NextResponse.json({ error: "Server misconfigured" }, { status: 500 });
111+
}
112+
113+
if (!signature || !(await isValidSignature(rawBody, signature, WEBHOOK_SECRET))) {
114+
console.log("[sanity-distribute] Invalid signature");
127115
return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
128116
}
129117

0 commit comments

Comments
 (0)