Sha256: c2741a056acde4cbdb459ffef6cef52ffd73008c235530ece325c6fd35fc4b7d

Contents?: true

Size: 1.08 KB

Versions: 1

Compression:

Stored size: 1.08 KB

Contents

# frozen_string_literal: true

require 'json'
require 'openssl'

module ModerationApi
  class Webhook
    class SignatureVerificationError < StandardError; end

    # This method attempts to verify the webhook signature from Moderation API.
    #   payload: The raw request body
    #   sig_header: The 'HTTP_MODAPI_SIGNATURE' header from the request
    #   secret: Your webhook signing secret
    #
    def self.construct_event(payload, sig_header, secret)
      # Verify the signature
      digest = OpenSSL::Digest.new('sha256')
      signed = OpenSSL::HMAC.hexdigest(digest, secret, payload)

      if secure_compare(signed, sig_header)
        JSON.parse(payload, symbolize_names: true)
      else
        raise SignatureVerificationError, 'Signature verification failed'
      end
    end

    private

    # Compares the signature in a way that mitigates timing attacks
    #
    def self.secure_compare(a, b)
      return false unless a.bytesize == b.bytesize

      l = a.unpack "C#{a.bytesize}"

      res = 0
      b.each_byte { |byte| res |= byte ^ l.shift }
      res == 0
    end
  end
end 

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
moderation_api-1.2.2 lib/moderation_api/webhook.rb