diff --git a/.env.example b/.env.example index b7ba0920d..2ab2933dc 100644 --- a/.env.example +++ b/.env.example @@ -2,7 +2,7 @@ # https://www.chatwoot.com/docs/self-hosted/configuration/environment-variables/#rails-production-variables # Used to verify the integrity of signed cookies. so ensure a secure value is set -# SECRET_KEY_BASE should be alphanumeric. Avoid special characters or symbols. +# SECRET_KEY_BASE should be alphanumeric. Avoid special characters or symbols. # Use `rake secret` to generate this variable SECRET_KEY_BASE=replace_with_lengthy_secure_hex @@ -216,6 +216,8 @@ ANDROID_SHA256_CERT_FINGERPRINT=AC:73:8E:DE:EB:56:EA:CC:10:87:02:A7:65:37:7B:38: # ENABLE_RACK_ATTACK=true # RACK_ATTACK_LIMIT=300 # ENABLE_RACK_ATTACK_WIDGET_API=true +# Comma-separated list of trusted IPs that bypass Rack Attack throttling rules +# RACK_ATTACK_ALLOWED_IPS=127.0.0.1,::1,192.168.0.10 ## Running chatwoot as an API only server ## setting this value to true will disable the frontend dashboard endpoints @@ -257,4 +259,3 @@ AZURE_APP_SECRET= # Set to true if you want to remove stale contact inboxes # contact_inboxes with no conversation older than 90 days will be removed # REMOVE_STALE_CONTACT_INBOX_JOB_STATUS=false - diff --git a/Gemfile.lock b/Gemfile.lock index d3ef47631..da19dbb72 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -567,7 +567,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (2.2.13) + rack (2.2.14) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-contrib (2.5.0) diff --git a/app/controllers/api/v1/accounts/custom_filters_controller.rb b/app/controllers/api/v1/accounts/custom_filters_controller.rb index f458c018f..b4345bb8a 100644 --- a/app/controllers/api/v1/accounts/custom_filters_controller.rb +++ b/app/controllers/api/v1/accounts/custom_filters_controller.rb @@ -1,6 +1,6 @@ class Api::V1::Accounts::CustomFiltersController < Api::V1::Accounts::BaseController before_action :check_authorization - before_action :fetch_custom_filters, except: [:create] + before_action :fetch_custom_filters, only: [:index] before_action :fetch_custom_filter, only: [:show, :update, :destroy] DEFAULT_FILTER_TYPE = 'conversation'.freeze @@ -9,8 +9,8 @@ class Api::V1::Accounts::CustomFiltersController < Api::V1::Accounts::BaseContro def show; end def create - @custom_filter = current_user.custom_filters.create!( - permitted_payload.merge(account_id: Current.account.id) + @custom_filter = Current.account.custom_filters.create!( + permitted_payload.merge(user: Current.user) ) render json: { error: @custom_filter.errors.messages }, status: :unprocessable_entity and return unless @custom_filter.valid? end @@ -27,14 +27,16 @@ class Api::V1::Accounts::CustomFiltersController < Api::V1::Accounts::BaseContro private def fetch_custom_filters - @custom_filters = current_user.custom_filters.where( - account_id: Current.account.id, + @custom_filters = Current.account.custom_filters.where( + user: Current.user, filter_type: permitted_params[:filter_type] || DEFAULT_FILTER_TYPE ) end def fetch_custom_filter - @custom_filter = @custom_filters.find(permitted_params[:id]) + @custom_filter = Current.account.custom_filters.where( + user: Current.user + ).find(permitted_params[:id]) end def permitted_payload diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index c0dac6d9e..c610dc846 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -44,8 +44,9 @@ class Api::V1::AccountsController < Api::BaseController end def update - @account.assign_attributes(account_params.slice(:name, :locale, :domain, :support_email, :auto_resolve_duration)) + @account.assign_attributes(account_params.slice(:name, :locale, :domain, :support_email)) @account.custom_attributes.merge!(custom_attributes_params) + @account.settings.merge!(settings_params) @account.custom_attributes['onboarding_step'] = 'invite_team' if @account.custom_attributes['onboarding_step'] == 'account_update' @account.save! end @@ -83,13 +84,17 @@ class Api::V1::AccountsController < Api::BaseController end def account_params - params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :auto_resolve_duration, :user_full_name) + params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :user_full_name) end def custom_attributes_params params.permit(:industry, :company_size, :timezone) end + def settings_params + params.permit(:auto_resolve_after, :auto_resolve_message, :auto_resolve_ignore_waiting) + end + def check_signup_enabled raise ActionController::RoutingError, 'Not Found' if GlobalConfigService.load('ENABLE_ACCOUNT_SIGNUP', 'false') == 'false' end diff --git a/app/controllers/api/v1/widget/campaigns_controller.rb b/app/controllers/api/v1/widget/campaigns_controller.rb index 10a73aa62..9cf8dcb6e 100644 --- a/app/controllers/api/v1/widget/campaigns_controller.rb +++ b/app/controllers/api/v1/widget/campaigns_controller.rb @@ -2,10 +2,15 @@ class Api::V1::Widget::CampaignsController < Api::V1::Widget::BaseController skip_before_action :set_contact def index - @campaigns = @web_widget - .inbox - .campaigns - .where(enabled: true, account_id: @web_widget.inbox.account_id) - .includes(:sender) + account = @web_widget.inbox.account + @campaigns = if account.feature_enabled?('campaigns') + @web_widget + .inbox + .campaigns + .where(enabled: true, account_id: account.id) + .includes(:sender) + else + [] + end end end diff --git a/app/controllers/api/v2/accounts_controller.rb b/app/controllers/api/v2/accounts_controller.rb index 45faca3d0..bed0a212a 100644 --- a/app/controllers/api/v2/accounts_controller.rb +++ b/app/controllers/api/v2/accounts_controller.rb @@ -54,7 +54,7 @@ class Api::V2::AccountsController < Api::BaseController end def account_params - params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :auto_resolve_duration, :user_full_name) + params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :user_full_name) end def check_signup_enabled diff --git a/app/controllers/concerns/access_token_auth_helper.rb b/app/controllers/concerns/access_token_auth_helper.rb index 2ee9f9854..9b0f9021f 100644 --- a/app/controllers/concerns/access_token_auth_helper.rb +++ b/app/controllers/concerns/access_token_auth_helper.rb @@ -1,6 +1,6 @@ module AccessTokenAuthHelper BOT_ACCESSIBLE_ENDPOINTS = { - 'api/v1/accounts/conversations' => %w[toggle_status toggle_priority create update], + 'api/v1/accounts/conversations' => %w[toggle_status toggle_priority create update custom_attributes], 'api/v1/accounts/conversations/messages' => ['create'], 'api/v1/accounts/conversations/assignments' => ['create'] }.freeze diff --git a/app/javascript/dashboard/components-next/captain/assistant/MessageList.vue b/app/javascript/dashboard/components-next/captain/assistant/MessageList.vue index 1d6529a45..3eca35744 100644 --- a/app/javascript/dashboard/components-next/captain/assistant/MessageList.vue +++ b/app/javascript/dashboard/components-next/captain/assistant/MessageList.vue @@ -65,7 +65,7 @@ watch(() => props.messages.length, scrollToBottom); class="max-w-[80%] rounded-lg p-3 text-sm" :class="getMessageStyle(message.sender)" > -
+
diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/assistant/EditAssistantForm.vue b/app/javascript/dashboard/components-next/captain/pageComponents/assistant/EditAssistantForm.vue index 3a668a757..249051878 100644 --- a/app/javascript/dashboard/components-next/captain/pageComponents/assistant/EditAssistantForm.vue +++ b/app/javascript/dashboard/components-next/captain/pageComponents/assistant/EditAssistantForm.vue @@ -214,7 +214,7 @@ watch( v-model="state.instructions" :placeholder="t('CAPTAIN.ASSISTANTS.FORM.INSTRUCTIONS.PLACEHOLDER')" :message="formErrors.instructions" - :max-length="2000" + :max-length="20000" :message-type="formErrors.instructions ? 'error' : 'info'" /> diff --git a/app/javascript/dashboard/components-next/copilot/Copilot.vue b/app/javascript/dashboard/components-next/copilot/Copilot.vue index e284bb983..5feb474a6 100644 --- a/app/javascript/dashboard/components-next/copilot/Copilot.vue +++ b/app/javascript/dashboard/components-next/copilot/Copilot.vue @@ -1,5 +1,6 @@