({
request,
rawBody,
requestId,
providerConfig,
}: AuthContext)
| 54 | |
| 55 | export const clerkHandler: WebhookProviderHandler = { |
| 56 | async verifyAuth({ |
| 57 | request, |
| 58 | rawBody, |
| 59 | requestId, |
| 60 | providerConfig, |
| 61 | }: AuthContext): Promise<NextResponse | null> { |
| 62 | const signingSecret = providerConfig.signingSecret as string | undefined |
| 63 | if (!signingSecret?.trim()) { |
| 64 | logger.warn(`[${requestId}] Clerk webhook missing signing secret in provider configuration`) |
| 65 | return new NextResponse('Unauthorized - Clerk signing secret is required', { status: 401 }) |
| 66 | } |
| 67 | |
| 68 | const svixId = request.headers.get('svix-id') |
| 69 | const svixTimestamp = request.headers.get('svix-timestamp') |
| 70 | const svixSignature = request.headers.get('svix-signature') |
| 71 | |
| 72 | if (!svixId || !svixTimestamp || !svixSignature) { |
| 73 | logger.warn(`[${requestId}] Clerk webhook missing Svix signature headers`) |
| 74 | return new NextResponse('Unauthorized - Missing Clerk signature headers', { status: 401 }) |
| 75 | } |
| 76 | |
| 77 | if (!verifySvixSignature(signingSecret, svixId, svixTimestamp, svixSignature, rawBody)) { |
| 78 | logger.warn(`[${requestId}] Clerk Svix signature verification failed`) |
| 79 | return new NextResponse('Unauthorized - Invalid Clerk signature', { status: 401 }) |
| 80 | } |
| 81 | |
| 82 | return null |
| 83 | }, |
| 84 | |
| 85 | async matchEvent({ body, providerConfig, requestId }: EventMatchContext): Promise<boolean> { |
| 86 | const triggerId = providerConfig.triggerId as string | undefined |
nothing calls this directly
no test coverage detected