I have the following code that allows a user to request a password reset in an AJAX form:
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post },:remote =>'true') do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.submit "Send me reset password instructions" %></div>
<% end %>
This is allowing the behavior whereby if the user clicks the button repeatedly, or presses "enter" repeatedly, before the server can provide a response, a corresponding # of password reset emails are being sent.
The following is within devise/password_controller.rb
def create
self.resource = resource_class.send_reset_password_instructions(resource_params)
if successfully_sent?(resource)
flash[:notice] = "You will receive an email with instructions about how to reset your password in a few minutes."
respond_to do |format|
format.html #responds with default html file
format.js
end
else
respond_to do |format|
format.html #responds with default html file
format.js{ render :js => "$(\".deviseErrors\").html(\"<span class='login-error'>Could not send reset instructions to that address.</span>\");" } #this will be the javascript file we respond with
end
end
end
Is there a way to only respond to the first submission?
Thanks
I would recommend to use JavaScript to prevent multiple submissions.
$('form#reset_password').on('submit', function() {
$(this).find('input[type="submit"]').attr('disabled', 'disabled')
})
This will set the submit button as "disabled" status and user can't submit again.
Reference about form's disabled attribute: http://www.w3schools.com/tags/att_input_disabled.asp*
Add: Response to thr's answer
I browsed Devise source and found there should be a solution at model level. To set the max interval allowed between each resetting request, add such in resource model
class User < ActiveRecord::Base
def self.reset_password_with
1.day
# Determine the interval. Any time objects will do, say 1.hour
end
end
Then Devise::Models::Recoverable will check this value to decide if a token should be sent. I have not verified this but it should work.