3
votes

I am using Devise with my Rails 3 application. The current behavior for resetting a password, is to click on the "Forgot your password?" link. The link here is:

(url)/password/new.user

Which will call the following method in the Devise passwords_controller.rb:

def new
    build_resource({})
end

This method will do:

  1. generates the password reset token and adds it to the database,

  2. sends an email to the person with a link that includes the token:

    (url)/password/edit?reset_password_token=xxxxxxxxxxxxxxx

Is there any way to convince Devise to perform step 1 ONLY and not step 2? Are there any security issues I should be aware of if this is possible, and I did take this approach in an effort to simplify a portion of the web site.

3
Is your question whether you can stop devise from sending the link in code, or as a result of some malformed request from a client? - Chris Cashwell
You could pull the gem into your vendor/cache and modify the code there. This would allow you to change how devise handles the build_resource method. - kobaltz
To Kobaltz: Yes, I can pull the gem in and modify it, but that's not what I'm after. - EastsideDev
To Chris Cashwell: Neither. I want it NOT to send the email. Please read the question. - EastsideDev

3 Answers

6
votes

I would recommend overriding send_devise_notification on your User (?) model and return true when the notification value is :reset_password_instructions. Something like this:

# app/models/user.rb
def send_devise_notification(notification)
    return true if notification == :reset_password_instructions
end

Check their example on how to override/customize behavior for sending emails https://github.com/plataformatec/devise/blob/master/lib/devise/models/authenticatable.rb#L127

2
votes

You can disable it at instance level:

# disable all notifications
user.define_singleton_method(:send_devise_notification) { |*_| true }

# disable the one you want
user.define_singleton_method(:send_devise_notification) do |*args|
  return true if args[0] == :reset_password_instructions
  super
end
0
votes

The title of the question is general, but the question itself is more specific. This is the answer to the general question as of 2021.

To prevent a password changed email notification from being sent when changing a user password, call skip_password_change_notification! on the user before saving the user.

user = User.find(123)
user.skip_password_change_notification!
user.password = 'DoNotUse$123'
user.save