From a13a474c239c77d523cf95ec5b6404396bdcf940 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Fri, 5 Jun 2020 00:15:50 +0530 Subject: [PATCH 01/50] Chore: Firebase Cloud Messaging Support (#858) --- .env.example | 3 ++ Gemfile | 1 + Gemfile.lock | 3 ++ .../notification_subscription_builder.rb | 2 ++ app/models/notification_subscription.rb | 2 +- .../notification/push_notification_service.rb | 18 ++++++++++- .../push_notification_service_spec.rb | 32 +++++++++++++++++++ 7 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 spec/services/notification/push_notification_service_spec.rb diff --git a/.env.example b/.env.example index d4fb1ea12..e8ec635f0 100644 --- a/.env.example +++ b/.env.example @@ -102,6 +102,9 @@ CHARGEBEE_WEBHOOK_PASSWORD= ## generate a new key value here : https://d3v.one/vapid-key-generator/ # VAPID_PUBLIC_KEY= # VAPID_PRIVATE_KEY= +# +# for mobile apps +# FCM_SERVER_KEY= ## Bot Customizations USE_INBOX_AVATAR_FOR_BOT=true diff --git a/Gemfile b/Gemfile index 50e3e2ce8..6d16179ea 100644 --- a/Gemfile +++ b/Gemfile @@ -84,6 +84,7 @@ gem 'sidekiq' gem 'flag_shih_tzu' ##-- Push notification service --## +gem 'fcm' gem 'webpush' group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 48e4e12a8..d8979b903 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -189,6 +189,8 @@ GEM multipart-post (>= 1.2, < 3) faraday_middleware (1.0.0) faraday (~> 1.0) + fcm (1.0.1) + faraday (~> 1.0.0) ffi (1.12.2) flag_shih_tzu (0.3.23) foreman (0.87.1) @@ -547,6 +549,7 @@ DEPENDENCIES facebook-messenger factory_bot_rails faker + fcm flag_shih_tzu foreman google-cloud-storage diff --git a/app/builders/notification_subscription_builder.rb b/app/builders/notification_subscription_builder.rb index 05b0bf984..3326b5cde 100644 --- a/app/builders/notification_subscription_builder.rb +++ b/app/builders/notification_subscription_builder.rb @@ -12,6 +12,8 @@ class NotificationSubscriptionBuilder def identifier @identifier ||= params[:subscription_attributes][:endpoint] if params[:subscription_type] == 'browser_push' + @identifier ||= params[:device_id] if params[:subscription_type] == 'fcm' + @identifier end def identifier_subscription diff --git a/app/models/notification_subscription.rb b/app/models/notification_subscription.rb index 534bced01..dbe148f71 100644 --- a/app/models/notification_subscription.rb +++ b/app/models/notification_subscription.rb @@ -22,7 +22,7 @@ class NotificationSubscription < ApplicationRecord SUBSCRIPTION_TYPES = { browser_push: 1, - gcm: 2 + fcm: 2 }.freeze enum subscription_type: SUBSCRIPTION_TYPES diff --git a/app/services/notification/push_notification_service.rb b/app/services/notification/push_notification_service.rb index e01d19679..c29796d64 100644 --- a/app/services/notification/push_notification_service.rb +++ b/app/services/notification/push_notification_service.rb @@ -7,7 +7,8 @@ class Notification::PushNotificationService return unless user_subscribed_to_notification? notification_subscriptions.each do |subscription| - send_browser_push(subscription) if subscription.browser_push? + send_browser_push(subscription) + send_fcm_push(subscription) end end @@ -53,6 +54,8 @@ class Notification::PushNotificationService end def send_browser_push(subscription) + return unless subscription.browser_push? + Webpush.payload_send( message: JSON.generate(push_message), endpoint: subscription.subscription_attributes['endpoint'], @@ -70,4 +73,17 @@ class Notification::PushNotificationService rescue Webpush::ExpiredSubscription subscription.destroy! end + + def send_fcm_push(subscription) + return unless subscription.fcm? + + fcm = FCM.new(ENV['FCM_SERVER_KEY']) + options = { "notification": { + "title": notification.notification_type.titleize, + "body": push_message_title, + "notification": notification.to_json + } } + response = fcm.send([subscription.subscription_attributes['push_token']], options) + subscription.destroy! if JSON.parse(response[:body])['results']&.first&.keys&.include?('error') + end end diff --git a/spec/services/notification/push_notification_service_spec.rb b/spec/services/notification/push_notification_service_spec.rb new file mode 100644 index 000000000..67fc9f999 --- /dev/null +++ b/spec/services/notification/push_notification_service_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +describe Notification::PushNotificationService do + let!(:account) { create(:account) } + let!(:user) { create(:user, account: account) } + let!(:notification) { create(:notification, user: user, account: user.accounts.first) } + let(:fcm_double) { double } + + before do + allow(Webpush).to receive(:payload_send).and_return(true) + allow(FCM).to receive(:new).and_return(fcm_double) + allow(fcm_double).to receive(:send).and_return({ body: { 'results': [] }.to_json }) + end + + describe '#perform' do + it 'sends webpush notifications for webpush subscription' do + create(:notification_subscription, user: notification.user) + + described_class.new(notification: notification).perform + expect(Webpush).to have_received(:payload_send) + expect(FCM).not_to have_received(:new) + end + + it 'sends a fcm notification for firebase subscription' do + create(:notification_subscription, user: notification.user, subscription_type: 'fcm') + + described_class.new(notification: notification).perform + expect(FCM).to have_received(:new) + expect(Webpush).not_to have_received(:payload_send) + end + end +end From b7f7b54f9be055173ebe56c543dd245f740ed7be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2020 15:56:54 +0530 Subject: [PATCH 02/50] Chore: Bump websocket-extensions from 0.1.4 to 0.1.5 (#928) Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-ruby) from 0.1.4 to 0.1.5. - [Release notes](https://github.com/faye/websocket-extensions-ruby/releases) - [Changelog](https://github.com/faye/websocket-extensions-ruby/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-ruby/compare/0.1.4...0.1.5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d8979b903..dffbfb1f3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -521,7 +521,7 @@ GEM jwt (~> 2.0) websocket-driver (0.7.1) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.4) + websocket-extensions (0.1.5) wisper (2.0.0) zeitwerk (2.3.0) From ede4dd9cb00b23c3107811ef3744db36ce2f4ed0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2020 18:56:58 +0530 Subject: [PATCH 03/50] Chore: Bump websocket-extensions from 0.1.3 to 0.1.4 (#929) Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. - [Release notes](https://github.com/faye/websocket-extensions-node/releases) - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 60dfd4fec..d78e760f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10555,9 +10555,9 @@ websocket-driver@>=0.5.1: websocket-extensions ">=0.1.1" websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: version "1.0.5" From 915eefdc366937e7e74ba1b014861b97516ccd92 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Sat, 6 Jun 2020 20:53:30 +0530 Subject: [PATCH 04/50] Bugfix: FCM push subscription builder fix (#930) --- app/builders/notification_subscription_builder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/builders/notification_subscription_builder.rb b/app/builders/notification_subscription_builder.rb index 3326b5cde..c1574bfc1 100644 --- a/app/builders/notification_subscription_builder.rb +++ b/app/builders/notification_subscription_builder.rb @@ -12,7 +12,7 @@ class NotificationSubscriptionBuilder def identifier @identifier ||= params[:subscription_attributes][:endpoint] if params[:subscription_type] == 'browser_push' - @identifier ||= params[:device_id] if params[:subscription_type] == 'fcm' + @identifier ||= params[:subscription_attributes][:device_id] if params[:subscription_type] == 'fcm' @identifier end From 3d84568a37ddecf8236018b8a67ffbe20c27f936 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Sun, 7 Jun 2020 11:17:13 +0530 Subject: [PATCH 05/50] Feature: Label APIs (#931) --- .../api/v1/accounts/labels_controller.rb | 36 ++++++++- app/models/account.rb | 1 + app/models/label.rb | 20 +++++ app/policies/label_policy.rb | 17 ++++ .../v1/accounts/labels/create.json.jbuilder | 5 ++ .../v1/accounts/labels/index.json.jbuilder | 13 +-- .../accounts/labels/most_used.json.jbuilder | 3 - .../api/v1/accounts/labels/show.json.jbuilder | 5 ++ .../v1/accounts/labels/update.json.jbuilder | 5 ++ config/routes.rb | 6 +- db/migrate/20200606132552_create_labels.rb | 13 +++ db/schema.rb | 13 ++- .../api/v1/accounts/labels_controller_spec.rb | 81 ++++++++++++++----- spec/factories/labels.rb | 8 ++ spec/models/label_spec.rb | 7 ++ 15 files changed, 196 insertions(+), 37 deletions(-) create mode 100644 app/models/label.rb create mode 100644 app/policies/label_policy.rb create mode 100644 app/views/api/v1/accounts/labels/create.json.jbuilder delete mode 100644 app/views/api/v1/accounts/labels/most_used.json.jbuilder create mode 100644 app/views/api/v1/accounts/labels/show.json.jbuilder create mode 100644 app/views/api/v1/accounts/labels/update.json.jbuilder create mode 100644 db/migrate/20200606132552_create_labels.rb create mode 100644 spec/factories/labels.rb create mode 100644 spec/models/label_spec.rb diff --git a/app/controllers/api/v1/accounts/labels_controller.rb b/app/controllers/api/v1/accounts/labels_controller.rb index c9f15bdae..5db0fb87b 100644 --- a/app/controllers/api/v1/accounts/labels_controller.rb +++ b/app/controllers/api/v1/accounts/labels_controller.rb @@ -1,10 +1,38 @@ class Api::V1::Accounts::LabelsController < Api::BaseController - # list all labels in account + before_action :current_account + before_action :fetch_label, except: [:index, :create] + before_action :check_authorization + def index - @labels = current_account.all_conversation_tags + @labels = policy_scope(current_account.labels) end - def most_used - @labels = ActsAsTaggableOn::Tag.most_used(params[:count] || 10) + def show; end + + def create + @label = current_account.labels.create!(permitted_params) + end + + def update + @label.update(permitted_params) + end + + def destroy + @label.destroy + head :ok + end + + private + + def fetch_label + @label = current_account.labels.find(params[:id]) + end + + def check_authorization + authorize(Label) + end + + def permitted_params + params.require(:label).permit(:title, :description, :color, :show_on_sidebar) end end diff --git a/app/models/account.rb b/app/models/account.rb index 42dcf75ae..dbae201d3 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -45,6 +45,7 @@ class Account < ApplicationRecord has_many :web_widgets, dependent: :destroy, class_name: '::Channel::WebWidget' has_many :canned_responses, dependent: :destroy has_many :webhooks, dependent: :destroy + has_many :labels, dependent: :destroy has_one :subscription, dependent: :destroy has_many :notification_settings, dependent: :destroy has_flags ACCOUNT_SETTINGS_FLAGS.merge(column: 'settings_flags').merge(DEFAULT_QUERY_SETTING) diff --git a/app/models/label.rb b/app/models/label.rb new file mode 100644 index 000000000..087e07637 --- /dev/null +++ b/app/models/label.rb @@ -0,0 +1,20 @@ +# == Schema Information +# +# Table name: labels +# +# id :bigint not null, primary key +# color :string +# description :text +# show_on_sidebar :boolean +# title :string +# created_at :datetime not null +# updated_at :datetime not null +# account_id :bigint +# +# Indexes +# +# index_labels_on_account_id (account_id) +# +class Label < ApplicationRecord + belongs_to :account +end diff --git a/app/policies/label_policy.rb b/app/policies/label_policy.rb new file mode 100644 index 000000000..986044ce6 --- /dev/null +++ b/app/policies/label_policy.rb @@ -0,0 +1,17 @@ +class LabelPolicy < ApplicationPolicy + def index? + @account_user.administrator? + end + + def update? + @account_user.administrator? + end + + def show? + @account_user.administrator? + end + + def create? + @account_user.administrator? + end +end diff --git a/app/views/api/v1/accounts/labels/create.json.jbuilder b/app/views/api/v1/accounts/labels/create.json.jbuilder new file mode 100644 index 000000000..edeff661f --- /dev/null +++ b/app/views/api/v1/accounts/labels/create.json.jbuilder @@ -0,0 +1,5 @@ +json.id @label.id +json.title @label.title +json.description @label.description +json.color @label.color +json.show_on_sidebar @label.show_on_sidebar diff --git a/app/views/api/v1/accounts/labels/index.json.jbuilder b/app/views/api/v1/accounts/labels/index.json.jbuilder index 13f99090d..ddff73eec 100644 --- a/app/views/api/v1/accounts/labels/index.json.jbuilder +++ b/app/views/api/v1/accounts/labels/index.json.jbuilder @@ -1,8 +1,9 @@ -json.data do - json.meta do - end - - json.payload do - json.labels @labels +json.payload do + json.array! @labels do |label| + json.id label.id + json.title label.title + json.description label.description + json.color label.color + json.show_on_sidebar label.show_on_sidebar end end diff --git a/app/views/api/v1/accounts/labels/most_used.json.jbuilder b/app/views/api/v1/accounts/labels/most_used.json.jbuilder deleted file mode 100644 index c411b47ed..000000000 --- a/app/views/api/v1/accounts/labels/most_used.json.jbuilder +++ /dev/null @@ -1,3 +0,0 @@ -json.payload do - json.labels @labels -end diff --git a/app/views/api/v1/accounts/labels/show.json.jbuilder b/app/views/api/v1/accounts/labels/show.json.jbuilder new file mode 100644 index 000000000..edeff661f --- /dev/null +++ b/app/views/api/v1/accounts/labels/show.json.jbuilder @@ -0,0 +1,5 @@ +json.id @label.id +json.title @label.title +json.description @label.description +json.color @label.color +json.show_on_sidebar @label.show_on_sidebar diff --git a/app/views/api/v1/accounts/labels/update.json.jbuilder b/app/views/api/v1/accounts/labels/update.json.jbuilder new file mode 100644 index 000000000..edeff661f --- /dev/null +++ b/app/views/api/v1/accounts/labels/update.json.jbuilder @@ -0,0 +1,5 @@ +json.id @label.id +json.title @label.title +json.description @label.description +json.color @label.color +json.show_on_sidebar @label.show_on_sidebar diff --git a/config/routes.rb b/config/routes.rb index 60b5c9736..dc1172660 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -76,12 +76,8 @@ Rails.application.routes.draw do post :set_agent_bot, on: :member end resources :inbox_members, only: [:create, :show], param: :inbox_id - resources :labels, only: [:index] do - collection do - get :most_used - end - end + resources :labels, only: [:index, :show, :create, :update, :destroy] resources :notifications, only: [:index, :update] resource :notification_settings, only: [:show, :update] diff --git a/db/migrate/20200606132552_create_labels.rb b/db/migrate/20200606132552_create_labels.rb new file mode 100644 index 000000000..81ac698e9 --- /dev/null +++ b/db/migrate/20200606132552_create_labels.rb @@ -0,0 +1,13 @@ +class CreateLabels < ActiveRecord::Migration[6.0] + def change + create_table :labels do |t| + t.string :title + t.text :description + t.string :color + t.boolean :show_on_sidebar + t.references :account, index: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 1509a912a..1ef9c48e1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_05_22_115645) do +ActiveRecord::Schema.define(version: 2020_06_06_132552) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" @@ -256,6 +256,17 @@ ActiveRecord::Schema.define(version: 2020_05_22_115645) do t.index ["name", "created_at"], name: "index_installation_configs_on_name_and_created_at", unique: true end + create_table "labels", force: :cascade do |t| + t.string "title" + t.text "description" + t.string "color" + t.boolean "show_on_sidebar" + t.bigint "account_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["account_id"], name: "index_labels_on_account_id" + end + create_table "messages", id: :serial, force: :cascade do |t| t.text "content" t.integer "account_id", null: false diff --git a/spec/controllers/api/v1/accounts/labels_controller_spec.rb b/spec/controllers/api/v1/accounts/labels_controller_spec.rb index a3d6fb347..3958390ab 100644 --- a/spec/controllers/api/v1/accounts/labels_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/labels_controller_spec.rb @@ -1,12 +1,8 @@ require 'rails_helper' RSpec.describe 'Label API', type: :request do - let(:account) { create(:account) } - let(:conversation) { create(:conversation, account: account) } - - before do - conversation.update_labels('label1, label2') - end + let!(:account) { create(:account) } + let!(:label) { create(:label, account: account) } describe 'GET /api/v1/accounts/{account.id}/labels' do context 'when it is an unauthenticated user' do @@ -18,7 +14,7 @@ RSpec.describe 'Label API', type: :request do end context 'when it is an authenticated user' do - let(:agent) { create(:user, account: account, role: :agent) } + let(:agent) { create(:user, account: account, role: :administrator) } it 'returns all the labels in account' do get "/api/v1/accounts/#{account.id}/labels", @@ -26,33 +22,82 @@ RSpec.describe 'Label API', type: :request do as: :json expect(response).to have_http_status(:success) - expect(response.body).to include('label1') - expect(response.body).to include('label2') + expect(response.body).to include(label.title) end end end - describe 'GET /api/v1/accounts/{account.id}/labels/most_used' do + describe 'GET /api/v1/accounts/{account.id}/labels/:id' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do - get "/api/v1/accounts/#{account.id}/labels" + get "/api/v1/accounts/#{account.id}/labels/#{label.id}" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do - let(:agent) { create(:user, account: account, role: :agent) } + let(:admin) { create(:user, account: account, role: :administrator) } - it 'returns most used labels' do - get "/api/v1/accounts/#{account.id}/labels/most_used", - headers: agent.create_new_auth_token, - params: { count: 1 }, + it 'shows the contact' do + get "/api/v1/accounts/#{account.id}/labels/#{label.id}", + headers: admin.create_new_auth_token, as: :json expect(response).to have_http_status(:success) - expect(response.body).to include('label1') - expect(response.body).not_to include('label2') + expect(response.body).to include(label.title) + end + end + end + + describe 'POST /api/v1/accounts/{account.id}/labels' do + let(:valid_params) { { label: { title: 'test' } } } + + context 'when it is an unauthenticated user' do + it 'returns unauthorized' do + expect { post "/api/v1/accounts/#{account.id}/labels", params: valid_params }.to change(Label, :count).by(0) + + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an authenticated user' do + let(:admin) { create(:user, account: account, role: :administrator) } + + it 'creates the contact' do + expect do + post "/api/v1/accounts/#{account.id}/labels", headers: admin.create_new_auth_token, + params: valid_params + end.to change(Label, :count).by(1) + + expect(response).to have_http_status(:success) + end + end + end + + describe 'PATCH /api/v1/accounts/{account.id}/labels/:id' do + let(:valid_params) { { title: 'Test 2' } } + + context 'when it is an unauthenticated user' do + it 'returns unauthorized' do + put "/api/v1/accounts/#{account.id}/labels/#{label.id}", + params: valid_params + + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an authenticated user' do + let(:admin) { create(:user, account: account, role: :administrator) } + + it 'updates the label' do + patch "/api/v1/accounts/#{account.id}/labels/#{label.id}", + headers: admin.create_new_auth_token, + params: valid_params, + as: :json + + expect(response).to have_http_status(:success) + expect(label.reload.title).to eq('Test 2') end end end diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb new file mode 100644 index 000000000..4602a8d1d --- /dev/null +++ b/spec/factories/labels.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :label do + account + sequence(:title) { |n| "Label #{n}" } + end +end diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb new file mode 100644 index 000000000..f44b4e07e --- /dev/null +++ b/spec/models/label_spec.rb @@ -0,0 +1,7 @@ +require 'rails_helper' + +RSpec.describe Label, type: :model do + describe 'associations' do + it { is_expected.to belong_to(:account) } + end +end From 051871a3cdf2b460a825c38339bebe74186b4b6b Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Sun, 7 Jun 2020 13:58:05 +0530 Subject: [PATCH 06/50] Chore: Code Cleanup in API controllers (#932) * Chore: Code Cleanup in API controllers * Remove unnecessary scoping for accounts controller --- app/controllers/api/base_controller.rb | 4 - .../actions/contact_merges_controller.rb | 6 +- .../api/v1/accounts/agents_controller.rb | 6 +- .../api/v1/accounts/base_controller.rb | 31 +++++ .../api/v1/accounts/callbacks_controller.rb | 14 +-- .../accounts/canned_responses_controller.rb | 10 +- .../channels/twilio_channels_controller.rb | 7 +- .../contacts/conversations_controller.rb | 6 +- .../api/v1/accounts/contacts_controller.rb | 10 +- .../conversations/assignments_controller.rb | 6 +- .../accounts/conversations/base_controller.rb | 9 ++ .../conversations/labels_controller.rb | 4 +- .../conversations/messages_controller.rb | 4 +- .../v1/accounts/conversations_controller.rb | 7 +- .../facebook_indicators_controller.rb | 4 +- .../v1/accounts/inbox_members_controller.rb | 6 +- .../api/v1/accounts/inboxes_controller.rb | 11 +- .../api/v1/accounts/labels_controller.rb | 8 +- .../notification_settings_controller.rb | 4 +- .../v1/accounts/notifications_controller.rb | 4 +- .../v1/accounts/subscriptions_controller.rb | 6 +- .../api/v1/accounts/webhooks_controller.rb | 9 +- .../v1/{accounts => }/accounts_controller.rb | 2 +- .../api/v1/widget/base_controller.rb | 3 + .../api/v1/widget/contacts_controller.rb | 3 - .../api/v1/widget/conversations_controller.rb | 2 - .../api/v1/widget/events_controller.rb | 2 - .../api/v1/widget/inbox_members_controller.rb | 2 +- .../api/v1/widget/labels_controller.rb | 3 - .../api/v1/widget/messages_controller.rb | 2 - .../api/v2/accounts/reports_controller.rb | 6 +- app/controllers/application_controller.rb | 44 ++----- config/routes.rb | 111 +++++++++--------- .../v1/accounts/contacts_controller_spec.rb | 2 +- .../accounts_controller_spec.rb | 0 35 files changed, 176 insertions(+), 182 deletions(-) create mode 100644 app/controllers/api/v1/accounts/base_controller.rb create mode 100644 app/controllers/api/v1/accounts/conversations/base_controller.rb rename app/controllers/api/v1/{accounts => }/accounts_controller.rb (96%) rename spec/controllers/api/v1/{accounts => }/accounts_controller_spec.rb (100%) diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 8db37ced7..9be255080 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -11,10 +11,6 @@ class Api::BaseController < ApplicationController request.headers[:api_access_token].present? || request.headers[:HTTP_API_ACCESS_TOKEN].present? end - def set_conversation - @conversation ||= current_account.conversations.find_by(display_id: params[:conversation_id]) - end - def check_billing_enabled raise ActionController::RoutingError, 'Not Found' unless ENV['BILLING_ENABLED'] end diff --git a/app/controllers/api/v1/accounts/actions/contact_merges_controller.rb b/app/controllers/api/v1/accounts/actions/contact_merges_controller.rb index 1296b6a55..9daee7b04 100644 --- a/app/controllers/api/v1/accounts/actions/contact_merges_controller.rb +++ b/app/controllers/api/v1/accounts/actions/contact_merges_controller.rb @@ -1,10 +1,10 @@ -class Api::V1::Accounts::Actions::ContactMergesController < Api::BaseController +class Api::V1::Accounts::Actions::ContactMergesController < Api::V1::Accounts::BaseController before_action :set_base_contact, only: [:create] before_action :set_mergee_contact, only: [:create] def create contact_merge_action = ContactMergeAction.new( - account: current_account, + account: Current.account, base_contact: @base_contact, mergee_contact: @mergee_contact ) @@ -23,6 +23,6 @@ class Api::V1::Accounts::Actions::ContactMergesController < Api::BaseController end def contacts - @contacts ||= current_account.contacts + @contacts ||= Current.account.contacts end end diff --git a/app/controllers/api/v1/accounts/agents_controller.rb b/app/controllers/api/v1/accounts/agents_controller.rb index 85a05fbc1..030c08045 100644 --- a/app/controllers/api/v1/accounts/agents_controller.rb +++ b/app/controllers/api/v1/accounts/agents_controller.rb @@ -1,4 +1,4 @@ -class Api::V1::Accounts::AgentsController < Api::BaseController +class Api::V1::Accounts::AgentsController < Api::V1::Accounts::BaseController before_action :fetch_agent, except: [:create, :index] before_action :check_authorization before_action :find_user, only: [:create] @@ -46,7 +46,7 @@ class Api::V1::Accounts::AgentsController < Api::BaseController def save_account_user AccountUser.create!( - account_id: current_account.id, + account_id: Current.account.id, user_id: @user.id, role: new_agent_params[:role], inviter_id: current_user.id @@ -64,6 +64,6 @@ class Api::V1::Accounts::AgentsController < Api::BaseController end def agents - @agents ||= current_account.users + @agents ||= Current.account.users end end diff --git a/app/controllers/api/v1/accounts/base_controller.rb b/app/controllers/api/v1/accounts/base_controller.rb new file mode 100644 index 000000000..01a0746b7 --- /dev/null +++ b/app/controllers/api/v1/accounts/base_controller.rb @@ -0,0 +1,31 @@ +class Api::V1::Accounts::BaseController < Api::BaseController + before_action :current_account + + 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 + switch_locale account + 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/callbacks_controller.rb b/app/controllers/api/v1/accounts/callbacks_controller.rb index 54c7bace4..77e46d669 100644 --- a/app/controllers/api/v1/accounts/callbacks_controller.rb +++ b/app/controllers/api/v1/accounts/callbacks_controller.rb @@ -1,4 +1,4 @@ -class Api::V1::Accounts::CallbacksController < Api::BaseController +class Api::V1::Accounts::CallbacksController < Api::V1::Accounts::BaseController before_action :inbox, only: [:reauthorize_page] def register_facebook_page @@ -7,11 +7,11 @@ class Api::V1::Accounts::CallbacksController < Api::BaseController page_id = params[:page_id] inbox_name = params[:inbox_name] ActiveRecord::Base.transaction do - facebook_channel = current_account.facebook_pages.create!( + facebook_channel = Current.account.facebook_pages.create!( page_id: page_id, user_access_token: user_access_token, page_access_token: page_access_token ) - @facebook_inbox = current_account.inboxes.create!(name: inbox_name, channel: facebook_channel) + @facebook_inbox = Current.account.inboxes.create!(name: inbox_name, channel: facebook_channel) set_avatar(@facebook_inbox, page_id) rescue StandardError => e Rails.logger.info e @@ -22,7 +22,7 @@ class Api::V1::Accounts::CallbacksController < Api::BaseController @page_details = mark_already_existing_facebook_pages(fb_object.get_connections('me', 'accounts')) end - # get params[:inbox_id], current_account, params[:omniauth_token] + # get params[:inbox_id], current_account. params[:omniauth_token] def reauthorize_page if @inbox&.facebook? fb_page_id = @inbox.channel.page_id @@ -40,7 +40,7 @@ class Api::V1::Accounts::CallbacksController < Api::BaseController private def inbox - @inbox = current_account.inboxes.find_by(id: params[:inbox_id]) + @inbox = Current.account.inboxes.find_by(id: params[:inbox_id]) end def update_fb_page(fb_page_id, access_token) @@ -50,7 +50,7 @@ class Api::V1::Accounts::CallbacksController < Api::BaseController end def get_fb_page(fb_page_id) - current_account.facebook_pages.find_by(page_id: fb_page_id) + Current.account.facebook_pages.find_by(page_id: fb_page_id) end def fb_object @@ -69,7 +69,7 @@ class Api::V1::Accounts::CallbacksController < Api::BaseController return [] if data.empty? data.inject([]) do |result, page_detail| - page_detail[:exists] = current_account.facebook_pages.exists?(page_id: page_detail['id']) ? true : false + page_detail[:exists] = Current.account.facebook_pages.exists?(page_id: page_detail['id']) ? true : false result << page_detail end end diff --git a/app/controllers/api/v1/accounts/canned_responses_controller.rb b/app/controllers/api/v1/accounts/canned_responses_controller.rb index b76da5f8c..16e16e4a6 100644 --- a/app/controllers/api/v1/accounts/canned_responses_controller.rb +++ b/app/controllers/api/v1/accounts/canned_responses_controller.rb @@ -1,4 +1,4 @@ -class Api::V1::Accounts::CannedResponsesController < Api::BaseController +class Api::V1::Accounts::CannedResponsesController < Api::V1::Accounts::BaseController before_action :fetch_canned_response, only: [:update, :destroy] def index @@ -6,7 +6,7 @@ class Api::V1::Accounts::CannedResponsesController < Api::BaseController end def create - @canned_response = current_account.canned_responses.new(canned_response_params) + @canned_response = Current.account.canned_responses.new(canned_response_params) @canned_response.save! render json: @canned_response end @@ -24,7 +24,7 @@ class Api::V1::Accounts::CannedResponsesController < Api::BaseController private def fetch_canned_response - @canned_response = current_account.canned_responses.find(params[:id]) + @canned_response = Current.account.canned_responses.find(params[:id]) end def canned_response_params @@ -33,9 +33,9 @@ class Api::V1::Accounts::CannedResponsesController < Api::BaseController def canned_responses if params[:search] - current_account.canned_responses.where('short_code ILIKE ?', "#{params[:search]}%") + Current.account.canned_responses.where('short_code ILIKE ?', "#{params[:search]}%") else - current_account.canned_responses + Current.account.canned_responses end end end diff --git a/app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb b/app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb index 8011d3891..ffbc78eb5 100644 --- a/app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb +++ b/app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb @@ -1,5 +1,4 @@ -class Api::V1::Accounts::Channels::TwilioChannelsController < Api::BaseController - before_action :current_account +class Api::V1::Accounts::Channels::TwilioChannelsController < Api::V1::Accounts::BaseController before_action :authorize_request def create @@ -38,13 +37,13 @@ class Api::V1::Accounts::Channels::TwilioChannelsController < Api::BaseControlle end def build_inbox - @twilio_channel = current_account.twilio_sms.create!( + @twilio_channel = Current.account.twilio_sms.create!( account_sid: permitted_params[:account_sid], auth_token: permitted_params[:auth_token], phone_number: phone_number, medium: medium ) - @inbox = current_account.inboxes.create( + @inbox = Current.account.inboxes.create( name: permitted_params[:name], channel: @twilio_channel ) diff --git a/app/controllers/api/v1/accounts/contacts/conversations_controller.rb b/app/controllers/api/v1/accounts/contacts/conversations_controller.rb index 8fcb4df13..5c7bf77d7 100644 --- a/app/controllers/api/v1/accounts/contacts/conversations_controller.rb +++ b/app/controllers/api/v1/accounts/contacts/conversations_controller.rb @@ -1,6 +1,6 @@ -class Api::V1::Accounts::Contacts::ConversationsController < Api::BaseController +class Api::V1::Accounts::Contacts::ConversationsController < Api::V1::Accounts::BaseController def index - @conversations = current_account.conversations.includes( + @conversations = Current.account.conversations.includes( :assignee, :contact, :inbox ).where(inbox_id: inbox_ids, contact_id: permitted_params[:contact_id]) end @@ -9,7 +9,7 @@ class Api::V1::Accounts::Contacts::ConversationsController < Api::BaseController def inbox_ids if current_user.administrator? - current_account.inboxes.pluck(:id) + Current.account.inboxes.pluck(:id) elsif current_user.agent? current_user.assigned_inboxes.pluck(:id) else diff --git a/app/controllers/api/v1/accounts/contacts_controller.rb b/app/controllers/api/v1/accounts/contacts_controller.rb index a3713660b..2208a2cf6 100644 --- a/app/controllers/api/v1/accounts/contacts_controller.rb +++ b/app/controllers/api/v1/accounts/contacts_controller.rb @@ -1,17 +1,17 @@ -class Api::V1::Accounts::ContactsController < Api::BaseController +class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController protect_from_forgery with: :null_session before_action :check_authorization before_action :fetch_contact, only: [:show, :update] def index - @contacts = current_account.contacts + @contacts = Current.account.contacts end def show; end def create - @contact = Contact.new(contact_create_params) + @contact = Current.account.contacts.new(contact_create_params) @contact.save! render json: @contact end @@ -31,10 +31,10 @@ class Api::V1::Accounts::ContactsController < Api::BaseController end def fetch_contact - @contact = current_account.contacts.find(params[:id]) + @contact = Current.account.contacts.find(params[:id]) end def contact_create_params - params.require(:contact).permit(:account_id, :inbox_id).merge!(name: SecureRandom.hex) + params.require(:contact).permit(:name, :email, :phone_number) end end diff --git a/app/controllers/api/v1/accounts/conversations/assignments_controller.rb b/app/controllers/api/v1/accounts/conversations/assignments_controller.rb index 6da3c05da..58fbc5b4e 100644 --- a/app/controllers/api/v1/accounts/conversations/assignments_controller.rb +++ b/app/controllers/api/v1/accounts/conversations/assignments_controller.rb @@ -1,10 +1,8 @@ -class Api::V1::Accounts::Conversations::AssignmentsController < Api::BaseController - before_action :set_conversation, only: [:create] - +class Api::V1::Accounts::Conversations::AssignmentsController < Api::V1::Accounts::Conversations::BaseController # assign agent to a conversation def create # if params[:assignee_id] is not a valid id, it will set to nil, hence unassigning the conversation - assignee = current_account.users.find_by(id: params[:assignee_id]) + assignee = Current.account.users.find_by(id: params[:assignee_id]) @conversation.update_assignee(assignee) render json: assignee end diff --git a/app/controllers/api/v1/accounts/conversations/base_controller.rb b/app/controllers/api/v1/accounts/conversations/base_controller.rb new file mode 100644 index 000000000..2dae59abd --- /dev/null +++ b/app/controllers/api/v1/accounts/conversations/base_controller.rb @@ -0,0 +1,9 @@ +class Api::V1::Accounts::Conversations::BaseController < Api::V1::Accounts::BaseController + before_action :conversation + + private + + def conversation + @conversation ||= Current.account.conversations.find_by(display_id: params[:conversation_id]) + end +end diff --git a/app/controllers/api/v1/accounts/conversations/labels_controller.rb b/app/controllers/api/v1/accounts/conversations/labels_controller.rb index 3e80e2825..306544200 100644 --- a/app/controllers/api/v1/accounts/conversations/labels_controller.rb +++ b/app/controllers/api/v1/accounts/conversations/labels_controller.rb @@ -1,6 +1,4 @@ -class Api::V1::Accounts::Conversations::LabelsController < Api::BaseController - before_action :set_conversation, only: [:create, :index] - +class Api::V1::Accounts::Conversations::LabelsController < Api::V1::Accounts::Conversations::BaseController def create @conversation.update_labels(params[:labels]) @labels = @conversation.label_list diff --git a/app/controllers/api/v1/accounts/conversations/messages_controller.rb b/app/controllers/api/v1/accounts/conversations/messages_controller.rb index d0ed39edb..601db872f 100644 --- a/app/controllers/api/v1/accounts/conversations/messages_controller.rb +++ b/app/controllers/api/v1/accounts/conversations/messages_controller.rb @@ -1,6 +1,4 @@ -class Api::V1::Accounts::Conversations::MessagesController < Api::BaseController - before_action :set_conversation, only: [:index, :create] - +class Api::V1::Accounts::Conversations::MessagesController < Api::V1::Accounts::Conversations::BaseController def index @messages = message_finder.perform end diff --git a/app/controllers/api/v1/accounts/conversations_controller.rb b/app/controllers/api/v1/accounts/conversations_controller.rb index fcda432a5..8d8099fdc 100644 --- a/app/controllers/api/v1/accounts/conversations_controller.rb +++ b/app/controllers/api/v1/accounts/conversations_controller.rb @@ -1,6 +1,5 @@ -class Api::V1::Accounts::ConversationsController < Api::BaseController +class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseController include Events::Types - before_action :current_account before_action :conversation, except: [:index] before_action :contact_inbox, only: [:create] @@ -62,7 +61,7 @@ class Api::V1::Accounts::ConversationsController < Api::BaseController end def conversation - @conversation ||= current_account.conversations.find_by(display_id: params[:id]) + @conversation ||= Current.account.conversations.find_by(display_id: params[:id]) end def contact_inbox @@ -71,7 +70,7 @@ class Api::V1::Accounts::ConversationsController < Api::BaseController def conversation_params { - account_id: current_account.id, + account_id: Current.account.id, inbox_id: @contact_inbox.inbox_id, contact_id: @contact_inbox.contact_id, contact_inbox_id: @contact_inbox.id diff --git a/app/controllers/api/v1/accounts/facebook_indicators_controller.rb b/app/controllers/api/v1/accounts/facebook_indicators_controller.rb index 7cea774cf..a0e42c040 100644 --- a/app/controllers/api/v1/accounts/facebook_indicators_controller.rb +++ b/app/controllers/api/v1/accounts/facebook_indicators_controller.rb @@ -1,4 +1,4 @@ -class Api::V1::Accounts::FacebookIndicatorsController < Api::BaseController +class Api::V1::Accounts::FacebookIndicatorsController < Api::V1::Accounts::BaseController before_action :set_access_token around_action :handle_with_exception @@ -38,7 +38,7 @@ class Api::V1::Accounts::FacebookIndicatorsController < Api::BaseController end def inbox - @inbox ||= current_account.inboxes.find(permitted_params[:inbox_id]) + @inbox ||= Current.account.inboxes.find(permitted_params[:inbox_id]) end def set_access_token diff --git a/app/controllers/api/v1/accounts/inbox_members_controller.rb b/app/controllers/api/v1/accounts/inbox_members_controller.rb index f71b3869d..9ad2ef93d 100644 --- a/app/controllers/api/v1/accounts/inbox_members_controller.rb +++ b/app/controllers/api/v1/accounts/inbox_members_controller.rb @@ -1,4 +1,4 @@ -class Api::V1::Accounts::InboxMembersController < Api::BaseController +class Api::V1::Accounts::InboxMembersController < Api::V1::Accounts::BaseController before_action :fetch_inbox, only: [:create, :show] before_action :current_agents_ids, only: [:create] @@ -12,7 +12,7 @@ class Api::V1::Accounts::InboxMembersController < Api::BaseController end def show - @agents = current_account.users.where(id: @inbox.members.pluck(:user_id)) + @agents = Current.account.users.where(id: @inbox.members.pluck(:user_id)) end private @@ -40,6 +40,6 @@ class Api::V1::Accounts::InboxMembersController < Api::BaseController end def fetch_inbox - @inbox = current_account.inboxes.find(params[:inbox_id]) + @inbox = Current.account.inboxes.find(params[:inbox_id]) end end diff --git a/app/controllers/api/v1/accounts/inboxes_controller.rb b/app/controllers/api/v1/accounts/inboxes_controller.rb index 8fdde8cc0..fe19400c3 100644 --- a/app/controllers/api/v1/accounts/inboxes_controller.rb +++ b/app/controllers/api/v1/accounts/inboxes_controller.rb @@ -1,17 +1,16 @@ -class Api::V1::Accounts::InboxesController < Api::BaseController - before_action :current_account +class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController before_action :fetch_inbox, except: [:index, :create] before_action :fetch_agent_bot, only: [:set_agent_bot] before_action :check_authorization def index - @inboxes = policy_scope(current_account.inboxes) + @inboxes = policy_scope(Current.account.inboxes) end def create ActiveRecord::Base.transaction do channel = web_widgets.create!(permitted_params[:channel].except(:type)) if permitted_params[:channel][:type] == 'web_widget' - @inbox = current_account.inboxes.build(name: permitted_params[:name], channel: channel) + @inbox = Current.account.inboxes.build(name: permitted_params[:name], channel: channel) @inbox.avatar.attach(permitted_params[:avatar]) @inbox.save! end @@ -41,7 +40,7 @@ class Api::V1::Accounts::InboxesController < Api::BaseController private def fetch_inbox - @inbox = current_account.inboxes.find(params[:id]) + @inbox = Current.account.inboxes.find(params[:id]) end def fetch_agent_bot @@ -49,7 +48,7 @@ class Api::V1::Accounts::InboxesController < Api::BaseController end def web_widgets - current_account.web_widgets + Current.account.web_widgets end def check_authorization diff --git a/app/controllers/api/v1/accounts/labels_controller.rb b/app/controllers/api/v1/accounts/labels_controller.rb index 5db0fb87b..12f0d404a 100644 --- a/app/controllers/api/v1/accounts/labels_controller.rb +++ b/app/controllers/api/v1/accounts/labels_controller.rb @@ -1,16 +1,16 @@ -class Api::V1::Accounts::LabelsController < Api::BaseController +class Api::V1::Accounts::LabelsController < Api::V1::Accounts::BaseController before_action :current_account before_action :fetch_label, except: [:index, :create] before_action :check_authorization def index - @labels = policy_scope(current_account.labels) + @labels = policy_scope(Current.account.labels) end def show; end def create - @label = current_account.labels.create!(permitted_params) + @label = Current.account.labels.create!(permitted_params) end def update @@ -25,7 +25,7 @@ class Api::V1::Accounts::LabelsController < Api::BaseController private def fetch_label - @label = current_account.labels.find(params[:id]) + @label = Current.account.labels.find(params[:id]) end def check_authorization diff --git a/app/controllers/api/v1/accounts/notification_settings_controller.rb b/app/controllers/api/v1/accounts/notification_settings_controller.rb index 14496969d..febad1a98 100644 --- a/app/controllers/api/v1/accounts/notification_settings_controller.rb +++ b/app/controllers/api/v1/accounts/notification_settings_controller.rb @@ -1,4 +1,4 @@ -class Api::V1::Accounts::NotificationSettingsController < Api::BaseController +class Api::V1::Accounts::NotificationSettingsController < Api::V1::Accounts::BaseController before_action :set_user, :load_notification_setting def show; end @@ -16,7 +16,7 @@ class Api::V1::Accounts::NotificationSettingsController < Api::BaseController end def load_notification_setting - @notification_setting = @user.notification_settings.find_by(account_id: current_account.id) + @notification_setting = @user.notification_settings.find_by(account_id: Current.account.id) end def notification_setting_params diff --git a/app/controllers/api/v1/accounts/notifications_controller.rb b/app/controllers/api/v1/accounts/notifications_controller.rb index 5d9a5ea54..0f82d0013 100644 --- a/app/controllers/api/v1/accounts/notifications_controller.rb +++ b/app/controllers/api/v1/accounts/notifications_controller.rb @@ -1,10 +1,10 @@ -class Api::V1::Accounts::NotificationsController < Api::BaseController +class Api::V1::Accounts::NotificationsController < Api::V1::Accounts::BaseController protect_from_forgery with: :null_session before_action :fetch_notification, only: [:update] def index - @notifications = current_user.notifications.where(account_id: current_account.id) + @notifications = current_user.notifications.where(account_id: Current.account.id) render json: @notifications end diff --git a/app/controllers/api/v1/accounts/subscriptions_controller.rb b/app/controllers/api/v1/accounts/subscriptions_controller.rb index f9b3141d6..4c4f6de01 100644 --- a/app/controllers/api/v1/accounts/subscriptions_controller.rb +++ b/app/controllers/api/v1/accounts/subscriptions_controller.rb @@ -1,13 +1,13 @@ -class Api::V1::Accounts::SubscriptionsController < Api::BaseController +class Api::V1::Accounts::SubscriptionsController < Api::V1::Accounts::BaseController skip_before_action :check_subscription before_action :check_billing_enabled def index - render json: current_account.subscription_data + render json: Current.account.subscription_data end def status - render json: current_account.subscription.summary + render json: Current.account.subscription.summary end end diff --git a/app/controllers/api/v1/accounts/webhooks_controller.rb b/app/controllers/api/v1/accounts/webhooks_controller.rb index d3afba2af..9e61904d6 100644 --- a/app/controllers/api/v1/accounts/webhooks_controller.rb +++ b/app/controllers/api/v1/accounts/webhooks_controller.rb @@ -1,14 +1,13 @@ -class Api::V1::Accounts::WebhooksController < Api::BaseController - before_action :current_account +class Api::V1::Accounts::WebhooksController < Api::V1::Accounts::BaseController before_action :check_authorization before_action :fetch_webhook, only: [:update, :destroy] def index - @webhooks = current_account.webhooks + @webhooks = Current.account.webhooks end def create - @webhook = current_account.webhooks.new(webhook_params) + @webhook = Current.account.webhooks.new(webhook_params) @webhook.save! end @@ -28,7 +27,7 @@ class Api::V1::Accounts::WebhooksController < Api::BaseController end def fetch_webhook - @webhook = current_account.webhooks.find(params[:id]) + @webhook = Current.account.webhooks.find(params[:id]) end def check_authorization diff --git a/app/controllers/api/v1/accounts/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb similarity index 96% rename from app/controllers/api/v1/accounts/accounts_controller.rb rename to app/controllers/api/v1/accounts_controller.rb index adb8bf11c..d23f535a5 100644 --- a/app/controllers/api/v1/accounts/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -1,4 +1,4 @@ -class Api::V1::Accounts::AccountsController < Api::BaseController +class Api::V1::AccountsController < Api::BaseController include AuthHelper skip_before_action :verify_authenticity_token, only: [:create] diff --git a/app/controllers/api/v1/widget/base_controller.rb b/app/controllers/api/v1/widget/base_controller.rb index 86bffb710..45cf3fc4f 100644 --- a/app/controllers/api/v1/widget/base_controller.rb +++ b/app/controllers/api/v1/widget/base_controller.rb @@ -1,4 +1,7 @@ class Api::V1::Widget::BaseController < ApplicationController + before_action :set_web_widget + before_action :set_contact + private def conversation diff --git a/app/controllers/api/v1/widget/contacts_controller.rb b/app/controllers/api/v1/widget/contacts_controller.rb index b7ac793e7..2a2b184fb 100644 --- a/app/controllers/api/v1/widget/contacts_controller.rb +++ b/app/controllers/api/v1/widget/contacts_controller.rb @@ -1,7 +1,4 @@ class Api::V1::Widget::ContactsController < Api::V1::Widget::BaseController - before_action :set_web_widget - before_action :set_contact - def update contact_identify_action = ContactIdentifyAction.new( contact: @contact, diff --git a/app/controllers/api/v1/widget/conversations_controller.rb b/app/controllers/api/v1/widget/conversations_controller.rb index cdfbd9d4a..e346b6367 100644 --- a/app/controllers/api/v1/widget/conversations_controller.rb +++ b/app/controllers/api/v1/widget/conversations_controller.rb @@ -1,7 +1,5 @@ class Api::V1::Widget::ConversationsController < Api::V1::Widget::BaseController include Events::Types - before_action :set_web_widget - before_action :set_contact def index @conversation = conversation diff --git a/app/controllers/api/v1/widget/events_controller.rb b/app/controllers/api/v1/widget/events_controller.rb index faa44994c..b32b0f78d 100644 --- a/app/controllers/api/v1/widget/events_controller.rb +++ b/app/controllers/api/v1/widget/events_controller.rb @@ -1,7 +1,5 @@ class Api::V1::Widget::EventsController < Api::V1::Widget::BaseController include Events::Types - before_action :set_web_widget - before_action :set_contact def create Rails.configuration.dispatcher.dispatch(permitted_params[:name], Time.zone.now, contact_inbox: @contact_inbox) diff --git a/app/controllers/api/v1/widget/inbox_members_controller.rb b/app/controllers/api/v1/widget/inbox_members_controller.rb index d978a9b6e..da7d6256b 100644 --- a/app/controllers/api/v1/widget/inbox_members_controller.rb +++ b/app/controllers/api/v1/widget/inbox_members_controller.rb @@ -1,5 +1,5 @@ class Api::V1::Widget::InboxMembersController < Api::V1::Widget::BaseController - before_action :set_web_widget + skip_before_action :set_contact def index @inbox_members = @web_widget.inbox.inbox_members.includes(:user) diff --git a/app/controllers/api/v1/widget/labels_controller.rb b/app/controllers/api/v1/widget/labels_controller.rb index efe84f5e3..e8e409244 100644 --- a/app/controllers/api/v1/widget/labels_controller.rb +++ b/app/controllers/api/v1/widget/labels_controller.rb @@ -1,7 +1,4 @@ class Api::V1::Widget::LabelsController < Api::V1::Widget::BaseController - before_action :set_web_widget - before_action :set_contact - def create conversation.label_list.add(permitted_params[:label]) conversation.save! diff --git a/app/controllers/api/v1/widget/messages_controller.rb b/app/controllers/api/v1/widget/messages_controller.rb index a65e01f9c..366aa3912 100644 --- a/app/controllers/api/v1/widget/messages_controller.rb +++ b/app/controllers/api/v1/widget/messages_controller.rb @@ -1,6 +1,4 @@ class Api::V1::Widget::MessagesController < Api::V1::Widget::BaseController - before_action :set_web_widget - before_action :set_contact before_action :set_conversation, only: [:create] before_action :set_message, only: [:update] diff --git a/app/controllers/api/v2/accounts/reports_controller.rb b/app/controllers/api/v2/accounts/reports_controller.rb index 6aa0355a4..c4f563d5d 100644 --- a/app/controllers/api/v2/accounts/reports_controller.rb +++ b/app/controllers/api/v2/accounts/reports_controller.rb @@ -1,6 +1,6 @@ -class Api::V2::Accounts::ReportsController < Api::BaseController +class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController def account - builder = V2::ReportBuilder.new(current_account, account_report_params) + builder = V2::ReportBuilder.new(Current.account, account_report_params) data = builder.build render json: data end @@ -29,7 +29,7 @@ class Api::V2::Accounts::ReportsController < Api::BaseController end def account_summary_metrics - builder = V2::ReportBuilder.new(current_account, account_summary_params) + builder = V2::ReportBuilder.new(Current.account, account_summary_params) builder.summary end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ae3e5e857..ab1be9b9b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -13,40 +13,6 @@ class ApplicationController < ActionController::Base private - def current_account - @current_account ||= find_current_account - Current.account = @current_account - end - - def find_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 - switch_locale account - account - end - - def switch_locale(account) - # priority is for locale set in query string (mostly for widget/from js sdk) - locale ||= (I18n.available_locales.map(&:to_s).include?(params[:locale]) ? params[:locale] : nil) - # if local is not set in param, lets try account - locale ||= (I18n.available_locales.map(&:to_s).include?(account.locale) ? account.locale : nil) - I18n.locale = locale || I18n.default_locale - 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 - def handle_with_exception yield rescue ActiveRecord::RecordNotFound => e @@ -65,7 +31,7 @@ class ApplicationController < ActionController::Base end def current_subscription - @subscription ||= current_account.subscription + @subscription ||= Current.account.subscription end def render_unauthorized(message) @@ -94,6 +60,14 @@ class ApplicationController < ActionController::Base render json: exception.to_hash, status: exception.http_status end + def switch_locale(account) + # priority is for locale set in query string (mostly for widget/from js sdk) + locale ||= (I18n.available_locales.map(&:to_s).include?(params[:locale]) ? params[:locale] : nil) + # if local is not set in param, lets try account + locale ||= (I18n.available_locales.map(&:to_s).include?(account.locale) ? account.locale : nil) + I18n.locale = locale || I18n.default_locale + end + def check_subscription # This block is left over from the initial version of chatwoot # We might reuse this later in the hosted version of chatwoot. diff --git a/config/routes.rb b/config/routes.rb index dc1172660..b0a9b9388 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,73 +22,76 @@ Rails.application.routes.draw do namespace :v1 do # ---------------------------------- # start of account scoped api routes - resources :accounts, only: [:create, :show, :update], module: :accounts do + resources :accounts, only: [:create, :show, :update] do member do post :update_active_at end - namespace :actions do - resource :contact_merge, only: [:create] - end - resources :agents, except: [:show, :edit, :new] - resources :callbacks, only: [] do - collection do - post :register_facebook_page - get :register_facebook_page - post :facebook_pages - post :reauthorize_page + scope module: :accounts do + namespace :actions do + resource :contact_merge, only: [:create] end - end - resources :canned_responses, except: [:show, :edit, :new] - namespace :channels do - resource :twilio_channel, only: [:create] - end - resources :conversations, only: [:index, :create, :show] do - get 'meta', on: :collection - scope module: :conversations do - resources :messages, only: [:index, :create] - resources :assignments, only: [:create] - resources :labels, only: [:create, :index] + + resources :agents, except: [:show, :edit, :new] + resources :callbacks, only: [] do + collection do + post :register_facebook_page + get :register_facebook_page + post :facebook_pages + post :reauthorize_page + end end - member do - post :mute - post :toggle_status - post :toggle_typing_status - post :update_last_seen + resources :canned_responses, except: [:show, :edit, :new] + namespace :channels do + resource :twilio_channel, only: [:create] end - end - - resources :contacts, only: [:index, :show, :update, :create] do - scope module: :contacts do - resources :conversations, only: [:index] + resources :conversations, only: [:index, :create, :show] do + get 'meta', on: :collection + scope module: :conversations do + resources :messages, only: [:index, :create] + resources :assignments, only: [:create] + resources :labels, only: [:create, :index] + end + member do + post :mute + post :toggle_status + post :toggle_typing_status + post :update_last_seen + end end - end - resources :facebook_indicators, only: [] do - collection do - post :mark_seen - post :typing_on - post :typing_off + resources :contacts, only: [:index, :show, :update, :create] do + scope module: :contacts do + resources :conversations, only: [:index] + end end - end - resources :inboxes, only: [:index, :create, :update, :destroy] do - post :set_agent_bot, on: :member - end - resources :inbox_members, only: [:create, :show], param: :inbox_id - - resources :labels, only: [:index, :show, :create, :update, :destroy] - resources :notifications, only: [:index, :update] - resource :notification_settings, only: [:show, :update] - - # this block is only required if subscription via chargebee is enabled - resources :subscriptions, only: [:index] do - collection do - get :summary + resources :facebook_indicators, only: [] do + collection do + post :mark_seen + post :typing_on + post :typing_off + end end - end - resources :webhooks, except: [:show] + resources :inboxes, only: [:index, :create, :update, :destroy] do + post :set_agent_bot, on: :member + end + resources :inbox_members, only: [:create, :show], param: :inbox_id + resources :labels, only: [:index, :show, :create, :update, :destroy] + + resources :notifications, only: [:index, :update] + resource :notification_settings, only: [:show, :update] + + # this block is only required if subscription via chargebee is enabled + resources :subscriptions, only: [:index] do + collection do + get :summary + end + end + + resources :webhooks, except: [:show] + end end # end of account scoped api routes diff --git a/spec/controllers/api/v1/accounts/contacts_controller_spec.rb b/spec/controllers/api/v1/accounts/contacts_controller_spec.rb index 27e5dfd37..1a1b82442 100644 --- a/spec/controllers/api/v1/accounts/contacts_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/contacts_controller_spec.rb @@ -53,7 +53,7 @@ RSpec.describe 'Contacts API', type: :request do end describe 'POST /api/v1/accounts/{account.id}/contacts' do - let(:valid_params) { { contact: { account_id: account.id } } } + let(:valid_params) { { contact: { name: 'test' } } } context 'when it is an unauthenticated user' do it 'returns unauthorized' do diff --git a/spec/controllers/api/v1/accounts/accounts_controller_spec.rb b/spec/controllers/api/v1/accounts_controller_spec.rb similarity index 100% rename from spec/controllers/api/v1/accounts/accounts_controller_spec.rb rename to spec/controllers/api/v1/accounts_controller_spec.rb From 52d28105e4a95259714c49ed80d900b54199a3e2 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Sun, 7 Jun 2020 20:31:48 +0530 Subject: [PATCH 07/50] Chore: Remove dead code related to billing (#935) - remove subscription model - remove billing-related code --- .env.example | 9 -- .rubocop.yml | 1 - .rubocop_todo.yml | 3 - Gemfile | 3 - Gemfile.lock | 5 - app/controllers/api/base_controller.rb | 4 - .../v1/accounts/subscriptions_controller.rb | 13 -- app/controllers/api/v1/accounts_controller.rb | 2 +- .../api/v1/agent_bots_controller.rb | 1 - app/controllers/api/v1/webhooks_controller.rb | 22 ---- app/controllers/api_controller.rb | 1 - app/controllers/application_controller.rb | 13 -- app/dispatchers/async_dispatcher.rb | 1 - app/helpers/api/v1/subscriptions_helper.rb | 2 - app/javascript/dashboard/api/billing.js | 20 --- app/javascript/dashboard/api/endPoints.js | 8 -- .../dashboard/assets/scss/_woot.scss | 1 - .../assets/scss/widgets/_billing.scss | 75 ----------- .../dashboard/components/layout/Sidebar.vue | 43 ------ .../components/widgets/StatusBar.vue | 24 ---- app/javascript/dashboard/helper/APIHelper.js | 7 - .../dashboard/i18n/default-sidebar.js | 9 -- .../dashboard/i18n/locale/ca/billing.json | 19 --- .../dashboard/i18n/locale/ca/index.js | 2 - .../dashboard/i18n/locale/ca/settings.json | 1 - .../dashboard/i18n/locale/cs/billing.json | 19 --- .../dashboard/i18n/locale/de/billing.json | 19 --- .../dashboard/i18n/locale/de/index.js | 2 - .../dashboard/i18n/locale/de/settings.json | 1 - .../dashboard/i18n/locale/el/billing.json | 19 --- .../dashboard/i18n/locale/el/index.js | 2 - .../dashboard/i18n/locale/el/settings.json | 1 - .../dashboard/i18n/locale/en/agentMgmt.json | 2 +- .../dashboard/i18n/locale/en/billing.json | 19 --- .../dashboard/i18n/locale/en/index.js | 2 - .../dashboard/i18n/locale/en/settings.json | 1 - .../dashboard/i18n/locale/es/billing.json | 19 --- .../dashboard/i18n/locale/es/index.js | 2 - .../dashboard/i18n/locale/es/settings.json | 1 - .../dashboard/i18n/locale/fr/billing.json | 19 --- .../dashboard/i18n/locale/fr/index.js | 2 - .../dashboard/i18n/locale/fr/settings.json | 1 - .../dashboard/i18n/locale/it/billing.json | 19 --- .../dashboard/i18n/locale/ml/billing.json | 19 --- .../dashboard/i18n/locale/ml/index.js | 2 - .../dashboard/i18n/locale/ml/settings.json | 1 - .../dashboard/i18n/locale/nl/billing.json | 19 --- .../dashboard/i18n/locale/nl/index.js | 2 - .../dashboard/i18n/locale/nl/settings.json | 1 - .../dashboard/i18n/locale/pl/billing.json | 19 --- .../dashboard/i18n/locale/pt/billing.json | 19 --- .../dashboard/i18n/locale/pt/index.js | 2 - .../dashboard/i18n/locale/pt/settings.json | 1 - .../dashboard/i18n/locale/pt_BR/billing.json | 19 --- .../dashboard/i18n/locale/pt_BR/index.js | 2 - .../dashboard/i18n/locale/pt_BR/settings.json | 1 - .../dashboard/i18n/locale/ro/billing.json | 19 --- .../dashboard/i18n/locale/ro/index.js | 2 - .../dashboard/i18n/locale/ro/settings.json | 1 - .../dashboard/i18n/locale/sv/billing.json | 19 --- .../dashboard/i18n/locale/uk/billing.json | 19 --- .../settings/billing/AccountLocked.vue | 22 ---- .../dashboard/settings/billing/Index.vue | 124 ------------------ .../settings/billing/billing.routes.js | 32 ----- .../dashboard/settings/settings.routes.js | 2 - app/javascript/dashboard/store/index.js | 2 - .../dashboard/store/modules/billing.js | 60 --------- .../dashboard/store/mutation-types.js | 4 - app/listeners/subscription_listener.rb | 35 ----- app/models/account.rb | 23 ---- app/models/channel/web_widget.rb | 19 ++- app/models/subscription.rb | 57 -------- app/models/user.rb | 1 - .../subscription/chargebee_service.rb | 70 ---------- app/views/layouts/vueapp.html.erb | 1 - config/initializers/00_init.rb | 2 - config/plans.yml | 17 --- config/routes.rb | 13 -- .../20200607140737_remove_subscriptions.rb | 15 +++ db/schema.rb | 14 +- lib/webhooks/chargebee.rb | 86 ------------ .../accounts/subscriptions_controller_spec.rb | 46 ------- spec/fixtures/subscriptions.yml | 15 --- spec/models/account_spec.rb | 1 - 84 files changed, 27 insertions(+), 1240 deletions(-) delete mode 100644 app/controllers/api/v1/accounts/subscriptions_controller.rb delete mode 100644 app/helpers/api/v1/subscriptions_helper.rb delete mode 100644 app/javascript/dashboard/api/billing.js delete mode 100644 app/javascript/dashboard/assets/scss/widgets/_billing.scss delete mode 100644 app/javascript/dashboard/components/widgets/StatusBar.vue delete mode 100644 app/javascript/dashboard/i18n/locale/ca/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/cs/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/de/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/el/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/en/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/es/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/fr/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/it/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/ml/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/nl/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/pl/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/pt/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/pt_BR/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/ro/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/sv/billing.json delete mode 100644 app/javascript/dashboard/i18n/locale/uk/billing.json delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/billing/AccountLocked.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/billing/Index.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js delete mode 100644 app/javascript/dashboard/store/modules/billing.js delete mode 100644 app/listeners/subscription_listener.rb delete mode 100644 app/models/subscription.rb delete mode 100644 app/services/subscription/chargebee_service.rb delete mode 100644 config/initializers/00_init.rb delete mode 100644 config/plans.yml create mode 100644 db/migrate/20200607140737_remove_subscriptions.rb delete mode 100644 lib/webhooks/chargebee.rb delete mode 100644 spec/controllers/api/v1/accounts/subscriptions_controller_spec.rb delete mode 100644 spec/fixtures/subscriptions.yml diff --git a/.env.example b/.env.example index e8ec635f0..7dcbe5e62 100644 --- a/.env.example +++ b/.env.example @@ -89,15 +89,6 @@ TWITTER_ENVIRONMENT= ## Mobile app env variables IOS_APP_ID=6C953F3RX2.com.chatwoot.app -#### This environment variables are only required in hosted version which has billing -ENABLE_BILLING= - -## chargebee settings -CHARGEBEE_API_KEY= -CHARGEBEE_SITE= -CHARGEBEE_WEBHOOK_USERNAME= -CHARGEBEE_WEBHOOK_PASSWORD= - ## Push Notification ## generate a new key value here : https://d3v.one/vapid-key-generator/ # VAPID_PUBLIC_KEY= diff --git a/.rubocop.yml b/.rubocop.yml index fac44c67a..af3e3f831 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -65,7 +65,6 @@ Style/GuardClause: - 'app/builders/account_builder.rb' - 'app/models/attachment.rb' - 'app/models/message.rb' - - 'lib/webhooks/chargebee.rb' - 'db/migrate/20190819005836_add_missing_indexes_on_taggings.acts_as_taggable_on_engine.rb' Metrics/AbcSize: Exclude: diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 06a287ae1..2569a6d66 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -88,7 +88,6 @@ Naming/MemoizedInstanceVariableName: - 'app/controllers/application_controller.rb' - 'app/models/message.rb' - 'lib/integrations/widget/outgoing_message_builder.rb' - - 'lib/webhooks/chargebee.rb' # Offense count: 4 # Cop supports --auto-correct. @@ -187,7 +186,6 @@ Rails/EnumHash: - 'app/models/attachment.rb' - 'app/models/conversation.rb' - 'app/models/message.rb' - - 'app/models/subscription.rb' - 'app/models/user.rb' # Offense count: 1 @@ -226,7 +224,6 @@ Rails/Output: Rails/TimeZone: Exclude: - 'app/builders/report_builder.rb' - - 'app/models/subscription.rb' - 'lib/reports/update_account_identity.rb' - 'lib/reports/update_agent_identity.rb' - 'lib/reports/update_identity.rb' diff --git a/Gemfile b/Gemfile index 6d16179ea..5397d5130 100644 --- a/Gemfile +++ b/Gemfile @@ -56,9 +56,6 @@ gem 'administrate' # https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/ gem 'wisper', '2.0.0' -##--- gems for billing ---## -gem 'chargebee' - ##--- gems for channels ---## gem 'facebook-messenger' gem 'telegram-bot-ruby' diff --git a/Gemfile.lock b/Gemfile.lock index dffbfb1f3..3f8ff49e7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -138,9 +138,6 @@ GEM bundler (>= 1.2.0, < 3) thor (~> 0.18) byebug (11.1.3) - chargebee (2.7.5) - json_pure (~> 2.1) - rest-client (>= 1.8, < 3.0) coderay (1.1.2) coercible (1.0.0) descendants_tracker (~> 0.0.1) @@ -249,7 +246,6 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (2.3.0) - json_pure (2.3.0) jwt (2.2.1) kaminari (1.2.1) activesupport (>= 4.1.0) @@ -542,7 +538,6 @@ DEPENDENCIES bullet bundle-audit byebug - chargebee devise devise_token_auth dotenv-rails diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 9be255080..1b9fa24cc 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -10,8 +10,4 @@ class Api::BaseController < ApplicationController def authenticate_by_access_token? request.headers[:api_access_token].present? || request.headers[:HTTP_API_ACCESS_TOKEN].present? end - - def check_billing_enabled - raise ActionController::RoutingError, 'Not Found' unless ENV['BILLING_ENABLED'] - end end diff --git a/app/controllers/api/v1/accounts/subscriptions_controller.rb b/app/controllers/api/v1/accounts/subscriptions_controller.rb deleted file mode 100644 index 4c4f6de01..000000000 --- a/app/controllers/api/v1/accounts/subscriptions_controller.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Api::V1::Accounts::SubscriptionsController < Api::V1::Accounts::BaseController - skip_before_action :check_subscription - - before_action :check_billing_enabled - - def index - render json: Current.account.subscription_data - end - - def status - render json: Current.account.subscription.summary - end -end diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index d23f535a5..3fb0509e3 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -2,7 +2,7 @@ class Api::V1::AccountsController < Api::BaseController include AuthHelper skip_before_action :verify_authenticity_token, only: [:create] - skip_before_action :authenticate_user!, :set_current_user, :check_subscription, :handle_with_exception, + skip_before_action :authenticate_user!, :set_current_user, :handle_with_exception, only: [:create], raise: false before_action :check_signup_enabled, only: [:create] before_action :fetch_account, except: [:create] diff --git a/app/controllers/api/v1/agent_bots_controller.rb b/app/controllers/api/v1/agent_bots_controller.rb index 4c17fd4f4..a82f71bb9 100644 --- a/app/controllers/api/v1/agent_bots_controller.rb +++ b/app/controllers/api/v1/agent_bots_controller.rb @@ -1,6 +1,5 @@ class Api::V1::AgentBotsController < Api::BaseController skip_before_action :authenticate_user! - skip_before_action :check_subscription def index render json: AgentBot.all diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 5db576000..b2c4949df 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -1,18 +1,6 @@ class Api::V1::WebhooksController < ApplicationController skip_before_action :authenticate_user!, raise: false skip_before_action :set_current_user - skip_before_action :check_subscription - - before_action :login_from_basic_auth, only: [:chargebee] - before_action :check_billing_enabled, only: [:chargebee] - - def chargebee - chargebee_consumer.consume - head :ok - rescue StandardError => e - Raven.capture_exception(e) - head :ok - end def twitter_crc render json: { response_token: "sha256=#{twitter_client.generate_crc(params[:crc_token])}" } @@ -34,16 +22,6 @@ class Api::V1::WebhooksController < ApplicationController end end - def login_from_basic_auth - authenticate_or_request_with_http_basic do |username, password| - username == ENV['CHARGEBEE_WEBHOOK_USERNAME'] && password == ENV['CHARGEBEE_WEBHOOK_PASSWORD'] - end - end - - def chargebee_consumer - @chargebee_consumer ||= ::Webhooks::Chargebee.new(params) - end - def twitter_consumer @twitter_consumer ||= ::Webhooks::Twitter.new(params) end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 3d7f59f0c..a7764cbc9 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -1,6 +1,5 @@ class ApiController < ApplicationController skip_before_action :set_current_user, only: [:index] - skip_before_action :check_subscription, only: [:index] def index render json: { version: Chatwoot.config[:version], timestamp: Time.now.utc.to_formatted_s(:db) } diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ab1be9b9b..4b22c8d32 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,7 +5,6 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :null_session before_action :set_current_user, unless: :devise_controller? - before_action :check_subscription, unless: :devise_controller? around_action :handle_with_exception, unless: :devise_controller? # after_action :verify_authorized @@ -68,18 +67,6 @@ class ApplicationController < ActionController::Base I18n.locale = locale || I18n.default_locale end - def check_subscription - # This block is left over from the initial version of chatwoot - # We might reuse this later in the hosted version of chatwoot. - return if !ENV['BILLING_ENABLED'] || !current_user - - if current_subscription.trial? && current_subscription.expiry < Date.current - render json: { error: 'Trial Expired' }, status: :trial_expired - elsif current_subscription.cancelled? - render json: { error: 'Account Suspended' }, status: :account_suspended - end - end - def pundit_user { user: Current.user, diff --git a/app/dispatchers/async_dispatcher.rb b/app/dispatchers/async_dispatcher.rb index 64ea55be3..8ddc963b5 100644 --- a/app/dispatchers/async_dispatcher.rb +++ b/app/dispatchers/async_dispatcher.rb @@ -10,7 +10,6 @@ class AsyncDispatcher < BaseDispatcher def listeners listeners = [EventListener.instance, WebhookListener.instance] - listeners << SubscriptionListener.instance if ENV['BILLING_ENABLED'] listeners end end diff --git a/app/helpers/api/v1/subscriptions_helper.rb b/app/helpers/api/v1/subscriptions_helper.rb deleted file mode 100644 index 2e7177559..000000000 --- a/app/helpers/api/v1/subscriptions_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module Api::V1::SubscriptionsHelper -end diff --git a/app/javascript/dashboard/api/billing.js b/app/javascript/dashboard/api/billing.js deleted file mode 100644 index 6bc076640..000000000 --- a/app/javascript/dashboard/api/billing.js +++ /dev/null @@ -1,20 +0,0 @@ -/* global axios */ - -import endPoints from './endPoints'; - -export default { - getSubscription() { - const urlData = endPoints('subscriptions').get(); - const fetchPromise = new Promise((resolve, reject) => { - axios - .get(urlData.url) - .then(response => { - resolve(response); - }) - .catch(error => { - reject(error); - }); - }); - return fetchPromise; - }, -}; diff --git a/app/javascript/dashboard/api/endPoints.js b/app/javascript/dashboard/api/endPoints.js index 53c669eb6..8df609f70 100644 --- a/app/javascript/dashboard/api/endPoints.js +++ b/app/javascript/dashboard/api/endPoints.js @@ -33,14 +33,6 @@ const endPoints = { }, params: { omniauth_token: '' }, }, - - subscriptions: { - get() { - return { - url: '/api/v1/subscriptions', - }; - }, - }, }; export default page => { diff --git a/app/javascript/dashboard/assets/scss/_woot.scss b/app/javascript/dashboard/assets/scss/_woot.scss index 947204ca6..7f5ef39c9 100644 --- a/app/javascript/dashboard/assets/scss/_woot.scss +++ b/app/javascript/dashboard/assets/scss/_woot.scss @@ -3,7 +3,6 @@ @import 'animations'; @import 'foundation-custom'; -@import 'widgets/billing'; @import 'widgets/buttons'; @import 'widgets/conv-header'; @import 'widgets/conversation-card'; diff --git a/app/javascript/dashboard/assets/scss/widgets/_billing.scss b/app/javascript/dashboard/assets/scss/widgets/_billing.scss deleted file mode 100644 index 0fd6d45ff..000000000 --- a/app/javascript/dashboard/assets/scss/widgets/_billing.scss +++ /dev/null @@ -1,75 +0,0 @@ -.billing { - @include full-height; - - .row { - @include full-height; - } - - .billing__stats { - @include flex; - } - - .billing__form { - @include thin-border($color-border-light); - @include margin($zero - $space-micro); - @include full-height; - background: $color-white; - - iframe { - @include full-height; - border: 0; - width: 100%; - } - } - - .account-row { - @include padding($space-normal); - @include flex; - flex-direction: column; - // @include thin-border($color-border-light); - // @include margin(-$space-micro $zero); - background: $color-white; - font-size: $font-size-small; - - .title { - color: $color-heading; - font-weight: $font-weight-medium; - } - - .value { - font-size: $font-size-mega; - font-weight: $font-weight-light; - text-transform: capitalize; - } - } -} - -.account-locked { - @include background-gray; - @include margin(0); -} - -.lock-message { - @include flex; - @include full-height; - flex-direction: column; - @include flex-align(center, middle); - - div { - @include flex; - @include full-height; - flex-direction: column; - @include flex-align(center, middle); - - img { - @include margin($space-normal); - width: 10rem; - } - - span { - font-size: $font-size-small; - font-weight: $font-weight-medium; - text-align: center; - } - } -} diff --git a/app/javascript/dashboard/components/layout/Sidebar.vue b/app/javascript/dashboard/components/layout/Sidebar.vue index 986232749..b2ccf1697 100644 --- a/app/javascript/dashboard/components/layout/Sidebar.vue +++ b/app/javascript/dashboard/components/layout/Sidebar.vue @@ -21,18 +21,6 @@ - - - - -
!menuItem.toState.includes('billing') - ); - }, filterMenuItemsByRole(menuItems) { if (!this.currentRole) { return []; diff --git a/app/javascript/dashboard/components/widgets/StatusBar.vue b/app/javascript/dashboard/components/widgets/StatusBar.vue deleted file mode 100644 index 902c2515e..000000000 --- a/app/javascript/dashboard/components/widgets/StatusBar.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/app/javascript/dashboard/helper/APIHelper.js b/app/javascript/dashboard/helper/APIHelper.js index b1692d492..03e902259 100644 --- a/app/javascript/dashboard/helper/APIHelper.js +++ b/app/javascript/dashboard/helper/APIHelper.js @@ -1,15 +1,8 @@ /* eslint no-console: 0 */ import constants from '../constants'; import Auth from '../api/auth'; -import router from '../routes'; const parseErrorCode = error => { - const errorStatus = error.response ? error.response.status : undefined; - // 901, 902 are used to identify billing related issues - if ([901, 902].includes(errorStatus)) { - const name = Auth.isAdmin() ? 'billing' : 'billing_deactivated'; - router.push({ name }); - } return Promise.reject(error); }; diff --git a/app/javascript/dashboard/i18n/default-sidebar.js b/app/javascript/dashboard/i18n/default-sidebar.js index f1823915c..5ada97da4 100644 --- a/app/javascript/dashboard/i18n/default-sidebar.js +++ b/app/javascript/dashboard/i18n/default-sidebar.js @@ -8,7 +8,6 @@ export const getSidebarItems = accountId => ({ 'inbox_conversation', 'conversation_through_inbox', 'settings_account_reports', - 'billing_deactivated', 'profile_settings', 'profile_settings_index', ], @@ -51,7 +50,6 @@ export const getSidebarItems = accountId => ({ 'settings_inboxes_page_channel', 'settings_inboxes_add_agents', 'settings_inbox_finish', - 'billing', 'settings_integrations', 'settings_integrations_webhook', 'general_settings', @@ -88,13 +86,6 @@ export const getSidebarItems = accountId => ({ ), toStateName: 'canned_list', }, - billing: { - icon: 'ion-card', - label: 'BILLING', - hasSubMenu: false, - toState: frontendURL(`accounts/${accountId}/settings/billing`), - toStateName: 'billing', - }, settings_integrations: { icon: 'ion-flash', label: 'INTEGRATIONS', diff --git a/app/javascript/dashboard/i18n/locale/ca/billing.json b/app/javascript/dashboard/i18n/locale/ca/billing.json deleted file mode 100644 index c44ba0dbf..000000000 --- a/app/javascript/dashboard/i18n/locale/ca/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Facturació", - "LOADING": "S'estan obtenin les suscripcions", - "ACCOUNT_STATE": "Estat del compte", - "AGENT_COUNT": "Compte d'agent", - "PER_AGENT_COST": "Per cost d'agent", - "TOTAL_COST": "Cost total", - "BUTTON": { - "ADD": "Afegir mètode de pagament", - "EDIT": "EDITAR Mètode de pagament" - }, - "TRIAL": { - "TITLE": "S'ha acabat el període de prova", - "MESSAGE": "Afegiu un mètode de pagament per continuar utilitzant Chatwoot." - }, - "ACCOUNT_LOCKED": "El seu compte no està disponible de moment.
Poseu-vos en contacte amb l'administrador per reactivar-lo." - } -} diff --git a/app/javascript/dashboard/i18n/locale/ca/index.js b/app/javascript/dashboard/i18n/locale/ca/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/ca/index.js +++ b/app/javascript/dashboard/i18n/locale/ca/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/ca/settings.json b/app/javascript/dashboard/i18n/locale/ca/settings.json index a36b33447..bf2ffbe39 100644 --- a/app/javascript/dashboard/i18n/locale/ca/settings.json +++ b/app/javascript/dashboard/i18n/locale/ca/settings.json @@ -87,7 +87,6 @@ "AGENTS": "Agents", "INBOXES": "Safates d'entrada", "CANNED_RESPONSES": "Respostes Predeterminades", - "BILLING": "Facturació", "INTEGRATIONS": "Integracions", "ACCOUNT_SETTINGS": "Configuració del compte" } diff --git a/app/javascript/dashboard/i18n/locale/cs/billing.json b/app/javascript/dashboard/i18n/locale/cs/billing.json deleted file mode 100644 index cf6469e88..000000000 --- a/app/javascript/dashboard/i18n/locale/cs/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Fakturace", - "LOADING": "Načítání předplatného", - "ACCOUNT_STATE": "Stav účtu", - "AGENT_COUNT": "Počet agentů", - "PER_AGENT_COST": "Náklady na jednoho agenta", - "TOTAL_COST": "Celkové náklady", - "BUTTON": { - "ADD": "Přidat způsob platby", - "EDIT": "Metoda platby EDIT" - }, - "TRIAL": { - "TITLE": "Vaše zkušební období skončilo", - "MESSAGE": "Přidejte platební metodu a pokračujte v používání Chatwoot." - }, - "ACCOUNT_LOCKED": "Váš účet není momentálně k dispozici.
Obraťte se na správce pro opětovné aktivaci." - } -} diff --git a/app/javascript/dashboard/i18n/locale/de/billing.json b/app/javascript/dashboard/i18n/locale/de/billing.json deleted file mode 100644 index 44f4f290f..000000000 --- a/app/javascript/dashboard/i18n/locale/de/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Abrechnung", - "LOADING": "Abonnements abrufen", - "ACCOUNT_STATE": "Kontostatus", - "AGENT_COUNT": "Anzahl der Agenten", - "PER_AGENT_COST": "Kosten pro Agent", - "TOTAL_COST": "Gesamtkosten", - "BUTTON": { - "ADD": "Zahlungsmethode hinzufügen", - "EDIT": "Zahlungsmethode BEARBEITEN" - }, - "TRIAL": { - "TITLE": "Ihre Probezeit ist vorbei", - "MESSAGE": "Fügen Sie eine Zahlungsmethode hinzu, um Chatwoot weiterhin zu verwenden." - }, - "ACCOUNT_LOCKED": "Ihr Konto ist derzeit nicht verfügbar.
Bitte wenden Sie sich zur Reaktivierung an Ihren Administrator." - } -} diff --git a/app/javascript/dashboard/i18n/locale/de/index.js b/app/javascript/dashboard/i18n/locale/de/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/de/index.js +++ b/app/javascript/dashboard/i18n/locale/de/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/de/settings.json b/app/javascript/dashboard/i18n/locale/de/settings.json index 70a99e24b..c9ff6b118 100644 --- a/app/javascript/dashboard/i18n/locale/de/settings.json +++ b/app/javascript/dashboard/i18n/locale/de/settings.json @@ -90,7 +90,6 @@ "AGENTS": "Agenten", "INBOXES": "Posteingänge", "CANNED_RESPONSES": "Vorgefertigte Antworten", - "BILLING": "Abrechnung", "INTEGRATIONS": "Integrationen", "ACCOUNT_SETTINGS": "Kontoeinstellungen" } diff --git a/app/javascript/dashboard/i18n/locale/el/billing.json b/app/javascript/dashboard/i18n/locale/el/billing.json deleted file mode 100644 index 6a96433ff..000000000 --- a/app/javascript/dashboard/i18n/locale/el/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Χρεώσεις", - "LOADING": "Λήψη Συνδρομών", - "ACCOUNT_STATE": "Κατάσταση Λογαριασμού", - "AGENT_COUNT": "Αριθμός Πρακτόρων", - "PER_AGENT_COST": "Κόστος ανά πράκτορα", - "TOTAL_COST": "Συνολικό κόστος", - "BUTTON": { - "ADD": "Προσθήκη μεθόδου πληρωμής", - "EDIT": "Επεξεργασία μεθόδου πληρωμής" - }, - "TRIAL": { - "TITLE": "Η δοκιμαστική περίοδος ολοκληρώθηκε", - "MESSAGE": "Προσθέστε μια μέθοδο πληρωμής για να συνεχίσετε την χρήση του Chatwoot." - }, - "ACCOUNT_LOCKED": "O Λογαριασμός σας δεν είναι ενεργός αυτήν τη στιγμή.
Παρακαλώ απευθυνθείτε στον διαχειριστή για ενεργοποίηση." - } -} diff --git a/app/javascript/dashboard/i18n/locale/el/index.js b/app/javascript/dashboard/i18n/locale/el/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/el/index.js +++ b/app/javascript/dashboard/i18n/locale/el/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/el/settings.json b/app/javascript/dashboard/i18n/locale/el/settings.json index 9f8790ffb..1af3e5b01 100644 --- a/app/javascript/dashboard/i18n/locale/el/settings.json +++ b/app/javascript/dashboard/i18n/locale/el/settings.json @@ -102,7 +102,6 @@ "AGENTS": "Πράκτορες", "INBOXES": "Κιβώτια Εισερχομένων", "CANNED_RESPONSES": "Έτοιμες Απαντήσεις", - "BILLING": "Χρεώσεις", "INTEGRATIONS": "Ενοποιήσεις", "ACCOUNT_SETTINGS": "Ρυθμίσεις Λογαριασμού" } diff --git a/app/javascript/dashboard/i18n/locale/en/agentMgmt.json b/app/javascript/dashboard/i18n/locale/en/agentMgmt.json index 6ec788207..633424fed 100644 --- a/app/javascript/dashboard/i18n/locale/en/agentMgmt.json +++ b/app/javascript/dashboard/i18n/locale/en/agentMgmt.json @@ -3,7 +3,7 @@ "HEADER": "Agents", "HEADER_BTN_TXT": "Add Agent", "LOADING": "Fetching Agent List", - "SIDEBAR_TXT": "

Agents

An Agent is a member of your Customer Support team.

Agents will be able to view and reply to messages from your users. The list shows all agents currently in your account.

Click on Add Agent to add a new agent. Agent you add will receive an email with a confirmation link to activate their account, after which they can access Chatwoot and respond to messages.

Access to Chatwoot's features are based on following roles.

Agent - Agents with this role can only access inboxes, reports and conversations. They can assign conversations to other agents or themselves and resolve conversations.

Administrator - Administrator will have access to all Chatwoot features enabled for your account, including settings and billing, along with all of a normal agents' privileges.

", + "SIDEBAR_TXT": "

Agents

An Agent is a member of your Customer Support team.

Agents will be able to view and reply to messages from your users. The list shows all agents currently in your account.

Click on Add Agent to add a new agent. Agent you add will receive an email with a confirmation link to activate their account, after which they can access Chatwoot and respond to messages.

Access to Chatwoot's features are based on following roles.

Agent - Agents with this role can only access inboxes, reports and conversations. They can assign conversations to other agents or themselves and resolve conversations.

Administrator - Administrator will have access to all Chatwoot features enabled for your account, including settings, along with all of a normal agents' privileges.

", "AGENT_TYPES": [ { "name": "administrator", diff --git a/app/javascript/dashboard/i18n/locale/en/billing.json b/app/javascript/dashboard/i18n/locale/en/billing.json deleted file mode 100644 index 4d300775d..000000000 --- a/app/javascript/dashboard/i18n/locale/en/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Billing", - "LOADING": "Fetching Subscriptions", - "ACCOUNT_STATE": "Account State", - "AGENT_COUNT": "Agent Count", - "PER_AGENT_COST": "Per Agent Cost", - "TOTAL_COST": "Total Cost", - "BUTTON": { - "ADD": "Add Payment Method", - "EDIT": "EDIT Payment Method" - }, - "TRIAL": { - "TITLE": "Your Trial period is over", - "MESSAGE": "Add a payment method to continue using Chatwoot." - }, - "ACCOUNT_LOCKED": "Your account is not available at the moment.
Please contact your administrator for reactivation." - } -} diff --git a/app/javascript/dashboard/i18n/locale/en/index.js b/app/javascript/dashboard/i18n/locale/en/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/en/index.js +++ b/app/javascript/dashboard/i18n/locale/en/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/en/settings.json b/app/javascript/dashboard/i18n/locale/en/settings.json index c1955d90d..38f5a4aac 100644 --- a/app/javascript/dashboard/i18n/locale/en/settings.json +++ b/app/javascript/dashboard/i18n/locale/en/settings.json @@ -102,7 +102,6 @@ "AGENTS": "Agents", "INBOXES": "Inboxes", "CANNED_RESPONSES": "Canned Responses", - "BILLING": "Billing", "INTEGRATIONS": "Integrations", "ACCOUNT_SETTINGS": "Account Settings" } diff --git a/app/javascript/dashboard/i18n/locale/es/billing.json b/app/javascript/dashboard/i18n/locale/es/billing.json deleted file mode 100644 index a7b7b58fb..000000000 --- a/app/javascript/dashboard/i18n/locale/es/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Facturación", - "LOADING": "Obteniendo suscripciones", - "ACCOUNT_STATE": "Estado de cuenta", - "AGENT_COUNT": "Contador de agentes", - "PER_AGENT_COST": "Coste por agente", - "TOTAL_COST": "Coste total", - "BUTTON": { - "ADD": "Añadir método de pago", - "EDIT": "Método de pago EDIT" - }, - "TRIAL": { - "TITLE": "Su período de prueba ha terminado", - "MESSAGE": "Añadir un método de pago para seguir usando Chatwoot." - }, - "ACCOUNT_LOCKED": "Su cuenta no está disponible en este momento.
Póngase en contacto con su administrador para reactivación." - } -} diff --git a/app/javascript/dashboard/i18n/locale/es/index.js b/app/javascript/dashboard/i18n/locale/es/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/es/index.js +++ b/app/javascript/dashboard/i18n/locale/es/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/es/settings.json b/app/javascript/dashboard/i18n/locale/es/settings.json index bd1838a69..0833a8f34 100644 --- a/app/javascript/dashboard/i18n/locale/es/settings.json +++ b/app/javascript/dashboard/i18n/locale/es/settings.json @@ -102,7 +102,6 @@ "AGENTS": "Agentes", "INBOXES": "Entradas", "CANNED_RESPONSES": "Respuestas predefinidas", - "BILLING": "Facturación", "INTEGRATIONS": "Integraciones", "ACCOUNT_SETTINGS": "Configuración de la cuenta" } diff --git a/app/javascript/dashboard/i18n/locale/fr/billing.json b/app/javascript/dashboard/i18n/locale/fr/billing.json deleted file mode 100644 index f66afe559..000000000 --- a/app/javascript/dashboard/i18n/locale/fr/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Facturation", - "LOADING": "Récupération des abonnements", - "ACCOUNT_STATE": "État du compte", - "AGENT_COUNT": "Nombre d'agents", - "PER_AGENT_COST": "Coût par agent", - "TOTAL_COST": "Coût total", - "BUTTON": { - "ADD": "Ajouter une méthode de paiement", - "EDIT": "MODIFIER la méthode de paiement" - }, - "TRIAL": { - "TITLE": "Votre période d'essai est terminée", - "MESSAGE": "Ajoutez une méthode de paiement pour continuer à utiliser Chatwoot." - }, - "ACCOUNT_LOCKED": "Votre compte n'est pas disponible pour le moment.
Veuillez contacter votre administrateur pour la réactivation." - } -} diff --git a/app/javascript/dashboard/i18n/locale/fr/index.js b/app/javascript/dashboard/i18n/locale/fr/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/fr/index.js +++ b/app/javascript/dashboard/i18n/locale/fr/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/fr/settings.json b/app/javascript/dashboard/i18n/locale/fr/settings.json index 7aca5abb1..ba7d64d0b 100644 --- a/app/javascript/dashboard/i18n/locale/fr/settings.json +++ b/app/javascript/dashboard/i18n/locale/fr/settings.json @@ -102,7 +102,6 @@ "AGENTS": "Agents", "INBOXES": "Boîtes de réception", "CANNED_RESPONSES": "Réponses standardisées", - "BILLING": "Facturation", "INTEGRATIONS": "Intégrations", "ACCOUNT_SETTINGS": "Paramètres du compte" } diff --git a/app/javascript/dashboard/i18n/locale/it/billing.json b/app/javascript/dashboard/i18n/locale/it/billing.json deleted file mode 100644 index af0c125e7..000000000 --- a/app/javascript/dashboard/i18n/locale/it/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Fatturazione", - "LOADING": "Recupero Iscrizioni", - "ACCOUNT_STATE": "Stato del conto", - "AGENT_COUNT": "Conteggio Agente", - "PER_AGENT_COST": "Costo per agente", - "TOTAL_COST": "Costo totale", - "BUTTON": { - "ADD": "Aggiungi metodo di pagamento", - "EDIT": "Metodo di pagamento EDIT" - }, - "TRIAL": { - "TITLE": "Il tuo periodo di prova è finito", - "MESSAGE": "Aggiungi un metodo di pagamento per continuare a utilizzare Chatwoot." - }, - "ACCOUNT_LOCKED": "Il tuo account non è al momento disponibile.
Si prega di contattare l'amministratore per la riattivazione." - } -} diff --git a/app/javascript/dashboard/i18n/locale/ml/billing.json b/app/javascript/dashboard/i18n/locale/ml/billing.json deleted file mode 100644 index d44fdd661..000000000 --- a/app/javascript/dashboard/i18n/locale/ml/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "ബില്ലിംഗ്", - "LOADING": "സബ്സ്ക്രിപ്ഷനുകൾ ലഭ്യമാക്കുന്നു", - "ACCOUNT_STATE": "അക്കൗണ്ടിന്റെ അവസ്ഥ", - "AGENT_COUNT": "ഏജന്റിന്റെ എണ്ണം ", - "PER_AGENT_COST": "ഓരോ ഏജന്റിന്റെ വില", - "TOTAL_COST": "ആകെ ചെലവ്", - "BUTTON": { - "ADD": "പേയ്‌മെന്റ് രീതി ചേർക്കുക", - "EDIT": "പേയ്‌മെന്റ് രീതി എഡിറ്റുചെയ്യുക" - }, - "TRIAL": { - "TITLE": "നിങ്ങളുടെ ട്രയൽ കാലയളവ് അവസാനിച്ചു", - "MESSAGE": "ചാറ്റ് വൂട്ട് ഉപയോഗിക്കുന്നത് തുടരാൻ ഒരു പേയ്‌മെന്റ് രീതി ചേർക്കുക." - }, - "ACCOUNT_LOCKED": "നിങ്ങളുടെ അക്കൗണ്ട് ഇപ്പോൾ ലഭ്യമല്ല.
വീണ്ടും സജീവമാക്കുന്നതിന് ദയവായി നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക." - } -} diff --git a/app/javascript/dashboard/i18n/locale/ml/index.js b/app/javascript/dashboard/i18n/locale/ml/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/ml/index.js +++ b/app/javascript/dashboard/i18n/locale/ml/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/ml/settings.json b/app/javascript/dashboard/i18n/locale/ml/settings.json index c768f6d1c..d7e89fb3f 100644 --- a/app/javascript/dashboard/i18n/locale/ml/settings.json +++ b/app/javascript/dashboard/i18n/locale/ml/settings.json @@ -90,7 +90,6 @@ "AGENTS": "ഏജന്റുമാർ", "INBOXES": "ഇൻബോക്സുകൾ", "CANNED_RESPONSES": "ക്യാൻഡ് പ്രതികരണങ്ങൾ", - "BILLING": "ബില്ലിംഗ്", "INTEGRATIONS": "സംയോജനങ്ങൾ", "ACCOUNT_SETTINGS": "അക്കൗണ്ട് ക്രമീകരണങ്ങൾ" } diff --git a/app/javascript/dashboard/i18n/locale/nl/billing.json b/app/javascript/dashboard/i18n/locale/nl/billing.json deleted file mode 100644 index d5a46cfd1..000000000 --- a/app/javascript/dashboard/i18n/locale/nl/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Facturatie", - "LOADING": "Ophalen Abonnementen", - "ACCOUNT_STATE": "Accountstatus", - "AGENT_COUNT": "Aantal Medewerkers", - "PER_AGENT_COST": "Kosten per medewerker", - "TOTAL_COST": "Totale kosten", - "BUTTON": { - "ADD": "Betaalmethode toevoegen", - "EDIT": "Betalingsmethode bewerken" - }, - "TRIAL": { - "TITLE": "Uw proefperiode is voorbij", - "MESSAGE": "Voeg een betaalmethode toe om Chatwoot te blijven gebruiken." - }, - "ACCOUNT_LOCKED": "Uw account is op dit moment niet beschikbaar.
Neem contact op met uw beheerder voor heractivatie." - } -} diff --git a/app/javascript/dashboard/i18n/locale/nl/index.js b/app/javascript/dashboard/i18n/locale/nl/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/nl/index.js +++ b/app/javascript/dashboard/i18n/locale/nl/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/nl/settings.json b/app/javascript/dashboard/i18n/locale/nl/settings.json index a5f604209..e013885d4 100644 --- a/app/javascript/dashboard/i18n/locale/nl/settings.json +++ b/app/javascript/dashboard/i18n/locale/nl/settings.json @@ -102,7 +102,6 @@ "AGENTS": "Medewerkers", "INBOXES": "Inboxen", "CANNED_RESPONSES": "Standaard antwoorden", - "BILLING": "Facturatie", "INTEGRATIONS": "Integraties", "ACCOUNT_SETTINGS": "Accountinstellingen" } diff --git a/app/javascript/dashboard/i18n/locale/pl/billing.json b/app/javascript/dashboard/i18n/locale/pl/billing.json deleted file mode 100644 index 6a3a07496..000000000 --- a/app/javascript/dashboard/i18n/locale/pl/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Płatność", - "LOADING": "Pobieranie subskrypcji", - "ACCOUNT_STATE": "Stan konta", - "AGENT_COUNT": "Liczba agentów", - "PER_AGENT_COST": "Koszt za agenta", - "TOTAL_COST": "Całkowity koszt", - "BUTTON": { - "ADD": "Dodaj metodę płatności", - "EDIT": "Metoda płatności EDIT" - }, - "TRIAL": { - "TITLE": "Twój okres próbny minął", - "MESSAGE": "Dodaj metodę płatności, aby kontynuować korzystanie z Chatwoot." - }, - "ACCOUNT_LOCKED": "Twoje konto nie jest obecnie dostępne.
Skontaktuj się z administratorem, aby reaktywować." - } -} diff --git a/app/javascript/dashboard/i18n/locale/pt/billing.json b/app/javascript/dashboard/i18n/locale/pt/billing.json deleted file mode 100644 index 07cc720f6..000000000 --- a/app/javascript/dashboard/i18n/locale/pt/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Faturamento", - "LOADING": "Buscando Assinaturas", - "ACCOUNT_STATE": "Estado do cliente", - "AGENT_COUNT": "Número de Representantes", - "PER_AGENT_COST": "Custo por agente", - "TOTAL_COST": "Custo Total", - "BUTTON": { - "ADD": "Adicionar método de pagamento", - "EDIT": "EDIT Método de Pagamento" - }, - "TRIAL": { - "TITLE": "Seu período de avaliação terminou", - "MESSAGE": "Adicione um método de pagamento para continuar usando o Chatwoot." - }, - "ACCOUNT_LOCKED": "Sua conta não está disponível no momento.
Por favor, entre em contato com o administrador para reativação." - } -} diff --git a/app/javascript/dashboard/i18n/locale/pt/index.js b/app/javascript/dashboard/i18n/locale/pt/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/pt/index.js +++ b/app/javascript/dashboard/i18n/locale/pt/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/pt/settings.json b/app/javascript/dashboard/i18n/locale/pt/settings.json index 2d1c5d4d5..95d891773 100644 --- a/app/javascript/dashboard/i18n/locale/pt/settings.json +++ b/app/javascript/dashboard/i18n/locale/pt/settings.json @@ -67,7 +67,6 @@ "AGENTS": "Agentes", "INBOXES": "Caixas de entrada", "CANNED_RESPONSES": "Respostas Enlatadas", - "BILLING": "Faturamento", "INTEGRATIONS": "Integrações", "ACCOUNT_SETTINGS": "Configurações da conta" } diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/billing.json b/app/javascript/dashboard/i18n/locale/pt_BR/billing.json deleted file mode 100644 index 2c7d5f390..000000000 --- a/app/javascript/dashboard/i18n/locale/pt_BR/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Faturamento", - "LOADING": "Buscando Assinaturas", - "ACCOUNT_STATE": "Estado do cliente", - "AGENT_COUNT": "Número de Agente", - "PER_AGENT_COST": "Custo por agente", - "TOTAL_COST": "Custo Total", - "BUTTON": { - "ADD": "Adicionar Forma de Pagamento", - "EDIT": "Editar Forma de Pagamento" - }, - "TRIAL": { - "TITLE": "Seu período de avaliação terminou", - "MESSAGE": "Adicione um método de pagamento para continuar usando o Chatwoot." - }, - "ACCOUNT_LOCKED": "Sua conta não está disponível no momento.
Por favor, entre em contato com o administrador para reativação." - } -} diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/index.js b/app/javascript/dashboard/i18n/locale/pt_BR/index.js index 351906dd9..558cc9b3a 100644 --- a/app/javascript/dashboard/i18n/locale/pt_BR/index.js +++ b/app/javascript/dashboard/i18n/locale/pt_BR/index.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/settings.json b/app/javascript/dashboard/i18n/locale/pt_BR/settings.json index 25c61cf86..65b7dc8e2 100644 --- a/app/javascript/dashboard/i18n/locale/pt_BR/settings.json +++ b/app/javascript/dashboard/i18n/locale/pt_BR/settings.json @@ -100,7 +100,6 @@ "AGENTS": "Agentes", "INBOXES": "Caixas de Entrada", "CANNED_RESPONSES": "Atalhos", - "BILLING": "Faturamento", "INTEGRATIONS": "Integrações", "ACCOUNT_SETTINGS": "Configurações da conta" } diff --git a/app/javascript/dashboard/i18n/locale/ro/billing.json b/app/javascript/dashboard/i18n/locale/ro/billing.json deleted file mode 100644 index fb5c851fd..000000000 --- a/app/javascript/dashboard/i18n/locale/ro/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Facturare", - "LOADING": "Preluare abonamente", - "ACCOUNT_STATE": "Stare cont", - "AGENT_COUNT": "Număr de agenți", - "PER_AGENT_COST": "Cost per Agent", - "TOTAL_COST": "Cost total", - "BUTTON": { - "ADD": "Adaugă metodă de plată", - "EDIT": "Adaugă metodă de plată" - }, - "TRIAL": { - "TITLE": "Perioada de evaluare s-a încheiat", - "MESSAGE": "Adaugă o metodă de plată pentru a continua să folosești Chatwoot." - }, - "ACCOUNT_LOCKED": "Contul dvs. nu este disponibil momentan.
Vă rugăm să contactaţi administratorul pentru reactivare." - } -} diff --git a/app/javascript/dashboard/i18n/locale/ro/index.js b/app/javascript/dashboard/i18n/locale/ro/index.js index 7cc96f9eb..6b0a4bb4d 100644 --- a/app/javascript/dashboard/i18n/locale/ro/index.js +++ b/app/javascript/dashboard/i18n/locale/ro/index.js @@ -1,5 +1,4 @@ import { default as _agentMgmt } from './agentMgmt.json'; -import { default as _billing } from './billing.json'; import { default as _cannedMgmt } from './cannedMgmt.json'; import { default as _chatlist } from './chatlist.json'; import { default as _contact } from './contact.json'; @@ -16,7 +15,6 @@ import { default as _generalSettings } from './generalSettings.json'; export default { ..._agentMgmt, - ..._billing, ..._cannedMgmt, ..._chatlist, ..._contact, diff --git a/app/javascript/dashboard/i18n/locale/ro/settings.json b/app/javascript/dashboard/i18n/locale/ro/settings.json index b85bdc9c0..0f8551131 100644 --- a/app/javascript/dashboard/i18n/locale/ro/settings.json +++ b/app/javascript/dashboard/i18n/locale/ro/settings.json @@ -102,7 +102,6 @@ "AGENTS": "Agenți", "INBOXES": "Căsuțe", "CANNED_RESPONSES": "Răspunsuri predefinite", - "BILLING": "Facturare", "INTEGRATIONS": "Integrări", "ACCOUNT_SETTINGS": "Setările contului" } diff --git a/app/javascript/dashboard/i18n/locale/sv/billing.json b/app/javascript/dashboard/i18n/locale/sv/billing.json deleted file mode 100644 index 2a2a1ba33..000000000 --- a/app/javascript/dashboard/i18n/locale/sv/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Fakturering", - "LOADING": "Hämtar prenumerationer", - "ACCOUNT_STATE": "Kontots status", - "AGENT_COUNT": "Agentkommando Antal", - "PER_AGENT_COST": "Per agent: kostnad", - "TOTAL_COST": "Total kostnad", - "BUTTON": { - "ADD": "Lägg till betalningsmetod", - "EDIT": "EDIT betalningsmetod" - }, - "TRIAL": { - "TITLE": "Din provperiod är över", - "MESSAGE": "Lägg till en betalningsmetod för att fortsätta använda Chatwoot." - }, - "ACCOUNT_LOCKED": "Ditt konto är inte tillgängligt just nu.
Kontakta administratören för återaktivering." - } -} diff --git a/app/javascript/dashboard/i18n/locale/uk/billing.json b/app/javascript/dashboard/i18n/locale/uk/billing.json deleted file mode 100644 index 0363d000b..000000000 --- a/app/javascript/dashboard/i18n/locale/uk/billing.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "BILLING": { - "HEADER": "Оплата", - "LOADING": "Отримання підписок", - "ACCOUNT_STATE": "Стан облікового запису", - "AGENT_COUNT": "Кількість агентів", - "PER_AGENT_COST": "Вартість одного агента", - "TOTAL_COST": "Загальна вартість", - "BUTTON": { - "ADD": "Додати спосіб оплати", - "EDIT": "РЕДАГУВАТИ спосіб оплати" - }, - "TRIAL": { - "TITLE": "Пробний період закінчився", - "MESSAGE": "Додайте спосіб оплати, щоб продовжити використовувати Chatwoot." - }, - "ACCOUNT_LOCKED": "На даний момент ваш обліковий запис недоступний.
Зверніться до свого адміністратора для повторної активації." - } -} diff --git a/app/javascript/dashboard/routes/dashboard/settings/billing/AccountLocked.vue b/app/javascript/dashboard/routes/dashboard/settings/billing/AccountLocked.vue deleted file mode 100644 index 1c26d0f48..000000000 --- a/app/javascript/dashboard/routes/dashboard/settings/billing/AccountLocked.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/app/javascript/dashboard/routes/dashboard/settings/billing/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/billing/Index.vue deleted file mode 100644 index 23099d858..000000000 --- a/app/javascript/dashboard/routes/dashboard/settings/billing/Index.vue +++ /dev/null @@ -1,124 +0,0 @@ - - - diff --git a/app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js b/app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js deleted file mode 100644 index 58bf309c3..000000000 --- a/app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js +++ /dev/null @@ -1,32 +0,0 @@ -import Index from './Index'; -import SettingsContent from '../Wrapper'; -import AccountLocked from './AccountLocked'; -import { frontendURL } from '../../../../helper/URLHelper'; - -export default { - routes: [ - { - path: frontendURL('accounts/:accountId/settings/billing'), - component: SettingsContent, - props: { - headerTitle: 'BILLING.HEADER', - icon: 'ion-card', - }, - children: [ - { - path: '', - name: 'billing', - component: Index, - roles: ['administrator'], - props: route => ({ state: route.query.state }), - }, - ], - }, - { - path: '/deactivated', - name: 'billing_deactivated', - component: AccountLocked, - roles: ['agent'], - }, - ], -}; diff --git a/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js b/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js index 5907768cc..f2f0d186c 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js @@ -1,6 +1,5 @@ import { frontendURL } from '../../../helper/URLHelper'; import agent from './agents/agent.routes'; -import billing from './billing/billing.routes'; import canned from './canned/canned.routes'; import inbox from './inbox/inbox.routes'; import profile from './profile/profile.routes'; @@ -23,7 +22,6 @@ export default { }, }, ...agent.routes, - ...billing.routes, ...canned.routes, ...inbox.routes, ...profile.routes, diff --git a/app/javascript/dashboard/store/index.js b/app/javascript/dashboard/store/index.js index f88139003..9df653765 100755 --- a/app/javascript/dashboard/store/index.js +++ b/app/javascript/dashboard/store/index.js @@ -4,7 +4,6 @@ import Vuex from 'vuex'; import accounts from './modules/accounts'; import agents from './modules/agents'; import auth from './modules/auth'; -import billing from './modules/billing'; import cannedResponse from './modules/cannedResponse'; import Channel from './modules/channels'; import contactConversations from './modules/contactConversations'; @@ -27,7 +26,6 @@ export default new Vuex.Store({ accounts, agents, auth, - billing, cannedResponse, Channel, contactConversations, diff --git a/app/javascript/dashboard/store/modules/billing.js b/app/javascript/dashboard/store/modules/billing.js deleted file mode 100644 index 4df528516..000000000 --- a/app/javascript/dashboard/store/modules/billing.js +++ /dev/null @@ -1,60 +0,0 @@ -/* eslint no-console: 0 */ -/* eslint no-param-reassign: 0 */ -/* eslint no-shadow: 0 */ -import * as types from '../mutation-types'; -import Billing from '../../api/billing'; - -const state = { - fetchingStatus: false, - billingDetails: {}, - status: null, -}; - -const getters = { - getBillingDetails(_state) { - return _state.billingDetails; - }, - billingFetchStatus(_state) { - return _state.fetchingStatus; - }, -}; - -const actions = { - fetchSubscription({ commit }) { - commit(types.default.TOGGLE_SUBSCRIPTION_LOADING, true); - Billing.getSubscription() - .then(billingDetails => { - commit(types.default.SET_SUBSCRIPTION, billingDetails.data); - commit( - types.default.TOGGLE_SUBSCRIPTION_LOADING, - false, - billingDetails.status - ); - }) - .catch(error => { - const { response } = error; - commit( - types.default.TOGGLE_SUBSCRIPTION_LOADING, - false, - response.status - ); - }); - }, -}; - -const mutations = { - [types.default.SET_SUBSCRIPTION](_state, billingDetails) { - _state.billingDetails = billingDetails; - }, - [types.default.TOGGLE_SUBSCRIPTION_LOADING](_state, flag, apiStatus) { - _state.fetchingStatus = flag; - _state.status = apiStatus; - }, -}; - -export default { - state, - getters, - actions, - mutations, -}; diff --git a/app/javascript/dashboard/store/mutation-types.js b/app/javascript/dashboard/store/mutation-types.js index 5357415b2..15c5fe577 100755 --- a/app/javascript/dashboard/store/mutation-types.js +++ b/app/javascript/dashboard/store/mutation-types.js @@ -93,10 +93,6 @@ export default { SET_ACCOUNT_SUMMARY: 'SET_ACCOUNT_SUMMARY', TOGGLE_ACCOUNT_REPORT_LOADING: 'TOGGLE_ACCOUNT_REPORT_LOADING', - // Billings - SET_SUBSCRIPTION: 'SET_SUBSCRIPTION', - TOGGLE_SUBSCRIPTION_LOADING: 'TOGGLE_SUBSCRIPTION_LOADING', - // Conversation Metadata SET_CONVERSATION_METADATA: 'SET_CONVERSATION_METADATA', diff --git a/app/listeners/subscription_listener.rb b/app/listeners/subscription_listener.rb deleted file mode 100644 index 947bcdee7..000000000 --- a/app/listeners/subscription_listener.rb +++ /dev/null @@ -1,35 +0,0 @@ -# This listener is left over from the initial version of chatwoot -# We might reuse this later in the hosted version of chatwoot. - -class SubscriptionListener < BaseListener - def subscription_created(event) - subscription = event.data[:subscription] - account = subscription.account - Subscription::ChargebeeService.create_subscription(account) - end - - def account_destroyed(event) - account = event.data[:account] - Subscription::ChargebeeService.cancel_subscription(account) - end - - def agent_added(event) - account = event.data[:account] - Subscription::ChargebeeService.update_subscription(account) - end - - def agent_removed(event) - account = event.data[:account] - Subscription::ChargebeeService.update_subscription(account) - end - - def subscription_reactivated(event) - account = event.data[:account] - Subscription::ChargebeeService.reactivate_subscription(account) - end - - def subscription_deactivated(event) - account = event.data[:account] - Subscription::ChargebeeService.deactivate_subscription(account) - end -end diff --git a/app/models/account.rb b/app/models/account.rb index dbae201d3..3e5b48f00 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -46,13 +46,11 @@ class Account < ApplicationRecord has_many :canned_responses, dependent: :destroy has_many :webhooks, dependent: :destroy has_many :labels, dependent: :destroy - has_one :subscription, dependent: :destroy has_many :notification_settings, dependent: :destroy has_flags ACCOUNT_SETTINGS_FLAGS.merge(column: 'settings_flags').merge(DEFAULT_QUERY_SETTING) enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_1_code], key] }.to_h - after_create :create_subscription after_create :notify_creation after_destroy :notify_deletion @@ -74,22 +72,6 @@ class Account < ApplicationRecord .map { |_| _.tag.name } end - def subscription_data - agents_count = users.count - per_agent_price = Plan.paid_plan.price - { - state: subscription.state, - expiry: subscription.expiry.to_i, - agents_count: agents_count, - per_agent_cost: per_agent_price, - total_cost: (per_agent_price * agents_count), - iframe_url: Subscription::ChargebeeService.hosted_page_url(self), - trial_expired: subscription.trial_expired?, - account_suspended: subscription.suspended?, - payment_source_added: subscription.payment_source_added - } - end - def webhook_data { id: id, @@ -99,11 +81,6 @@ class Account < ApplicationRecord private - def create_subscription - subscription = build_subscription - subscription.save - end - def notify_creation Rails.configuration.dispatcher.dispatch(ACCOUNT_CREATED, Time.zone.now, account: self) end diff --git a/app/models/channel/web_widget.rb b/app/models/channel/web_widget.rb index 203049f64..5b3762a5b 100644 --- a/app/models/channel/web_widget.rb +++ b/app/models/channel/web_widget.rb @@ -2,16 +2,15 @@ # # Table name: channel_web_widgets # -# id :integer not null, primary key -# agent_away_message :string -# website_token :string -# website_url :string -# welcome_tagline :string -# welcome_title :string -# widget_color :string default("#1f93ff") -# created_at :datetime not null -# updated_at :datetime not null -# account_id :integer +# id :integer not null, primary key +# website_token :string +# website_url :string +# welcome_tagline :string +# welcome_title :string +# widget_color :string default("#1f93ff") +# created_at :datetime not null +# updated_at :datetime not null +# account_id :integer # # Indexes # diff --git a/app/models/subscription.rb b/app/models/subscription.rb deleted file mode 100644 index 8a3afebe3..000000000 --- a/app/models/subscription.rb +++ /dev/null @@ -1,57 +0,0 @@ -# == Schema Information -# -# Table name: subscriptions -# -# id :integer not null, primary key -# billing_plan :string default("trial") -# expiry :datetime -# payment_source_added :boolean default(FALSE) -# pricing_version :string -# state :integer default("trial") -# created_at :datetime not null -# updated_at :datetime not null -# account_id :integer -# stripe_customer_id :string -# - -class Subscription < ApplicationRecord - include Events::Types - - belongs_to :account - before_create :set_default_billing_params - after_create :notify_creation - - enum state: [:trial, :active, :cancelled] - - def payment_source_added! - self.payment_source_added = true - save - end - - def trial_expired? - (trial? && expiry < Date.current) || - (cancelled? && !payment_source_added) - end - - def suspended? - cancelled? && payment_source_added - end - - def summary - { - state: state, - expiry: expiry.to_i - } - end - - private - - def set_default_billing_params - self.expiry = Time.now + Plan.default_trial_period - self.pricing_version = Plan.default_pricing_version - end - - def notify_creation - Rails.configuration.dispatcher.dispatch(SUBSCRIPTION_CREATED, Time.zone.now, subscription: self) - end -end diff --git a/app/models/user.rb b/app/models/user.rb index 2476f586e..6157767a2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -118,7 +118,6 @@ class User < ApplicationRecord def serializable_hash(options = nil) serialized_user = super(options).merge(confirmed: confirmed?) - serialized_user.merge(subscription: account.try(:subscription).try(:summary)) if ENV['BILLING_ENABLED'] serialized_user end diff --git a/app/services/subscription/chargebee_service.rb b/app/services/subscription/chargebee_service.rb deleted file mode 100644 index 2df2af660..000000000 --- a/app/services/subscription/chargebee_service.rb +++ /dev/null @@ -1,70 +0,0 @@ -class Subscription::ChargebeeService - class << self - def create_subscription(account) - result = ChargeBee::Subscription.create( - plan_id: Plan.paid_plan.id, - customer: { - email: account.users.administrator.try(:first).try(:email), - first_name: account.name, - company: account.name - } - ) - subscription = account.subscription - subscription.stripe_customer_id = result.subscription.customer_id - subscription.save - rescue StandardError => e - Raven.capture_exception(e) - end - - def update_subscription(account) - subscription = account.subscription - agents_count = account.users.count - ChargeBee::Subscription.update(subscription.stripe_customer_id, plan_quantity: agents_count) - rescue StandardError => e - Raven.capture_exception(e) - end - - def cancel_subscription(account) - subscription = account.subscription - ChargeBee::Subscription.delete(subscription.stripe_customer_id) - rescue StandardError => e - Raven.capture_exception(e) - end - - def reactivate_subscription(account) - subscription = account.subscription - ChargeBee::Subscription.reactivate(subscription.stripe_customer_id) - subscription.active! - rescue StandardError => e - Raven.capture_exception(e) - end - - def deactivate_subscription(account) - subscription = account.subscription - ChargeBee::Subscription.cancel(subscription.stripe_customer_id) - subscription.cancelled! - rescue StandardError => e - Raven.capture_exception(e) - end - - def hosted_page_url(account) - subscription = account.subscription - - # result = ChargeBee::HostedPage.checkout_existing({ - # :subscription => { - # :id => subscription.stripe_customer_id, - # :plan_id => Plan.paid_plan.id - # } - # }) - - result = ChargeBee::HostedPage.update_payment_method( - customer: { - id: subscription.stripe_customer_id - } - ) - result.hosted_page.url - rescue StandardError => e - Raven.capture_exception(e) - end - end -end diff --git a/app/views/layouts/vueapp.html.erb b/app/views/layouts/vueapp.html.erb index f93ccb464..c2dae5279 100644 --- a/app/views/layouts/vueapp.html.erb +++ b/app/views/layouts/vueapp.html.erb @@ -31,7 +31,6 @@ window.chatwootConfig = { hostURL: '<%= ENV.fetch('FRONTEND_URL', '') %>', fbAppId: '<%= ENV.fetch('FB_APP_ID', nil) %>', - billingEnabled: <%= ActiveModel::Type::Boolean.new.cast(ENV.fetch('BILLING_ENABLED', false)) %>, signupEnabled: '<%= ENV.fetch('ENABLE_ACCOUNT_SIGNUP', true) %>', <% if ENV['VAPID_PUBLIC_KEY'] %> vapidPublicKey: new Uint8Array(<%= Base64.urlsafe_decode64(ENV['VAPID_PUBLIC_KEY']).bytes %>), diff --git a/config/initializers/00_init.rb b/config/initializers/00_init.rb deleted file mode 100644 index f2fc3c112..000000000 --- a/config/initializers/00_init.rb +++ /dev/null @@ -1,2 +0,0 @@ -PLAN_CONFIG = YAML.load_file(File.join(Rails.root, 'config', 'plans.yml')) -$chargebee = ChargeBee.configure(site: ENV['CHARGEBEE_SITE'], api_key: ENV['CHARGEBEE_API_KEY']) diff --git a/config/plans.yml b/config/plans.yml deleted file mode 100644 index a00917dd4..000000000 --- a/config/plans.yml +++ /dev/null @@ -1,17 +0,0 @@ -active: - v1: - paid: - name: 'Platinum' - id: 'v1-platinum' - price: 29 - trial: - name: 'Trial' - id: 'v1Trial' - price: 0 -inactive: - v0: - free: - name: 'Free' - price: 0 -trial_period: 365 -default_pricing_version: 'v1' diff --git a/config/routes.rb b/config/routes.rb index b0a9b9388..f1c3327d4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -83,13 +83,6 @@ Rails.application.routes.draw do resources :notifications, only: [:index, :update] resource :notification_settings, only: [:show, :update] - # this block is only required if subscription via chargebee is enabled - resources :subscriptions, only: [:index] do - collection do - get :summary - end - end - resources :webhooks, except: [:show] end end @@ -114,12 +107,6 @@ Rails.application.routes.draw do resources :inbox_members, only: [:index] resources :labels, only: [:create, :destroy] end - - resources :webhooks, only: [] do - collection do - post :chargebee - end - end end namespace :v2 do diff --git a/db/migrate/20200607140737_remove_subscriptions.rb b/db/migrate/20200607140737_remove_subscriptions.rb new file mode 100644 index 000000000..33f756083 --- /dev/null +++ b/db/migrate/20200607140737_remove_subscriptions.rb @@ -0,0 +1,15 @@ +class RemoveSubscriptions < ActiveRecord::Migration[6.0] + def change + drop_table :subscriptions do |t| + t.string 'pricing_version' + t.integer 'account_id' + t.datetime 'expiry' + t.string 'billing_plan', default: 'trial' + t.string 'stripe_customer_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.integer 'state', default: 0 + t.boolean 'payment_source_added', default: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 1ef9c48e1..914058c79 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_06_06_132552) do +ActiveRecord::Schema.define(version: 2020_06_07_140737) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" @@ -328,18 +328,6 @@ ActiveRecord::Schema.define(version: 2020_06_06_132552) do t.index ["user_id"], name: "index_notifications_on_user_id" end - create_table "subscriptions", id: :serial, force: :cascade do |t| - t.string "pricing_version" - t.integer "account_id" - t.datetime "expiry" - t.string "billing_plan", default: "trial" - t.string "stripe_customer_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "state", default: 0 - t.boolean "payment_source_added", default: false - end - create_table "super_admins", force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false diff --git a/lib/webhooks/chargebee.rb b/lib/webhooks/chargebee.rb deleted file mode 100644 index dd28a110b..000000000 --- a/lib/webhooks/chargebee.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -class Webhooks::Chargebee - SUPPORTED_EVENTS = [:subscription_created, :subscription_trial_end_reminder, - :subscription_activated, :subscription_cancelled, - :subscription_reactivated, :subscription_deleted, - :subscription_renewed, :payment_source_added, :subscription_changed].freeze - - attr_accessor :params, :account - - def initialize(params) - @params = params - end - - def consume - send(event_name) if supported_event? - end - - private - - def event_name - @params[:event_type] - end - - def customer_id - @params[:content][:customer][:id] - end - - def trial_ends_on - trial_end = @params[:content][:subscription][:trial_end] - DateTime.strptime(trial_end, '%s') - end - - def supported_event? - SUPPORTED_EVENTS.include?(event_name.to_sym) - end - - def subscription - @subscriptiom ||= Subscription.find_by(stripe_customer_id: customer_id) - end - - def subscription_created - Raven.capture_message("subscription created for #{customer_id}") - end - - def subscription_changed - if subscription.expiry != trial_ends_on - subscription.expiry = trial_ends_on - subscription.save - subscription.trial! - end - end - - def subscription_trial_end_reminder - # Raven.capture_message("subscription trial end reminder for #{customer_id}") - end - - def subscription_activated - subscription.active! - Raven.capture_message("subscription activated for #{customer_id}") - end - - def subscription_cancelled - # if there is a reason field in response. Then cancellation is due to payment failure - subscription.cancelled! - Raven.capture_message("subscription cancelled for #{customer_id}") - end - - def subscription_reactivated - # TODO: send mail to user that account is reactivated - subscription.active! - Raven.capture_message("subscription reactivated for #{customer_id}") - end - - def subscription_renewed - # TODO: Needs this to show payment history. - Raven.capture_message("subscription renewed for #{customer_id}") - end - - def subscription_deleted; end - - def payment_source_added - Raven.capture_message("payment source added for #{customer_id}") - subscription.payment_source_added! - end -end diff --git a/spec/controllers/api/v1/accounts/subscriptions_controller_spec.rb b/spec/controllers/api/v1/accounts/subscriptions_controller_spec.rb deleted file mode 100644 index af7071f21..000000000 --- a/spec/controllers/api/v1/accounts/subscriptions_controller_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'Subscriptions API', type: :request do - let(:account) { create(:account) } - - describe 'GET /api/v1/accounts/{account.id}/subscriptions' do - context 'when it is an unauthenticated user' do - it 'returns unauthorized' do - ENV['BILLING_ENABLED'] = 'true' - - get "/api/v1/accounts/#{account.id}/subscriptions" - - expect(response).to have_http_status(:unauthorized) - - ENV['BILLING_ENABLED'] = nil - end - end - - context 'when it is an authenticated user' do - let(:agent) { create(:user, account: account, role: :agent) } - - it 'returns all subscriptions' do - ENV['BILLING_ENABLED'] = 'true' - - get "/api/v1/accounts/#{account.id}/subscriptions", - headers: agent.create_new_auth_token, - as: :json - - expect(response).to have_http_status(:success) - expect(JSON.parse(response.body)).to eq(account.subscription_data.as_json) - - ENV['BILLING_ENABLED'] = nil - end - - it 'throws 404 error if env variable is not set' do - ENV['BILLING_ENABLED'] = nil - - get "/api/v1/accounts/#{account.id}/subscriptions", - headers: agent.create_new_auth_token, - as: :json - - expect(response).to have_http_status(:not_found) - end - end - end -end diff --git a/spec/fixtures/subscriptions.yml b/spec/fixtures/subscriptions.yml deleted file mode 100644 index f279a5c48..000000000 --- a/spec/fixtures/subscriptions.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html - -one: - pricing_version: MyString - account_id: 1 - expiry: 2017-04-24 22:47:08 - billing_plan: MyString - stripe_customer_id: MyString - -two: - pricing_version: MyString - account_id: 1 - expiry: 2017-04-24 22:47:08 - billing_plan: MyString - stripe_customer_id: MyString diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 821eb31ba..59929ae8f 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -14,7 +14,6 @@ RSpec.describe Account do it { is_expected.to have_many(:canned_responses).dependent(:destroy) } it { is_expected.to have_many(:facebook_pages).class_name('::Channel::FacebookPage').dependent(:destroy) } it { is_expected.to have_many(:web_widgets).class_name('::Channel::WebWidget').dependent(:destroy) } - it { is_expected.to have_one(:subscription).dependent(:destroy) } it { is_expected.to have_many(:webhooks).dependent(:destroy) } it { is_expected.to have_many(:notification_settings).dependent(:destroy) } it { is_expected.to have_many(:events) } From 602132119b7da5a8692888d4d0184ab0d86d3aed Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Mon, 8 Jun 2020 19:13:33 +0530 Subject: [PATCH 08/50] Fix socket reconnect if the pubsub token is same (#942) --- app/javascript/widget/helpers/actionCable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/widget/helpers/actionCable.js b/app/javascript/widget/helpers/actionCable.js index a743471f5..c4ab32b27 100644 --- a/app/javascript/widget/helpers/actionCable.js +++ b/app/javascript/widget/helpers/actionCable.js @@ -56,7 +56,7 @@ class ActionCableConnector extends BaseActionCableConnector { } export const refreshActionCableConnector = pubsubToken => { - if (!pubsubToken) { + if (!pubsubToken || window.chatwootPubsubToken === pubsubToken) { return; } window.chatwootPubsubToken = pubsubToken; From 40481f64623df2dfd5da8c5db144725d5a77d4ab Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Tue, 9 Jun 2020 16:26:33 +0530 Subject: [PATCH 09/50] Bugfix: Update conversation counters in realtime (#944) * Bug: Update conversation counters in realtime --- .../dashboard/api/inbox/conversation.js | 10 +++++++ .../api/specs/inbox/conversation.spec.js | 19 ++++++++++++ .../dashboard/api/specs/inboxes.spec.js | 2 +- .../assets/scss/widgets/_conv-header.scss | 2 ++ .../scss/widgets/_conversation-view.scss | 1 + .../dashboard/components/ChatList.vue | 20 +++++++++---- .../dashboard/helper/actionCable.js | 8 +++++ .../store/modules/conversations/actions.js | 9 ++++++ .../conversations/specs/actions.spec.js | 30 +++++++++++++++++++ .../accounts/conversations/meta.json.jbuilder | 10 +++---- .../accounts/conversations_controller_spec.rb | 2 +- 11 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 app/javascript/dashboard/api/specs/inbox/conversation.spec.js create mode 100644 app/javascript/dashboard/store/modules/conversations/specs/actions.spec.js diff --git a/app/javascript/dashboard/api/inbox/conversation.js b/app/javascript/dashboard/api/inbox/conversation.js index 9a50ef1c8..d3942efea 100644 --- a/app/javascript/dashboard/api/inbox/conversation.js +++ b/app/javascript/dashboard/api/inbox/conversation.js @@ -43,6 +43,16 @@ class ConversationApi extends ApiClient { mute(conversationId) { return axios.post(`${this.url}/${conversationId}/mute`); } + + meta({ inboxId, status, assigneeType }) { + return axios.get(`${this.url}/meta`, { + params: { + inbox_id: inboxId, + status, + assignee_type: assigneeType, + }, + }); + } } export default new ConversationApi(); diff --git a/app/javascript/dashboard/api/specs/inbox/conversation.spec.js b/app/javascript/dashboard/api/specs/inbox/conversation.spec.js new file mode 100644 index 000000000..4eceba728 --- /dev/null +++ b/app/javascript/dashboard/api/specs/inbox/conversation.spec.js @@ -0,0 +1,19 @@ +import conversationAPI from '../../inbox/conversation'; +import ApiClient from '../../ApiClient'; + +describe('#ConversationAPI', () => { + it('creates correct instance', () => { + expect(conversationAPI).toBeInstanceOf(ApiClient); + expect(conversationAPI).toHaveProperty('get'); + expect(conversationAPI).toHaveProperty('show'); + expect(conversationAPI).toHaveProperty('create'); + expect(conversationAPI).toHaveProperty('update'); + expect(conversationAPI).toHaveProperty('delete'); + expect(conversationAPI).toHaveProperty('toggleStatus'); + expect(conversationAPI).toHaveProperty('assignAgent'); + expect(conversationAPI).toHaveProperty('markMessageRead'); + expect(conversationAPI).toHaveProperty('toggleTyping'); + expect(conversationAPI).toHaveProperty('mute'); + expect(conversationAPI).toHaveProperty('meta'); + }); +}); diff --git a/app/javascript/dashboard/api/specs/inboxes.spec.js b/app/javascript/dashboard/api/specs/inboxes.spec.js index d1a1d2683..c4927e2bb 100644 --- a/app/javascript/dashboard/api/specs/inboxes.spec.js +++ b/app/javascript/dashboard/api/specs/inboxes.spec.js @@ -1,7 +1,7 @@ import inboxes from '../inboxes'; import ApiClient from '../ApiClient'; -describe('#AgentAPI', () => { +describe('#InboxesAPI', () => { it('creates correct instance', () => { expect(inboxes).toBeInstanceOf(ApiClient); expect(inboxes).toHaveProperty('get'); diff --git a/app/javascript/dashboard/assets/scss/widgets/_conv-header.scss b/app/javascript/dashboard/assets/scss/widgets/_conv-header.scss index 6de396353..e1aef9307 100644 --- a/app/javascript/dashboard/assets/scss/widgets/_conv-header.scss +++ b/app/javascript/dashboard/assets/scss/widgets/_conv-header.scss @@ -66,6 +66,8 @@ } .button.resolve--button { + @include flex-align($x: center, $y: middle); + width: 13.2rem; >.icon { diff --git a/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss b/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss index 6aef3e3f9..12d0f21a9 100644 --- a/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss +++ b/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss @@ -26,6 +26,7 @@ .link { color: $color-white; + text-decoration: underline; } } diff --git a/app/javascript/dashboard/components/ChatList.vue b/app/javascript/dashboard/components/ChatList.vue index 59012d516..a4cec45e3 100644 --- a/app/javascript/dashboard/components/ChatList.vue +++ b/app/javascript/dashboard/components/ChatList.vue @@ -55,6 +55,7 @@ From b0bbd757b519a915a83edf0177cf86ec6f3137e3 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Mon, 15 Jun 2020 13:36:56 +0530 Subject: [PATCH 25/50] Chore: FCM Notification Improvements (#957) Co-authored-by: Pranav Raj Sreepuram --- .../v1/accounts/notifications_controller.rb | 16 ++++++++++++- app/models/notification.rb | 5 ++++ .../notification/push_notification_service.rb | 13 +++++++---- .../notifications/index.json.jbuilder | 2 ++ .../accounts/notifications_controller_spec.rb | 23 ++++++++++++++++--- spec/models/notification_spec.rb | 21 +++++++++++++++++ 6 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 spec/models/notification_spec.rb diff --git a/app/controllers/api/v1/accounts/notifications_controller.rb b/app/controllers/api/v1/accounts/notifications_controller.rb index 1ec27ba29..8ae1629ca 100644 --- a/app/controllers/api/v1/accounts/notifications_controller.rb +++ b/app/controllers/api/v1/accounts/notifications_controller.rb @@ -2,6 +2,7 @@ class Api::V1::Accounts::NotificationsController < Api::V1::Accounts::BaseContro protect_from_forgery with: :null_session before_action :fetch_notification, only: [:update] + before_action :set_primary_actor, only: [:read_all] def index @unread_count = current_user.notifications.where(account_id: current_account.id, read_at: nil).count @@ -9,7 +10,13 @@ class Api::V1::Accounts::NotificationsController < Api::V1::Accounts::BaseContro end def read_all - current_user.notifications.where(account_id: current_account.id, read_at: nil).update(read_at: DateTime.now.utc) + if @primary_actor + current_user.notifications.where(account_id: current_account.id, primary_actor: @primary_actor, read_at: nil) + .update(read_at: DateTime.now.utc) + else + current_user.notifications.where(account_id: current_account.id, read_at: nil).update(read_at: DateTime.now.utc) + end + head :ok end @@ -20,6 +27,13 @@ class Api::V1::Accounts::NotificationsController < Api::V1::Accounts::BaseContro private + def set_primary_actor + return unless params[:primary_actor_type] + return unless Notification::PRIMARY_ACTORS.include?(params[:primary_actor_type]) + + @primary_actor = params[:primary_actor_type].safe_constantize.find_by(id: params[:primary_actor_id]) + end + def fetch_notification @notification = current_user.notifications.find(params[:id]) end diff --git a/app/models/notification.rb b/app/models/notification.rb index 660bcc33c..33c04dda2 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -37,11 +37,16 @@ class Notification < ApplicationRecord enum notification_type: NOTIFICATION_TYPES after_create_commit :process_notification_delivery + default_scope { order(id: :desc) } + + PRIMARY_ACTORS = ['Conversation'].freeze def push_event_data { id: id, notification_type: notification_type, + primary_actor_type: primary_actor_type, + primary_actor_id: primary_actor_id, primary_actor: primary_actor&.push_event_data, read_at: read_at, secondary_actor: secondary_actor&.push_event_data, diff --git a/app/services/notification/push_notification_service.rb b/app/services/notification/push_notification_service.rb index fadfddf53..275e10c2b 100644 --- a/app/services/notification/push_notification_service.rb +++ b/app/services/notification/push_notification_service.rb @@ -66,15 +66,18 @@ class Notification::PushNotificationService return unless subscription.fcm? fcm = FCM.new(ENV['FCM_SERVER_KEY']) - options = { + response = fcm.send([subscription.subscription_attributes['push_token']], fcm_options) + subscription.destroy! if JSON.parse(response[:body])['results']&.first&.keys&.include?('error') + end + + def fcm_options + { "notification": { "title": notification.notification_type.titleize, "body": notification.push_message_title }, - "data": { notification: notification.push_event_data.to_json } + "data": { notification: notification.push_event_data.to_json }, + "collapse_key": "chatwoot_#{notification.primary_actor_type.downcase}_#{notification.primary_actor_id}" } - - response = fcm.send([subscription.subscription_attributes['push_token']], options) - subscription.destroy! if JSON.parse(response[:body])['results']&.first&.keys&.include?('error') end end diff --git a/app/views/api/v1/accounts/notifications/index.json.jbuilder b/app/views/api/v1/accounts/notifications/index.json.jbuilder index 048c3d85c..b69d869e6 100644 --- a/app/views/api/v1/accounts/notifications/index.json.jbuilder +++ b/app/views/api/v1/accounts/notifications/index.json.jbuilder @@ -8,6 +8,8 @@ json.data do json.id notification.id json.notification_type notification.notification_type json.push_message_title notification.push_message_title + json.primary_actor_type notification.primary_actor_type + json.primary_actor_id notification.primary_actor_id json.primary_actor notification.primary_actor&.push_event_data json.read_at notification.read_at json.secondary_actor notification.secondary_actor&.push_event_data diff --git a/spec/controllers/api/v1/accounts/notifications_controller_spec.rb b/spec/controllers/api/v1/accounts/notifications_controller_spec.rb index 594a198b6..8f61cd803 100644 --- a/spec/controllers/api/v1/accounts/notifications_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/notifications_controller_spec.rb @@ -14,7 +14,8 @@ RSpec.describe 'Notifications API', type: :request do context 'when it is an authenticated user' do let(:admin) { create(:user, account: account, role: :administrator) } - let!(:notification) { create(:notification, account: account, user: admin) } + let!(:notification1) { create(:notification, account: account, user: admin) } + let!(:notification2) { create(:notification, account: account, user: admin) } it 'returns all notifications' do get "/api/v1/accounts/#{account.id}/notifications", @@ -23,8 +24,10 @@ RSpec.describe 'Notifications API', type: :request do response_json = JSON.parse(response.body) expect(response).to have_http_status(:success) - expect(response.body).to include(notification.notification_type) - expect(response_json['data']['meta']['unread_count']).to eq 1 + expect(response.body).to include(notification1.notification_type) + expect(response_json['data']['meta']['unread_count']).to eq 2 + # notification appear in descending order + expect(response_json['data']['payload'].first['id']).to eq notification2.id end end end @@ -54,6 +57,20 @@ RSpec.describe 'Notifications API', type: :request do expect(notification1.reload.read_at).not_to eq('') expect(notification2.reload.read_at).not_to eq('') end + + it 'updates only the notifications read at for primary actor when param is passed' do + post "/api/v1/accounts/#{account.id}/notifications/read_all", + headers: admin.create_new_auth_token, + params: { + primary_actor_id: notification1.primary_actor_id, + primary_actor_type: notification1.primary_actor_type + }, + as: :json + + expect(response).to have_http_status(:success) + expect(notification1.reload.read_at).not_to eq('') + expect(notification2.reload.read_at).to eq nil + end end end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb new file mode 100644 index 000000000..7920df919 --- /dev/null +++ b/spec/models/notification_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Notification do + context 'with associations' do + it { is_expected.to belong_to(:account) } + it { is_expected.to belong_to(:user) } + end + + context 'with default order by' do + it 'sort by primary id desc' do + notification1 = create(:notification) + create(:notification) + notification3 = create(:notification) + + expect(described_class.all.first).to eq notification3 + expect(described_class.all.last).to eq notification1 + end + end +end From 04f6460afb2cdaf880eda7d07d8c3cb9f1eae055 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Tue, 16 Jun 2020 19:39:57 +0530 Subject: [PATCH 26/50] Chore: Fix failing sidekiq events for contact create (#966) --- .rubocop.yml | 2 +- app/models/contact.rb | 4 ++-- .../notification/push_notification_service.rb | 7 ++++++- config/initializers/00_init.rb | 2 +- config/initializers/custom_error_codes.rb | 6 ++---- config/routes.rb | 11 +++++------ .../notification/push_notification_service_spec.rb | 4 ++++ 7 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index af3e3f831..d1a1cb5f5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -102,8 +102,8 @@ AllCops: Exclude: - 'bin/**/*' - 'db/schema.rb' - - 'config/**/*' - 'public/**/*' + - 'config/initializers/bot.rb' - 'vendor/**/*' - 'node_modules/**/*' - 'lib/tasks/auto_annotate_models.rake' diff --git a/app/models/contact.rb b/app/models/contact.rb index 00783f5bc..9ea82ba4c 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -38,8 +38,8 @@ class Contact < ApplicationRecord has_many :messages, dependent: :destroy before_validation :downcase_email - after_create :dispatch_create_event - after_update :dispatch_update_event + after_create_commit :dispatch_create_event + after_update_commit :dispatch_update_event def get_source_id(inbox_id) contact_inboxes.find_by!(inbox_id: inbox_id).source_id diff --git a/app/services/notification/push_notification_service.rb b/app/services/notification/push_notification_service.rb index 275e10c2b..76aa44478 100644 --- a/app/services/notification/push_notification_service.rb +++ b/app/services/notification/push_notification_service.rb @@ -41,8 +41,12 @@ class Notification::PushNotificationService app_account_conversation_url(account_id: conversation.account_id, id: conversation.display_id) end + def send_browser_push?(subscription) + ENV['VAPID_PUBLIC_KEY'] && subscription.browser_push? + end + def send_browser_push(subscription) - return unless subscription.browser_push? + return unless send_browser_push?(subscription) Webpush.payload_send( message: JSON.generate(push_message), @@ -63,6 +67,7 @@ class Notification::PushNotificationService end def send_fcm_push(subscription) + return unless ENV['FCM_SERVER_KEY'] return unless subscription.fcm? fcm = FCM.new(ENV['FCM_SERVER_KEY']) diff --git a/config/initializers/00_init.rb b/config/initializers/00_init.rb index b72fc4be1..8a12cc226 100644 --- a/config/initializers/00_init.rb +++ b/config/initializers/00_init.rb @@ -1 +1 @@ -APPS_CONFIG = YAML.load_file(File.join(Rails.root, 'config/integration', 'apps.yml')) \ No newline at end of file +APPS_CONFIG = YAML.load_file(Rails.root.join('config/integration/apps.yml')) diff --git a/config/initializers/custom_error_codes.rb b/config/initializers/custom_error_codes.rb index d5efcb034..e2800b2a3 100644 --- a/config/initializers/custom_error_codes.rb +++ b/config/initializers/custom_error_codes.rb @@ -1,4 +1,2 @@ -Rack::Utils::HTTP_STATUS_CODES.merge!( - 901 => 'Trial Expired', - 902 => 'Account Suspended' -) +Rack::Utils::HTTP_STATUS_CODES[901] = 'Trial Expired' +Rack::Utils::HTTP_STATUS_CODES[902] = 'Account Suspended' diff --git a/config/routes.rb b/config/routes.rb index 9602020e3..c4b6aeb62 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -87,11 +87,11 @@ Rails.application.routes.draw do end resource :notification_settings, only: [:show, :update] - resources :webhooks, except: [:show] - namespace :integrations do - resources :apps, only: [:index, :show] - resources :slack, only: [:create, :update, :destroy] - end + resources :webhooks, except: [:show] + namespace :integrations do + resources :apps, only: [:index, :show] + resources :slack, only: [:create, :update, :destroy] + end end end # end of account scoped api routes @@ -106,7 +106,6 @@ Rails.application.routes.draw do resources :agent_bots, only: [:index] - namespace :widget do resources :events, only: [:create] resources :messages, only: [:index, :create, :update] diff --git a/spec/services/notification/push_notification_service_spec.rb b/spec/services/notification/push_notification_service_spec.rb index 67fc9f999..44a5dbaf5 100644 --- a/spec/services/notification/push_notification_service_spec.rb +++ b/spec/services/notification/push_notification_service_spec.rb @@ -14,19 +14,23 @@ describe Notification::PushNotificationService do describe '#perform' do it 'sends webpush notifications for webpush subscription' do + ENV['VAPID_PUBLIC_KEY'] = 'test' create(:notification_subscription, user: notification.user) described_class.new(notification: notification).perform expect(Webpush).to have_received(:payload_send) expect(FCM).not_to have_received(:new) + ENV['ENABLE_ACCOUNT_SIGNUP'] = nil end it 'sends a fcm notification for firebase subscription' do + ENV['FCM_SERVER_KEY'] = 'test' create(:notification_subscription, user: notification.user, subscription_type: 'fcm') described_class.new(notification: notification).perform expect(FCM).to have_received(:new) expect(Webpush).not_to have_received(:payload_send) + ENV['ENABLE_ACCOUNT_SIGNUP'] = nil end end end From 963f173730691dcfa7fe8a4c21ae6d887e8dc1fe Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Thu, 18 Jun 2020 15:17:45 +0530 Subject: [PATCH 27/50] Feature: ResizableTextArea in widget and dashboard (#969) * Create ResizableTextArea component * Rubocop fixes and spec fixes Co-authored-by: Sojan --- .rubocop.yml | 17 ++ Gemfile.lock | 192 +++++++++--------- .../assets/scss/widgets/_reply-box.scss | 7 +- .../widgets/conversation/ReplyBox.vue | 7 +- .../shared/components/ResizableTextArea.vue | 56 +++++ .../widget/components/ChatInputArea.vue | 56 ----- .../widget/components/ChatInputWrap.vue | 28 ++- .../widget/components/ResizableTextarea.vue | 26 --- .../widget/components/UserMessageBubble.vue | 1 + app/presenters/mail_presenter.rb | 2 +- config/initializers/assets.rb | 1 + 11 files changed, 208 insertions(+), 185 deletions(-) create mode 100644 app/javascript/shared/components/ResizableTextArea.vue delete mode 100755 app/javascript/widget/components/ChatInputArea.vue delete mode 100644 app/javascript/widget/components/ResizableTextarea.vue diff --git a/.rubocop.yml b/.rubocop.yml index d1a1cb5f5..4d75629e8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,8 +8,17 @@ Lint/RaiseException: Enabled: true Lint/StructNewOverride: Enabled: true +Lint/DeprecatedOpenSSLConstant: + Enabled: true +Lint/MixedRegexpCaptureTypes: + Enabled: true Layout/LineLength: Max: 150 +Layout/EmptyLinesAroundAttributeAccessor: + Enabled: true +Layout/SpaceAroundMethodCallOperator: + Enabled: true + Metrics/ClassLength: Max: 125 Exclude: @@ -18,6 +27,8 @@ RSpec/ExampleLength: Max: 25 Style/Documentation: Enabled: false +Style/ExponentialNotation: + Enabled: false Style/FrozenStringLiteralComment: Enabled: false Style/SymbolArray: @@ -28,6 +39,12 @@ Style/HashTransformKeys: Enabled: true Style/HashTransformValues: Enabled: true +Style/RedundantRegexpCharacterClass: + Enabled: true +Style/RedundantRegexpEscape: + Enabled: true +Style/SlicingWithRange: + Enabled: true Style/GlobalVars: Exclude: - 'config/initializers/redis.rb' diff --git a/Gemfile.lock b/Gemfile.lock index aadeaf5be..a71da76b2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,56 +18,56 @@ GEM specs: action-cable-testing (0.6.1) actioncable (>= 5.0) - actioncable (6.0.3.1) - actionpack (= 6.0.3.1) + actioncable (6.0.3.2) + actionpack (= 6.0.3.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.3.1) - actionpack (= 6.0.3.1) - activejob (= 6.0.3.1) - activerecord (= 6.0.3.1) - activestorage (= 6.0.3.1) - activesupport (= 6.0.3.1) + actionmailbox (6.0.3.2) + actionpack (= 6.0.3.2) + activejob (= 6.0.3.2) + activerecord (= 6.0.3.2) + activestorage (= 6.0.3.2) + activesupport (= 6.0.3.2) mail (>= 2.7.1) - actionmailer (6.0.3.1) - actionpack (= 6.0.3.1) - actionview (= 6.0.3.1) - activejob (= 6.0.3.1) + actionmailer (6.0.3.2) + actionpack (= 6.0.3.2) + actionview (= 6.0.3.2) + activejob (= 6.0.3.2) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.3.1) - actionview (= 6.0.3.1) - activesupport (= 6.0.3.1) + actionpack (6.0.3.2) + actionview (= 6.0.3.2) + activesupport (= 6.0.3.2) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.3.1) - actionpack (= 6.0.3.1) - activerecord (= 6.0.3.1) - activestorage (= 6.0.3.1) - activesupport (= 6.0.3.1) + actiontext (6.0.3.2) + actionpack (= 6.0.3.2) + activerecord (= 6.0.3.2) + activestorage (= 6.0.3.2) + activesupport (= 6.0.3.2) nokogiri (>= 1.8.5) - actionview (6.0.3.1) - activesupport (= 6.0.3.1) + actionview (6.0.3.2) + activesupport (= 6.0.3.2) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.0.3.1) - activesupport (= 6.0.3.1) + activejob (6.0.3.2) + activesupport (= 6.0.3.2) globalid (>= 0.3.6) - activemodel (6.0.3.1) - activesupport (= 6.0.3.1) - activerecord (6.0.3.1) - activemodel (= 6.0.3.1) - activesupport (= 6.0.3.1) - activestorage (6.0.3.1) - actionpack (= 6.0.3.1) - activejob (= 6.0.3.1) - activerecord (= 6.0.3.1) + activemodel (6.0.3.2) + activesupport (= 6.0.3.2) + activerecord (6.0.3.2) + activemodel (= 6.0.3.2) + activesupport (= 6.0.3.2) + activestorage (6.0.3.2) + actionpack (= 6.0.3.2) + activejob (= 6.0.3.2) + activerecord (= 6.0.3.2) marcel (~> 0.3.1) - activesupport (6.0.3.1) + activesupport (6.0.3.2) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -91,25 +91,25 @@ GEM annotate (3.1.1) activerecord (>= 3.2, < 7.0) rake (>= 10.4, < 14.0) - ast (2.4.0) - attr_extras (6.2.3) + ast (2.4.1) + attr_extras (6.2.4) autoprefixer-rails (9.7.6) execjs aws-eventstream (1.1.0) - aws-partitions (1.317.0) - aws-sdk-core (3.96.1) + aws-partitions (1.329.0) + aws-sdk-core (3.100.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.31.0) - aws-sdk-core (~> 3, >= 3.71.0) + aws-sdk-kms (1.34.1) + aws-sdk-core (~> 3, >= 3.99.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.65.0) - aws-sdk-core (~> 3, >= 3.96.1) + aws-sdk-s3 (1.68.1) + aws-sdk-core (~> 3, >= 3.99.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) - aws-sigv4 (1.1.3) + aws-sigv4 (1.1.4) aws-eventstream (~> 1.0, >= 1.0.2) axiom-types (0.1.1) descendants_tracker (~> 0.0.4) @@ -127,22 +127,22 @@ GEM bootsnap (1.4.6) msgpack (~> 1.0) brakeman (4.8.2) - browser (4.1.0) + browser (4.2.0) builder (3.2.4) bullet (6.1.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) bundle-audit (0.1.0) bundler-audit - bundler-audit (0.6.1) + bundler-audit (0.7.0.1) bundler (>= 1.2.0, < 3) - thor (~> 0.18) + thor (>= 0.18, < 2) byebug (11.1.3) - coderay (1.1.2) + coderay (1.1.3) coercible (1.0.0) descendants_tracker (~> 0.0.1) concurrent-ruby (1.1.6) - connection_pool (2.2.2) + connection_pool (2.2.3) crack (0.4.3) safe_yaml (~> 1.0.0) crass (1.0.6) @@ -152,16 +152,17 @@ GEM declarative-option (0.1.0) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - devise (4.7.1) + devise (4.7.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - devise_token_auth (1.1.3) + devise_token_auth (1.1.4) bcrypt (~> 3.0) devise (> 3.5.2, < 5) rails (>= 4.2.0, < 6.1) + sprockets (= 3.7.2) diff-lcs (1.3) digest-crc (0.5.1) docile (1.3.2) @@ -182,7 +183,7 @@ GEM factory_bot_rails (5.2.0) factory_bot (~> 5.2.0) railties (>= 4.2.0) - faker (2.11.0) + faker (2.12.0) i18n (>= 1.6, < 2) faraday (1.0.1) multipart-post (>= 1.2, < 3) @@ -190,13 +191,13 @@ GEM faraday (~> 1.0) fcm (1.0.1) faraday (~> 1.0.0) - ffi (1.12.2) + ffi (1.13.1) flag_shih_tzu (0.3.23) foreman (0.87.1) - gli (2.19.0) + gli (2.19.1) globalid (0.4.2) activesupport (>= 4.2.0) - google-api-client (0.39.4) + google-api-client (0.40.2) addressable (~> 2.5, >= 2.5.1) googleauth (~> 0.9) httpclient (>= 2.8.1, < 3.0) @@ -207,10 +208,10 @@ GEM google-cloud-core (1.5.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.3.1) + google-cloud-env (1.3.2) faraday (>= 0.17.3, < 2.0) - google-cloud-errors (1.0.0) - google-cloud-storage (1.26.1) + google-cloud-errors (1.0.1) + google-cloud-storage (1.26.2) addressable (~> 2.5) digest-crc (~> 0.4) google-api-client (~> 0.33) @@ -234,11 +235,11 @@ GEM http-accept (1.7.0) http-cookie (1.0.3) domain_name (~> 0.5) - httparty (0.18.0) + httparty (0.18.1) mime-types (~> 3.0) multi_xml (>= 0.5.2) httpclient (2.8.3) - i18n (1.8.2) + i18n (1.8.3) concurrent-ruby (~> 1.0) ice_nine (0.11.2) inflecto (0.0.2) @@ -274,7 +275,7 @@ GEM listen (3.2.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.5.0) + loofah (2.6.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) @@ -304,8 +305,8 @@ GEM oauth (0.5.4) orm_adapter (0.5.0) os (1.1.0) - parallel (1.19.1) - parser (2.7.1.2) + parallel (1.19.2) + parser (2.7.1.3) ast (~> 2.4.0) pg (1.2.3) pry (0.13.1) @@ -318,8 +319,8 @@ GEM nio4r (~> 2.0) pundit (2.1.0) activesupport (>= 3.0.0) - rack (2.2.2) - rack-cache (1.11.1) + rack (2.2.3) + rack-cache (1.12.0) rack (>= 0.4) rack-cors (1.1.1) rack (>= 2.0.0) @@ -329,29 +330,29 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.0.3.1) - actioncable (= 6.0.3.1) - actionmailbox (= 6.0.3.1) - actionmailer (= 6.0.3.1) - actionpack (= 6.0.3.1) - actiontext (= 6.0.3.1) - actionview (= 6.0.3.1) - activejob (= 6.0.3.1) - activemodel (= 6.0.3.1) - activerecord (= 6.0.3.1) - activestorage (= 6.0.3.1) - activesupport (= 6.0.3.1) + rails (6.0.3.2) + actioncable (= 6.0.3.2) + actionmailbox (= 6.0.3.2) + actionmailer (= 6.0.3.2) + actionpack (= 6.0.3.2) + actiontext (= 6.0.3.2) + actionview (= 6.0.3.2) + activejob (= 6.0.3.2) + activemodel (= 6.0.3.2) + activerecord (= 6.0.3.2) + activestorage (= 6.0.3.2) + activesupport (= 6.0.3.2) bundler (>= 1.3.0) - railties (= 6.0.3.1) + railties (= 6.0.3.2) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - railties (6.0.3.1) - actionpack (= 6.0.3.1) - activesupport (= 6.0.3.1) + railties (6.0.3.2) + actionpack (= 6.0.3.2) + activesupport (= 6.0.3.2) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) @@ -360,7 +361,7 @@ GEM rb-fsevent (0.10.4) rb-inotify (0.10.1) ffi (~> 1.0) - redis (4.1.4) + redis (4.2.1) redis-namespace (1.7.0) redis (>= 3.0.4) redis-rack-cache (2.2.1) @@ -368,11 +369,12 @@ GEM redis-store (>= 1.6, < 2) redis-store (1.8.2) redis (>= 4, < 5) + regexp_parser (1.7.1) representable (3.0.4) declarative (< 0.1.0) declarative-option (< 0.2.0) uber (< 0.2.0) - responders (3.0.0) + responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) rest-client (2.1.0) @@ -399,20 +401,24 @@ GEM rspec-mocks (~> 3.9) rspec-support (~> 3.9) rspec-support (3.9.3) - rubocop (0.83.0) + rubocop (0.85.1) parallel (~> 1.10) parser (>= 2.7.0.1) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.7) rexml + rubocop-ast (>= 0.0.3) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) - rubocop-performance (1.5.2) + rubocop-ast (0.0.3) + parser (>= 2.7.0.1) + rubocop-performance (1.6.1) rubocop (>= 0.71.0) - rubocop-rails (2.5.2) - activesupport + rubocop-rails (2.6.0) + activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.72.0) - rubocop-rspec (1.39.0) + rubocop (>= 0.82.0) + rubocop-rspec (1.40.0) rubocop (>= 0.68.1) ruby-progressbar (1.10.1) safe_yaml (1.0.5) @@ -421,7 +427,7 @@ GEM sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sassc (2.3.0) + sassc (2.4.0) ffi (~> 1.9) sassc-rails (2.1.2) railties (>= 4.0.0) @@ -468,7 +474,7 @@ GEM spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) - sprockets (4.0.0) + sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.2.1) @@ -480,7 +486,7 @@ GEM inflecto virtus telephone_number (1.4.7) - thor (0.20.3) + thor (1.0.1) thread_safe (0.3.6) tilt (2.0.10) time_diff (0.3.0) @@ -514,7 +520,7 @@ GEM equalizer (~> 0.0, >= 0.0.9) warden (1.2.8) rack (>= 2.0.6) - web-console (4.0.2) + web-console (4.0.3) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) @@ -531,7 +537,7 @@ GEM webpush (1.0.0) hkdf (~> 0.2) jwt (~> 2.0) - websocket-driver (0.7.1) + websocket-driver (0.7.2) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) wisper (2.0.0) diff --git a/app/javascript/dashboard/assets/scss/widgets/_reply-box.scss b/app/javascript/dashboard/assets/scss/widgets/_reply-box.scss index d0bab2074..f5322ac92 100644 --- a/app/javascript/dashboard/assets/scss/widgets/_reply-box.scss +++ b/app/javascript/dashboard/assets/scss/widgets/_reply-box.scss @@ -3,7 +3,7 @@ border-bottom: 0; margin: $space-normal; margin-top: 0; - max-height: $space-jumbo * 2; + max-height: $space-mega * 3; transition: height 2s $ease-in-out-cubic; .reply-box__top { @@ -68,13 +68,14 @@ padding: 0 $space-small; } - >textarea { + > textarea { @include ghost-input(); @include margin(0); background: transparent; // Override min-height : 50px in foundation // - min-height: 1rem; + max-height: $space-mega * 2.4; + min-height: 4rem; resize: none; } } diff --git a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue index df2e03398..c74854ff3 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue @@ -13,13 +13,12 @@ v-on-clickaway="hideEmojiPicker" :on-click="emojiOnClick" /> -