app/controllers/ahoy/messages_controller.rb in ahoy_email-0.5.2 vs app/controllers/ahoy/messages_controller.rb in ahoy_email-1.0.0
- old
+ new
@@ -1,32 +1,46 @@
module Ahoy
- class MessagesController < ActionController::Base
- if respond_to? :before_action
- before_action :set_message
+ class MessagesController < ApplicationController
+ filters = _process_action_callbacks.map(&:filter) - AhoyEmail.preserve_callbacks
+ if Rails::VERSION::MAJOR >= 5
+ skip_before_action(*filters, raise: false)
+ skip_after_action(*filters, raise: false)
+ skip_around_action(*filters, raise: false)
else
- before_filter :set_message
+ skip_action_callback *filters
end
+ before_action :set_message
+
def open
if @message && !@message.opened_at
@message.opened_at = Time.now
@message.save!
end
+
publish :open
+
send_data Base64.decode64("R0lGODlhAQABAPAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="), type: "image/gif", disposition: "inline"
end
def click
if @message && !@message.clicked_at
@message.clicked_at = Time.now
@message.opened_at ||= @message.clicked_at
@message.save!
end
+
+ user_signature = params[:signature].to_s
url = params[:url].to_s
- signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), AhoyEmail.secret_token, url)
- publish :click, url: params[:url]
- if secure_compare(params[:signature].to_s, signature)
+
+ # TODO sign more than just url and transition to HMAC-SHA256
+ digest = "SHA1"
+ signature = OpenSSL::HMAC.hexdigest(digest, AhoyEmail.secret_token, url)
+
+ if ActiveSupport::SecurityUtils.secure_compare(user_signature, signature)
+ publish :click, url: params[:url]
+
redirect_to url
else
redirect_to AhoyEmail.invalid_redirect_url || main_app.root_url
end
end
@@ -43,20 +57,8 @@
event[:message] = @message
event[:controller] = self
subscriber.send name, event
end
end
- end
-
- # from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/message_verifier.rb
- # constant-time comparison algorithm to prevent timing attacks
- def 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