How to override the Devise Passwords Controller? - ruby-on-rails

How to override the Devise Passwords Controller:
https://github.com/plataformatec/devise/blob/master/app/controllers/devise/passwords_controller.rb
I want to do the following:
downcase all emails submitted for password reset. All the emails in the DB as lowercase. If a user tried to reset a valid email with any characters uppercase, the reset fails to find a user. And devise doesn't even give a error message saying no user found
If no user is found in def create, I want to add a flash that says, no user found, did you enter the right email?
How can I accomplish the 2 items above? I believe that required overriding the devise password controller. How do I do that? Or if you have a better solution that's even cleaner, I would like to hear it.
Thanks

the devise initializer has a option to make any field case insensitive:
config.case_insensitive_keys = [ :email ]
If I remember correctly it was added in the newer version and if you don't see some related comments in you initializer then you should upgrade your devise gem using bundle upgrade devise. I am using version 1.3.3.
And this version also shows an error "Email not found" if an invalid email is entered.
If you not getting the error message add <%= devise_error_messages! %> to your view. You can customize the error messages by editing config/locales/devise.en.yml

Related

Rails a href in devise translation .yml

In my Rails 5 app I want to display custom error message if the user enters the password incorrectly for a custom strategy method. What I did is:
devise.en.yml
en:
devise:
failure:
custom_auth: "Email is already registered. \nPlease login <a href='https://www.some_page.com'>Some Page</a> or create an account with a different email address.
But it won't worked, the same as:
custom_auth: "Email is already registered. \nPlease login [Some Page](https://www.some_page.com/login) or create an account with a different email address.
Most likely you need to use html_safe, as in I18n.t("devise.failure.custom_auth").html_safe - otherwise the translation will be escaped, and the link will not work.

How to edit devise varification message and remove "email" text from it

We are using devise gem on ruby on rails for user account. If anyone click on our verification link 3 days later, we can see this message -
Email needs to be confirmed within 3 days, please request a new one
we are seeing like this cause on the config/locales/devise.en.yml there is -
confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
But I have changed the confirmation_period_expired variable like this -
confirmation_period_expired: " hello world"
but i can see the verification message like this -
Email hello world
Hope you understand the problem. by default "email" text is comming. I want to remove this.
I can see on the devise gem, this file is responsible for automatic adding "email" text.
Now just say me how can I remove the by default "email" text from the devise varification message?
To solve this problem on devise helper you will see a method resource.errors.full_messages
you have to rename it resource.errors.messages

Ruby on Rails - Devise welcome email to new users with reset password in Active Admin

Im using RoR 3.2.3 and Devise and Active Admin is working great.
However, there is something I am not getting.
In my app, users cannot register themselves, only an Admin can register other users.
This is all working, the Admin goes into the Active Admin panel->Users->New and fills the username and email and clicks "Create".
In order to give the customer the option of clreating his new password I'm using in mt AA user model:
after_create { |user| user.send_reset_password_instructions }
def password_required?
new_record? ? false : super
end
However, I don't want the email to send the text that devise uses, but rather a welcoming text and not something like "A link to change your password has been requested..." as there was no password to begin with.
In short, I want to use the send_reset_password_instructionsdevise method without using it's devise/mailer/reset_password_instructions view for when a new user is created.
However if the user forgets his password then he clicks the "Forgot Password" link and an email is to be sent with that default text already provided by Devise.
Any tips on how to make this work?
Thanks in advance,
Regards
Its very simple actually, set config.scoped_views = true in config/initializers/devise.rb
Then run
rails g devise:views users
this will generate all the views files devise uses, you can make changes to the
app/views/users/mailer/reset_password_instructions.html.erb file to what you need or any other file you wish to change.

Devise, validate current_password if any important fields have been changed

Specifically, I'm using Devise with Typus. But, I think my misunderstanding resides in my knowledge of Devise.
I'm trying to achieve the functionality of when you want to change an important model via form, you have to provide your current password to confirm you can change it, a la google.
Right now, I can log in and change any of the fields of my User model. Including the password, without having to confirm my password prior. Not good. So, I've added current_password to the form. But that didn't do anything. Then I tried to validate presence on current_password. Then it doesn't seem to accept any value for it.
Google didn't help me. All of the relevant posts were about removing current_password instead of confirming it. Which makes me think I'm misunderstanding the use of current_password.
Anyone care to share some insight? Thanks.
You should add the password field to the form, and then in your controller's action you can validate the password using:
user.valid_password?(params[:user][:password])
Note that probably you should change params[:user][:password] to the the name of the param for your password's field in the form (perhaps just params[:password]).
Hope it helps.
Actually, devise has a builtin method for this:
user.update_with_password(params, *options) you can read the rdoc here.
Update record attributes when :current_password matches, otherwise returns error on :current_password. It also automatically rejects :password and :password_confirmation if they are blank.

Is there a way in Rails to say "run all the validates EXCEPT :password"?

I am using Devise for my authentication. If a hashed_password isn't set, Rails/Devise's validations will require a password to be set, as well as the password_confirmation.
When I invite new users, I obviously don't want to set their password, so when I create the invitation in my system, it fails because user.password is blank.
I can set a temporary hashed_password on the user, but when they enter their own password, the validation checks for :password and :password_confirmation will not happen because hashed_password is set, which is a real problem.
Is there any way to tell Rails that I want to run all the validations except for the ones associated with :password?
I know Rails has :if conditions, which might fix my problem, but Devise declares the :password validation on my behalf, so that essentially is hidden.
How can I get the desired result here?, hopefully in a way that is not a hack.
My current hypothetical solution that is somewhat messy: The only thing I can think of is to create a new Invitation model that is not the User model, and use the Invitation model for the form. When the invitation is submitted I can validate that Invitation and copy over all the values to the new User model. I can save that User without any validations at all.
That's the best solution I dreamed up.
It seems like my solution will be a lot more work than saying something simple like:
user.save(validations => {:except => :password})
EDIT: I have found one part of the solution, but I am still having problems. In our user model, we can override a Devise method to prevent the validation of the password for invitations with this bit of code:
#protected
def password_required?
!is_invited && super
end
The is_invited attribute is just a column I added to the users table/model.
However, there is one gotcha here. When a user accepts an invitation and they arrive to the form where they need to set their password/password_confirmation, valid? will always return true.
This one has me deeply perplexed. I don't see how requires_password? and valid? can be true at the same time. If it requires the password, it should do a validation check and cause the validations to fail.
I'm starting to hate Devise - or just the idea of using gems to build parts of your application in a blackbox. I think the real solution probably is to rip out Devise and just do it all from scratch. That way your app has total control of how all of this works :(
I recently started using this great devise add-on: devise_invitable
It's commonly used so users (or any model) can invite other users to join.
But I adapt it for manually (via an admin panel) invite new potential users to my app.
Hope this helps!

Resources