refactor(webhook): extract verifyHmac helper and createWebhookVerifier factory#1007
refactor(webhook): extract verifyHmac helper and createWebhookVerifier factory#1007
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
nhopeatall
left a comment
There was a problem hiding this comment.
Summary
Clean, well-executed deduplication refactor. The verifyHmac helper and createWebhookVerifier factory correctly consolidate ~76 lines of near-identical HMAC logic and ~110 lines of near-identical verifier-callback boilerplate into parameterized, reusable code. All public APIs maintain identical signatures and behavior. CI is green (all 7 checks pass).
Notes
Sentry behavioral change (benign): The old verifySentryWebhookSignature went directly from projectId (URL param) → resolveWebhookSecret() without calling loadProjectConfig(). The new factory always calls loadProjectConfig() and findProject() first. In practice this is equivalent — resolveWebhookSecret returns null for non-existent projects anyway, and loadProjectConfig() is cached — but it's a difference worth noting.
Sentry error message change (cosmetic): The old Sentry code returned 'Missing Sentry-Hook-Signature header' while the new factory returns 'Missing signature header'. Since this string is only used for logging/debugging, the normalization is fine.
Both changes are intentional consequences of the factory pattern and don't affect runtime behavior.
🕵️ claude-code · claude-opus-4-6 · run details
Summary
verifyHmac()generic helper insrc/webhook/signatureVerification.ts— replaces ~76 lines of near-identical HMAC verification code across 4 functions with a single timing-safe implementation parameterized by algorithm, encoding, and optional prefixcreateWebhookVerifier()factory insrc/router/webhookVerification.ts— replaces 4 near-identicalverify*WebhookSignatureasync callback functions with a single factory parameterized by header name, platform, extractor, project finder, and verify functionverifyGitHubSignature,verifyTrelloSignature,verifySentrySignature,verifyJiraSignatureand their router callbacks keep identical signatures and behaviorverifyHmac()edge-case tests added tosignatureVerification.test.ts; 9createWebhookVerifier()factory tests added towebhook-signature.test.tsKey decisions
VerifyHmacOptions.prefixis optional (defaults to'') — allows Sentry (no prefix) and Trello (no prefix, base64) to use the same helper without forcing an artificial empty-string prefix everywhereplatformtyped asWebhookPlatformliteral union — preserves the narrow type expected byresolveWebhookSecretwhile keeping the factory genericextractIdentifierreadsc.req.param('projectId')— the existing unique-URL approach is preserved; the factory'sfindProjectuses directp.id === projectIdmatching instead of body parsingextractTrelloBoardId,buildTrelloCallbackUrl,extractJiraProjectKeyremain exported as-is (used by tests and the verifier configs)Test plan
signatureVerification.test.tstests passwebhook-signature.test.tstests passverifyHmac()edge-case tests passcreateWebhookVerifier()factory tests passnpm run typecheck— zero errorsnpm run lint— zero errorsCard: https://trello.com/c/69c1829c1337276ace4155f5
🤖 Generated with Claude Code
🕵️ claude-code · claude-sonnet-4-6 · run details