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
Related
I'm using devise and devise-token-auth for auth in the backend and 'redux-auth` on the client side.
I'm trying to get devise to send a proper error message to show to a client in case the account is temporarily locked
this is my user.rb file
# devise method to check if user is banned
def active_for_authentication?
super && !self.banned?
end
# message to send in case of ban. doesnt work yet
def inactive_message
self.banned? ? :locked : super
end
def banned?
return self.role == 'banned'
end
my devise.en.yml file
en:
devise:
confirmations:
confirmed: "Your email address has been successfully confirmed."
failure:
locked: "Your account is locked."
errors:
messages:
locked: "Your account has been banned"
I seem to be getting a standard error response from devise when trying to login either with redux-auth or CURL (i cant seem to find the given message anywhere in devise.en.yml file)
curl http://localhost:3000/auth/sign_in -d "email=foo#foo.com&password=123"
the response
{"success":false,"errors":["A confirmation email was sent to your account at 'foo#foo.com'."]}
Where can i customize the message?
The message is in the devise_token_auth yaml file: https://github.com/lynndylanhurley/devise_token_auth/blob/123cfb730ebaf4e2acc124edd39e68816cb0b8cf/config/locales/en.yml
so you need to override it by adding the following to one of your local yaml files:
en:
devise_token_auth:
sessions:
not_confirmed: "Custom message"
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.
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
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
In my application I have a user confirmation process. When a user signs up four things happen:
An account_status_id is set to 1 (unconfirmed)
The user is signed in (now current_user exists)
A new_account_confirmation_token is generated
A confirmation email is sent to the new user with a link that includes the new_account_confirmation_token
I initially tried to handle the confirmation link with this method. It finds the user without issue and the code flows through the update_attributes! method, however it wasn't updating the account_status. From what I can tell it is due to the fact that the current_user object exists, therefore the user Im trying to update is already "in memory". Is that correct?
def new_account_confirmation
#title = "Account Confirmation"
logger.info("User is not logged in")
#user = User.find_by_new_account_confirmation_token(params[:confirm_id])
if #user
#user.update_attributes!(:account_status_id => 2)
else
redirect_to root_path
end
end
My work around is as follows. The code below works but I'd like to know why the code above doesn't work. Why won't it update the account_status?
def new_account_confirmation
#title = "Account Confirmation"
if current_user
logger.info("User is logged in")
current_user.update_attributes!(:account_status_id => 2)
else
logger.info("User is not logged in")
#user = User.find_by_new_account_confirmation_token(params[:confirm_id])
if #user
#user.update_attributes!(:account_status_id => 2)
else
redirect_to root_path
end
end
end
Even if your user is "in memory" as you say, that's no reason for it not to update. I believe your update IS happening but you're just not seeing it because current_user is not in sync with #user.
I don't know how you're verifying that #user is not being updated but if update_attributes! is not throwing an error then it's being saved.