2019-05-21 21:53:34 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-11-06 18:29:00 +08:00
|
|
|
module Users
|
|
|
|
class InvitationsController < Devise::InvitationsController
|
2017-05-12 04:20:06 +08:00
|
|
|
include InputSanitizeHelper
|
2016-11-06 18:29:00 +08:00
|
|
|
include UsersGenerator
|
2019-07-01 19:44:27 +08:00
|
|
|
include NotificationsHelper
|
2016-11-06 18:29:00 +08:00
|
|
|
|
2016-11-23 21:28:32 +08:00
|
|
|
prepend_before_action :check_captcha, only: [:update]
|
|
|
|
|
2019-01-23 16:17:27 +08:00
|
|
|
prepend_before_action :check_captcha_for_invite, only: [:invite_users]
|
|
|
|
|
2016-11-06 18:29:00 +08:00
|
|
|
before_action :check_invite_users_permission, only: :invite_users
|
|
|
|
|
2017-06-30 16:23:28 +08:00
|
|
|
before_action :update_sanitized_params, only: :update
|
2016-11-25 18:15:10 +08:00
|
|
|
|
2016-11-06 18:29:00 +08:00
|
|
|
def update
|
2017-10-25 21:29:04 +08:00
|
|
|
return super unless Rails.configuration.x.new_team_on_signup
|
2019-05-21 21:53:34 +08:00
|
|
|
|
2017-01-24 23:57:14 +08:00
|
|
|
# Instantialize a new team with the provided name
|
2017-01-25 00:06:51 +08:00
|
|
|
@team = Team.new
|
2017-01-24 23:57:14 +08:00
|
|
|
@team.name = params[:team][:name]
|
2016-11-06 18:29:00 +08:00
|
|
|
|
|
|
|
super do |user|
|
2021-07-23 17:56:28 +08:00
|
|
|
if user.errors.blank?
|
2017-01-24 23:57:14 +08:00
|
|
|
@team.created_by = user
|
|
|
|
@team.save
|
2016-11-06 18:29:00 +08:00
|
|
|
end
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-11-06 18:29:00 +08:00
|
|
|
def accept_resource
|
2017-10-25 21:29:04 +08:00
|
|
|
return super unless Rails.configuration.x.new_team_on_signup
|
|
|
|
|
2017-01-24 23:57:14 +08:00
|
|
|
unless @team.valid?
|
2016-11-18 17:57:03 +08:00
|
|
|
# Find the user being invited
|
|
|
|
resource = User.find_by_invitation_token(
|
|
|
|
update_resource_params[:invitation_token],
|
|
|
|
false
|
|
|
|
)
|
|
|
|
|
|
|
|
# Check if user's data (passwords etc.) is valid
|
|
|
|
resource.assign_attributes(
|
|
|
|
update_resource_params.except(:invitation_token)
|
|
|
|
)
|
|
|
|
resource.valid? # Call validation to generate errors
|
|
|
|
|
2017-01-24 23:57:14 +08:00
|
|
|
# In any case, add the team name error
|
|
|
|
resource.errors.add(:base, @team.errors.to_a.first)
|
2016-11-18 17:57:03 +08:00
|
|
|
return resource
|
|
|
|
end
|
|
|
|
|
|
|
|
super
|
2016-11-06 18:29:00 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def invite_users
|
|
|
|
@invite_results = []
|
|
|
|
@too_many_emails = false
|
|
|
|
|
2019-05-21 21:53:34 +08:00
|
|
|
@emails.each_with_index do |email, email_counter|
|
|
|
|
# email_counter starts with 0
|
|
|
|
if email_counter >= Constants::INVITE_USERS_LIMIT
|
2016-11-06 18:29:00 +08:00
|
|
|
@too_many_emails = true
|
|
|
|
break
|
|
|
|
end
|
|
|
|
|
2022-09-26 18:14:03 +08:00
|
|
|
result = { email: email }
|
2019-05-21 21:53:34 +08:00
|
|
|
unless Constants::BASIC_EMAIL_REGEX.match?(email)
|
|
|
|
result[:status] = :user_invalid
|
|
|
|
@invite_results << result
|
|
|
|
next
|
|
|
|
end
|
|
|
|
# Check if user already exists
|
2022-05-19 15:04:25 +08:00
|
|
|
user = User.find_by(email: email)
|
2016-11-06 18:29:00 +08:00
|
|
|
|
2019-05-21 21:53:34 +08:00
|
|
|
if user
|
2016-11-06 18:29:00 +08:00
|
|
|
result[:status] = :user_exists
|
|
|
|
else
|
2019-05-21 21:53:34 +08:00
|
|
|
user = User.invite!(
|
|
|
|
full_name: email,
|
|
|
|
email: email,
|
|
|
|
initials: email.upcase[0..1],
|
|
|
|
skip_invitation: true
|
|
|
|
)
|
|
|
|
user.update(invited_by: @user)
|
2016-11-06 18:29:00 +08:00
|
|
|
|
2019-05-21 21:53:34 +08:00
|
|
|
result[:status] = :user_created
|
2016-11-06 18:29:00 +08:00
|
|
|
|
2019-05-21 21:53:34 +08:00
|
|
|
# Sending email invitation is done in background job to prevent
|
|
|
|
# issues with email delivery. Also invite method must be call
|
|
|
|
# with :skip_invitation attribute set to true - see above.
|
|
|
|
user.delay.deliver_invitation
|
2016-11-06 18:29:00 +08:00
|
|
|
end
|
|
|
|
|
2021-07-05 18:39:54 +08:00
|
|
|
if @teams.any? && user
|
2022-10-14 17:35:35 +08:00
|
|
|
@user_role ||= UserRole.find_predefined_normal_user_role
|
2021-07-05 18:39:54 +08:00
|
|
|
@teams.each do |team|
|
2022-05-19 15:04:25 +08:00
|
|
|
if team.user_assignments.exists?(user: user)
|
2021-07-05 18:39:54 +08:00
|
|
|
result[:status] = :user_exists_and_in_team
|
|
|
|
else
|
|
|
|
# Also generate user team relation
|
2022-12-13 18:34:56 +08:00
|
|
|
team.user_assignments.create!(user: user, user_role: @user_role, assigned_by: current_user)
|
2021-07-05 18:39:54 +08:00
|
|
|
|
|
|
|
generate_notification(
|
|
|
|
@user,
|
|
|
|
user,
|
2022-05-19 15:04:25 +08:00
|
|
|
team,
|
|
|
|
@user_role.name
|
2021-07-05 18:39:54 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
Activities::CreateActivityService
|
|
|
|
.call(activity_type: :invite_user_to_team,
|
|
|
|
owner: current_user,
|
|
|
|
subject: team,
|
|
|
|
team: team,
|
|
|
|
message_items: {
|
|
|
|
team: team.id,
|
|
|
|
user_invited: user.id,
|
2022-05-19 15:04:25 +08:00
|
|
|
role: @user_role.name
|
2021-07-05 18:39:54 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
result[:status] = if result[:status] == :user_exists && !user.confirmed?
|
|
|
|
:user_exists_unconfirmed_invited_to_team
|
|
|
|
elsif result[:status] == :user_exists
|
|
|
|
:user_exists_invited_to_team
|
|
|
|
else
|
|
|
|
:user_created_invited_to_team
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-05-19 15:04:25 +08:00
|
|
|
result[:user_role_name] = @user_role.name
|
|
|
|
result[:team_name] = team.name
|
2016-11-06 18:29:00 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@invite_results << result
|
|
|
|
end
|
|
|
|
|
2023-06-21 20:13:20 +08:00
|
|
|
render json: {
|
2023-07-05 18:43:23 +08:00
|
|
|
html: render_to_string(partial: 'shared/invite_users_modal_results', formats: :html)
|
2023-06-21 20:13:20 +08:00
|
|
|
}
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
|
|
|
|
2021-07-05 18:39:54 +08:00
|
|
|
def invitable_teams
|
|
|
|
teams = current_user.teams
|
|
|
|
.select(:id, :name)
|
2022-05-19 15:04:25 +08:00
|
|
|
.joins(user_assignments: :user_role)
|
|
|
|
.where(user_assignments: { user: current_user })
|
|
|
|
.where('? = ANY(user_roles.permissions)', TeamPermissions::USERS_MANAGE)
|
2021-07-05 18:39:54 +08:00
|
|
|
.distinct
|
2023-04-11 22:09:24 +08:00
|
|
|
teams = teams.where_attributes_like('teams.name', params[:query]) if params[:query].present?
|
2021-07-08 22:10:20 +08:00
|
|
|
|
|
|
|
teams.select { |team| can_invite_team_users?(team) }
|
2021-07-05 18:39:54 +08:00
|
|
|
|
2023-03-15 18:14:52 +08:00
|
|
|
render json: teams.map { |t| { value: t.id, label: escape_input(t.name) } }.to_json
|
2021-07-05 18:39:54 +08:00
|
|
|
end
|
|
|
|
|
2016-11-06 18:29:00 +08:00
|
|
|
private
|
|
|
|
|
2016-11-25 18:15:10 +08:00
|
|
|
def update_sanitized_params
|
|
|
|
# Solution for Devise < 4.0.0
|
2018-01-17 22:06:43 +08:00
|
|
|
devise_parameter_sanitizer.permit(:accept_invitation, keys: [:full_name])
|
2016-11-25 18:15:10 +08:00
|
|
|
end
|
|
|
|
|
2016-11-23 21:28:32 +08:00
|
|
|
def check_captcha
|
|
|
|
if Rails.configuration.x.enable_recaptcha
|
|
|
|
unless verify_recaptcha
|
|
|
|
self.resource = resource_class.new
|
|
|
|
resource.invitation_token = update_resource_params[:invitation_token]
|
|
|
|
respond_with_navigational(resource) { render :edit }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-01-23 16:17:27 +08:00
|
|
|
def check_captcha_for_invite
|
|
|
|
if Rails.configuration.x.enable_recaptcha
|
|
|
|
unless verify_recaptcha
|
|
|
|
render json: { recaptcha_error: t('invite_users.errors.recaptcha') },
|
|
|
|
status: :unprocessable_entity
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-11-06 18:29:00 +08:00
|
|
|
def check_invite_users_permission
|
|
|
|
@user = current_user
|
2022-01-05 06:40:08 +08:00
|
|
|
@emails = params[:emails]&.map(&:strip)&.map(&:downcase)
|
2021-07-05 18:39:54 +08:00
|
|
|
|
|
|
|
@teams = Team.where(id: params[:team_ids]).select { |team| can_manage_team_users?(team) }
|
2022-01-05 06:40:08 +08:00
|
|
|
return render_403 if params[:team_ids].present? && @teams.blank?
|
2021-07-05 18:39:54 +08:00
|
|
|
|
2022-05-19 15:04:25 +08:00
|
|
|
@user_role = UserRole.find_by(id: params[:role_id])
|
2016-11-03 18:27:17 +08:00
|
|
|
|
2019-08-14 20:47:02 +08:00
|
|
|
return render_403 if @emails.blank? # We must have at least one email
|
2016-11-06 18:29:00 +08:00
|
|
|
end
|
2016-11-03 18:27:17 +08:00
|
|
|
end
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|