Class: Wajub::Webhooks
- Inherits:
-
Object
- Object
- Wajub::Webhooks
- Defined in:
- lib/wajub/webhooks.rb
Constant Summary collapse
- DEFAULT_TOLERANCE =
300
Instance Attribute Summary collapse
-
#secret ⇒ Object
readonly
Returns the value of attribute secret.
Instance Method Summary collapse
- #construct_event(payload, signature, timestamp, tolerance = DEFAULT_TOLERANCE) ⇒ Object
-
#initialize(secret) ⇒ Webhooks
constructor
A new instance of Webhooks.
Constructor Details
#initialize(secret) ⇒ Webhooks
Returns a new instance of Webhooks.
14 15 16 |
# File 'lib/wajub/webhooks.rb', line 14 def initialize(secret) @secret = secret.to_s end |
Instance Attribute Details
#secret ⇒ Object (readonly)
Returns the value of attribute secret.
12 13 14 |
# File 'lib/wajub/webhooks.rb', line 12 def secret @secret end |
Instance Method Details
#construct_event(payload, signature, timestamp, tolerance = DEFAULT_TOLERANCE) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/wajub/webhooks.rb', line 18 def construct_event(payload, signature, , tolerance = DEFAULT_TOLERANCE) raise ArgumentError, 'Wajub: webhook_secret is required for construct_event' if @secret.empty? raise WebhookSignatureVerificationError, 'Invalid webhook signature format. Expected v1={hash}.' unless signature.start_with?('v1=') raise ArgumentError, 'Wajub: payload must be the raw request body as a String, not a parsed object' unless payload.is_a?(String) body = payload expected = Crypto.hmac_sha256(@secret, "#{}.#{body}") received = signature.delete_prefix('v1=') raise WebhookSignatureVerificationError, 'Webhook signature verification failed.' unless Crypto.timing_safe_equal(expected, received) ts = Float() raise WebhookSignatureVerificationError, 'Invalid webhook timestamp.' unless ts.finite? drift = (Time.now.to_i - ts).abs if tolerance.positive? && drift > tolerance raise WebhookSignatureVerificationError, "Timestamp outside tolerance zone (#{drift.to_i}s drift, allowed #{tolerance}s)." end event = JSON.parse(body) raise WebhookSignatureVerificationError, 'Invalid webhook payload JSON.' unless event.is_a?(Hash) event end |