Devise Token Auth confirmation email link expired - ruby-on-rails

I am currently developing a website and i have a problem with te confirmation link with devise token auth.
Everything is working right, after someones registers they get an email with a confirmation link. This link is confirming and working properly BUT when this link expires (i set it up in the configuration with config.confirm_within = 1.day ) or someone clicks this link again they get a "Routing error". So i suppose there should be a way of redirecting to the homepage when that link expires and maybe showing a message saying that they have to ask for the email confirmation again..
i have this confirmation routes:
new_api_user_confirmation GET /api/auth/confirmation/new(.:format) devise_token_auth/confirmations#new
api_user_confirmation GET /api/auth/confirmation(.:format) devise_token_auth/confirmations#show
POST /api/auth/confirmation(.:format) devise_token_auth/confirmations#create
I use the last route POST for resending the email and it is working, but the other to routes are not working and that makes sense because i am using API. But there should be a redirect url for when you get an error
Any thoughts? thank you in advance

you can override the DeviseTokenAuth::ConfirmationsController#show and redirect to root_path
DeviseTokenAuth ConfirmationsController#show
class ConfirmationsController < DeviseTokenAuth::ConfirmationsController
def show
...
else
# raise ActionController::RoutingError, 'Not Found'
redirect_to :root_path
end
...
in routes
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
# confirmations: 'devise_token_auth/confirmations',
confirmations: 'confirmations',
devise-token-auth docs

Related

How to redirect to login page/ or making user login successful after confirm email in devise token auth

I am using devise token auth with React frontend and now I am making user confirmable through email. Email is being sent but somehow it generates a wrong URL.
The URL that is generated is.
http://localhost:3001/auth/confirmation.4?confirmation_token=AoWH2yYxuHHnBzJRF746
My routes.
new_user_confirmation GET /auth/confirmation/new(.:format) users/confirmations#new
user_confirmation GET /auth/confirmation(.:format) users/confirmations#show
POST /auth/confirmation(.:format) users/confirmations#create
My app/views/devise/mailer/confirmation_instructions.html.erb
<p>Welcome <%= #email %>!</p>
<p>You can confirm your account email through the link below:</p>
<p><%= link_to 'Confirm my account', user_confirmation_url(confirmation_token: #token) %></p>
After clicking confirm my account, it takes me to my application successfully, but with the wrong URL. I will be happy if I achieve one of the following.
User is automatically logged in after confirming.
It goes to login page after confirm account and after that he gives thee credentials and login.
For 1, I have overridden the confirmations_controller.rb like.
# frozen_string_literal: true
class Users::ConfirmationsController < Devise::ConfirmationsController
# The path used after confirmation.
def after_confirmation_path_for(resource_name, resource)
sign_in(resource) # In case you want to sign in the user
root_path
end
end
In routes.rb
mount_devise_token_auth_for 'User', at: 'auth', controllers: { confirmations: 'users/confirmations' }
First, the url helper that you use in the email doesn't need to receive the #resource - this is why it generates the url with the .4. It should rather be
<p><%= link_to 'Confirm my account', user_confirmation_url(confirmation_token: #token) %></p
Second, according to this tutorial, you can redirect the user after confirmation, like you tried already.
https://github.com/heartcombo/devise/wiki/How-To:-Add-:confirmable-to-Users#redirecting-user
Just give a path in your app after you signed in the user
def after_confirmation_path_for(resource_name, resource)
sign_in(resource) # In case you want to sign in the user
your_new_after_confirmation_path
end
So no need to go to session_new again after signing in.

Rails 4 devise_invitable "The invitation token provided is not valid!" error

I have been following Ryan Boland's Rails multitenancy tutorial, but have run into a snag with devise_invitable.
I create a new account and user/account owner on a chosen subdomain (mysubdomain.lvh.me:3000), from which I can send a user invitation just fine. I open the invitation link in an incognito Chrome session to ensure I am not logged in or have any current session. Upon clicking on the invitation link, I am redirected to the sign in page (mysubdomain.lvh.me:3000/users/sign_in) and see a flash notice: "The invitation token provided is not valid!"
Related to this one:
Rails 4 devise_invitable invitation token invalid
[SOLVED]
In case anyone has the same issue, override the invitations controller and change the Tenant with Apartment:
# app/controllers/users/invitations_controller.rb
class Users::InvitationsController < Devise::InvitationsController
private
def resource_from_invitation_token
Apartment::Tenant.switch!(request.subdomain) //ADD THIS BABY!
unless params[:invitation_token] &&
self.resource = resource_class.find_by_invitation_token(params[:invitation_token], true)
set_flash_message(:alert, :invitation_token_invalid)
redirect_to after_sign_out_path_for(resource_name)
end
end
end
Remember to update your routes also, like this:
# config/routes.rb
devise_for :users, :controllers => { :invitations => 'users/invitations' }

Why isn't Devise + Omniauth callback hitting the correct controller?

Can anyone help me get to the bottom of this problem?
I'm using Devise + Omniauth in a Rails 3.2 app. What I want to know is, what's happening behind the scenes with Devise's user_omniauth_authorize_path(provider) method.
I've had a dig through rake routes and the gem's source, but I can't see anything obvious that would cause the issue I'm having.
I assume this method simply calls the provider's signin url (e.g. Twitter) and then returns to the callback path defined in routes.rb.
In my routes.rb I have
devise_for :users, :controllers => { :omniauth_callbacks => 'users/omniauth_callbacks'}
devise_scope :user do
get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
end
In users/omniauth_callbacks_controller.rb I have
def twitter
render :text => "This works"
end
def passthru
render :text => "This doesn't work"
end
In a view I have <%= link_to "Twitter", user_omniauth_authorize_path(:twitter) %>. Clicking this link goes to Twitter where I can log in, but upon return to my app I get an error "You are already signed in".
I can't work out how or why this error is being generated. I should only be seeing "This works" or "This doesn't work".
I also have a Facebook provider set up in exactly the same way, and this works as expected.
If I replace Devise's omniauth link with Twitter then I get "This works".
So this solves my issue, but its not ideal and I'd like to know why.
Can anyone shed any light?
EDIT
Rake routes looks like this:
user_omniauth_callback /users/auth/:action/callback(.:format) users/omniauth_callbacks#(?-mix:twitter|facebook)
Well, it is working for me, so it is definitely something on your end. First of all, have you compared in the console the GET calls /users/auth/twitter and /users/auth/twitter?callback obtained by the 2 different methods? They should look exactly the same (except for the token and the verifier, of course).
Now, I'm not sure if this is related, but with devise you don't use a passthru route, so you can remove that route. Instead, in your callbacks controller, you should implement an action called failure that handles a bad request. See here for devise's implementation.
I'm grasping at straws here, but you should also have this at the end of your callbacks controller:
# This is necessary since Rails 3.0.4
# See https://github.com/intridea/omniauth/issues/185
# and http://www.arailsdemo.com/posts/44
protected
def handle_unverified_request
true
end

Remove Devise Flash Notices for Sign out

As the name says, I am using devise for user auth in a rails 3 app
Upon user log out, there is a flash notice, "User Successfully signed out" that I don't want to appear. However, I can't figure out how to remove the notice.
Is there a way to get around just making it blank? I would like to completely remove the notice so that, ideally, there's not even an html div for notice
If you explicitly put in a blank string for this in your locale file, then Devise "won't bother" to render the message at all (e.g. there won't even be an empty HTML div).
#en.yml
devise:
sessions:
signed_in: 'Signed in successfully.'
signed_out: ''
My routes.rb
devise_for :users, :controllers => {
sessions: 'user/sessions'
}
My controller "account/sessions_controller.rb"
class User::SessionsController < Devise::SessionsController
def destroy
super
flash.delete(:notice)
end
end

Devise hijacking a 401 response

I'm trying to create an API and for one of my actions I'm restricting it to just admins. To do this, I'm using a before_filter that goes like this:
def authorize_admin!
if !#current_user.admin?
error = { :error => "You must be an admin to do that." }
render params[:format].to_sym => error, :status => 401
end
end
The problem is that when we send back a 401 response, the error is transformed into:
"{\"error\":\"You need to sign in or sign up before continuing.\"}"
This is the response that Devise sends back for when you send a 401 response.
Is there a way that I can turn off this functionality?
What is the Devise version? This wiki page suggests that it should work on 1.2.
https://github.com/plataformatec/devise/wiki/How-To:-Provide-a-custom-failure-response-with-Warden
I think that this page from the Devise wiki can help you.
How To Use HTTP Authentication in Devise

Resources