diff --git a/packages/features/webhooks/lib/cron.ts b/packages/features/webhooks/lib/cron.ts index 913217b2741a87..92ca8b0712bba3 100644 --- a/packages/features/webhooks/lib/cron.ts +++ b/packages/features/webhooks/lib/cron.ts @@ -5,7 +5,7 @@ import dayjs from "@calcom/dayjs"; import { defaultHandler } from "@calcom/lib/server"; import prisma from "@calcom/prisma"; -import { jsonParse } from "./sendPayload"; +import { createWebhookSignature, jsonParse } from "./sendPayload"; async function handler(req: NextApiRequest, res: NextApiResponse) { const apiKey = req.headers.authorization || req.query.apiKey; @@ -25,6 +25,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { // run jobs for (const job of jobsToRun) { + // Fetch the webhook configuration so that we can get the secret. + const [appId, subscriberId] = job.jobName.split("_"); + const webhook = await prisma.webhook.findUniqueOrThrow({ + where: { id: subscriberId, appId: appId !== "null" ? appId : null }, + }); try { await fetch(job.subscriberUrl, { method: "POST", @@ -32,6 +37,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { headers: { "Content-Type": !job.payload || jsonParse(job.payload) ? "application/json" : "application/x-www-form-urlencoded", + "X-Cal-Signature-256": createWebhookSignature({ secret: webhook.secret, body: job.payload }), }, }); } catch (error) { diff --git a/packages/features/webhooks/lib/sendPayload.ts b/packages/features/webhooks/lib/sendPayload.ts index cad89ca7c99ce0..d0670b0153d08a 100644 --- a/packages/features/webhooks/lib/sendPayload.ts +++ b/packages/features/webhooks/lib/sendPayload.ts @@ -189,6 +189,11 @@ export const sendGenericWebhookPayload = async ({ return _sendPayload(secretKey, webhook, body, "application/json"); }; +export const createWebhookSignature = (params: { secret?: string | null; body: string }) => + params.secret + ? createHmac("sha256", params.secret).update(`${params.body}`).digest("hex") + : "no-secret-provided"; + const _sendPayload = async ( secretKey: string | null, webhook: Pick, @@ -200,15 +205,11 @@ const _sendPayload = async ( throw new Error("Missing required elements to send webhook payload."); } - const secretSignature = secretKey - ? createHmac("sha256", secretKey).update(`${body}`).digest("hex") - : "no-secret-provided"; - const response = await fetch(subscriberUrl, { method: "POST", headers: { "Content-Type": contentType, - "X-Cal-Signature-256": secretSignature, + "X-Cal-Signature-256": createWebhookSignature({ secret: secretKey, body }), }, redirect: "manual", body,