From 16e96ed9d12e40f3a9644b90429a81d2c140647b Mon Sep 17 00:00:00 2001 From: Henrique Magarotto Date: Thu, 22 Feb 2018 15:07:23 -0300 Subject: [PATCH 1/7] Added api to enable external system sends visitor message --- .../imports/server/rest/messages.js | 71 +++++++++++++++++++ packages/rocketchat-livechat/server/api.js | 1 + 2 files changed, 72 insertions(+) create mode 100644 packages/rocketchat-livechat/imports/server/rest/messages.js diff --git a/packages/rocketchat-livechat/imports/server/rest/messages.js b/packages/rocketchat-livechat/imports/server/rest/messages.js new file mode 100644 index 000000000000..2e45df5469d0 --- /dev/null +++ b/packages/rocketchat-livechat/imports/server/rest/messages.js @@ -0,0 +1,71 @@ +import LivechatVisitors from '../../../server/models/LivechatVisitors'; + +function checkAuthentication(request) { + const receivedToken = request.headers['x-rocketchat-livechat-token']; + const secretToken = RocketChat.settings.get('Livechat_secret_token'); + return receivedToken && receivedToken === secretToken; +} + +RocketChat.API.v1.addRoute('livechat/status/:visitorToken', { + get() { + if (!checkAuthentication(this.request)) { + return RocketChat.API.v1.unauthorized(); + } + + const info = Meteor.call('livechat:getInitialData', this.urlParams.visitorToken); + return RocketChat.API.v1.success(info); + } +}); + +RocketChat.API.v1.addRoute('livechat/messages', { + post() { + if (!checkAuthentication(this.request)) { + return RocketChat.API.v1.unauthorized(); + } + + if (!this.bodyParams.visitor) { + return RocketChat.API.v1.failure('Body param "visitor" is required'); + } + if (!this.bodyParams.visitor.token) { + return RocketChat.API.v1.failure('Body param "visitor.token" is required'); + } + const visitorToken = this.bodyParams.visitor.token; + + let visitor = LivechatVisitors.getVisitorByToken(visitorToken); + let rid; + if (visitor) { + const rooms = RocketChat.models.Rooms.findOpenByVisitorToken(visitorToken).fetch(); + if (rooms && rooms.length > 0) { + rid = rooms[0]._id; + } else { + rid = Random.id(); + } + } else { + rid = Random.id(); + const visitorId = RocketChat.Livechat.registerGuest(this.bodyParams.visitor); + visitor = LivechatVisitors.findOneById(visitorId); + } + + const sentMessages = this.bodyParams.messages.map((message) => { + const sendMessage = { + guest: visitor, + message: { + _id: Random.id(), + rid, + token: visitorToken, + msg: message.msg + } + }; + const sentMessage = RocketChat.Livechat.sendMessage(sendMessage); + return { + username: sentMessage.u.username, + msg: sentMessage.msg, + ts: sentMessage.ts + }; + }); + + return RocketChat.API.v1.success({ + messages: sentMessages + }); + } +}); diff --git a/packages/rocketchat-livechat/server/api.js b/packages/rocketchat-livechat/server/api.js index 2c2b9307a64c..cd50c284dac7 100644 --- a/packages/rocketchat-livechat/server/api.js +++ b/packages/rocketchat-livechat/server/api.js @@ -2,3 +2,4 @@ import '../imports/server/rest/departments.js'; import '../imports/server/rest/facebook.js'; import '../imports/server/rest/sms.js'; import '../imports/server/rest/users.js'; +import '../imports/server/rest/messages.js'; From 322b09d9cb07abd162190ecf91dcce28006dae59 Mon Sep 17 00:00:00 2001 From: Henrique Magarotto Date: Mon, 12 Mar 2018 17:23:30 -0300 Subject: [PATCH 2/7] Added validations for "messages" body param --- .../imports/server/rest/messages.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/rocketchat-livechat/imports/server/rest/messages.js b/packages/rocketchat-livechat/imports/server/rest/messages.js index 2e45df5469d0..96d2ad2b9a2b 100644 --- a/packages/rocketchat-livechat/imports/server/rest/messages.js +++ b/packages/rocketchat-livechat/imports/server/rest/messages.js @@ -29,6 +29,16 @@ RocketChat.API.v1.addRoute('livechat/messages', { if (!this.bodyParams.visitor.token) { return RocketChat.API.v1.failure('Body param "visitor.token" is required'); } + if (!this.bodyParams.messages) { + return RocketChat.API.v1.failure('Body param "messages" is required'); + } + if (!(this.bodyParams.messages instanceof Array)) { + return RocketChat.API.v1.failure('Body param "messages" is not an array'); + } + if (this.bodyParams.messages.length === 0) { + return RocketChat.API.v1.failure('Body param "messages" is empty'); + } + const visitorToken = this.bodyParams.visitor.token; let visitor = LivechatVisitors.getVisitorByToken(visitorToken); From eb2627cf78651374804eb46b71da47dec5dcc7e7 Mon Sep 17 00:00:00 2001 From: Henrique Magarotto Date: Mon, 12 Mar 2018 17:26:06 -0300 Subject: [PATCH 3/7] Picked only relevant fields for status result --- packages/rocketchat-livechat/imports/server/rest/messages.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/rocketchat-livechat/imports/server/rest/messages.js b/packages/rocketchat-livechat/imports/server/rest/messages.js index 96d2ad2b9a2b..a687b199b5de 100644 --- a/packages/rocketchat-livechat/imports/server/rest/messages.js +++ b/packages/rocketchat-livechat/imports/server/rest/messages.js @@ -1,3 +1,4 @@ +import _ from 'underscore'; import LivechatVisitors from '../../../server/models/LivechatVisitors'; function checkAuthentication(request) { @@ -12,7 +13,8 @@ RocketChat.API.v1.addRoute('livechat/status/:visitorToken', { return RocketChat.API.v1.unauthorized(); } - const info = Meteor.call('livechat:getInitialData', this.urlParams.visitorToken); + const initialData = Meteor.call('livechat:getInitialData', this.urlParams.visitorToken); + const info = _.pick(initialData, 'visitor', 'room', 'departments', 'online', 'agentData'); return RocketChat.API.v1.success(info); } }); From 1ee167ddfe561e016ed9080d96edc8e279f3d4c5 Mon Sep 17 00:00:00 2001 From: Henrique Magarotto Date: Mon, 26 Mar 2018 22:29:33 -0300 Subject: [PATCH 4/7] Removed status endpoint and changed authentication method --- .../imports/server/rest/messages.js | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/packages/rocketchat-livechat/imports/server/rest/messages.js b/packages/rocketchat-livechat/imports/server/rest/messages.js index a687b199b5de..b9d4e347efd3 100644 --- a/packages/rocketchat-livechat/imports/server/rest/messages.js +++ b/packages/rocketchat-livechat/imports/server/rest/messages.js @@ -1,27 +1,8 @@ -import _ from 'underscore'; import LivechatVisitors from '../../../server/models/LivechatVisitors'; -function checkAuthentication(request) { - const receivedToken = request.headers['x-rocketchat-livechat-token']; - const secretToken = RocketChat.settings.get('Livechat_secret_token'); - return receivedToken && receivedToken === secretToken; -} - -RocketChat.API.v1.addRoute('livechat/status/:visitorToken', { - get() { - if (!checkAuthentication(this.request)) { - return RocketChat.API.v1.unauthorized(); - } - - const initialData = Meteor.call('livechat:getInitialData', this.urlParams.visitorToken); - const info = _.pick(initialData, 'visitor', 'room', 'departments', 'online', 'agentData'); - return RocketChat.API.v1.success(info); - } -}); - RocketChat.API.v1.addRoute('livechat/messages', { post() { - if (!checkAuthentication(this.request)) { + if (!RocketChat.authz.hasPermission(this.userId, 'view-livechat-manager')) { return RocketChat.API.v1.unauthorized(); } From 57db7a348f6caae277b73fd011c413f6e6f2cda9 Mon Sep 17 00:00:00 2001 From: Henrique Magarotto Date: Mon, 26 Mar 2018 22:30:44 -0300 Subject: [PATCH 5/7] Added name and status to user payload --- packages/rocketchat-livechat/imports/server/rest/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-livechat/imports/server/rest/users.js b/packages/rocketchat-livechat/imports/server/rest/users.js index 8d874a36ec32..c40b6dc45b44 100644 --- a/packages/rocketchat-livechat/imports/server/rest/users.js +++ b/packages/rocketchat-livechat/imports/server/rest/users.js @@ -23,7 +23,7 @@ RocketChat.API.v1.addRoute('livechat/users/:type', { authRequired: true }, { const users = RocketChat.authz.getUsersInRole(role); return RocketChat.API.v1.success({ - users: users.fetch().map(user => ({ _id: user._id, username: user.username })) + users: users.fetch().map(user => _.pick(user, '_id', 'username', 'name', 'status', 'statusLivechat')) }); } catch (e) { return RocketChat.API.v1.failure(e.error); From 5e0444be59e4f921f746551e662370274eb09f76 Mon Sep 17 00:00:00 2001 From: Henrique Magarotto Date: Mon, 26 Mar 2018 22:31:04 -0300 Subject: [PATCH 6/7] Added visitors endpoint --- .../imports/server/rest/visitors.js | 32 +++++++++++++++++++ packages/rocketchat-livechat/server/api.js | 1 + 2 files changed, 33 insertions(+) create mode 100644 packages/rocketchat-livechat/imports/server/rest/visitors.js diff --git a/packages/rocketchat-livechat/imports/server/rest/visitors.js b/packages/rocketchat-livechat/imports/server/rest/visitors.js new file mode 100644 index 000000000000..1fe3d0297d7b --- /dev/null +++ b/packages/rocketchat-livechat/imports/server/rest/visitors.js @@ -0,0 +1,32 @@ +import LivechatVisitors from '../../../server/models/LivechatVisitors'; + +RocketChat.API.v1.addRoute('livechat/visitor/:visitorToken', { authRequired: true }, { + get() { + if (!RocketChat.authz.hasPermission(this.userId, 'view-livechat-manager')) { + return RocketChat.API.v1.unauthorized(); + } + + const visitor = LivechatVisitors.getVisitorByToken(this.urlParams.visitorToken); + return RocketChat.API.v1.success(visitor); + } +}); + +RocketChat.API.v1.addRoute('livechat/visitor/:visitorToken/room', { authRequired: true }, { + get() { + if (!RocketChat.authz.hasPermission(this.userId, 'view-livechat-manager')) { + return RocketChat.API.v1.unauthorized(); + } + + const rooms = RocketChat.models.Rooms.findOpenByVisitorToken(this.urlParams.visitorToken, { + fields: { + name: 1, + t: 1, + cl: 1, + u: 1, + usernames: 1, + servedBy: 1 + } + }).fetch(); + return RocketChat.API.v1.success({ rooms }); + } +}); diff --git a/packages/rocketchat-livechat/server/api.js b/packages/rocketchat-livechat/server/api.js index cd50c284dac7..1fdd545230e7 100644 --- a/packages/rocketchat-livechat/server/api.js +++ b/packages/rocketchat-livechat/server/api.js @@ -3,3 +3,4 @@ import '../imports/server/rest/facebook.js'; import '../imports/server/rest/sms.js'; import '../imports/server/rest/users.js'; import '../imports/server/rest/messages.js'; +import '../imports/server/rest/visitors.js'; From 976b0922eac55d5b40550304033cd635fcd24f48 Mon Sep 17 00:00:00 2001 From: Henrique Magarotto Date: Tue, 27 Mar 2018 15:16:19 -0300 Subject: [PATCH 7/7] Fixing endpoint to use require authentication --- packages/rocketchat-livechat/imports/server/rest/messages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-livechat/imports/server/rest/messages.js b/packages/rocketchat-livechat/imports/server/rest/messages.js index b9d4e347efd3..54d70af09e9e 100644 --- a/packages/rocketchat-livechat/imports/server/rest/messages.js +++ b/packages/rocketchat-livechat/imports/server/rest/messages.js @@ -1,6 +1,6 @@ import LivechatVisitors from '../../../server/models/LivechatVisitors'; -RocketChat.API.v1.addRoute('livechat/messages', { +RocketChat.API.v1.addRoute('livechat/messages', { authRequired: true }, { post() { if (!RocketChat.authz.hasPermission(this.userId, 'view-livechat-manager')) { return RocketChat.API.v1.unauthorized();