@tiledesk/tiledesk-server 2.3.71 → 2.3.73

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