1

Users on my page can sign up with their phone numbers. If they forget the password, it should be resent via SMS.

My goal is to have on my registrations/new.html.haml page a link, which will trigger some custom controller (which sends a SMS with a password).

I thought of replacing Devise's passwords_controller.rb edit action, but it seems not to be triggered:

class Front::Users::PasswordsController < Devise::PasswordsController
  # GET /resource/password/new
  def new
    p "hello"
    super

  end
end

-> "Hello" never appears in the logs.

After that I created a custom controller "profile_controller.rb" with route as following: get 'reset_password', to: 'front/profile#change_password'

Now, my sessions/new looks like this:

=form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
    .section.section-inset-1
        .container
            .row
                .col-xs-12.col-md-8.col-md-offset-2
                    %section
                        %h4 Sign in
                        .rd-mailform.row.flow-offset-6
                            .col-xs-12.col-sm-6
                                =f.text_field :phone, placeholder: "Phone number", data: { constraints: "@NotEmpty" }, autofocus: true, id: "standard_order_phone"
                            .col-xs-12.col-sm-6
                                =f.password_field :password, placeholder: "Password", data: { constraints: "@Password" }, class: "form-input", autocomplete: "off" 

                            .col-xs-12.col-sm-6.text-left
                                %label.mfCheckbox
                                    =f.check_box :remember_me, class: 'mfCheckbox__input'
                                    %span Remember me
                            .col-xs-12.col-sm-6.text-right
                                %label.mfCheckbox#send_password
                                    =link_to 'Send password via SMS', reset_password_path(phone: params["user[phone]"]), method: :get
                    %section.section-inset-3
                        .row.offset-5
                            .col-xs-12
                                =f.submit 'Sign in', class: 'btn btn-sm btn-min-width btn-success'
        %section.section-inset-3
            .row.ud_mt_4em
                %h6 Not signed up yet?
            .row.offset-5
                =link_to 'Sign up', new_user_registration_path, method: :get, class: 'btn btn-sm btn-min-width btn-success-mod-1'

So, basically what I need right now is to somehow pass the :phone param from this form to link_to helper. I tried all results from googling "rails pass params to link_to", but when calling my profile_controller

class Front::ProfileController < FrontController

    def change_password
        logger.debug "This is Patrick with params: #{params}"
    end
end

Params do not contain the phone number. How can I achieve passing the params or elsewise the desired functionality?

mohnstrudel
  • 639
  • 8
  • 22

2 Answers2

0

Do you need something like this?

link_to 'Send me the pass', send_pass_path(@user, param: 'foo')

Also, Devise use BCrypt to encrypt the password. BCrypt is a hashing function and because that, you can't get the real password. You can regenerate a new one and send that new password via SMS if you need, but you can't send the old real pass.

Andrés
  • 624
  • 7
  • 12
  • Yes, I need something like this, but how do I extract `f.text_field :phone` - value from the form? – mohnstrudel Nov 27 '16 at 08:58
  • The model has the field `:phone`? If yes, that should work, if not, you should use `text_field_tag 'phone', @phone_value` – Andrés Nov 27 '16 at 10:17
  • I changed my link_to to `=link_to 'Send password via SMS', reset_password_path(@user, phone: params[:phone]), method: :get` But still don't receive the parameter in my parameters hash `params => "get", "authenticity_token"=>"ze8PgJinJuiIsROfAHca+fU+Owp0IKtXBkJw0R1ik6f+S0E2zB4aOvj5jdq8CGkwib8IlN8RascVIFZdIdJqFw==", "controller"=>"front/profile", "action"=>"change_password"} permitted: false>` – mohnstrudel Nov 27 '16 at 10:26
  • How it's the link that is generating? I means the html that `link_to` is creating. – Andrés Nov 27 '16 at 10:31
  • try `reset_password_path(user_id: @user.id, phone: params[:phone])` (or `id`, I don't know how it's in your. The first param of `link_to` it's the data, the second are options. Then, all params to the path are @user only, the second (`phone`) is a link_to options (unknown option) – Andrés Nov 27 '16 at 11:27
  • that doesn't work either, unfortunately, params still empty – mohnstrudel Nov 29 '16 at 17:52
0

Search for a solution led me to this SO question and this is how I solved the issue in the end.

My final form code:

=form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
    .section.section-inset-1
        .container
            .row
                .col-xs-12.col-md-8.col-md-offset-2
                    %section
                        %h4 Sign in
                        .rd-mailform.row.flow-offset-6
                            .col-xs-12.col-sm-6
                                =f.text_field :phone, placeholder: "Phone number", data: { constraints: "@NotEmpty" }, autofocus: true, id: "standard_order_phone"
                            .col-xs-12.col-sm-6
                                =f.password_field :password, placeholder: "Password", data: { constraints: "@Password" }, class: "form-input", autocomplete: "off" 

                            .col-xs-12.col-sm-6.text-left
                                %label.mfCheckbox
                                    =f.check_box :remember_me, class: 'mfCheckbox__input'
                                    %span Remember me
                            .col-xs-12.col-sm-6.text-right
                                #send_password
                                    =submit_tag 'Send password per SMS', class: "reset_password", id: 'reset_btn', name: 'reset', remote: true
                    %section.section-inset-3
                        .row.offset-5
                            .col-xs-12
                                =f.submit 'Sign in', class: 'btn btn-sm btn-min-width btn-success'
        %section.section-inset-3
            .row.ud_mt_4em
                %h6 No account yet?
            .row.offset-5
                =link_to 'Create one!', new_user_registration_path, method: :get, class: 'btn btn-sm btn-min-width btn-success-mod-1'

I then extend devise sessions controller:

class Front::Users::SessionsController < Devise::SessionsController


# before_action :configure_sign_in_params, only: [:create]

  # GET /resource/sign_in
  def new
    if params[:reset]
      phone = params[:user][:phone]
      # logger.debug("Phone is: #{phone}")
      new_password = Array.new
      5.times do
        new_password << rand(9)  
      end
      password = new_password.join("")
      User.where(phone: phone).update(password: password)

      stripped_phone = phone.gsub(/\s+/, "").gsub(/[()]/, "").gsub(/-/, "")
      encoded_phone = URI.escape(stripped_phone)
      encoded_message = URI.escape("Your new password - #{password}.")
      # logger.debug("New password for user #{phone} - #{password}")
      # Some code for sending SMS
      # doc = Nokogiri::HTML(open(url))
      flash[:success] = "New password sent per SMS."
      redirect_to new_user_session_path
    else
      super
    end
  end
end
Community
  • 1
  • 1
mohnstrudel
  • 639
  • 8
  • 22