* Validate Slack request signature using HMAC-SHA256. * Basestring format: `v0:{timestamp}:{rawBody}` * Signature header format: `v0={hex}`
( signingSecret: string, signature: string, timestamp: string, rawBody: string )
| 410 | * Signature header format: `v0={hex}` |
| 411 | */ |
| 412 | function validateSlackSignature( |
| 413 | signingSecret: string, |
| 414 | signature: string, |
| 415 | timestamp: string, |
| 416 | rawBody: string |
| 417 | ): boolean { |
| 418 | try { |
| 419 | if (!signingSecret || !signature || !rawBody) { |
| 420 | return false |
| 421 | } |
| 422 | |
| 423 | if (!signature.startsWith('v0=')) { |
| 424 | logger.warn('Slack signature has invalid format (missing v0= prefix)') |
| 425 | return false |
| 426 | } |
| 427 | |
| 428 | const providedSignature = signature.substring(3) |
| 429 | const basestring = `v0:${timestamp}:${rawBody}` |
| 430 | const computedHash = hmacSha256Hex(basestring, signingSecret) |
| 431 | |
| 432 | return safeCompare(computedHash, providedSignature) |
| 433 | } catch (error) { |
| 434 | logger.error('Error validating Slack signature:', error) |
| 435 | return false |
| 436 | } |
| 437 | } |
| 438 | |
| 439 | /** |
| 440 | * Handle Slack verification challenges |
no test coverage detected