From 9ca731dff3b2bb4678c16b82b18d67b83bdff2cd Mon Sep 17 00:00:00 2001 From: Marcos Spessatto Defendi Date: Fri, 18 Oct 2019 22:44:59 -0300 Subject: [PATCH] [IMPROVE] Replace livechat:integration publication by REST (#15607) * Replace livechat:integration pub by REST * Remove unnecessary collection * update var after save --- .../client/collections/LivechatIntegration.js | 3 -- .../livechatIntegrationWebhook.js | 44 +++++++++++-------- .../imports/server/rest/integrations.js | 12 +++++ app/livechat/server/api.js | 1 + app/livechat/server/api/lib/integrations.js | 12 +++++ .../publications/livechatIntegration.js | 1 + app/models/server/raw/Settings.js | 12 +++++ tests/end-to-end/api/livechat/integrations.js | 41 +++++++++++++++++ 8 files changed, 105 insertions(+), 21 deletions(-) delete mode 100644 app/livechat/client/collections/LivechatIntegration.js create mode 100644 app/livechat/imports/server/rest/integrations.js create mode 100644 app/livechat/server/api/lib/integrations.js create mode 100644 tests/end-to-end/api/livechat/integrations.js diff --git a/app/livechat/client/collections/LivechatIntegration.js b/app/livechat/client/collections/LivechatIntegration.js deleted file mode 100644 index 2a899965e95..00000000000 --- a/app/livechat/client/collections/LivechatIntegration.js +++ /dev/null @@ -1,3 +0,0 @@ -import { Mongo } from 'meteor/mongo'; - -export const LivechatIntegration = new Mongo.Collection('livechatIntegration'); diff --git a/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.js b/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.js index c1470419aca..2770fb95628 100644 --- a/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.js +++ b/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.js @@ -7,53 +7,56 @@ import toastr from 'toastr'; import { modal } from '../../../../../ui-utils'; import { t, handleError } from '../../../../../utils'; -import { LivechatIntegration } from '../../../collections/LivechatIntegration'; import './livechatIntegrationWebhook.html'; +import { APIClient } from '../../../../../utils/client'; + +const getIntegrationSettingById = (settings, id) => settings.find((setting) => setting._id === id); Template.livechatIntegrationWebhook.helpers({ webhookUrl() { - const setting = LivechatIntegration.findOne('Livechat_webhookUrl'); + const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhookUrl'); return setting && setting.value; }, secretToken() { - const setting = LivechatIntegration.findOne('Livechat_secret_token'); + const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_secret_token'); return setting && setting.value; }, disableTest() { return Template.instance().disableTest.get(); }, sendOnCloseChecked() { - const setting = LivechatIntegration.findOne('Livechat_webhook_on_close'); + const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_close'); return setting && setting.value; }, sendOnOfflineChecked() { - const setting = LivechatIntegration.findOne('Livechat_webhook_on_offline_msg'); + const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_offline_msg'); return setting && setting.value; }, sendOnVisitorMessageChecked() { - const setting = LivechatIntegration.findOne('Livechat_webhook_on_visitor_message'); + const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_visitor_message'); return setting && setting.value; }, sendOnAgentMessageChecked() { - const setting = LivechatIntegration.findOne('Livechat_webhook_on_agent_message'); + const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_agent_message'); return setting && setting.value; }, }); -Template.livechatIntegrationWebhook.onCreated(function() { +Template.livechatIntegrationWebhook.onCreated(async function() { this.disableTest = new ReactiveVar(true); + this.settings = new ReactiveVar([]); this.autorun(() => { - const webhook = LivechatIntegration.findOne('Livechat_webhookUrl'); + const webhook = getIntegrationSettingById(this.settings.get(), 'Livechat_webhookUrl'); this.disableTest.set(!webhook || _.isEmpty(webhook.value)); }); - - this.subscribe('livechat:integration'); + const { settings } = await APIClient.v1.get('livechat/integrations.settings'); + this.settings.set(settings); }); Template.livechatIntegrationWebhook.events({ 'change #webhookUrl, blur #webhookUrl'(e, instance) { - const setting = LivechatIntegration.findOne('Livechat_webhookUrl'); + const setting = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhookUrl'); instance.disableTest.set(!setting || e.currentTarget.value !== setting.value); }, 'click .test'(e, instance) { @@ -73,12 +76,12 @@ Template.livechatIntegrationWebhook.events({ 'click .reset-settings'(e, instance) { e.preventDefault(); - const webhookUrl = LivechatIntegration.findOne('Livechat_webhookUrl'); - const secretToken = LivechatIntegration.findOne('Livechat_secret_token'); - const webhookOnClose = LivechatIntegration.findOne('Livechat_webhook_on_close'); - const webhookOnOfflineMsg = LivechatIntegration.findOne('Livechat_webhook_on_offline_msg'); - const webhookOnVisitorMessage = LivechatIntegration.findOne('Livechat_webhook_on_visitor_message'); - const webhookOnAgentMessage = LivechatIntegration.findOne('Livechat_webhook_on_agent_message'); + const webhookUrl = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhookUrl'); + const secretToken = getIntegrationSettingById(instance.settings.get(), 'Livechat_secret_token'); + const webhookOnClose = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_close'); + const webhookOnOfflineMsg = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_offline_msg'); + const webhookOnVisitorMessage = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_visitor_message'); + const webhookOnAgentMessage = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_agent_message'); instance.$('#webhookUrl').val(webhookUrl && webhookUrl.value); instance.$('#secretToken').val(secretToken && secretToken.value); @@ -104,6 +107,11 @@ Template.livechatIntegrationWebhook.events({ if (err) { return handleError(err); } + const savedValues = instance.settings.get().map((setting) => { + setting.value = settings[setting._id]; + return setting; + }); + instance.settings.set(savedValues); toastr.success(t('Saved')); }); }, diff --git a/app/livechat/imports/server/rest/integrations.js b/app/livechat/imports/server/rest/integrations.js new file mode 100644 index 00000000000..08d9d064892 --- /dev/null +++ b/app/livechat/imports/server/rest/integrations.js @@ -0,0 +1,12 @@ +import { API } from '../../../../api'; +import { findIntegrationSettings } from '../../../server/api/lib/integrations'; + +API.v1.addRoute('livechat/integrations.settings', { authRequired: true }, { + get() { + const settings = Promise.await(findIntegrationSettings({ + userId: this.userId, + })); + + return API.v1.success(settings); + }, +}); diff --git a/app/livechat/server/api.js b/app/livechat/server/api.js index 8c59951412a..7dd93338037 100644 --- a/app/livechat/server/api.js +++ b/app/livechat/server/api.js @@ -7,3 +7,4 @@ import '../imports/server/rest/inquiries.js'; import '../imports/server/rest/rooms.js'; import '../imports/server/rest/appearance.js'; import '../imports/server/rest/triggers.js'; +import '../imports/server/rest/integrations.js'; diff --git a/app/livechat/server/api/lib/integrations.js b/app/livechat/server/api/lib/integrations.js new file mode 100644 index 00000000000..942dada044f --- /dev/null +++ b/app/livechat/server/api/lib/integrations.js @@ -0,0 +1,12 @@ +import { hasPermissionAsync } from '../../../../authorization/server/functions/hasPermission'; +import { Settings } from '../../../../models/server/raw'; + +export async function findIntegrationSettings({ userId }) { + if (!await hasPermissionAsync(userId, 'view-livechat-manager')) { + throw new Error('error-not-authorized'); + } + + const settings = await Settings.findByIds(['Livechat_webhookUrl', 'Livechat_secret_token', 'Livechat_webhook_on_close', 'Livechat_webhook_on_offline_msg', 'Livechat_webhook_on_visitor_message', 'Livechat_webhook_on_agent_message']).toArray(); + + return { settings }; +} diff --git a/app/livechat/server/publications/livechatIntegration.js b/app/livechat/server/publications/livechatIntegration.js index 45df6fa6e5a..0d5b4e71ce2 100644 --- a/app/livechat/server/publications/livechatIntegration.js +++ b/app/livechat/server/publications/livechatIntegration.js @@ -3,6 +3,7 @@ import { Meteor } from 'meteor/meteor'; import { hasPermission } from '../../../authorization'; import { Settings } from '../../../models'; +console.warn('The publication "livechat:integration" is deprecated and will be removed after version v3.0.0'); Meteor.publish('livechat:integration', function() { if (!this.userId) { return this.error(new Meteor.Error('error-not-authorized', 'Not authorized', { publish: 'livechat:integration' })); diff --git a/app/models/server/raw/Settings.js b/app/models/server/raw/Settings.js index fb2a1c3e319..9c762f8e614 100644 --- a/app/models/server/raw/Settings.js +++ b/app/models/server/raw/Settings.js @@ -6,4 +6,16 @@ export class SettingsRaw extends BaseRaw { return setting.value; } + + findByIds(_id = []) { + _id = [].concat(_id); + + const query = { + _id: { + $in: _id, + }, + }; + + return this.find(query); + } } diff --git a/tests/end-to-end/api/livechat/integrations.js b/tests/end-to-end/api/livechat/integrations.js new file mode 100644 index 00000000000..3b188c2c801 --- /dev/null +++ b/tests/end-to-end/api/livechat/integrations.js @@ -0,0 +1,41 @@ +import { getCredentials, api, request, credentials } from '../../../data/api-data.js'; +import { updatePermission, updateSetting } from '../../../data/permissions.helper'; + +describe('LIVECHAT - Integrations', function() { + this.retries(0); + + before((done) => getCredentials(done)); + + before((done) => updateSetting('Livechat_enabled', true).then(done)); + + describe('livechat/integrations.settings', () => { + it('should return an "unauthorized error" when the user does not have the necessary permission', (done) => { + updatePermission('view-livechat-manager', []) + .then(() => { + request.get(api('livechat/integrations.settings')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body.error).to.be.equal('error-not-authorized'); + }) + .end(done); + }); + }); + it('should return an array of settings', (done) => { + updatePermission('view-livechat-manager', ['admin']) + .then(() => { + request.get(api('livechat/integrations.settings')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body.settings).to.be.an('array'); + }) + .end(done); + }); + }); + }); +});