mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 18:13:39 +08:00
Invite link can't be used to log in after you set a password or sign in with 3rd party
This commit is contained in:
parent
1dbc1c56b4
commit
da825451d0
|
@ -27,6 +27,9 @@ class SessionController < ApplicationController
|
|||
return
|
||||
end
|
||||
|
||||
# User signed on with username and password, so let's prevent the invite link
|
||||
# from being used to log in (if one exists).
|
||||
Invite.invalidate_for_email(user.email)
|
||||
else
|
||||
invalid_credentials
|
||||
return
|
||||
|
|
|
@ -85,8 +85,8 @@ class Users::OmniauthCallbacksController < ApplicationController
|
|||
# log on any account that is active with forum access
|
||||
if Guardian.new(user).can_access_forum? && user.active
|
||||
log_on_user(user)
|
||||
# don't carry around old auth info, perhaps move elsewhere
|
||||
session[:authentication] = nil
|
||||
Invite.invalidate_for_email(user.email) # invite link can't be used to log in anymore
|
||||
session[:authentication] = nil # don't carry around old auth info, perhaps move elsewhere
|
||||
@data.authenticated = true
|
||||
else
|
||||
if SiteSetting.must_approve_users? && !user.approved?
|
||||
|
|
|
@ -173,7 +173,10 @@ class UsersController < ApplicationController
|
|||
raise Discourse::InvalidParameters.new(:password) unless params[:password].present?
|
||||
@user.password = params[:password]
|
||||
@user.password_required!
|
||||
logon_after_password_reset if @user.save
|
||||
if @user.save
|
||||
Invite.invalidate_for_email(@user.email) # invite link can't be used to log in anymore
|
||||
logon_after_password_reset
|
||||
end
|
||||
end
|
||||
render layout: 'no_js'
|
||||
end
|
||||
|
|
|
@ -26,7 +26,8 @@ class Invite < ActiveRecord::Base
|
|||
def user_doesnt_already_exist
|
||||
@email_already_exists = false
|
||||
return if email.blank?
|
||||
if User.where("email = ?", Email.downcase(email)).exists?
|
||||
u = User.where("email = ?", Email.downcase(email)).first
|
||||
if u && u.id != self.user_id
|
||||
@email_already_exists = true
|
||||
errors.add(:email)
|
||||
end
|
||||
|
@ -40,8 +41,13 @@ class Invite < ActiveRecord::Base
|
|||
created_at < SiteSetting.invite_expiry_days.days.ago
|
||||
end
|
||||
|
||||
# link_valid? indicates whether the invite link can be used to log in to the site
|
||||
def link_valid?
|
||||
invalidated_at.nil?
|
||||
end
|
||||
|
||||
def redeem
|
||||
InviteRedeemer.new(self).redeem unless expired? || destroyed?
|
||||
InviteRedeemer.new(self).redeem unless expired? || destroyed? || !link_valid?
|
||||
end
|
||||
|
||||
|
||||
|
@ -100,6 +106,15 @@ class Invite < ActiveRecord::Base
|
|||
rails4? ? all : scoped
|
||||
end
|
||||
end
|
||||
|
||||
def self.invalidate_for_email(email)
|
||||
i = Invite.where(email: Email.downcase(email)).first
|
||||
if i
|
||||
i.invalidated_at = Time.zone.now
|
||||
i.save
|
||||
end
|
||||
i
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddInvalidatedAtToInvites < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :invites, :invalidated_at, :datetime
|
||||
end
|
||||
end
|
|
@ -167,6 +167,11 @@ describe Invite do
|
|||
invite.redeem.should be_blank
|
||||
end
|
||||
|
||||
it "won't redeem an invalidated invite" do
|
||||
invite.invalidated_at = 1.day.ago
|
||||
invite.redeem.should be_blank
|
||||
end
|
||||
|
||||
context 'invite trust levels' do
|
||||
|
||||
it "returns the trust level in default_invitee_trust_level" do
|
||||
|
@ -350,4 +355,28 @@ describe Invite do
|
|||
expect(invites.first).to eq redeemed_invite
|
||||
end
|
||||
end
|
||||
|
||||
describe '.invalidate_for_email' do
|
||||
let(:email) { 'invite.me@example.com' }
|
||||
subject { described_class.invalidate_for_email(email) }
|
||||
|
||||
it 'returns nil if there is no invite for the given email' do
|
||||
subject.should == nil
|
||||
end
|
||||
|
||||
it 'sets the matching invite to be invalid' do
|
||||
invite = Fabricate(:invite, invited_by: Fabricate(:user), user_id: nil, email: email)
|
||||
subject.should == invite
|
||||
subject.link_valid?.should == false
|
||||
subject.should be_valid
|
||||
end
|
||||
|
||||
it 'sets the matching invite to be invalid without being case-sensitive' do
|
||||
invite = Fabricate(:invite, invited_by: Fabricate(:user), user_id: nil, email: 'invite.me2@Example.COM')
|
||||
result = described_class.invalidate_for_email('invite.me2@EXAMPLE.com')
|
||||
result.should == invite
|
||||
result.link_valid?.should == false
|
||||
result.should be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user