FIX: Invite redemption error if user had already redeemed (#19070)
When opening the invite acceptance page when the user was already logged in, we were still showing the Accept Invitation prompt even if the user had already redeemed the invitation and was present in the `InvitedUser` table. This would lead to errors when the user clicked on the button. This commit fixes the issue by hiding the Accept Invitation button and showing an error message instead indicating that the user had already redeemed the invitation. This only applies to multi-use invite links.
This commit is contained in:
parent
5ee3e2932f
commit
40e8912395
|
@ -31,6 +31,9 @@ export default Controller.extend(
|
|||
accountEmail: alias("email"),
|
||||
existingUserId: readOnly("model.existing_user_id"),
|
||||
existingUserCanRedeem: readOnly("model.existing_user_can_redeem"),
|
||||
existingUserCanRedeemError: readOnly(
|
||||
"model.existing_user_can_redeem_error"
|
||||
),
|
||||
existingUserRedeeming: bool("existingUserId"),
|
||||
hiddenEmail: alias("model.hidden_email"),
|
||||
emailVerifiedByLink: alias("model.email_verified_by_link"),
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
{{#if this.existingUserCanRedeem}}
|
||||
<DButton @class="btn-primary" @action={{action "submit"}} @type="submit" @disabled={{this.submitDisabled}} @label="invites.accept_invite" />
|
||||
{{else}}
|
||||
<div class="alert alert-error">{{i18n "invites.existing_user_cannot_redeem"}}</div>
|
||||
<div class="alert alert-error">{{this.existingUserCanRedeemError}}</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
|
|
@ -408,6 +408,7 @@ class InvitesController < ApplicationController
|
|||
if current_user
|
||||
info[:existing_user_id] = current_user.id
|
||||
info[:existing_user_can_redeem] = invite.can_be_redeemed_by?(current_user)
|
||||
info[:existing_user_can_redeem_error] = existing_user_can_redeem_error(invite)
|
||||
info[:email] = current_user.email
|
||||
info[:username] = current_user.username
|
||||
end
|
||||
|
@ -493,4 +494,13 @@ class InvitesController < ApplicationController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def existing_user_can_redeem_error(invite)
|
||||
return if invite.can_be_redeemed_by?(current_user)
|
||||
if invite.invited_users.exists?(user: current_user)
|
||||
I18n.t("invite.existing_user_already_redemeed")
|
||||
else
|
||||
I18n.t("invite.existing_user_cannot_redeem")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -90,6 +90,10 @@ class Invite < ActiveRecord::Base
|
|||
!redeemed? && !expired? && !deleted_at? && !destroyed? && link_valid?
|
||||
end
|
||||
|
||||
def redeemed_by_user?(redeeming_user)
|
||||
self.invited_users.exists?(user: redeeming_user)
|
||||
end
|
||||
|
||||
def redeemed?
|
||||
if is_invite_link?
|
||||
redemption_count >= max_redemptions_allowed
|
||||
|
@ -109,7 +113,7 @@ class Invite < ActiveRecord::Base
|
|||
|
||||
def can_be_redeemed_by?(user)
|
||||
return false if !self.redeemable?
|
||||
return true if self.email.blank? && self.domain.blank?
|
||||
return false if redeemed_by_user?(user)
|
||||
return true if self.email.present? && email_matches?(user.email)
|
||||
self.domain.present? && domain_matches?(user.email)
|
||||
end
|
||||
|
|
|
@ -2097,7 +2097,6 @@ en:
|
|||
name_label: "Name"
|
||||
password_label: "Password"
|
||||
existing_user_can_redeem: "Redeem your invitation to a topic or group."
|
||||
existing_user_cannot_redeem: "This invitation cannot be redeemed. Please ask the person who invited you to send you a new invitation."
|
||||
|
||||
password_reset:
|
||||
continue: "Continue to %{site_name}"
|
||||
|
|
|
@ -250,6 +250,8 @@ en:
|
|||
<p>Otherwise please <a href="%{base_url}/password-reset">Reset Password</a>.</p>
|
||||
not_found_template_link: |
|
||||
<p>This invitation to <a href="%{base_url}">%{site_name}</a> can no longer be redeemed. Please ask the person who invited you to send you a new invitation.</p>
|
||||
existing_user_cannot_redeem: "This invitation cannot be redeemed. Please ask the person who invited you to send you a new invitation."
|
||||
existing_user_already_redemeed: "You have already redeemed this invite link."
|
||||
user_exists: "There's no need to invite <b>%{email}</b>, they already have an account!"
|
||||
invite_exists: "You already invited <b>%{email}</b>."
|
||||
invalid_email: "%{email} isn't a valid email address."
|
||||
|
|
|
@ -126,6 +126,7 @@ RSpec.describe InvitesController do
|
|||
json = JSON.parse(element.current_scope.attribute('data-preloaded').value)
|
||||
invite_info = JSON.parse(json['invite_info'])
|
||||
expect(invite_info['existing_user_can_redeem']).to eq(false)
|
||||
expect(invite_info['existing_user_can_redeem_error']).to eq(I18n.t("invite.existing_user_cannot_redeem"))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -141,6 +142,22 @@ RSpec.describe InvitesController do
|
|||
expect(invite_info['existing_user_can_redeem']).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not allow the user to accept the invite when a multi-use invite link has already been redeemed by the user" do
|
||||
invite.update!(email: nil, max_redemptions_allowed: 10)
|
||||
expect(invite.redeem(redeeming_user: user)).not_to eq(nil)
|
||||
|
||||
get "/invites/#{invite.invite_key}"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
expect(response.body).to have_tag('div#data-preloaded') do |element|
|
||||
json = JSON.parse(element.current_scope.attribute('data-preloaded').value)
|
||||
invite_info = JSON.parse(json['invite_info'])
|
||||
expect(invite_info['existing_user_id']).to eq(user.id)
|
||||
expect(invite_info['existing_user_can_redeem']).to eq(false)
|
||||
expect(invite_info['existing_user_can_redeem_error']).to eq(I18n.t("invite.existing_user_already_redemeed"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'fails if invite does not exist' do
|
||||
|
|
Loading…
Reference in New Issue