Customize the validation when user sign in in devise - ruby-on-rails

I have a website that uses Devise for authentication.
While sign in if email and password both are empty it is giving me error
Invalid email or password.
but I want to show different error messages for users for different cases:
For instance,
if email field is empty and the password is present then show
Email can't be blank.
else if password field is empty and email is present than show
Password can't be blank.
else password and email are unauthenticated than show
invalid email or password
which currently working.
I don't want to remove :validatable from my model.
I tired validates :email, :presence => true, :email => true
from here
but when I sign up it shows 2 errors of
Email can't be blank.
one error of Devise and the other for the model.
please tell me how to do this validation only for user sign-in.

Try this in your devise session controller's create action.
def create
user = User.find_by(email: params[:user][:email])
if user
if user.valid_password?(params[:user][:password])
sign_in_and_redirect user
else
flash[:error] = "Please enter the valid password."
end
end
end

Please prefer this
Link
If the user is signing in, you can edit all the error messages in devise.en.yml under config/locales.

Related

Displaying failure messages using Devise gem in Rails

Hello I have a problem with displaying Devise failure messages. No matter what I do, I always get the "invalid" message even though the account is locked. My goal is to display the "locked" message for 10 minutes after 5 failed attempts.
The gem is configured properly because accounts are being locked correctly. The only problem I have is with the messages.
This is my code from the devise.rb file, which is related to the lockable module:
config.paranoid = false
config.lock_strategy = :failed_attempts
config.unlock_keys = [:time]
config.unlock_strategy = :time
config.maximum_attempts = 5
config.unlock_in = 10.minutes
config.last_attempt_warning = true
I found other topics on stackoverflow (e.g. Some devise messages are not shown, Devise: lockable - last_attempt_warning not displaying), where people say it's because of the paranoid mode, that's why I disabled it, but it still doesn't solve my issue. Devise does not seem to display any other message than "invalid" no matter what I put in the Devise config file (last_attempt_warning isn't showing up as well).
This is part of devise.en.yml related to failures:
en:
devise:
failure:
already_authenticated: "You are already logged in."
deactivated: "Your account is no longer active. Please contact your administrator for access."
inactive: "Your account is not activated yet."
invalid: "Sorry, the email or password you entered is incorrect."
last_attempt: "You have one more attempt before your account will be locked."
locked: "Your account has been locked. Try to log in again in 5 minutes."
not_found_in_database: "Sorry, the email or password you entered is incorrect."
timeout: "Your session expired. Please log in again to continue."
unauthenticated: "You need to log in or sign up before continuing."
unconfirmed: "You have to confirm your account before continuing."
I tried to workaround it by creating a method in Sessions Controller:
before_action :check_failed_attempts, only: :create
def check_failed_attempts
flash.clear
email = params["educator"]["email"]
return unless email
user = Person.find_by(email: email)
return unless user
if user.access_locked?
flash[:alert] = I18n.t "devise.failure.locked"
end
end
but devise seems to override the flash[:alert] and displays the invalid message anyway.
I spent a few hours trying to fix it and run out of ideas already, so I appreciate any help.
You are not halting the request cycle in your before_action, so the request is proceeding to call the create action which is overriding the flash[:alert]. From the documentation:
If a "before" filter renders or redirects, the action will not run. If
there are additional filters scheduled to run after that filter, they
are also cancelled.
def check_failed_attempts
flash.clear
email = params["educator"]["email"]
return unless email
user = Person.find_by(email: email)
return unless user
if user.access_locked?
flash[:alert] = I18n.t "devise.failure.locked"
redirect_to new_educator_session_path
end
end

How to implement "forgot password" using Warden?

In the process of switching from Devise to directly using Warden.
How can I go about implementing a "forgot password" functionality that comes out of the box with Devise?
Is there a gem that can add this onto Warden?
PS. The reason for not using Devise is because of some customization needed that makes hacking Devise to make it work not worthwhile.
I don't know if there is a gem, but doing it yourself doesn't take to long. Assuming that each account has an email attached to it. Have a forgot password button that links to a page where the user will input there username or whatever information that is unique to the user and once the user submits the form. Send a new password to there email.
Step-by-step:
Create a forgot password button on your login page to link to a new forgot password page.
Make the route, controller actions for the this new forgot password page.
Make a form on the forgot password page that takes in a unique piece of information about the user. ex. username. This form will be a post request to a action in your controller that will email a new password to the user who has this username for example.
This is what one of mine looked like:
def emailor
#user = User.find_by username: params[:user][:username]
random_password = Array.new(10).map { (65 + rand(58)).chr }.join
#user.password = random_password
if #user.save
UserMailer.reset_password_email(#user.email, random_password ).deliver
flash[:notice] = "Email has been sent";
redirect_to root_path
end
end
Make your mailer. This guide goes over how its done if you don't know. Mailers in Rails

Log in existent user when they try to register - Devise

I'm using Devise
If an existing user enters correct email / password combo on registration, I'm trying to sign him in instead of displaying an error message e.g. 'email is already in use'.
The Registration form has 4 fields:
Firstname
Lastname
Email
Password
How can i lookup if the user exists and then log him in?
Where i am stuck:
# Finding the user and if the entered password is valid
user = User.find_by_email(params[:user][:email])
user.valid_password?(params[:user][:password])
Just use sign_in method in controller.
if user.valid_password?(params[:user][:password])
sign_in(user, :bypass => true)
redirect root_path
else
# do something else.
end

Devise create guest records/user results in email can't be blank

I am currently trying to add guest users/records to my application and am encountering having some difficulty getting devise to play along. I am trying to follow the tutorial at http://railscasts.com/episodes/393-guest-user-record, but am stuck when it comes to bypassing the devise validation for the email, password, and username if the user is a guest. In the video tutorial at about 5:40 he quickly mentions devise but i am lost as to how to implement this change. Thanks for the help.
Update** Here is my code. Thanks for the help guys.
Here is my create action under my users_controller.rb
def create
#user = params[:user] ? User.new(params[:user]) : User.new_guest
if #user.save
current_user.move_to(#user) if current_user && current.user.guest?
session[:user_id] = #user.id
redirect_to root_url
else
render "new"
end
end
Here is code from my user.rb
validates_presence_of :username, unless: :guest?
validates_uniqueness_of :username, :email, allow_blank: true
Here is the link that starts the Guest Record
<%= button_to "Try it!", users_path, method: :post %>
The errors that I am getting is are
3 errors prohibited this user from being saved:
Email can't be blank
Password can't be blank
Username can't be blank
You may be receiving the “can't be blank” errors as the parameters are not being allowed through the Devise controller as they're not listed as permitted params?
https://github.com/plataformatec/devise#strong-parameters
Check for 'Unpermitted parameters' errors in your logs to see if this is the issue.

Devise: Sign user in if duplicate sign up

I would like to sign a user in if he attempts to sign up a second time ie. email and password in params is exactly the same.
I added this line to my RegistrationsController (if a duplicate email is detected)
resource = warden.authenticate!(auth_options)
however I can get it to successfully authenticate even though the correct email and password is provided in the params. am I missing something?
I'm on Rails 3.2 and Devise 2.2.7
#user = User.find_by_email(email)
if #user and #user.confirmed? and #user.valid_password?(password)
sign_in #user, :bypass => true
end

Resources