Search code examples
ruby-on-railsruby-on-rails-3ruby-on-rails-3.2devisemandrill

mandrill break reset password instruction with devise 2.2.3


All my emails in local works fine with my gmail account. However in production env, I'm using mandrill to deliver the email.

My problem is when a user want reset the password. This is my email config in production:

config.action_mailer.default_url_options = { :host => 'mydomain.com' }
 config.action_mailer.delivery_method = :smtp
 config.action_mailer.perform_deliveries = true
 config.action_mailer.raise_delivery_errors = false
 config.action_mailer.default :charset => "utf-8"
 config.action_mailer.asset_host = "mydomain.com"

  ActionMailer::Base.default :from => '[email protected]'
  config.action_mailer.smtp_settings = {
    :address   => "smtp.mandrillapp.com",
    :port      => 25,
    :user_name => Settings.email.username,
    :password  => Settings.email.password
  }

This is my mailer controller:

require 'digest/sha2'
class UserMailer < Devise::Mailer
default "Message-ID"=>"#{Digest::SHA2.hexdigest(Time.now.to_i.to_s)}@mydomain.com"
  def confirmation_instructions(record, opts={})
    set_locale(record)
    headers["template_path"] = "user_mailer"
    headers["template_name"] = "confirmation_instructions"
    headers({'X-No-Spam' => 'True', 'In-Reply-To' => '[email protected]'})
    super
  end

  def reset_password_instructions(record, opts={})
    set_locale(record)
    headers["template_path"] = "user_mailer"
    headers["template_name"] = "reset_password_instructions"
    headers({'X-No-Spam' => 'True', 'In-Reply-To' => '[email protected]'})
    super
  end

  def unlock_instructions(record, opts={})
    set_locale(record)
    headers["template_path"] = "user_mailer"
    headers["template_name"] = "unlock_instructions"
    headers({'X-No-Spam' => 'True', 'In-Reply-To' => '[email protected]'})
    super
  end
  private
  def set_locale(user)
    I18n.locale = user.locale || I18n.default_locale
  end
end

This is the link with the problem in production:

<%= link_to "Change password", edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %>

Mandrill generate a link something like:

http://mandrillapp.com/track/click.php?u=30029014&id=890aac6b235b4802883f75b484d5ac8f&url=http%3A%2F%2Fmydomain.com%2Fusers%2Fpassword%2Fedit&url_id=18754ce20fc88b338f0aa3993686e33be8ab84a1

However in development is working fine:

http://localhost:3000/users/password/edit?reset_password_token=yzYyyZuZArq7ksLZdgh3

When use click on link I can see the error:

You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided

How can I fix this error with mandrill?

Thanks!


Solution

  • I have fixed the problem with the next code:

    def reset_password_instructions(record, opts={})
      set_locale(record)
      headers["template_path"] = "user_mailer"
      headers["template_name"] = "reset_password_instructions"
      headers({'X-No-Spam' => 'True', 'In-Reply-To' => '[email protected]'})
      headers['X-MC-Track'] = "False, False"
      super
    end
    

    You must add headers['X-MC-Track'] = "False, False" to your action reset_password_instructions

    You can see the doc in the mandrill help from http://help.mandrill.com/entries/21688056-Using-SMTP-Headers-to-customize-your-messages#enable-open-and-click-tracking

    Thanks!