@tiledesk/tiledesk-server 2.2.39 → 2.3.1-8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/LICENSE +14 -657
  3. package/README.md +17 -3
  4. package/app.js +21 -60
  5. package/channels/chat21/chat21Handler.js +18 -3
  6. package/channels/chat21/chat21WebHook.js +31 -15
  7. package/channels/chat21/package-lock.json +663 -706
  8. package/channels/chat21/package.json +2 -2
  9. package/deploy.sh +2 -0
  10. package/event/botEvent.js +1 -1
  11. package/event/subscriptionEvent.js +11 -0
  12. package/fonts/Roboto-Italic.ttf +0 -0
  13. package/fonts/Roboto-Medium.ttf +0 -0
  14. package/fonts/Roboto-MediumItalic.ttf +0 -0
  15. package/fonts/Roboto-Regular.ttf +0 -0
  16. package/middleware/ipFilter.js +220 -0
  17. package/middleware/passport.js +11 -2
  18. package/models/lead.js +2 -0
  19. package/models/project.js +10 -0
  20. package/models/project_user.js +4 -0
  21. package/models/request.js +50 -12
  22. package/models/subscriptionLog.js +34 -0
  23. package/models/tagLibrary.js +42 -0
  24. package/package.json +6 -12
  25. package/pubmodules/activities/activityArchiver.js +314 -0
  26. package/pubmodules/activities/index.js +3 -0
  27. package/pubmodules/activities/models/activity.js +88 -0
  28. package/pubmodules/activities/routes/activity.js +710 -0
  29. package/pubmodules/activities/test/activityRoute.js +85 -0
  30. package/pubmodules/analytics/analytics.js +1719 -0
  31. package/pubmodules/analytics/index.js +3 -0
  32. package/pubmodules/canned/cannedResponse.js +55 -0
  33. package/pubmodules/canned/cannedResponseRoute.js +163 -0
  34. package/pubmodules/canned/index.js +3 -0
  35. package/pubmodules/emailNotification/requestNotification.js +215 -28
  36. package/pubmodules/events/eventRoute.js +37 -7
  37. package/pubmodules/messageActions/messageActionsInterceptor.js +4 -2
  38. package/pubmodules/pubModulesManager.js +129 -5
  39. package/pubmodules/rasa/listener.js +5 -5
  40. package/pubmodules/rules/conciergeBot.js +4 -4
  41. package/pubmodules/scheduler/tasks/closeAgentUnresponsiveRequestTask.js +3 -1
  42. package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +3 -1
  43. package/pubmodules/tilebot/index.js +11 -0
  44. package/pubmodules/tilebot/listener.js +69 -0
  45. package/pubmodules/trigger/default.js +271 -0
  46. package/pubmodules/trigger/event/actionEventEmitter.js +10 -0
  47. package/pubmodules/trigger/event/flowEventEmitter.js +10 -0
  48. package/pubmodules/trigger/event/triggerEventEmitter.js +10 -0
  49. package/pubmodules/trigger/index.js +3 -0
  50. package/pubmodules/trigger/models/trigger.js +149 -0
  51. package/pubmodules/trigger/rulesTrigger.js +1181 -0
  52. package/pubmodules/trigger/start.js +118 -0
  53. package/pubmodules/trigger/triggerRoute.js +150 -0
  54. package/routes/auth.js +7 -2
  55. package/routes/department.js +51 -0
  56. package/routes/faq.js +7 -0
  57. package/routes/faq_kb.js +1 -1
  58. package/routes/group.js +140 -0
  59. package/routes/lead.js +24 -1
  60. package/routes/message.js +6 -3
  61. package/routes/project.js +118 -0
  62. package/routes/project_user.js +9 -0
  63. package/routes/public-request.js +280 -2
  64. package/routes/request.js +122 -16
  65. package/routes/subscription.js +140 -0
  66. package/routes/tag.js +138 -0
  67. package/routes/user-request.js +3 -2
  68. package/routes/users.js +1 -1
  69. package/routes/widget.js +80 -3
  70. package/routes/widgetLoader.js +31 -0
  71. package/services/banUserNotifier.js +86 -0
  72. package/services/emailService.js +189 -11
  73. package/services/faqService.js +2 -2
  74. package/services/geoService.js +30 -4
  75. package/services/leadService.js +2 -0
  76. package/services/modulesManager.js +7 -188
  77. package/services/requestService.js +364 -6
  78. package/services/subscriptionNotifier.js +485 -0
  79. package/template/email/assignedEmailMessage.html +1 -1
  80. package/template/email/assignedRequest.html +1 -1
  81. package/template/email/newMessage.html +1 -1
  82. package/template/email/newMessageFollower.html +236 -0
  83. package/template/email/passwordChanged.html +1 -1
  84. package/template/email/pooledEmailMessage.html +1 -1
  85. package/template/email/pooledRequest.html +1 -1
  86. package/template/email/resetPassword.html +2 -2
  87. package/template/email/ticket.html +1 -1
  88. package/test/cannedRoute.js +166 -0
  89. package/test/messageRoute.js +69 -0
  90. package/test/requestService.js +3 -1
  91. package/utils/orgUtil.js +3 -3
  92. package/views/messages.jade +2 -2
  93. package/websocket/webSocketServer.js +23 -5
package/routes/project.js CHANGED
@@ -2,6 +2,8 @@ var express = require('express');
2
2
  var router = express.Router();
3
3
  var Project = require("../models/project");
4
4
  var projectEvent = require("../event/projectEvent");
5
+ var projectService = require("../services/projectService");
6
+
5
7
  var Project_user = require("../models/project_user");
6
8
 
7
9
  var operatingHoursService = require("../services/operatingHoursService");
@@ -17,6 +19,56 @@ var RoleConstants = require("../models/roleConstants");
17
19
  var cacheUtil = require('../utils/cacheUtil');
18
20
  var orgUtil = require("../utils/orgUtil");
19
21
 
22
+
23
+ router.post('/', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken], async (req, res) => {
24
+
25
+ // create(name, createdBy, settings)
26
+ return projectService.create(req.body.name, req.user.id, undefined, req.body.defaultLanguage).then(function(savedProject) {
27
+ res.json(savedProject);
28
+ });
29
+
30
+ });
31
+
32
+ // DOWNGRADE PLAN. UNUSED
33
+ router.put('/:projectid/downgradeplan', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('owner')], function (req, res) {
34
+ winston.debug('downgradeplan - UPDATE PROJECT REQ BODY ', req.body);
35
+ Project.findByIdAndUpdate(req.params.projectid, req.body, { new: true, upsert: true }, function (err, updatedProject) {
36
+ if (err) {
37
+ winston.error('Error putting project ', err);
38
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
39
+ }
40
+ projectEvent.emit('project.downgrade', updatedProject );
41
+ res.json(updatedProject);
42
+ });
43
+ });
44
+
45
+
46
+ router.delete('/:projectid/physical', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('owner')], function (req, res) {
47
+ winston.debug(req.body);
48
+ // TODO delete also department, faq_kb, faq, group, label, lead, message, project_users, requests, subscription
49
+ Project.remove({ _id: req.params.projectid }, function (err, project) {
50
+ if (err) {
51
+ winston.error('Error deleting project ', err);
52
+ return res.status(500).send({ success: false, msg: 'Error deleting object.' });
53
+ }
54
+ projectEvent.emit('project.delete', project );
55
+ res.json(project);
56
+ });
57
+ });
58
+
59
+ router.delete('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('owner')], function (req, res) {
60
+ winston.debug(req.body);
61
+ // TODO delete also department, faq_kb, faq, group, label, lead, message, project_users, requests, subscription
62
+ Project.findByIdAndUpdate(req.params.projectid, {status:0}, { new: true, upsert: true }, function (err, project) {
63
+ if (err) {
64
+ winston.error('Error deleting project ', err);
65
+ return res.status(500).send({ success: false, msg: 'Error deleting object.' });
66
+ }
67
+ projectEvent.emit('project.delete', project );
68
+ res.json(project);
69
+ });
70
+ });
71
+
20
72
  router.put('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
21
73
  winston.debug('UPDATE PROJECT REQ BODY ', req.body);
22
74
 
@@ -161,6 +213,22 @@ router.put('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: fa
161
213
  update.ipFilter = req.body.ipFilter;
162
214
  }
163
215
 
216
+ if (req.body.ipFilterDenyEnabled!=undefined) {
217
+ update.ipFilterDenyEnabled = req.body.ipFilterDenyEnabled;
218
+ }
219
+
220
+ if (req.body.ipFilterDeny!=undefined) {
221
+ update.ipFilterDeny = req.body.ipFilterDeny;
222
+ }
223
+
224
+ if (req.body.bannedUsers!=undefined) {
225
+ update.bannedUsers = req.body.bannedUsers;
226
+ }
227
+
228
+
229
+
230
+
231
+
164
232
 
165
233
  // if (req.body.defaultLanguage!=undefined) {
166
234
  // update.defaultLanguage = req.body.defaultLanguage;
@@ -308,6 +376,19 @@ router.patch('/:projectid', [passport.authenticate(['basic', 'jwt'], { session:
308
376
  if (req.body.ipFilter!=undefined) {
309
377
  update.ipFilter = req.body.ipFilter;
310
378
  }
379
+
380
+ if (req.body.ipFilterDenyEnabled!=undefined) {
381
+ update.ipFilterDenyEnabled = req.body.ipFilterDenyEnabled;
382
+ }
383
+
384
+ if (req.body.ipFilterDeny!=undefined) {
385
+ update.ipFilterDeny = req.body.ipFilterDeny;
386
+ }
387
+
388
+ if (req.body.bannedUsers!=undefined) {
389
+ update.bannedUsers = req.body.bannedUsers;
390
+ }
391
+
311
392
 
312
393
  // if (req.body.defaultLanguage!=undefined) {
313
394
  // update.defaultLanguage = req.body.defaultLanguage;
@@ -326,6 +407,43 @@ router.patch('/:projectid', [passport.authenticate(['basic', 'jwt'], { session:
326
407
  });
327
408
  });
328
409
 
410
+
411
+ router.post('/:projectid/ban', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
412
+ winston.debug('PATCH PROJECT REQ BODY ', req.body);
413
+
414
+ var ban = {};
415
+ ban.id = req.body.id;
416
+ ban.ip = req.body.ip;
417
+
418
+ Project.findByIdAndUpdate(req.params.projectid, { $push: { bannedUsers: ban } }, { new: true, upsert: false }, function (err, updatedProject) {
419
+ if (err) {
420
+ winston.error('Error putting project ', err);
421
+ return res.status(500).send({ success: false, msg: 'Error patching object.' });
422
+ }
423
+ projectEvent.emit('project.update', updatedProject );
424
+ projectEvent.emit('project.update.user.ban', {banInfo: ban, project: updatedProject });
425
+ res.json(updatedProject);
426
+ });
427
+
428
+ });
429
+ router.delete('/:projectid/ban/:banid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
430
+
431
+ // winston.info('quiiiiii');
432
+ //cacheinvalidation
433
+ Project.findByIdAndUpdate(req.params.projectid, { $pull: { bannedUsers: { "_id": req.params.banid }}}, { new: true, upsert: false }, function (err, updatedProject) {
434
+ if (err) {
435
+ winston.error('Error putting project ', err);
436
+ return res.status(500).send({ success: false, msg: 'Error patching object.' });
437
+ }
438
+ projectEvent.emit('project.update', updatedProject );
439
+ projectEvent.emit('project.update.user.unban', {banInfo: req.params.banid, project: updatedProject});
440
+ res.json(updatedProject);
441
+ });
442
+
443
+ });
444
+
445
+
446
+
329
447
  //roleChecker.hasRole('agent') works because req.params.projectid is valid using :projectid of this method
330
448
  router.get('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], function (req, res) {
331
449
  winston.debug(req.body);
@@ -220,6 +220,10 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
220
220
  if (req.body.user_available!=undefined) {
221
221
  update.user_available = req.body.user_available;
222
222
  }
223
+
224
+ if (req.body.profileStatus!=undefined) {
225
+ update.profileStatus = req.body.profileStatus;
226
+ }
223
227
 
224
228
  if (req.body.max_assigned_chat!=undefined) {
225
229
  update.max_assigned_chat = req.body.max_assigned_chat;
@@ -241,6 +245,7 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
241
245
 
242
246
 
243
247
 
248
+
244
249
  Project_user.findByIdAndUpdate(req.projectuser.id, update, { new: true, upsert: true }, function (err, updatedProject_user) {
245
250
  if (err) {
246
251
  winston.error("Error gettting project_user for update", err);
@@ -274,6 +279,10 @@ router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
274
279
  update.user_available = req.body.user_available;
275
280
  }
276
281
 
282
+ if (req.body.profileStatus!=undefined) {
283
+ update.profileStatus = req.body.profileStatus;
284
+ }
285
+
277
286
  if (req.body.max_assigned_chat!=undefined) {
278
287
  update.max_assigned_chat = req.body.max_assigned_chat;
279
288
  }
@@ -3,10 +3,22 @@ var router = express.Router();
3
3
  var Message = require("../models/message");
4
4
  var Request = require("../models/request");
5
5
  var User = require("../models/user");
6
- var Project = require("../models/project");
7
- var emailService = require("../services/emailService");
8
6
  var winston = require('../config/winston');
9
7
 
8
+ var fonts = {
9
+ Roboto: {
10
+ normal: 'fonts/Roboto-Regular.ttf',
11
+ bold: 'fonts/Roboto-Medium.ttf',
12
+ italics: 'fonts/Roboto-Italic.ttf',
13
+ bolditalics: 'fonts/Roboto-MediumItalic.ttf'
14
+ }
15
+ };
16
+
17
+ var PdfPrinter = require('pdfmake');
18
+ var printer = new PdfPrinter(fonts);
19
+ // var fs = require('fs');
20
+
21
+
10
22
 
11
23
 
12
24
 
@@ -49,6 +61,134 @@ var winston = require('../config/winston');
49
61
  });
50
62
 
51
63
 
64
+ router.get('/:requestid/messages.csv', function(req, res) {
65
+
66
+ winston.debug(req.params);
67
+ winston.debug("here");
68
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).lean().exec(function(err, messages) {
69
+ if (err) {
70
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
71
+ }
72
+
73
+ if(!messages){
74
+ return res.status(404).send({success: false, msg: 'Object not found.'});
75
+ }
76
+
77
+ messages.forEach(function(element) {
78
+
79
+ var channel_name = "";
80
+ if (element.channel && element.channel.name) {
81
+ channel_name = element.channel.name;
82
+ }
83
+ delete element.channel;
84
+ element.channel_name = channel_name;
85
+
86
+ delete element.attributes;
87
+ });
88
+
89
+ res.setHeader('Content-Type', 'applictext/csv');
90
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.csv');
91
+
92
+ return res.csv(messages, true);
93
+ });
94
+
95
+ });
96
+
97
+
98
+ router.get('/:requestid/messages.txt', function(req, res) {
99
+
100
+ winston.debug(req.params);
101
+ winston.debug("here");
102
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
103
+ if (err) {
104
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
105
+ }
106
+
107
+ if(!messages){
108
+ return res.status(404).send({success: false, msg: 'Object not found.'});
109
+ }
110
+
111
+
112
+ var text = "Chat transcript:\n" //+ req.project.name;
113
+
114
+ messages.forEach(function(element) {
115
+ text = text + "[ " + element.createdAt.toLocaleString('en', { timeZone: 'UTC' })+ "] " + element.senderFullname + ": " + element.text + "\n";
116
+ });
117
+
118
+
119
+ res.set({"Content-Disposition":"attachment; filename=\"transcript.txt\""});
120
+ res.send(text);
121
+ });
122
+
123
+ });
124
+
125
+
126
+
127
+ router.get('/:requestid/messages.pdf', function(req, res) {
128
+
129
+
130
+ winston.debug(req.params);
131
+ winston.debug("here");
132
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
133
+ if (err) {
134
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
135
+ }
136
+
137
+
138
+ if(!messages){
139
+ return res.status(404).send({success: false, msg: 'Object not found.'});
140
+ }
141
+
142
+
143
+ var docDefinition = {
144
+ content: [
145
+ { text: 'Chat Transcript', style: 'header' },
146
+ {
147
+ ul: [
148
+ // 'item 1',
149
+ // 'item 2',
150
+ // 'item 3'
151
+ ]
152
+ },
153
+
154
+ ],
155
+ styles: {
156
+ header: {
157
+ bold: true,
158
+ fontSize: 15
159
+ }
160
+ },
161
+ defaultStyle: {
162
+ fontSize: 12
163
+ }
164
+ };
165
+
166
+
167
+
168
+ messages.forEach(function(element) {
169
+ docDefinition.content[1].ul.push("[ " + element.createdAt.toLocaleString('en', { timeZone: 'UTC' })+ "] " + element.senderFullname + ": " + element.text );
170
+ });
171
+
172
+ console.log(docDefinition);
173
+
174
+ var pdfDoc = printer.createPdfKitDocument(docDefinition);
175
+ // pdfDoc.pipe(fs.createWriteStream('lists.pdf'));
176
+
177
+ res.setHeader('Content-Type', 'application/pdf');
178
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.pdf');
179
+
180
+
181
+ pdfDoc.pipe(res);
182
+ pdfDoc.end();
183
+
184
+
185
+
186
+ });
187
+
188
+ });
189
+
190
+
191
+
52
192
  router.get('/:requestid/messages-user.html', function(req, res) {
53
193
 
54
194
  winston.debug(req.params);
@@ -60,6 +200,7 @@ var winston = require('../config/winston');
60
200
 
61
201
  var messages = messages.filter(m => m.sender != "system" );
62
202
 
203
+
63
204
  //skip info message
64
205
  if(!messages){
65
206
  return res.status(404).send({success: false, msg: 'Object not found.'});
@@ -70,4 +211,141 @@ var winston = require('../config/winston');
70
211
 
71
212
  });
72
213
 
214
+
215
+
216
+ router.get('/:requestid/messages-user.txt', function(req, res) {
217
+
218
+ winston.debug(req.params);
219
+ winston.debug("here");
220
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
221
+ if (err) {
222
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
223
+ }
224
+
225
+ if(!messages){
226
+ return res.status(404).send({success: false, msg: 'Object not found.'});
227
+ }
228
+
229
+
230
+ var messages = messages.filter(m => m.sender != "system" );
231
+
232
+ var text = "Chat transcript:\n" //+ req.project.name;
233
+
234
+ messages.forEach(function(element) {
235
+ text = text + "[ " + element.createdAt.toLocaleString('en', { timeZone: 'UTC' })+ "] " + element.senderFullname + ": " + element.text + "\n";
236
+ });
237
+
238
+
239
+ res.set({"Content-Disposition":"attachment; filename=\"transcript.txt\""});
240
+ res.send(text);
241
+ });
242
+
243
+ });
244
+
245
+
246
+ router.get('/:requestid/messages-user.pdf', function(req, res) {
247
+
248
+
249
+ winston.debug(req.params);
250
+ winston.debug("here");
251
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
252
+ if (err) {
253
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
254
+ }
255
+
256
+ var messages = messages.filter(m => m.sender != "system" );
257
+
258
+
259
+ //skip info message
260
+ if(!messages){
261
+ return res.status(404).send({success: false, msg: 'Object not found.'});
262
+ }
263
+
264
+
265
+ var docDefinition = {
266
+ content: [
267
+ { text: 'Chat Transcript', style: 'header' },
268
+ {
269
+ ul: [
270
+ // 'item 1',
271
+ // 'item 2',
272
+ // 'item 3'
273
+ ]
274
+ },
275
+
276
+ ],
277
+ styles: {
278
+ header: {
279
+ bold: true,
280
+ fontSize: 15
281
+ }
282
+ },
283
+ defaultStyle: {
284
+ fontSize: 12
285
+ }
286
+ };
287
+
288
+
289
+
290
+ messages.forEach(function(element) {
291
+ docDefinition.content[1].ul.push("[ " + element.createdAt.toLocaleString('en', { timeZone: 'UTC' })+ "] " + element.senderFullname + ": " + element.text );
292
+ });
293
+
294
+ console.log(docDefinition);
295
+
296
+ var pdfDoc = printer.createPdfKitDocument(docDefinition);
297
+ // pdfDoc.pipe(fs.createWriteStream('lists.pdf'));
298
+
299
+ res.setHeader('Content-Type', 'application/pdf');
300
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.pdf');
301
+
302
+ pdfDoc.pipe(res);
303
+ pdfDoc.end();
304
+
305
+
306
+
307
+ });
308
+
309
+ });
310
+
311
+
312
+ router.get('/:requestid/messages-user.csv', function(req, res) {
313
+
314
+ winston.debug(req.params);
315
+ winston.debug("here");
316
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).lean().exec(function(err, messages) {
317
+ if (err) {
318
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
319
+ }
320
+
321
+ var messages = messages.filter(m => m.sender != "system" );
322
+
323
+
324
+ //skip info message
325
+ if(!messages){
326
+ return res.status(404).send({success: false, msg: 'Object not found.'});
327
+ }
328
+
329
+
330
+ messages.forEach(function(element) {
331
+
332
+ var channel_name = "";
333
+ if (element.channel && element.channel.name) {
334
+ channel_name = element.channel.name;
335
+ }
336
+ delete element.channel;
337
+ element.channel_name = channel_name;
338
+
339
+ delete element.attributes;
340
+ });
341
+
342
+
343
+ res.setHeader('Content-Type', 'applictext/csv');
344
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.csv');
345
+
346
+ return res.csv(messages, true);
347
+ });
348
+
349
+ });
350
+
73
351
  module.exports = router;