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.
CodePudding user response:
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