mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FIX: ensures users can open channel invites (#24067)
We were incorrectly generating URLs with message id even when it was not provided, resulting in a route ending with "undefined", which was causing an error. This commit also uses this opportunity to: - move `invite_users` into a proper controller inside the API namespace - refactors the code into a service: `Chat::InviteUsersToChannel`
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Chat::Api::ChannelsInvitesController < Chat::ApiController
|
||||
def create
|
||||
with_service(Chat::InviteUsersToChannel) do
|
||||
on_failed_policy(:can_view_channel) { raise Discourse::InvalidAccess }
|
||||
on_model_not_found(:channel) { raise Discourse::NotFound }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -114,37 +114,6 @@ module Chat
|
||||
render json: { chat_enabled: current_user.user_option.chat_enabled }
|
||||
end
|
||||
|
||||
def invite_users
|
||||
params.require(:user_ids)
|
||||
|
||||
users =
|
||||
User
|
||||
.includes(:groups)
|
||||
.joins(:user_option)
|
||||
.where(user_options: { chat_enabled: true })
|
||||
.not_suspended
|
||||
.where(id: params[:user_ids])
|
||||
users.each do |user|
|
||||
if user.guardian.can_join_chat_channel?(@chat_channel)
|
||||
data = {
|
||||
message: "chat.invitation_notification",
|
||||
chat_channel_id: @chat_channel.id,
|
||||
chat_channel_title: @chat_channel.title(user),
|
||||
chat_channel_slug: @chat_channel.slug,
|
||||
invited_by_username: current_user.username,
|
||||
}
|
||||
data[:chat_message_id] = params[:chat_message_id] if params[:chat_message_id]
|
||||
user.notifications.create(
|
||||
notification_type: Notification.types[:chat_invitation],
|
||||
high_priority: true,
|
||||
data: data.to_json,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
render json: success_json
|
||||
end
|
||||
|
||||
def dismiss_retention_reminder
|
||||
params.require(:chatable_type)
|
||||
guardian.ensure_can_chat!
|
||||
|
||||
@@ -9,7 +9,7 @@ module Chat
|
||||
class CreateThread
|
||||
include Service::Base
|
||||
|
||||
# @!method call(thread_id:, channel_id:, guardian:, **params_to_edit)
|
||||
# @!method call(thread_id:, channel_id:, guardian:, **params_to_create)
|
||||
# @param [Integer] original_message_id
|
||||
# @param [Integer] channel_id
|
||||
# @param [Guardian] guardian
|
||||
|
||||
76
plugins/chat/app/services/chat/invite_users_to_channel.rb
Normal file
76
plugins/chat/app/services/chat/invite_users_to_channel.rb
Normal file
@@ -0,0 +1,76 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Chat
|
||||
# Invites users to a channel.
|
||||
#
|
||||
# @example
|
||||
# Chat::InviteUsersToChannel.call(channel_id: 2, user_ids: [2, 43], guardian: guardian, **optional_params)
|
||||
#
|
||||
class InviteUsersToChannel
|
||||
include Service::Base
|
||||
|
||||
# @!method call(user_ids:, channel_id:, guardian:)
|
||||
# @param [Array<Integer>] user_ids
|
||||
# @param [Integer] channel_id
|
||||
# @param [Guardian] guardian
|
||||
# @option optional_params [Integer, nil] message_id
|
||||
# @return [Service::Base::Context]
|
||||
|
||||
contract
|
||||
model :channel
|
||||
policy :can_view_channel
|
||||
model :users, optional: true
|
||||
step :send_invite_notifications
|
||||
|
||||
# @!visibility private
|
||||
class Contract
|
||||
attribute :user_ids, :array
|
||||
validates :user_ids, presence: true
|
||||
|
||||
attribute :channel_id, :integer
|
||||
validates :channel_id, presence: true
|
||||
|
||||
attribute :message_id, :integer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_channel(contract:, **)
|
||||
::Chat::Channel.find_by(id: contract.channel_id)
|
||||
end
|
||||
|
||||
def can_view_channel(guardian:, channel:, **)
|
||||
guardian.can_preview_chat_channel?(channel)
|
||||
end
|
||||
|
||||
def fetch_users(contract:, **)
|
||||
::User
|
||||
.joins(:user_option)
|
||||
.where(user_options: { chat_enabled: true })
|
||||
.not_suspended
|
||||
.where(id: contract.user_ids)
|
||||
.limit(50)
|
||||
end
|
||||
|
||||
def send_invite_notifications(channel:, guardian:, users:, contract:, **)
|
||||
users&.each do |invited_user|
|
||||
next if !invited_user.guardian.can_join_chat_channel?(channel)
|
||||
|
||||
data = {
|
||||
message: "chat.invitation_notification",
|
||||
chat_channel_id: channel.id,
|
||||
chat_channel_title: channel.title(invited_user),
|
||||
chat_channel_slug: channel.slug,
|
||||
invited_by_username: guardian.user.username,
|
||||
}
|
||||
data[:chat_message_id] = contract.message_id if contract.message_id
|
||||
|
||||
invited_user.notifications.create(
|
||||
notification_type: ::Notification.types[:chat_invitation],
|
||||
high_priority: true,
|
||||
data: data.to_json,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user