lib/ahoy_email/utils.rb in ahoy_email-2.2.0 vs lib/ahoy_email/utils.rb in ahoy_email-2.3.0

- old
+ new

@@ -5,17 +5,32 @@ utm_params: %i(utm_source utm_medium utm_term utm_content utm_campaign), click: %i(campaign url_options unsubscribe_links) } class << self - def signature(token:, campaign:, url:) + def signature(token:, campaign:, url:, secret_token: nil) + secret_token ||= secret_tokens.first + # encode and join with a character outside encoding data = [token, campaign, url].map { |v| Base64.strict_encode64(v.to_s) }.join("|") Base64.urlsafe_encode64(OpenSSL::HMAC.digest("SHA256", secret_token, data), padding: false) end + def signature_verified?(legacy:, token:, campaign:, url:, signature:) + secret_tokens.any? do |secret_token| + expected_signature = + if legacy + OpenSSL::HMAC.hexdigest("SHA1", secret_token, url) + else + signature(token: token, campaign: campaign, url: url, secret_token: secret_token) + end + + ActiveSupport::SecurityUtils.secure_compare(signature, expected_signature) + end + end + def publish(name, event) method_name = "track_#{name}" AhoyEmail.subscribers.each do |subscriber| subscriber = subscriber.new if subscriber.is_a?(Class) if subscriber.respond_to?(method_name) @@ -25,11 +40,11 @@ subscriber.send(:click, event.dup) end end end - def secret_token - AhoyEmail.secret_token || (raise "Secret token is empty") + def secret_tokens + Array(AhoyEmail.secret_token || (raise "Secret token is empty")) end end end end