@clerk/express
Version:
Clerk server SDK for usage with Express
1 lines • 3.03 kB
Source Map (JSON)
{"version":3,"sources":["../src/webhooks.ts"],"sourcesContent":["/* eslint-disable import/export */\nimport type { VerifyWebhookOptions } from '@clerk/backend/webhooks';\nimport { verifyWebhook as verifyWebhookBase } from '@clerk/backend/webhooks';\nimport type { Request as ExpressRequest } from 'express';\n\nimport { incomingMessageToRequest } from './utils';\n\n// Ordering of exports matter here since\n// we're overriding the base verifyWebhook\nexport * from '@clerk/backend/webhooks';\n\n/**\n * Verifies the authenticity of a webhook request using Svix.\n *\n * @param request - The incoming webhook Express Request object\n * @param options - Optional configuration object\n * @param options.signingSecret - Custom signing secret. If not provided, falls back to CLERK_WEBHOOK_SIGNING_SECRET env variable\n * @throws Will throw an error if the webhook signature verification fails\n * @returns A promise that resolves to the verified webhook event data\n *\n * @example\n * ```typescript\n * import { verifyWebhook } from '@clerk/express/webhooks';\n *\n * app.post('/api/webhooks', async (req, res) => {\n * try {\n * const evt = await verifyWebhook(req);\n * // handle event\n * res.send('Webhook received');\n * } catch (err) {\n * res.status(400).send('Webhook verification failed');\n * }\n * });\n * ```\n *\n * @see {@link https://clerk.com/docs/webhooks/sync-data} to learn more about syncing Clerk data to your application using webhooks\n */\nexport async function verifyWebhook(req: ExpressRequest, options?: VerifyWebhookOptions) {\n const webRequest = incomingMessageToRequest(req);\n // Cloning instead of implementing the body inside incomingMessageToRequest\n // to make it more predictable\n // we must pass in body as string not as an Object or Buffer\n let serializedBody: string;\n if (typeof req.body === 'string') {\n serializedBody = req.body;\n } else if (Buffer.isBuffer(req.body)) {\n serializedBody = req.body.toString('utf8');\n } else if (req.body === undefined || req.body === null) {\n serializedBody = '';\n } else {\n try {\n serializedBody = JSON.stringify(req.body);\n } catch (error) {\n throw new Error(`Failed to serialize request body: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n const clonedRequest = new Request(webRequest, {\n body: serializedBody,\n });\n return verifyWebhookBase(clonedRequest, options);\n}\n"],"mappings":";;;;;AAEA,SAAS,iBAAiB,yBAAyB;AAOnD,cAAc;AA4Bd,eAAsB,cAAc,KAAqB,SAAgC;AACvF,QAAM,aAAa,yBAAyB,GAAG;AAI/C,MAAI;AACJ,MAAI,OAAO,IAAI,SAAS,UAAU;AAChC,qBAAiB,IAAI;AAAA,EACvB,WAAW,OAAO,SAAS,IAAI,IAAI,GAAG;AACpC,qBAAiB,IAAI,KAAK,SAAS,MAAM;AAAA,EAC3C,WAAW,IAAI,SAAS,UAAa,IAAI,SAAS,MAAM;AACtD,qBAAiB;AAAA,EACnB,OAAO;AACL,QAAI;AACF,uBAAiB,KAAK,UAAU,IAAI,IAAI;AAAA,IAC1C,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,IACjH;AAAA,EACF;AACA,QAAM,gBAAgB,IAAI,QAAQ,YAAY;AAAA,IAC5C,MAAM;AAAA,EACR,CAAC;AACD,SAAO,kBAAkB,eAAe,OAAO;AACjD;","names":[]}