4
votes

I'm attempting to display a users password along in his confirmation page sent by the Devise mailer. The confirmation page is the default

Welcome [email protected]!

You can confirm your account email through the link below:

Confirm my account

However, I wish to have

Welcome [email protected]!

Your password is currently DASADSADS

You can confirm your account email through the link below:

Confirm my account

How do I access the user object in the view? Do I need to override the mailer controller with a custom one? If so, how do I tell what the methods of the current mailer do (tried looking at documentation but can't find any clues)?

I noticed that @email and @resource are used in the view. Can I use any of these to access the current password in its unhashed form?

Note that I am sending this email manually with user.find(1).send_confirmation_instructions

3

3 Answers

6
votes

Although this can be done, I would caution very strongly against doing so. Hashed passwords are specifically used so that the password cannot be recreated easily. Passing the original password back to the user will cause it to be sent back in plain text which sort of defeats the whole purpose. Also, shouldn't the user already know their password (they did type it in twice after all)?!?

To do this, you would need to capture the original (unhashed) password in the registration create action and send the email at that point (passing along the password). You can do this by overriding the sign_up method - you can do this in an initializer:

class Devise::RegistrationsController < DeviseController
  def sign_up(resource_name, resource)
    sign_in(resource_name, resource)
    resource.unhashed_password = resource_params[:password]
    resource.send_confirmation_instructions
  end
end

Alternatively, you can derive a new controller from Devise::RegistrationsController and put this override code there (the recommended approach - but then again, this whole operation isn't really recommended). You'll need to add the unhashed_password accessor for this to work:

class User < ActiveRecord::Base
  attr_accessor :unhashed_password
end

And then you can update your confirmation view (at app/views/devise/mailer/confirmation_instructions.html.erb) to contain this:

<p>Your password is currently <%= @resource.unhashed_password %></p>
1
votes

Devise save password in encrypted form: You can decrypt it using,

Generate new migration:

$ rails g migration AddLegacyPasswordToUser legacy_password:boolean
      invoke  active_record
      create    db/migrate/20120508083355_add_legacy_password_to_users.rb
$ rake db:migrate

Using legacy_password method in following code you can decrypt your password:

class User < ActiveRecord::Base

...

  def valid_password?(password)
    if self.legacy_password?
      # Use Devise's secure_compare to avoid timing attacks
      if Devise.secure_compare(self.encrypted_password, User.legacy_password(password))

        self.password = password
        self.password_confirmation = password
        self.legacy_password = false
        self.save!

      else
        return false
      end
    end

    super(password)
  end

  # Put your legacy password hashing method here
  def self.legacy_password(password)
    return Digest::MD5.hexdigest("#{password}-salty-herring");
  end
end
0
votes

You can just use request.request_parameters[:user][:password] to get the plain text password on the create or update action.