diff --git a/packages/trigger-sdk/src/triggers/httpTrigger.ts b/packages/trigger-sdk/src/triggers/httpTrigger.ts index b06e879b2..b2b3d8c00 100644 --- a/packages/trigger-sdk/src/triggers/httpTrigger.ts +++ b/packages/trigger-sdk/src/triggers/httpTrigger.ts @@ -5,14 +5,12 @@ import { Prettify, RequestFilter, TriggerMetadata, - deepMergeFilters, } from "@trigger.dev/core"; +import { ParsedPayloadSchemaError } from "../errors"; import { Job } from "../job"; import { TriggerClient } from "../triggerClient"; import { EventSpecification, EventSpecificationExample, SchemaParser, Trigger } from "../types"; import { formatSchemaErrors } from "../utils/formatSchemaErrors"; -import { ParsedPayloadSchemaError } from "../errors"; -import { z } from "zod"; type Options> = { id: string; @@ -65,10 +63,11 @@ export type HttpTriggerOptions = { filter?: EventFilter; examples?: EventSpecificationExample[]; properties?: DisplayProperty[]; - verify?: { - requestFilter: RequestFilter; + sendResponse?: { + ifRequest: RequestFilter; onRequest: (request: Request, context: RequestContext) => Promise; }; + verify: (request: Request, context: RequestContext) => Promise; }; type HttpRequest = { diff --git a/references/job-catalog/src/httpTrigger.ts b/references/job-catalog/src/httpTrigger.ts index 8b7cbe47c..eb0a186c7 100644 --- a/references/job-catalog/src/httpTrigger.ts +++ b/references/job-catalog/src/httpTrigger.ts @@ -1,5 +1,6 @@ import { createExpressServer } from "@trigger.dev/express"; -import { TriggerClient, eventTrigger } from "@trigger.dev/sdk"; +import { TriggerClient } from "@trigger.dev/sdk"; +import crypto from "crypto"; import { z } from "zod"; export const client = new TriggerClient({ @@ -24,9 +25,9 @@ const whatsApp = client.defineHttpTrigger({ }), }), }), - //todo, this is confusing because verifying refers to when data is sent and checking the headers - verify: { - requestFilter: { + //only needed for strange APIs like WhatsApp which don't setup the webhook until you pass the test + sendResponse: { + ifRequest: { method: ["GET"], }, onRequest: async (request, context) => { @@ -38,9 +39,19 @@ const whatsApp = client.defineHttpTrigger({ return new Response(searchParams.get("challenge") ?? "OK", { status: 200 }); }, }, -}); + verify: async (request, context) => { + //todo turn this into a function + const signature = Buffer.from(request.headers.get("X-Signature-SHA256") || "", "utf8"); + const hmac = crypto.createHmac("sha256", context.secret ?? ""); + const rawBody = await request.text(); + const digest = Buffer.from("sha256" + "=" + hmac.update(rawBody).digest("hex"), "utf8"); -//todo what about verifying the actual webhooks?!?! + const isAllowed = + signature.length === digest.length && crypto.timingSafeEqual(digest, signature); + + return isAllowed; + }, +}); client.defineJob({ id: "event-example-1",