diff --git a/apps/web/app/api/webhooks/callback/route.ts b/apps/web/app/api/webhooks/callback/route.ts index 9988d29f66..58a8013997 100644 --- a/apps/web/app/api/webhooks/callback/route.ts +++ b/apps/web/app/api/webhooks/callback/route.ts @@ -18,12 +18,12 @@ const searchParamsSchema = z.object({ // POST /api/webhooks/callback – listen to webhooks status from QStash export const POST = async (req: Request) => { - const rawBody = await req.json(); + const rawBody = await req.text(); - await verifyQstashSignature(req, rawBody); + await verifyQstashSignature(req, rawBody, "text"); const { url, status, body, sourceBody, sourceMessageId } = - webhookCallbackSchema.parse(rawBody); + webhookCallbackSchema.parse(JSON.parse(rawBody)); const { webhookId, eventId, event } = searchParamsSchema.parse( getSearchParams(req.url), diff --git a/apps/web/lib/cron/verify-qstash.ts b/apps/web/lib/cron/verify-qstash.ts index 729a8fa499..eea74dc605 100644 --- a/apps/web/lib/cron/verify-qstash.ts +++ b/apps/web/lib/cron/verify-qstash.ts @@ -9,13 +9,14 @@ const receiver = new Receiver({ export const verifyQstashSignature = async ( req: Request, - body?: Record, + body?: any, + bodyType: "json" | "text" = "json", ) => { - body = body || (await req.json()); + body = body || (bodyType === "json" ? await req.json() : await req.text()); const isValid = await receiver.verify({ signature: req.headers.get("Upstash-Signature") || "", - body: JSON.stringify(body), + body: bodyType === "json" ? JSON.stringify(body) : body, }); if (!isValid) {