diff options
Diffstat (limited to 'app/services/members/invite_service.rb')
-rw-r--r-- | app/services/members/invite_service.rb | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/app/services/members/invite_service.rb b/app/services/members/invite_service.rb index 85acb720f0f..1bf209ab79d 100644 --- a/app/services/members/invite_service.rb +++ b/app/services/members/invite_service.rb @@ -7,6 +7,8 @@ module Members def initialize(*args) super + @invites += parsed_emails + @errors = {} end @@ -14,38 +16,63 @@ module Members alias_method :formatted_errors, :errors - def invites_from_params - params[:email] + def parsed_emails + # can't put this in the initializer since `invites_from_params` is called in super class + # and needs it + @parsed_emails ||= (formatted_param(params[:email]) || []) + end + + def formatted_param(parameter) + parameter&.split(',')&.uniq&.flatten end def validate_invitable! super + return if params[:email].blank? + # we need the below due to add_users hitting Members::CreatorService.parse_users_list and ignoring invalid emails # ideally we wouldn't need this, but we can't really change the add_users method - valid, invalid = invites.partition { |email| Member.valid_email?(email) } - @invites = valid + invalid_emails.each { |email| errors[email] = s_('AddMember|Invite email is invalid') } + end + + def invalid_emails + parsed_emails.each_with_object([]) do |email, invalid| + next if Member.valid_email?(email) - invalid.each { |email| errors[email] = s_('AddMember|Invite email is invalid') } + invalid << email + @invites.delete(email) + end end override :blank_invites_message def blank_invites_message - s_('AddMember|Emails cannot be blank') + s_('AddMember|Invites cannot be blank') end override :add_error_for_member - def add_error_for_member(member) - errors[invite_email(member)] = member.errors.full_messages.to_sentence + def add_error_for_member(member, existing_errors) + errors[invited_object(member)] = all_member_errors(member, existing_errors).to_sentence end - override :create_tasks_to_be_done - def create_tasks_to_be_done - # Only create task issues for existing users. Tasks for new users are created when they signup. - end + def invited_object(member) + return member.invite_email if member.invite_email - def invite_email(member) - member.invite_email || member.user.email + # There is a case where someone was invited by email, but the `user` record exists. + # The member record returned will not have an invite_email attribute defined since + # the CreatorService finds `user` record sometimes by email. + # At that point we lose the info of whether this invite was done by `user` or by email. + # Here we will give preference to check invites by user_id first. + # There is also a case where a user could be invited by their email and + # at the same time via the API in the same request. + # This would would mean the same user is invited as user_id and email. + # However, that isn't as likely from the UI at least since the token generator checks + # for that case and doesn't allow email being used if the user exists as a record already. + if member.user_id.to_s.in?(invites) + member.user.username + else + member.user.all_emails.detect { |email| email.in?(invites) } + end end end end |