diff --git a/.codeclimate.yml b/.codeclimate.yml index c9910f9ed..916b98510 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -50,3 +50,6 @@ exclude_patterns: - 'app/javascript/dashboard/routes/dashboard/settings/automation/constants.js' - 'app/javascript/dashboard/components/widgets/FilterInput/FilterOperatorTypes.js' - 'app/javascript/dashboard/routes/dashboard/settings/reports/constants.js' + - 'app/javascript/dashboard/i18n/index.js' + - 'app/javascript/widget/i18n/index.js' + - 'app/javascript/survey/i18n/index.js' diff --git a/.eslintrc.js b/.eslintrc.js index a52594492..f30e21e03 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -29,8 +29,8 @@ module.exports = { 'vue/html-self-closing': 'off', "vue/no-v-html": 'off', 'vue/singleline-html-element-content-newline': 'off', - 'import/extensions': ['off'] - + 'import/extensions': ['off'], + 'no-console': 'error' }, settings: { 'import/resolver': { diff --git a/.rubocop.yml b/.rubocop.yml index e0c98cdc4..c3096dd4a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -16,6 +16,7 @@ Metrics/ClassLength: - 'app/models/message.rb' - 'app/builders/messages/facebook/message_builder.rb' - 'app/controllers/api/v1/accounts/contacts_controller.rb' + - 'app/listeners/action_cable_listener.rb' RSpec/ExampleLength: Max: 25 Style/Documentation: diff --git a/Gemfile b/Gemfile index 0664e5aef..297a88497 100644 --- a/Gemfile +++ b/Gemfile @@ -42,7 +42,7 @@ gem 'down', '~> 5.0' gem 'aws-sdk-s3', require: false gem 'azure-storage-blob', require: false gem 'google-cloud-storage', require: false -gem 'image_processing' +gem 'image_processing', '~> 1.12.2' ##-- gems for database --# gem 'groupdate' diff --git a/Gemfile.lock b/Gemfile.lock index 2222403f1..eb6022ac7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -688,7 +688,7 @@ DEPENDENCIES hairtrigger hashie html2text - image_processing + image_processing (~> 1.12.2) jbuilder json_refs json_schemer diff --git a/app/controllers/api/v1/accounts/automation_rules_controller.rb b/app/controllers/api/v1/accounts/automation_rules_controller.rb index 2dc71bcec..3971dbcaf 100644 --- a/app/controllers/api/v1/accounts/automation_rules_controller.rb +++ b/app/controllers/api/v1/accounts/automation_rules_controller.rb @@ -34,7 +34,7 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont params.permit( :name, :description, :event_name, :account_id, :active, conditions: [:attribute_key, :filter_operator, :query_operator, { values: [] }], - actions: [:action_name, { action_params: [] }] + actions: [:action_name, { action_params: [{}] }] ) end diff --git a/app/controllers/api/v1/accounts/base_controller.rb b/app/controllers/api/v1/accounts/base_controller.rb index ddb0f44f4..e30effc59 100644 --- a/app/controllers/api/v1/accounts/base_controller.rb +++ b/app/controllers/api/v1/accounts/base_controller.rb @@ -1,32 +1,6 @@ class Api::V1::Accounts::BaseController < Api::BaseController include SwitchLocale + include EnsureCurrentAccountHelper before_action :current_account around_action :switch_locale_using_account_locale - - private - - def current_account - @current_account ||= ensure_current_account - Current.account = @current_account - end - - def ensure_current_account - account = Account.find(params[:account_id]) - if current_user - account_accessible_for_user?(account) - elsif @resource.is_a?(AgentBot) - account_accessible_for_bot?(account) - end - account - end - - def account_accessible_for_user?(account) - @current_account_user = account.account_users.find_by(user_id: current_user.id) - Current.account_user = @current_account_user - render_unauthorized('You are not authorized to access this account') unless @current_account_user - end - - def account_accessible_for_bot?(account) - render_unauthorized('You are not authorized to access this account') unless @resource.agent_bot_inboxes.find_by(account_id: account.id) - end end diff --git a/app/controllers/api/v1/accounts/conversations/base_controller.rb b/app/controllers/api/v1/accounts/conversations/base_controller.rb index f521719ae..b55b72013 100644 --- a/app/controllers/api/v1/accounts/conversations/base_controller.rb +++ b/app/controllers/api/v1/accounts/conversations/base_controller.rb @@ -1,4 +1,5 @@ class Api::V1::Accounts::Conversations::BaseController < Api::V1::Accounts::BaseController + include EnsureCurrentAccountHelper before_action :conversation private diff --git a/app/controllers/api/v1/accounts/conversations/direct_uploads_controller.rb b/app/controllers/api/v1/accounts/conversations/direct_uploads_controller.rb new file mode 100644 index 000000000..f4ac05d6e --- /dev/null +++ b/app/controllers/api/v1/accounts/conversations/direct_uploads_controller.rb @@ -0,0 +1,17 @@ +class Api::V1::Accounts::Conversations::DirectUploadsController < ActiveStorage::DirectUploadsController + include EnsureCurrentAccountHelper + before_action :current_account + before_action :conversation + + def create + return if @conversation.nil? || @current_account.nil? + + super + end + + private + + def conversation + @conversation ||= Current.account.conversations.find_by(display_id: params[:conversation_id]) + end +end diff --git a/app/controllers/api/v1/accounts/inboxes_controller.rb b/app/controllers/api/v1/accounts/inboxes_controller.rb index 2bda5c07a..bcea2d9d7 100644 --- a/app/controllers/api/v1/accounts/inboxes_controller.rb +++ b/app/controllers/api/v1/accounts/inboxes_controller.rb @@ -48,7 +48,10 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController # Inbox update doesn't necessarily need channel attributes return if permitted_params(channel_attributes)[:channel].blank? - validate_email_channel(channel_attributes) if @inbox.inbox_type == 'Email' + if @inbox.inbox_type == 'Email' + validate_email_channel(channel_attributes) + @inbox.channel.reauthorized! + end @inbox.channel.update!(permitted_params(channel_attributes)[:channel]) update_channel_feature_flags diff --git a/app/controllers/api/v1/widget/base_controller.rb b/app/controllers/api/v1/widget/base_controller.rb index 0a50835bc..8df4737db 100644 --- a/app/controllers/api/v1/widget/base_controller.rb +++ b/app/controllers/api/v1/widget/base_controller.rb @@ -1,5 +1,6 @@ class Api::V1::Widget::BaseController < ApplicationController include SwitchLocale + include WebsiteTokenHelper before_action :set_web_widget before_action :set_contact @@ -19,25 +20,6 @@ class Api::V1::Widget::BaseController < ApplicationController @conversation ||= conversations.last end - def auth_token_params - @auth_token_params ||= ::Widget::TokenService.new(token: request.headers['X-Auth-Token']).decode_token - end - - def set_web_widget - @web_widget = ::Channel::WebWidget.find_by!(website_token: permitted_params[:website_token]) - @current_account = @web_widget.account - end - - def set_contact - @contact_inbox = @web_widget.inbox.contact_inboxes.find_by( - source_id: auth_token_params[:source_id] - ) - @contact = @contact_inbox&.contact - raise ActiveRecord::RecordNotFound unless @contact - - Current.contact = @contact - end - def create_conversation ::Conversation.create!(conversation_params) end @@ -96,10 +78,6 @@ class Api::V1::Widget::BaseController < ApplicationController { timestamp: permitted_params[:message][:timestamp] } end - def permitted_params - params.permit(:website_token) - end - def message_params { account_id: conversation.account_id, diff --git a/app/controllers/api/v1/widget/conversations_controller.rb b/app/controllers/api/v1/widget/conversations_controller.rb index e2ee61424..cc1b16b75 100644 --- a/app/controllers/api/v1/widget/conversations_controller.rb +++ b/app/controllers/api/v1/widget/conversations_controller.rb @@ -47,7 +47,7 @@ class Api::V1::Widget::ConversationsController < Api::V1::Widget::BaseController def toggle_status head :not_found && return if conversation.nil? unless conversation.resolved? - conversation.status = 'resolved' + conversation.status = :resolved conversation.save end head :ok diff --git a/app/controllers/api/v1/widget/direct_uploads_controller.rb b/app/controllers/api/v1/widget/direct_uploads_controller.rb new file mode 100644 index 000000000..a6abdb3e1 --- /dev/null +++ b/app/controllers/api/v1/widget/direct_uploads_controller.rb @@ -0,0 +1,11 @@ +class Api::V1::Widget::DirectUploadsController < ActiveStorage::DirectUploadsController + include WebsiteTokenHelper + before_action :set_web_widget + before_action :set_contact + + def create + return if @contact.nil? || @current_account.nil? + + super + end +end diff --git a/app/controllers/concerns/ensure_current_account_helper.rb b/app/controllers/concerns/ensure_current_account_helper.rb new file mode 100644 index 000000000..dccc64350 --- /dev/null +++ b/app/controllers/concerns/ensure_current_account_helper.rb @@ -0,0 +1,28 @@ +module EnsureCurrentAccountHelper + private + + def current_account + @current_account ||= ensure_current_account + Current.account = @current_account + end + + def ensure_current_account + account = Account.find(params[:account_id]) + if current_user + account_accessible_for_user?(account) + elsif @resource.is_a?(AgentBot) + account_accessible_for_bot?(account) + end + account + end + + def account_accessible_for_user?(account) + @current_account_user = account.account_users.find_by(user_id: current_user.id) + Current.account_user = @current_account_user + render_unauthorized('You are not authorized to access this account') unless @current_account_user + end + + def account_accessible_for_bot?(account) + render_unauthorized('You are not authorized to access this account') unless @resource.agent_bot_inboxes.find_by(account_id: account.id) + end +end diff --git a/app/controllers/concerns/website_token_helper.rb b/app/controllers/concerns/website_token_helper.rb new file mode 100644 index 000000000..0158a4107 --- /dev/null +++ b/app/controllers/concerns/website_token_helper.rb @@ -0,0 +1,24 @@ +module WebsiteTokenHelper + def auth_token_params + @auth_token_params ||= ::Widget::TokenService.new(token: request.headers['X-Auth-Token']).decode_token + end + + def set_web_widget + @web_widget = ::Channel::WebWidget.find_by!(website_token: permitted_params[:website_token]) + @current_account = @web_widget.account + end + + def set_contact + @contact_inbox = @web_widget.inbox.contact_inboxes.find_by( + source_id: auth_token_params[:source_id] + ) + @contact = @contact_inbox&.contact + raise ActiveRecord::RecordNotFound unless @contact + + Current.contact = @contact + end + + def permitted_params + params.permit(:website_token) + end +end diff --git a/app/controllers/platform/api/v1/users_controller.rb b/app/controllers/platform/api/v1/users_controller.rb index 960dee0e3..bf5b642f8 100644 --- a/app/controllers/platform/api/v1/users_controller.rb +++ b/app/controllers/platform/api/v1/users_controller.rb @@ -9,7 +9,7 @@ class Platform::Api::V1::UsersController < PlatformController @resource = (User.find_by(email: user_params[:email]) || User.new(user_params)) @resource.save! @resource.confirm - @platform_app.platform_app_permissibles.find_or_create_by(permissible: @resource) + @platform_app.platform_app_permissibles.find_or_create_by!(permissible: @resource) end def login diff --git a/app/javascript/dashboard/assets/scss/_foundation-custom.scss b/app/javascript/dashboard/assets/scss/_foundation-custom.scss index 3b7eca0f7..650fa884d 100644 --- a/app/javascript/dashboard/assets/scss/_foundation-custom.scss +++ b/app/javascript/dashboard/assets/scss/_foundation-custom.scss @@ -26,7 +26,8 @@ code { border: 0; - font-family: 'Monaco', Verdana; + font-family: 'ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', + '"Liberation Mono"', '"Courier New"', 'monospace'; font-size: $font-size-mini; &.hljs { @@ -55,7 +56,6 @@ code { padding-right: var(--space-normal); } - .badge { border-radius: var(--border-radius-normal); } diff --git a/app/javascript/dashboard/components/widgets/AttachmentsPreview.vue b/app/javascript/dashboard/components/widgets/AttachmentsPreview.vue index 3d5846215..0264748a9 100644 --- a/app/javascript/dashboard/components/widgets/AttachmentsPreview.vue +++ b/app/javascript/dashboard/components/widgets/AttachmentsPreview.vue @@ -1,5 +1,5 @@