devise_invitable
devise_invitable copied to clipboard
Inviting a user just redirects to main page with a message that "the user is already logged in"
I'm having a strange error and it only happens with one user (I've tested it with several).
When I login an try to invite another user, I simply get redirected to the root url, with a message saying I'm already logged in. The create method, doesn't even get touched.
In the console, I get the error "Filter chain halted as :require_no_authentication rendered or redirected".
Any suggestions on what might be happening?
Stack trace:
Started PUT "/users/invitation" for 127.0.0.1 at 2014-08-12 16:25:37 +0200
Processing by Users::InvitationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"0jcXaiqyytJWLv5PopyGG0Ptquc+eT/s7xagdEB56A8=", "user"=>{"first_name"=>"", "last_name"=>"", "role"=>"team_member", "email"=>"", "team_name_one"=>"", "team_name_two"=>"", "make_admin"=>"1"}, "commit"=>"Invitér bruger"}
MOPED: 127.0.0.1:27017 QUERY database=vsa-web-app collection=users selector={"$query"=>{"_id"=>"53cadfcdb56c2fd077000003"}, "$orderby"=>{:_id=>1}} flags=[:slave_ok] limit=-1 skip=0 batch_size=nil fields=nil (0.4039ms)
Redirected to http://localhost:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 1.9ms
Controller:
class Users::InvitationsController < DeviseController
prepend_before_filter :authenticate_inviter!, :only => [:new, :create]
prepend_before_filter :has_invitations_left?, :only => [:create]
prepend_before_filter :require_no_authentication, :only => [:edit, :update, :destroy]
prepend_before_filter :resource_from_invitation_token, :only => [:edit, :destroy]
helper_method :after_sign_in_path_for
# GET /resource/invitation/new
def new
@new_user_role = new_user_role
@institution = current_inviter.institution
@team = current_inviter.team
self.resource = resource_class.new
render :new
end
# POST /resource/invitation
def create
# Make institution name be correct name
if !params[:user][:institution_name_one].blank? || !params[:user][:institution_name_two].blank?
params[:user][:institution_name] = Institution.find(params[:user][:institution_name_one]).name.capitalize unless params[:user][:institution_name_one].blank?
params[:user][:institution_name] = params[:user][:institution_name_two].capitalize unless params[:user][:institution_name_two].blank?
end
# Make team name be correct name
if !params[:user][:team_name_one].blank? || !params[:user][:team_name_two].blank?
params[:user][:institution_name] = current_inviter.institution ? current_inviter.institution.name : current_inviter.institution_name
params[:user][:team_name] = Team.find(params[:user][:team_name_one]).name.capitalize unless params[:user][:team_name_one].blank?
params[:user][:team_name] = params[:user][:team_name_two].capitalize unless params[:user][:team_name_two].blank?
end
# Set resource to parameters
self.resource = invite_resource
# Save invitation
if resource.errors.empty?
yield resource if block_given?
set_flash_message :notice, :send_instructions, :email => self.resource.email if self.resource.invitation_sent_at
respond_with resource, :location => after_invite_path_for(resource)
else
respond_with_navigational(resource) { render :new }
end
end
# GET /resource/invitation/accept?invitation_token=abcdef
def edit
resource.invitation_token = params[:invitation_token]
render :edit
end
# PUT /resource/invitation
def update
self.resource = accept_resource
if resource.errors.empty?
yield resource if block_given?
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
# If user updated and he is an institution admin, then assign him an institution, else assign him a team
if flash_message==:updated && resource.role=="institution_admin"
institution = Institution.where(:name => resource.institution_name.capitalize).first
institution = Institution.create(:name => resource.institution_name.capitalize) unless institution
institution.users << resource
elsif flash_message==:updated && (resource.role=="team_admin" || resource.role=="team_member")
institution = Institution.where(:name => resource.institution_name.capitalize).first
first_team = Team.where(:name => resource.team_name.capitalize).first
if first_team
team = first_team
else
team = Team.create(:name => resource.team_name.capitalize)
end
team.users << resource
team.institution = institution if institution
institution.teams << team if institution
# Create first documents
unless first_team
team.documents.create(:active => true, :role => "teaching_environments", :saved_by => resource.first_name+" "+resource.last_name)
team.documents.create(:active => true, :role => "evaluation_and_feedback", :saved_by => resource.first_name+" "+resource.last_name)
team.documents.create(:active => true, :role => "personal", :saved_by => resource.first_name+" "+resource.last_name)
team.documents.create(:active => true, :role => "open_school", :saved_by => resource.first_name+" "+resource.last_name)
team.documents.create(:active => true, :role => "purpose_teaching_and_education", :saved_by => resource.first_name+" "+resource.last_name)
team.documents.create(:active => true, :role => "students_and_parents", :saved_by => resource.first_name+" "+resource.last_name)
end
end
set_flash_message :notice, flash_message
sign_in(resource_name, resource)
respond_with resource, :location => after_accept_path_for(resource)
else
respond_with_navigational(resource){ render :edit }
end
end
# GET /resource/invitation/remove?invitation_token=abcdef
def destroy
resource.destroy
set_flash_message :notice, :invitation_removed
redirect_to :back
end
def new_user_role
if current_inviter.role=="project_owner"
return "institution_admin"
elsif current_inviter.role=="institution_admin"
return "team_admin"
elsif current_inviter.role=="team_admin"
return "team_member"
end
end
protected
def invite_resource(&block)
resource_class.invite!(invite_params, current_inviter, &block)
end
def accept_resource
resource_class.accept_invitation!(update_resource_params)
end
def current_inviter
authenticate_inviter!
end
def has_invitations_left?
unless current_inviter.nil? || current_inviter.has_invitations_left?
self.resource = resource_class.new
set_flash_message :alert, :no_invitations_remaining
respond_with_navigational(resource) { render :new }
end
end
def resource_from_invitation_token
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
def invite_params
devise_parameter_sanitizer.sanitize(:invite)
end
def update_resource_params
devise_parameter_sanitizer.sanitize(:accept_invitation)
end
def after_invite_path_for(resource)
new_user_invitation_path
end
end
No clues anybody? I'm kind of lost here!
You are sending form with PUT, which is update action (accept invitation) instead of create action (invite). Did you change invite view?
Thanks for the response... I am sending it with put:
= simple_form_for @plan, :html => {:method => :put} do |f|
.col-sm-3
.form-group
= f.input :name, placeholder: "Plan navn (eks. 4b)", label: false, input_html: { class: 'form-control' }
.col-sm-3
= f.button :submit, 'Gem navn', :class => 'btn btn-primary btn-block'
.col-sm-6
a.pull-right data-container="body" data-content="Her kan du invitere og administrere gruppens brugere." data-placement="left" data-toggle="popover" data-trigger="hover"
img alt="Forklaring" height="35" src="#{asset_path '[email protected]'}" width="35"
.col-sm-12
hr.clearfix
Should I just take away ", :html => {:method => :put}" and it should work?
Probably. form_for uses :put if @plan is persisted, :post in other case, I guess simple_form_for does it in same way
I still seem to have the same issue. This is my routes file for devise invitable:
devise_for :users, :controllers => { :invitations => 'users/invitations' }
resources :users, except: [:new, :create, :destroy] do
get 'request_invitation', on: :collection
post 'send_invitation', on: :collection
get 'make_admin', on: :member
end
Does everything look good to you?
I tried both deleting the method :put and replacing it with post, but nothing seems to work. Any suggestions?
It's not a routes issue. This is request:
Started PUT "/users/invitation" for 127.0.0.1 at 2014-08-12 16:25:37 +0200 Processing by Users::InvitationsController#update as HTML
It's a request to update action, because HTTP method is PUT. That's usual behavior. If removing :method => :put doesn't work, try adding :method => :post
Or maybe you posted wrong view, because I see record hash with 7 parameters in request, but form only has name input for @plan.
Background
-
resource
is the new record created when you invite, e.g.User.create
-
current_inviter
is the current user, commonly referred to ascurrent_user
class Devise::InvitationsController < DeviseController
# ...
def create
# ...
respond_with resource, :location => after_invite_path_for(resource)
This bug is occurring because the code is trying to redirect to after_invite_path_for
based on resource
when it should more correctly be
respond_with resource, :location => after_invite_path_for(current_inviter)
It works for most people likely because after_sign_in_path_for
or after_invite_path_for
does not change based on the argument. For our app (and probably yours), you look at the current instance and redirect to the appropriate route
Apologies, seems it'll take considerable effort to add a PR with test, so here is the workaround instead.
Override default controller and fix the after_invite_path_for
class Users::InvitationsController < Devise::InvitationsController
def after_invite_path_for(resource)
after_sign_in_path_for(current_inviter)
end
end
This happens for GET
requests too:
Started GET "/devise/users/invitation/accept?invitation_token=cmkv-2--HpJDJxBBz5Xa" for 10.0.2.2 at 2019-03-11 13:17:56 +0000
Processing by InvitationsController#edit as JSON
Parameters: {"invitation_token"=>"cmkv-2--HpJDJxBBz5Xa"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."invitation_token" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["invitation_token", "bb8e74deadcc5039735d1e1927ce483be7b8cb5a247a3e8004bf3bae65b40cc7"], ["LIMIT", 1]]
↳ /usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:97
Redirected to http://localhost:3000/
Filter chain halted as :resource_from_invitation_token rendered or redirected
Completed 302 Found in 3ms (ActiveRecord: 0.5ms)
Though it seems to only happen for certain invitations. Over a 3 day period I only had this happen for one specific user invite. I ended up deleting that user and making a new invitation and it went back to working as expected 🤷♂️
Same issue here as @rally25rs and I can't understand why it happens for certain invites only. 🤷♂️ @rally25rs did you managet to find a root cause?