class Svix::Webhook
Constants
- SECRET_PREFIX
- TOLERANCE
Public Class Methods
new(secret)
click to toggle source
# File src/svix/webhook.rb, line 6 def initialize(secret) if secret.start_with?(SECRET_PREFIX) secret = secret[SECRET_PREFIX.length..-1] end @secret = Base64.decode64(secret) end
Public Instance Methods
sign(msgId, timestamp, payload)
click to toggle source
# File src/svix/webhook.rb, line 44 def sign(msgId, timestamp, payload) begin now = Integer(timestamp) rescue raise WebhookSigningError, "Invalid timestamp" end toSign = "#{msgId}.#{timestamp}.#{payload}" signature = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha256"), @secret, toSign)).strip return "v1,#{signature}" end
verify(payload, headers)
click to toggle source
# File src/svix/webhook.rb, line 14 def verify(payload, headers) msgId = headers["svix-id"] msgSignature = headers["svix-signature"] msgTimestamp = headers["svix-timestamp"] if !msgSignature || !msgId || !msgTimestamp msgId = headers["webhook-id"] msgSignature = headers["webhook-signature"] msgTimestamp = headers["webhook-timestamp"] if !msgSignature || !msgId || !msgTimestamp raise WebhookVerificationError, "Missing required headers" end end verify_timestamp(msgTimestamp) _, signature = sign(msgId, msgTimestamp, payload).split(",", 2) passedSignatures = msgSignature.split(" ") passedSignatures.each do |versionedSignature| version, expectedSignature = versionedSignature.split(",", 2) if version != "v1" next end if Svix.secure_compare(signature, expectedSignature) return JSON.parse(payload, symbolize_names: true) end end raise WebhookVerificationError, "No matching signature found" end
Private Instance Methods
verify_timestamp(timestampHeader)
click to toggle source
# File src/svix/webhook.rb, line 59 def verify_timestamp(timestampHeader) begin now = Integer(Time.now) timestamp = Integer(timestampHeader) rescue raise WebhookVerificationError, "Invalid Signature Headers" end if timestamp < (now - TOLERANCE) raise WebhookVerificationError, "Message timestamp too old" end if timestamp > (now + TOLERANCE) raise WebhookVerificationError, "Message timestamp too new" end end