Reputation: 22731
If a user requests 2 password reset links in a row, then only the most recent one is valid.
If a user clicks on the older one, they are not immediately informed of the token being invalid. They are asked to type in the new password twice. Only upon hitting submit are they informed that the token is not valid.
Is there a standard way to change this behavior, so the user is immediately informed that they used the wrong link?
Upvotes: 0
Views: 1565
Reputation: 305
There is another safety solution for this question;
class User::PasswordsController < Devise::PasswordsController
def update
super do |resource|
# Jump to super code
next unless resource.errors.any?
token_errors = resource.errors.details[:reset_password_token]
expired_error = token_errors.select { |detail| detail[:error] == :expired }
# Jump to super code
next unless expired_error.present?
message = resource.errors.full_messages_for(:reset_password_token).join(',')
return redirect_to new_user_password_path, alert: message
end
end
end
Upvotes: 0
Reputation: 11904
I was a bit surprised to find out that this is standard behavior - thanks for bringing it up! I would probably use a custom controller that inherits from Devise::PasswordsController
and simply override :edit
. The trouble is we're working with an abstract user (since no user is actually authenticated at this point), so we can't check it against a particular token in the database, and we have to check whether the given token exists.
class PasswordsController < Devise::PasswordsController
before_filter :validate_reset_password_token, only: :edit
private
def validate_reset_password_token
recoverable = resource_class.find_by_reset_password_token(params[:reset_password_token])
redirect_to root_path unless (recoverable && recoverable.reset_password_period_valid?)
end
end
This will redirect unless a user exists with the token passed. You can handle the redirection/error display however you wish.
Finally, in your routes file, change the controller used by devise for passwords:
devise_for :users, :controllers => { passwords: "passwords" }
Caveats:
reset_password_by_token
)By the way, there is no way to tell them that they used the wrong link and they should click the other one, as there is no way to positively identify them in the first place, and therefore no way to know that they have already generated another valid token.
Upvotes: 4