@tiledesk/tiledesk-server 2.2.39 → 2.3.1-8.2

Sign up to get free protection for your applications and to get access to all the features.
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;