Solution
Thanks to this gist form Steven Harman, I got it working. devise_mail_helpers.rb
module Features
module MailHelpers
As others have noted: the reason is that the view which generates the mail which includes the reset password link needs to be changed.
I saw this error because I was still using the devise-i18n-views
gem, which generates the old link. Removing that gem and relying on the views which are now a part of the devise-i18n
gem solved the problem for me.
In your devise reset password template make sure following content should correct:
=link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token)
You commented on my similar question a bit ago, and I found an answer that might help you as well.
Upgrading to Devise 3.1.0 left some 'cruft' in a view that I hadn't touched in a while. According to this blog post, you need to change your Devise mailer to use @token
instead of the old @resource.confirmation_token
.
Find this in app/views/<user>/mailer/reset_password_instructions.html.erb
and change it to something like:
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password, and you can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
This should fix any token-based confirmation problems you're having. This is likely to fix any unlock or confirmation token problems as well.
I had this error on specs. I was trying to manually set reset_password_token
on User so I could just pass in the token to the edit_user_password_path
. However, the reset tokens are hashed, so setting it manually won't work. Oops! To avoid this error, I set reset_token
equal to the actual token generated which is returned by user.send_reset_password_instructions
.
Working spec:
require 'spec_helper'
feature 'User resets password' do
scenario 'fills out reset form' do
user = create(:user)
reset_token = user.send_reset_password_instructions
new_password = 'newpassword!'
visit edit_user_password_path(user, reset_password_token: reset_token)
fill_in :user_password, with: new_password
fill_in :user_password_confirmation, with: new_password
click_button 'Change my password'
expect(page).to have_content(
'Your password was changed successfully. You are now signed in.'
)
end
end
FYI, if you're trying to send a reset password token via another means (i.e. different mailer), you can use code like this (dug out of Devise source), in your User class:
def send_invitation
raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)
self.reset_password_token = enc
self.reset_password_sent_at = Time.now.utc
self.save(:validate => false)
Notifier.signup_notification(contactable: self, token: raw).deliver
end
I guess you've upgraded Devise to v3.1 not v3.01, because of config.secret_key
. So I think it is somehow related to new devise feature - secret key.
I found two commits for secret key feature that can be helpful to better understanding:
https://github.com/plataformatec/devise/commit/32648027e282eb4c0f4f42e9c9cc0c961765faa8
https://github.com/plataformatec/devise/commit/d56641f514f54da04f778b2a9b816561df7910c2
Probably you will find something useful for you on http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ as well.
Also you can grep reset_password_token on https://github.com/plataformatec/devise/compare/v3.0...v3.1.0.
EDIT
Read on http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/: