Module: BellaBaxter::WebhookSignature
- Defined in:
- lib/bella_baxter/webhook_signature.rb
Overview
Verifies the X-Bella-Signature header on incoming Bella Baxter webhook requests.
Signature format: X-Bella-Signature: t=unix_epoch_seconds,v1=hmac_sha256_hex Signing input: “t.rawBodyJson” (UTF-8) HMAC key: the raw signing secret string (full whsec-xxx value, UTF-8 encoded)
Constant Summary collapse
- DEFAULT_TOLERANCE =
300
Class Method Summary collapse
-
.verify(secret:, signature_header:, raw_body:, tolerance: DEFAULT_TOLERANCE) ⇒ Boolean
Verifies the X-Bella-Signature header on an incoming webhook.
Class Method Details
.verify(secret:, signature_header:, raw_body:, tolerance: DEFAULT_TOLERANCE) ⇒ Boolean
Verifies the X-Bella-Signature header on an incoming webhook.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/bella_baxter/webhook_signature.rb', line 22 def self.verify(secret:, signature_header:, raw_body:, tolerance: DEFAULT_TOLERANCE) parts = signature_header.to_s.split(",") t_part = parts.find { |p| p.start_with?("t=") } v1_part = parts.find { |p| p.start_with?("v1=") } raise BellaBaxter::WebhookSignatureError, "Malformed X-Bella-Signature header: missing t= or v1=" \ if t_part.nil? || v1_part.nil? begin = Integer(t_part[2..], 10) rescue ArgumentError raise BellaBaxter::WebhookSignatureError, "Malformed X-Bella-Signature header: t= is not a valid integer" end v1 = v1_part[3..] age = Time.now.utc.to_i - raise BellaBaxter::WebhookSignatureError, "Webhook timestamp is stale or in the future (age=#{age}s, tolerance=#{tolerance}s)" \ if age.abs > tolerance signing_input = "#{}.#{raw_body}" expected = OpenSSL::HMAC.hexdigest("SHA256", secret, signing_input) secure_compare(expected, v1) end |