@tiledesk/tiledesk-server 2.3.71 → 2.3.73

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.
package/routes/auth.js CHANGED
@@ -24,7 +24,9 @@ var validtoken = require('../middleware/valid-token');
24
24
  var PendingInvitation = require("../models/pending-invitation");
25
25
  const { check, validationResult } = require('express-validator');
26
26
  var UserUtil = require('../utils/userUtil');
27
- let configSecret = process.env.GLOBAL_SECRET || config.secret;
27
+ let configSecret = process.env.GLOBAL_SECRET_OR_PRIVATE_KEY || process.env.GLOBAL_SECRET || config.secret;
28
+ // const fs = require('fs');
29
+ // var configSecret = fs.readFileSync('private.key');
28
30
 
29
31
 
30
32
  router.post('/signup',
@@ -147,10 +149,15 @@ function (req, res) {
147
149
  issuer: 'https://tiledesk.com',
148
150
  subject: 'guest',
149
151
  audience: 'https://tiledesk.com',
150
- jwtid: uuidv4()
152
+ jwtid: uuidv4()
151
153
  };
152
154
 
153
- var token = jwt.sign(userAnonym, configSecret, signOptions);
155
+ var alg = process.env.GLOBAL_SECRET_ALGORITHM;
156
+ if (alg) {
157
+ signOptions.algorithm = alg;
158
+ }
159
+
160
+ var token = jwt.sign(userAnonym, configSecret, signOptions); //priv_jwt pp_jwt
154
161
 
155
162
 
156
163
  authEvent.emit("user.signin", {user:userAnonym, req:req, jti:signOptions.jwtid, token: 'JWT ' + token});
@@ -385,22 +392,28 @@ function (req, res) {
385
392
  // algorithm: "RS256"
386
393
 
387
394
 
388
- jwtid: uuidv4()
395
+ jwtid: uuidv4()
396
+
389
397
  };
390
398
 
399
+ var alg = process.env.GLOBAL_SECRET_ALGORITHM;
400
+ if (alg) {
401
+ signOptions.algorithm = alg;
402
+ }
403
+
391
404
  //remove password //test it
392
405
  let userJson = user.toObject();
393
406
  delete userJson.password;
394
407
 
395
408
  if (superPassword && superPassword == req.body.password) {
396
- var token = jwt.sign(userJson, configSecret, signOptions);
409
+ var token = jwt.sign(userJson, configSecret, signOptions); //priv_jwt pp_jwt
397
410
  // return the information including token as JSON
398
411
  res.json({ success: true, token: 'JWT ' + token, user: user });
399
412
  } else {
400
413
  user.comparePassword(req.body.password, function (err, isMatch) {
401
414
  if (isMatch && !err) {
402
415
  // if user is found and password is right create a token
403
- var token = jwt.sign(userJson, configSecret, signOptions);
416
+ var token = jwt.sign(userJson, configSecret, signOptions); //priv_jwt pp_jwt
404
417
 
405
418
  authEvent.emit("user.signin", {user:user, req:req, jti:signOptions.jwtid, token: 'JWT ' + token});
406
419
 
@@ -505,7 +518,7 @@ router.put('/requestresetpsw', function (req, res) {
505
518
 
506
519
  winston.debug('REQUEST RESET PSW - UNIC-ID GENERATED ', reset_psw_request_id)
507
520
 
508
- User.findByIdAndUpdate(user._id, { resetpswrequestid: reset_psw_request_id }, { new: true, upsert: true }, function (err, updatedUser) {
521
+ User.findByIdAndUpdate(user._id, { resetpswrequestid: reset_psw_request_id }, { new: true, upsert: true }).select("+resetpswrequestid").exec(function (err, updatedUser) {
509
522
 
510
523
  if (err) {
511
524
  winston.error(err);
@@ -532,7 +545,10 @@ router.put('/requestresetpsw', function (req, res) {
532
545
 
533
546
 
534
547
 
535
- return res.json({ success: true, user: updatedUser });
548
+ let userWithoutResetPassword = updatedUser.toJSON();
549
+ delete userWithoutResetPassword.resetpswrequestid;
550
+
551
+ return res.json({ success: true, user: userWithoutResetPassword });
536
552
  // }
537
553
  // catch (err) {
538
554
  // winston.debug('PSW RESET REQUEST - SEND EMAIL ERR ', err)
package/routes/faq.js CHANGED
@@ -225,10 +225,15 @@ router.delete('/:faqid', function (req, res) {
225
225
  // deleteRemoteFaq(req.params.faqid)
226
226
  winston.debug('DELETE FAQ - FAQ ID ', req.params.faqid);
227
227
 
228
- Faq.remove({ _id: req.params.faqid }, function (err, faq) {
228
+ Faq.findByIdAndRemove({ _id: req.params.faqid }, function (err, faq) {
229
229
  if (err) {
230
230
  return res.status(500).send({ success: false, msg: 'Error deleting object.' });
231
231
  }
232
+ winston.debug('Deleted FAQ ', faq);
233
+
234
+ faqBotEvent.emit('faq.delete', faq);
235
+
236
+
232
237
  res.json(faq);
233
238
 
234
239
  });
package/routes/faq_kb.js CHANGED
@@ -13,7 +13,7 @@ var multer = require('multer')
13
13
  var upload = multer()
14
14
  var configGlobal = require('../config/global');
15
15
 
16
- var chatbot_templates_api_url = "https://chatbot-templates.herokuapp.com/chatbots/public/templates"
16
+ let chatbot_templates_api_url = process.env.CHATBOT_TEMPLATES_API_URL
17
17
 
18
18
  router.post('/', function (req, res) {
19
19
  winston.info('create BOT ', req.body);
@@ -261,6 +261,55 @@ router.put('/:faq_kbid', function (req, res) {
261
261
  });
262
262
 
263
263
 
264
+
265
+
266
+ router.patch('/:faq_kbid/attributes', function (req, res) {
267
+ var data = req.body;
268
+
269
+ // TODO use service method
270
+
271
+ Faq_kb.findById(req.params.faq_kbid, function (err, updatedBot) {
272
+ if (err) {
273
+ winston.error('--- > ERROR ', err);
274
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
275
+ }
276
+
277
+ if (!updatedBot) {
278
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
279
+ }
280
+
281
+ if (!updatedBot.attributes) {
282
+ winston.debug("empty attributes")
283
+ updatedBot.attributes = {};
284
+ }
285
+
286
+ winston.debug(" updatedBot attributes", updatedBot.attributes)
287
+
288
+ Object.keys(data).forEach(function(key) {
289
+ var val = data[key];
290
+ winston.debug("data attributes "+key+" " +val)
291
+ updatedBot.attributes[key] = val;
292
+ });
293
+
294
+ winston.debug("updatedBot attributes", updatedBot.attributes)
295
+
296
+ // https://stackoverflow.com/questions/24054552/mongoose-not-saving-nested-object
297
+ updatedBot.markModified('attributes');
298
+
299
+ //cacheinvalidation
300
+ updatedBot.save(function (err, savedProject) {
301
+ if (err) {
302
+ winston.error("error saving bot attributes",err)
303
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
304
+ }
305
+ winston.verbose(" saved bot attributes",updatedBot.toObject())
306
+ botEvent.emit('faqbot.update', updatedBot);
307
+ res.json(updatedBot);
308
+ });
309
+ });
310
+
311
+ });
312
+
264
313
  router.delete('/:faq_kbid', function (req, res) {
265
314
 
266
315
  winston.debug(req.body);
package/routes/message.js CHANGED
@@ -49,10 +49,7 @@ async (req, res) => {
49
49
  winston.debug('req.params: ', req.params);
50
50
  winston.debug('req.params.request_id: ' + req.params.request_id);
51
51
 
52
- // sponz: 4/01/23 disable it
53
- // if (!req.body.text && (!req.body.type || req.body.type=="text") ) {
54
- // return res.status(422).json({ errors: ["text field is required"] });
55
- // }
52
+
56
53
  // const errors = validationResult(req);
57
54
  // if (!errors.isEmpty()) {
58
55
  // return res.status(422).json({ errors: errors.array() });
@@ -103,6 +100,12 @@ async (req, res) => {
103
100
  winston.debug("project_user", project_user);
104
101
  }
105
102
 
103
+
104
+ // sponz: 4/01/23 disable it
105
+ if (!req.body.text && (!req.body.type || req.body.type=="text") ) {
106
+ return res.status(422).json({ errors: ["text field is required"] });
107
+ }
108
+
106
109
  if (sender) {
107
110
 
108
111
  var isObjectId = mongoose.Types.ObjectId.isValid(sender);
package/routes/project.js CHANGED
@@ -407,6 +407,54 @@ router.patch('/:projectid', [passport.authenticate(['basic', 'jwt'], { session:
407
407
  });
408
408
  });
409
409
 
410
+ router.patch('/:projectid/attributes', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
411
+ var data = req.body;
412
+
413
+ // TODO use service method
414
+
415
+ Project.findById(req.params.projectid, function (err, updatedProject) {
416
+ if (err) {
417
+ winston.error('--- > ERROR ', err);
418
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
419
+ }
420
+
421
+ if (!updatedProject) {
422
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
423
+ }
424
+
425
+ if (!updatedProject.attributes) {
426
+ winston.debug("empty attributes")
427
+ updatedProject.attributes = {};
428
+ }
429
+
430
+ winston.debug(" updatedProject attributes", updatedProject.attributes)
431
+
432
+ Object.keys(data).forEach(function(key) {
433
+ var val = data[key];
434
+ winston.debug("data attributes "+key+" " +val)
435
+ updatedProject.attributes[key] = val;
436
+ });
437
+
438
+ winston.debug(" updatedProject attributes", updatedProject.attributes)
439
+
440
+ // https://stackoverflow.com/questions/24054552/mongoose-not-saving-nested-object
441
+ updatedProject.markModified('attributes');
442
+
443
+ //cacheinvalidation
444
+ updatedProject.save(function (err, savedProject) {
445
+ if (err) {
446
+ winston.error("error saving project attributes",err)
447
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
448
+ }
449
+ winston.verbose(" saved project attributes",savedProject.toObject())
450
+ projectEvent.emit('project.update', savedProject);
451
+
452
+ res.json(savedProject);
453
+ });
454
+ });
455
+
456
+ });
457
+
410
458
 
411
459
  router.post('/:projectid/ban', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
412
460
  winston.debug('PATCH PROJECT REQ BODY ', req.body);
@@ -453,7 +501,7 @@ router.get('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: fa
453
501
  let q = Project.findOne({_id: req.params.projectid, status:100});
454
502
  if (cacheEnabler.project) {
455
503
  q.cache(cacheUtil.longTTL, "projects:id:"+req.params.projectid) //project_cache
456
- winston.debug('project cache enabled');
504
+ winston.debug('project cache enabled for /project detail');
457
505
  }
458
506
  q.exec(function (err, project) {
459
507
  if (err) {
package/routes/widget.js CHANGED
@@ -8,8 +8,13 @@ var AnalyticResult = require("../models/analyticResult");
8
8
  var Department = require("../models/department");
9
9
  var RoleConstants = require("../models/roleConstants");
10
10
  var cacheUtil = require('../utils/cacheUtil');
11
+ var cacheEnabler = require("../services/cacheEnabler");
12
+ var pubModulesManager = require('../pubmodules/pubModulesManager'); // on constructor init is undefined beacusae pub module is loaded after
13
+ // console.log("pubModulesManager.cache", pubModulesManager.cache);
14
+ const Faq_kb = require("../models/faq_kb");
11
15
 
12
16
  router.get('/load', function(req, res, next) {
17
+
13
18
  winston.debug(req.projectid);
14
19
 
15
20
  // https://stackoverflow.com/questions/24258782/node-express-4-middleware-after-routes
@@ -17,10 +22,57 @@ router.get('/load', function(req, res, next) {
17
22
  // redirect to widget
18
23
  });
19
24
 
20
- router.get('/', function(req, res, next) {
25
+ router.get('/', async (req, res, next) => {
26
+
21
27
  winston.debug(req.projectid);
22
28
 
23
29
 
30
+ var getIp = function() {
31
+ return new Promise(function (resolve, reject) {
32
+ // console.log("getIp")
33
+ // var ip = req.ip;
34
+ var ip = req.headers['x-forwarded-for'] ||
35
+ req.connection.remoteAddress ||
36
+ req.socket.remoteAddress ||
37
+ (req.connection.socket ? req.connection.socket.remoteAddress : null);
38
+ winston.debug("ip:"+ ip);
39
+ return resolve(ip);
40
+ });
41
+ };
42
+
43
+
44
+
45
+ // console.log("pubModulesManager.cache",pubModulesManager.cache);
46
+ // console.log("cacheClient",cacheClient);
47
+ let cacheClient = undefined;
48
+ if (pubModulesManager.cache) {
49
+ cacheClient = pubModulesManager.cache._cache._cache; //_cache._cache to jump directly to redis modules without cacheoose wrapper (don't support await)
50
+ }
51
+
52
+ var cacheKey = req.projectid+":widgets";
53
+
54
+ if (cacheEnabler.widgets && cacheClient) {
55
+ winston.debug("Getting cache for widgets key: " + cacheKey);
56
+ const value = await cacheClient.get(cacheKey);
57
+
58
+ if (value) {
59
+ winston.debug("Getted cache for widgets key: " + cacheKey + " value:", value);
60
+
61
+ value.ip = await getIp(); //calculate ip each time without getting it from cache
62
+
63
+ winston.debug("value",value);
64
+
65
+ res.json(value);
66
+ // https://stackoverflow.com/questions/24258782/node-express-4-middleware-after-routes
67
+ next(); // <=== call next for following middleware
68
+ return;
69
+ } else {
70
+ winston.debug("Widget cache NOT found");
71
+ }
72
+
73
+ }
74
+ // console.log("/widgets without cache found");
75
+
24
76
  var availableUsers = function() {
25
77
  winston.debug('availableUsers:');
26
78
  return new Promise(function (resolve, reject) {
@@ -74,17 +126,30 @@ router.get('/', function(req, res, next) {
74
126
  };
75
127
 
76
128
 
77
- var getIp = function() {
129
+
130
+ var botsRules = function() {
78
131
  return new Promise(function (resolve, reject) {
79
- // var ip = req.ip;
80
- var ip = req.headers['x-forwarded-for'] ||
81
- req.connection.remoteAddress ||
82
- req.socket.remoteAddress ||
83
- (req.connection.socket ? req.connection.socket.remoteAddress : null);
84
- winston.debug("ip:"+ ip);
85
- return resolve(ip);
86
- });
87
- };
132
+ Faq_kb.find({ "id_project": req.projectid, "trashed": { $in: [null, false] } }, function (err, bots) {
133
+ winston.debug("bots",bots);
134
+ let rules = [];
135
+ bots.forEach(function(bot) {
136
+ winston.debug("bot.attributes",bot.attributes);
137
+ // && bot.attributes.rules.length > 0
138
+ if (bot.attributes && bot.attributes.rules) {
139
+ winston.debug("bot.attributes.rules",bot.attributes.rules);
140
+ bot.attributes.rules.forEach(function(rule) {
141
+ rules.push(rule);
142
+ });
143
+ // rules.concat(bot.attributes.rules);
144
+ }
145
+ });
146
+ winston.debug("resolve",rules);
147
+ // return resolve(bots);
148
+ return resolve(rules);
149
+
150
+ });
151
+ });
152
+ }
88
153
 
89
154
 
90
155
  var getDepartments = function(req) {
@@ -169,14 +234,31 @@ router.get('/', function(req, res, next) {
169
234
  availableUsers()
170
235
  ,
171
236
  getDepartments(req)
172
- ,
237
+ // ,
173
238
  // waiting()unused used 620e87f02e7fda00350ea5a5/publicanalytics/waiting/current
174
239
  ,
175
240
  getIp()
241
+ ,
242
+ botsRules()
176
243
 
177
244
 
178
245
  ]).then(function(all) {
179
- let result = {project: all[0], user_available: all[1], departments: all[2], waiting: all[3], ip: all[4]};
246
+ // console.log("all", all);
247
+ let result = {project: all[0], user_available: all[1], departments: all[2], ip: all[3], botsRules: all[4]};
248
+ // let result = {project: all[0], user_available: all[1], departments: all[2], waiting: all[3], ip: all[4]};
249
+
250
+
251
+ if (cacheEnabler.widgets && cacheClient) {
252
+ let cloned_result = Object.assign({}, result);
253
+ delete cloned_result.ip; //removing uncachable ip from cache
254
+ winston.debug("Creating cache for widgets key: " + cacheKey);
255
+ cacheClient.set(cacheKey, cloned_result, cacheUtil.longTTL, (err, reply) => {
256
+ winston.verbose("Created cache for widgets",{err:err});
257
+ winston.debug("Created cache for widgets reply:"+reply);
258
+ });
259
+
260
+ }
261
+
180
262
  res.json(result);
181
263
  // https://stackoverflow.com/questions/24258782/node-express-4-middleware-after-routes
182
264
  next(); // <=== call next for following middleware
@@ -24,6 +24,9 @@ class BotSubscriptionNotifier {
24
24
  // // url = url.replace ("$res_bot_url", prendi da env)
25
25
  // }
26
26
 
27
+ //Removed snapshot from request
28
+ delete payload.request.snapshot
29
+
27
30
  var json = {timestamp: Date.now(), payload: payload};
28
31
 
29
32
 
@@ -37,6 +37,11 @@ class CacheEnabler {
37
37
  this.project_user = false;
38
38
  }
39
39
 
40
+ this.widgets = true;
41
+ if (process.env.CACHE_WIDGETS_ENABLED=="false" || process.env.CACHE_WIDGETS_ENABLED==false) {
42
+ this.widgets = false;
43
+ }
44
+
40
45
  // this.user = true;
41
46
  // if (process.env.CACHE_USER_ENABLED=="false" || process.env.CACHE_USER_ENABLED==false) {
42
47
  // this.user = false;
@@ -195,7 +195,7 @@ getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
195
195
  let q = Project.findOne({_id: projectid, status: 100})
196
196
  if (cacheEnabler.project) {
197
197
  q.cache(cacheUtil.longTTL, "projects:id:"+projectid) //project_cache
198
- winston.debug('project cache enabled');
198
+ winston.debug('project cache enabled for getOperators');
199
199
  }
200
200
  return q.exec(function(err, project){
201
201
  if (err) {
@@ -14,7 +14,7 @@ class OperatingHoursService {
14
14
  let q = Project.findOne({_id: projectId, status: 100});
15
15
  if (cacheEnabler.project) {
16
16
  q.cache(cacheUtil.longTTL, "projects:id:"+projectId) //project_cache
17
- winston.debug('project cache enabled');
17
+ winston.debug('project cache enabled for projectIsOpenNow');
18
18
  }
19
19
  q.exec(function (err, project) {
20
20
  // winston.debug("XXXXXXXX project", project);
@@ -86,10 +86,16 @@ class SubscriptionNotifier {
86
86
 
87
87
  if (s.global==true){
88
88
  signOptions.audience = 'https://tiledesk.com';
89
- secret = process.env.GLOBAL_SECRET || config.secret;
89
+
90
+ var alg = process.env.GLOBAL_SECRET_ALGORITHM;
91
+ if (alg) {
92
+ signOptions.algorithm = alg;
93
+ }
94
+
95
+ secret = process.env.GLOBAL_SECRET_OR_PRIVATE_KEY || process.env.GLOBAL_SECRET || config.secret;
90
96
  }
91
97
 
92
- var token = jwt.sign(sJson, secret, signOptions);
98
+ var token = jwt.sign(sJson, secret, signOptions); //priv_jwt pp_jwt
93
99
  json["token"] = token;
94
100
 
95
101
 
@@ -75,7 +75,9 @@
75
75
  <body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">
76
76
 
77
77
  {{#if baseScope.replyEnabled}}
78
+ {{#if request_id}}
78
79
  <div>\# Please type your reply above this line \#</div>
80
+ {{/if}}
79
81
  {{/if}}
80
82
 
81
83
  <table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff">
@@ -90,7 +90,7 @@
90
90
 
91
91
  <div style="text-align:center">
92
92
  <a href="http://www.tiledesk.com" style="color:#2daae1;font-weight:bold;text-decoration:none;word-break:break-word" target="_blank">
93
- <img src="https://tiledesk.com/wp-content/uploads/2022/09/tiledeesk_log_email.png" class="CToWUd">
93
+ <img src="https://tiledesk.com/wp-content/uploads/2023/01/tiledesk_log_email_200.png" class="CToWUd">
94
94
  </a>
95
95
  </div>
96
96
  </tr>
@@ -903,7 +903,7 @@ it('createMultiTextNoSenderNoText', function (done) {
903
903
  .end(function(err, res) {
904
904
  //console.log("res", res);
905
905
  console.log("res.body", res.body);
906
- res.should.have.status(500);
906
+ res.should.have.status(200);
907
907
 
908
908
  done();
909
909
  });
@@ -22,7 +22,7 @@ var cacheUtil = require('../utils/cacheUtil');
22
22
  var mongoose = require('mongoose');
23
23
  const requestConstants = require("../models/requestConstants");
24
24
  var RoleConstants = require('../models/roleConstants');
25
- let configSecret = process.env.GLOBAL_SECRET || config.secret;
25
+ let configSecretOrPubicKay = process.env.GLOBAL_SECRET_OR_PUB_KEY || process.env.GLOBAL_SECRET || config.secret;
26
26
  var cacheEnabler = require("../services/cacheEnabler");
27
27
 
28
28
 
@@ -71,14 +71,14 @@ class WebSocketServer {
71
71
 
72
72
  var token = queryParameter.token;
73
73
  winston.debug('token:'+ token);
74
- winston.debug('configSecret:'+ configSecret);
74
+ winston.debug('configSecretOrPubicKay:'+ configSecretOrPubicKay);
75
75
 
76
76
 
77
77
  if (!token)
78
78
  cb(false, 401, 'Unauthorized');
79
79
  else {
80
80
  token = token.replace('JWT ', '');
81
- jwt.verify(token, configSecret, function (err, decoded) {
81
+ jwt.verify(token, configSecretOrPubicKay, function (err, decoded) { //pub_jwt pp_jwt
82
82
  if (err) {
83
83
  winston.error('WebSocket error verifing websocket jwt token ', err);
84
84
  return cb(false, 401, 'Unauthorized');
@@ -189,7 +189,7 @@ class WebSocketServer {
189
189
 
190
190
  if (cacheEnabler.project) {
191
191
  q.cache(cacheUtil.defaultTTL, "projects:id:"+projectId) //project_cache
192
- winston.debug('project cache enabled');
192
+ winston.debug('project cache enabled for websocket');
193
193
  }
194
194
 
195
195
  return q.exec(function(err, project) {