Log in existent user when they try to register - Devise - ruby-on-rails

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

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

Customize the validation when user sign in in devise

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.

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

Devise Mailer, using custom email template for existing module

I'm using ruby on rails, with devise.
I have a senario wherin an Administrator would be able to add new user to the web application giving his email id and under this senario i'd be creating a new user. and would like to issue an Auth-Token to the user email. so when he clicks the link in his email, he'd be prompted to issue his/her new password.
My forgot password implementation.
def create
resource = User.send_reset_password_instructions(params[:user])
if successfully_sent?(resource)
render json: {status: :true},status: 200
else
render json: {status: :false, error: user.errors.full_messages.join(",") } , status: 200
end
end
Now my question is how do i use the same logic as that of forgot password, but use different Email-template for the user-added by the administrator screen. ?
Thanks a lot.
Why are you redirecting a user to forgot your password page when you can simply redirect him/her to settings page from where a user can change his/her password?
Create a mailer action with its template and simply call that mailer action inside the method where your admin is creating users. e.g:
if your mailer action is:
def forgot_pass(email)
mail(to: email, subject: 'Change your pass')
end
and your method where your admin is creating users is:
def create_user
# your logic
YourMailerClass.forgot_pass(xyz#abc.com).deliver
end
For more details on mailer refer to here

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