diff --git a/Gemfile.lock b/Gemfile.lock index de348a2b5..06f479659 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -467,7 +467,7 @@ GEM mini_magick (4.12.0) mini_mime (1.1.5) mini_portile2 (2.8.7) - minitest (5.24.1) + minitest (5.25.1) mock_redis (0.36.0) ruby2_keywords msgpack (1.7.0) @@ -480,7 +480,7 @@ GEM uri net-http-persistent (4.0.2) connection_pool (~> 2.2) - net-imap (0.4.12) + net-imap (0.4.14) date net-protocol net-pop (0.1.2) @@ -634,7 +634,7 @@ GEM retriable (3.1.2) reverse_markdown (2.1.1) nokogiri - rexml (3.3.4) + rexml (3.3.6) strscan rspec-core (3.13.0) rspec-support (~> 3.13.0) @@ -796,7 +796,7 @@ GEM uniform_notifier (1.16.0) uri (0.13.0) uri_template (0.7.0) - valid_email2 (4.0.6) + valid_email2 (5.2.6) activemodel (>= 3.2) mail (~> 2.5) version_gem (1.1.4) diff --git a/app/builders/account_builder.rb b/app/builders/account_builder.rb index f179c6405..ff67eefc5 100644 --- a/app/builders/account_builder.rb +++ b/app/builders/account_builder.rb @@ -32,11 +32,13 @@ class AccountBuilder end def validate_email + raise InvalidEmail.new({ domain_blocked: domain_blocked }) if domain_blocked? + address = ValidEmail2::Address.new(@email) - if address.valid? # && !address.disposable? + if address.valid? && !address.disposable? true else - raise InvalidEmail.new(valid: address.valid?) + raise InvalidEmail.new({ valid: address.valid?, disposable: address.disposable? }) end end @@ -79,4 +81,21 @@ class AccountBuilder @user.confirm if @confirmed @user.save! end + + def domain_blocked? + domain = @email.split('@').last + + blocked_domains.each do |blocked_domain| + return true if domain.match?(blocked_domain) + end + + false + end + + def blocked_domains + domains = GlobalConfigService.load('BLOCKED_EMAIL_DOMAINS', '') + domains.split("\n").map(&:strip) if domains.present? + + [] + end end diff --git a/app/controllers/api/v1/accounts/agents_controller.rb b/app/controllers/api/v1/accounts/agents_controller.rb index 4eff10127..01aa42620 100644 --- a/app/controllers/api/v1/accounts/agents_controller.rb +++ b/app/controllers/api/v1/accounts/agents_controller.rb @@ -24,7 +24,7 @@ class Api::V1::Accounts::AgentsController < Api::V1::Accounts::BaseController def update @agent.update!(agent_params.slice(:name).compact) - @agent.current_account_user.update!(agent_params.slice(:role, :availability, :auto_offline).compact) + @agent.current_account_user.update!(agent_params.slice(*account_user_attributes).compact) end def destroy @@ -67,8 +67,16 @@ class Api::V1::Accounts::AgentsController < Api::V1::Accounts::BaseController @agent = agents.find(params[:id]) end + def account_user_attributes + [:role, :availability, :auto_offline] + end + + def allowed_agent_params + [:name, :email, :name, :role, :availability, :auto_offline] + end + def agent_params - params.require(:agent).permit(:name, :email, :name, :role, :availability, :auto_offline) + params.require(:agent).permit(allowed_agent_params) end def new_agent_params @@ -101,3 +109,5 @@ class Api::V1::Accounts::AgentsController < Api::V1::Accounts::BaseController DeleteObjectJob.perform_later(agent) if agent.reload.account_users.blank? end end + +Api::V1::Accounts::AgentsController.prepend_mod_with('Api::V1::Accounts::AgentsController') diff --git a/app/controllers/api/v1/accounts/integrations/hooks_controller.rb b/app/controllers/api/v1/accounts/integrations/hooks_controller.rb index d09ea2f00..087a9b78d 100644 --- a/app/controllers/api/v1/accounts/integrations/hooks_controller.rb +++ b/app/controllers/api/v1/accounts/integrations/hooks_controller.rb @@ -11,7 +11,17 @@ class Api::V1::Accounts::Integrations::HooksController < Api::V1::Accounts::Base end def process_event - render json: { message: @hook.process_event(params[:event]) } + response = @hook.process_event(params[:event]) + + # for cases like an invalid event, or when conversation does not have enough messages + # for a label suggestion, the response is nil + if response.nil? + render json: { message: nil } + elsif response[:error] + render json: { error: response[:error] }, status: :unprocessable_entity + else + render json: { message: response[:message] } + end end def destroy diff --git a/app/javascript/dashboard/components/ChatList.vue b/app/javascript/dashboard/components/ChatList.vue index fa95c5024..476fc7438 100644 --- a/app/javascript/dashboard/components/ChatList.vue +++ b/app/javascript/dashboard/components/ChatList.vue @@ -141,7 +141,7 @@ export default { allowOnFocusedInput: true, }, }; - useKeyboardEvents(keyboardEvents, conversationListRef); + useKeyboardEvents(keyboardEvents); return { uiSettings, diff --git a/app/javascript/dashboard/components/buttons/ResolveAction.vue b/app/javascript/dashboard/components/buttons/ResolveAction.vue index 7c4c4daaa..0ff363874 100644 --- a/app/javascript/dashboard/components/buttons/ResolveAction.vue +++ b/app/javascript/dashboard/components/buttons/ResolveAction.vue @@ -13,13 +13,12 @@ import wootConstants from 'dashboard/constants/globals'; import { CMD_REOPEN_CONVERSATION, CMD_RESOLVE_CONVERSATION, -} from 'dashboard/routes/dashboard/commands/commandBarBusEvents'; +} from 'dashboard/helper/commandbar/events'; const store = useStore(); const getters = useStoreGetters(); const { t } = useI18n(); -const resolveActionsRef = ref(null); const arrowDownButtonRef = ref(null); const isLoading = ref(false); @@ -131,17 +130,14 @@ const keyboardEvents = { }, }; -useKeyboardEvents(keyboardEvents, resolveActionsRef); +useKeyboardEvents(keyboardEvents); useEmitter(CMD_REOPEN_CONVERSATION, onCmdOpenConversation); useEmitter(CMD_RESOLVE_CONVERSATION, onCmdResolveConversation);