@tiledesk/tiledesk-server 2.17.4 → 2.18.3

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 (49) hide show
  1. package/CHANGELOG.md +8 -3
  2. package/app.js +4 -0
  3. package/channels/chat21/chat21WebHook.js +6 -1
  4. package/docs/routes-answered.md +153 -0
  5. package/event/authEvent.js +16 -0
  6. package/event/projectUserEvent.js +39 -0
  7. package/event/roleEvent.js +9 -0
  8. package/middleware/has-role.js +160 -121
  9. package/middleware/passport.js +180 -179
  10. package/migrations/1757601159298-project_user_role_type.js +104 -0
  11. package/models/department.js +3 -0
  12. package/models/groupMemberSchama.js +19 -0
  13. package/models/kb_setting.js +74 -4
  14. package/models/permissionConstants.js +19 -0
  15. package/models/project_user.js +86 -8
  16. package/models/request.js +1 -0
  17. package/models/role.js +31 -0
  18. package/models/roleConstants.js +2 -0
  19. package/package.json +1 -1
  20. package/pubmodules/analytics/analytics.js +2 -2
  21. package/pubmodules/cache/mongoose-cachegoose-fn.js +37 -0
  22. package/pubmodules/canned/cannedResponseRoute.js +34 -6
  23. package/pubmodules/routing-queue/listener.js +7 -1
  24. package/pubmodules/trigger/rulesTrigger.js +1 -6
  25. package/routes/answered.js +227 -0
  26. package/routes/auth.js +3 -1
  27. package/routes/department.js +7 -1
  28. package/routes/message.js +4 -1
  29. package/routes/project.js +41 -3
  30. package/routes/project_user.js +62 -11
  31. package/routes/request.js +32 -30
  32. package/routes/roles.js +151 -0
  33. package/routes/unanswered.js +32 -19
  34. package/routes/widget.js +3 -1
  35. package/services/cacheEnabler.js +5 -8
  36. package/services/departmentService.js +39 -11
  37. package/services/emailService.js +2 -2
  38. package/services/pendingInvitationService.js +2 -0
  39. package/services/projectService.js +3 -1
  40. package/services/projectUserService.js +67 -4
  41. package/services/subscriptionNotifierQueued.js +8 -0
  42. package/services/updateRequestSnapshotQueued.js +0 -3
  43. package/test/departmentService.js +5 -0
  44. package/test/messageRoute.js +7 -4
  45. package/test/projectUserRoute.js +116 -0
  46. package/test/requestService.js +7 -3
  47. package/test-int/bot.js +3 -2
  48. package/websocket/webSocketServer.js +273 -225
  49. package/routes/auth_newjwt.js +0 -648
package/routes/message.js CHANGED
@@ -268,7 +268,10 @@ async (req, res) => {
268
268
 
269
269
  // TOOD update also request attributes and sourcePage
270
270
  // return requestService.incrementMessagesCountByRequestId(request.request_id, request.id_project).then(function(savedRequest) {
271
- // console.log("savedRequest.participants.indexOf(message.sender)", savedRequest.participants.indexOf(message.sender));
271
+ Request.findOneAndUpdate({request_id: request.request_id, id_project: request.id_project}, { "attributes.last_message": savedMessage}).catch((err) => {
272
+ winston.error("Create message - saved last message in request error: ", error);
273
+ })
274
+
272
275
 
273
276
  if (request.participants && request.participants.indexOf(sender) > -1) { //update waiitng time if write an agent (member of participants)
274
277
  winston.debug("updateWaitingTimeByRequestId");
package/routes/project.js CHANGED
@@ -900,8 +900,10 @@ router.get('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
900
900
  var sortQuery={};
901
901
  sortQuery[sortField] = direction;
902
902
 
903
+ // rolequery
903
904
 
904
- Project_user.find({ id_user: req.user._id , role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT]}, status: "active"}).
905
+ Project_user.find({ id_user: req.user._id , roleType: RoleConstants.TYPE_AGENTS, status: "active"}).
906
+ // Project_user.find({ id_user: req.user._id , role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT]}, status: "active"}).
905
907
  // populate('id_project').
906
908
  populate({
907
909
  path: 'id_project',
@@ -1037,8 +1039,10 @@ router.get('/:projectid/users/availables', async (req, res) => {
1037
1039
  if (isOpen === false) {
1038
1040
  return res.json(available_agents_array);
1039
1041
  }
1042
+ // rolequery
1043
+ let query = { id_project: projectid, user_available: true, roleType: RoleConstants.TYPE_AGENTS };
1044
+ // let query = { id_project: projectid, user_available: true, role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT]} };
1040
1045
 
1041
- let query = { id_project: projectid, user_available: true, role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT]} };
1042
1046
 
1043
1047
  if (dep_id) {
1044
1048
  let department = await Department.findById(dep_id).catch((err) => {
@@ -1052,7 +1056,41 @@ router.get('/:projectid/users/availables', async (req, res) => {
1052
1056
  }
1053
1057
 
1054
1058
  let group_id = department.id_group;
1055
- if (group_id) {
1059
+ let groups = department.groups;
1060
+
1061
+ if (groups && Array.isArray(groups) && groups.length > 0) {
1062
+ // Converti i group_id in ObjectId per la query
1063
+ const groupIds = groups
1064
+ .map(g => g.group_id)
1065
+ .filter(id => !!id)
1066
+ .map(id => mongoose.Types.ObjectId(id));
1067
+
1068
+ if (groupIds.length > 0) {
1069
+ const dbGroups = await Group.find({ _id: { $in: groupIds } }).catch((err) => {
1070
+ winston.error("(Users Availables) find groups error: ", err);
1071
+ return res.status(500).send({ success: false, error: err });
1072
+ });
1073
+
1074
+ if (!dbGroups || dbGroups.length === 0) {
1075
+ winston.error("(Users Availables) no valid groups found");
1076
+ return res.status(404).send({ success: false, error: "No valid groups found" });
1077
+ }
1078
+
1079
+ // Filtra i gruppi abilitati
1080
+ const enabledGroups = dbGroups.filter(g => g.enabled !== false);
1081
+
1082
+ if (enabledGroups.length === 0) {
1083
+ winston.error("(Users Availables) all groups are disabled");
1084
+ return res.status(403).send({ success: false, error: "All groups are currently disabled" });
1085
+ }
1086
+
1087
+ // Raccogli tutti i membri (stringhe) e rimuovi duplicati
1088
+ const members = [...new Set(enabledGroups.flatMap(g => g.members))];
1089
+
1090
+ query.id_user = { $in: members };
1091
+ }
1092
+ }
1093
+ else if (group_id) {
1056
1094
  let group = await Group.findById(group_id).catch((err) => {
1057
1095
  winston.error("(Users Availables) find group error: ", err)
1058
1096
  return res.status(500).send({ success: false, error: err })
@@ -16,6 +16,7 @@ var passport = require('passport');
16
16
  require('../middleware/passport')(passport);
17
17
  var validtoken = require('../middleware/valid-token')
18
18
  var roleChecker = require('../middleware/has-role');
19
+ const puEvent = require('../event/projectUserEvent');
19
20
 
20
21
 
21
22
  router.post('/invite', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
@@ -56,18 +57,30 @@ router.post('/invite', [passport.authenticate(['basic', 'jwt'], { session: false
56
57
 
57
58
  } else {
58
59
 
59
- let roles = [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT];
60
-
61
- Project_user.findOne({ id_project: id_project, id_user: user._id, role: { $in: roles }}, (err, puser) => {
60
+ /**
61
+ * *** IT IS NOT ALLOWED TO INVITE A USER WHO IS ALREADY A MEMBER OF THE PROJECT ***
62
+ * FIND THE PROJECT USERS FOR THE PROJECT ID PASSED BY THE CLIENT IN THE BODY OF THE REQUEST
63
+ * IF THE ID OF THE USER FOUND FOR THE EMAIL (PASSED IN THE BODY OF THE REQUEST - see above)
64
+ * MATCHES ONE OF THE USER ID CONTENTS IN THE PROJECTS USER OBJECT STOP THE WORKFLOW AND RETURN AN ERROR */
65
+
66
+ // rolequery
67
+ // var role = [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT];
68
+ // winston.debug("role", role);
69
+
70
+ // winston.debug("PROJECT USER ROUTES - req projectid", req.projectid);
71
+ return Project_user.findOne({ id_project: req.projectid, id_user: user._id, roleType: RoleConstants.TYPE_AGENTS, status: "active"}, function (err, puser) {
72
+ // return Project_user.find({ id_project: req.projectid, role: { $in : role }, status: "active"}, function (err, projectuser) {
73
+ //puser = projectuser
74
+
75
+ winston.debug('PRJCT-USERS FOUND (FILTERED FOR THE PROJECT ID) ', puser )
62
76
  if (err) {
63
77
  winston.error("Error inviting an already existing user: ", err);
64
78
  return res.status(500).send({ success: false, msg: "An error occurred on inviting user " + email + " on project " + id_project })
65
79
  }
66
80
 
67
- if (!roles.includes(req.body.role)) {
68
- return res.status(400).send({ success: false, msg: 'Invalid role specified: ' + req.body.role });
69
- }
70
-
81
+ // if (!roles.includes(req.body.role)) {
82
+ // return res.status(400).send({ success: false, msg: 'Invalid role specified: ' + req.body.role });
83
+ // }
71
84
  let user_available = typeof req.body.user_available === 'boolean' ? req.body.user_available : true
72
85
 
73
86
  if (puser) {
@@ -76,7 +89,20 @@ router.post('/invite', [passport.authenticate(['basic', 'jwt'], { session: false
76
89
  return res.status(403).send({ success: false, msg: 'Forbidden. User is already a member', code: 4001 });
77
90
  }
78
91
 
79
- Project_user.findByIdAndUpdate(puser._id, { role: req.body.role, user_available: user_available, trashed: false, status: 'active' }, { new: true}, (err, updatedPuser) => {
92
+ winston.debug('NO ERROR, SO CREATE AND SAVE A NEW PROJECT USER ')
93
+
94
+ var newProject_user = new Project_user({
95
+ // _id: new mongoose.Types.ObjectId(),
96
+ id_project: req.projectid,
97
+ id_user: user._id,
98
+ role: req.body.role,
99
+ roleType : RoleConstants.TYPE_AGENTS,
100
+ user_available: user_available,
101
+ createdBy: req.user.id,
102
+ updatedBy: req.user.id
103
+ });
104
+
105
+ return newProject_user.save(function (err, savedProject_user) {
80
106
  if (err) {
81
107
  winston.error("Error update existing project user before inviting it ", err)
82
108
  return res.status(500).send({ success: false, msg: "An error occurred on inviting user " + email + " on project " + id_project })
@@ -101,6 +127,7 @@ router.post('/invite', [passport.authenticate(['basic', 'jwt'], { session: false
101
127
  id_project: id_project,
102
128
  id_user: user._id,
103
129
  role: req.body.role,
130
+ roleType : RoleConstants.TYPE_AGENTS,
104
131
  user_available: user_available,
105
132
  createdBy: req.user.id,
106
133
  updatedBy: req.user.id
@@ -138,6 +165,7 @@ router.post('/', [passport.authenticate(['basic', 'jwt'], { session: false }), v
138
165
  // role: RoleConstants.USER,
139
166
  // - Create project_user endpoint by agent (Ticketing) now is with Guest Role
140
167
  role: RoleConstants.GUEST,
168
+ roleType : RoleConstants.TYPE_USERS,
141
169
  user_available: false,
142
170
  tags: req.body.tags,
143
171
  createdBy: req.user.id,
@@ -298,6 +326,7 @@ router.delete('/:project_userid', [passport.authenticate(['basic', 'jwt'], { ses
298
326
  return res.status(404).send({ success: false, error: 'Project user not found with id ' + pu_id });
299
327
  }
300
328
 
329
+ puEvent.emit('project_user.deleted', project_user);
301
330
  // Event 'project_user.delete' not working - Check it and improve it to manage soft/hard delete
302
331
  return res.status(200).send(project_user);
303
332
 
@@ -324,6 +353,7 @@ router.delete('/:project_userid', [passport.authenticate(['basic', 'jwt'], { ses
324
353
  });
325
354
  }
326
355
 
356
+ puEvent.emit('project_user.deleted', project_user);
327
357
  return res.status(200).send(project_user);
328
358
  });
329
359
  }
@@ -387,6 +417,20 @@ router.put('/:project_userid/restore', [passport.authenticate(['basic', 'jwt'],
387
417
  });
388
418
  });
389
419
 
420
+ router.get('/me', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], function (req, res, next) {
421
+ if (!req.project) {
422
+ return res.status(404).send({ success: false, msg: 'Project not found.' });
423
+ }
424
+ var project_user = req.projectuser;
425
+
426
+ var pu = project_user.toJSON();
427
+
428
+ pu.isBusy = ProjectUserUtil.isBusy(project_user, req.project.settings && req.project.settings.max_agent_assigned_chat);
429
+ res.json([pu]);
430
+
431
+
432
+ });
433
+
390
434
  router.get('/:project_userid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], function (req, res) {
391
435
  // router.get('/details/:project_userid', function (req, res) {
392
436
  // winston.debug("PROJECT USER ROUTES - req projectid", req.projectid);
@@ -513,18 +557,25 @@ router.get('/users/:user_id', [passport.authenticate(['basic', 'jwt'], { session
513
557
  */
514
558
  router.get('/', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot', 'subscription'])], function (req, res) {
515
559
 
516
- var role = [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT];
560
+ // rolequery
561
+ // var role = [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT];
517
562
 
563
+ var query;
518
564
  if (req.query.role) {
519
565
  role = req.query.role;
566
+ winston.debug("role", role);
567
+ query = {id_project: req.projectid, role: { $in : role } };
568
+ } else {
569
+ query = {id_project: req.projectid, roleType: RoleConstants.TYPE_AGENTS };
520
570
  }
521
- winston.debug("role", role);
522
571
 
523
- var query = { id_project: req.projectid, role: { $in : role } };
524
572
  if (!req.query.trashed || req.query.trashed === 'false' || req.query.trashed === false) {
525
573
  query.trashed = { $ne: true };
526
574
  }
527
575
 
576
+ // var query = {id_project: req.projectid, role: { $in : role } };
577
+
578
+
528
579
  if (req.query.presencestatus) {
529
580
  query["presence.status"] = req.query.presencestatus;
530
581
  }
package/routes/request.js CHANGED
@@ -33,6 +33,7 @@ const RoleConstants = require('../models/roleConstants');
33
33
  const eventService = require('../pubmodules/events/eventService');
34
34
  const { Scheduler } = require('../services/Scheduler');
35
35
  const faq_kb = require('../models/faq_kb');
36
+
36
37
  const datesUtil = require('../utils/datesUtil');
37
38
  //const JobManager = require('../utils/jobs-worker-queue-manager-v2/JobManagerV2');
38
39
 
@@ -188,19 +189,7 @@ router.post('/',
188
189
  };
189
190
 
190
191
  return requestService.create(new_request).then(function (savedRequest) {
191
- // createWithIdAndRequester(request_id, project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes) {
192
- // return requestService.createWithIdAndRequester(request_id, req.projectuser._id, createdLead._id, req.projectid,
193
- // req.body.text, req.body.departmentid, req.body.sourcePage,
194
- // req.body.language, req.body.userAgent, null, req.user._id, req.body.attributes, req.body.subject).then(function (savedRequest) {
195
-
196
-
197
- // return messageService.create(sender || req.user._id, fullname, request_id, req.body.text,
198
- // req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata, req.body.language, undefined, req.body.channel).then(function(savedMessage){
199
-
200
- // create(sender, senderFullname, recipient, text, id_project, createdBy, status, attributes, type, metadata) {
201
- // return messageService.create(req.body.sender || req.user._id, req.body.senderFullname || req.user.fullName, request_id, req.body.text,
202
- // req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata).then(function(savedMessage){
203
-
192
+
204
193
 
205
194
  winston.debug('res.json(savedRequest)');
206
195
  var endTimestamp = new Date();
@@ -377,7 +366,7 @@ router.put('/:requestid/close', async function (req, res) {
377
366
 
378
367
  // TODO make a synchronous chat21 version (with query parameter?) with request.support_group.created
379
368
  router.put('/:requestid/reopen', function (req, res) {
380
- winston.debug(req.body);
369
+ winston.debug(req.body);
381
370
  // reopenRequestByRequestId(request_id, id_project) {
382
371
  return requestService.reopenRequestByRequestId(req.params.requestid, req.projectid).then(function (reopenRequest) {
383
372
 
@@ -399,12 +388,13 @@ router.put('/:requestid/assignee', function (req, res) {
399
388
  //TODO change assignee
400
389
  });
401
390
 
391
+ // curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@f21.it:123456 -d '{"member":"ciao"}' http://localhost:3000/68d4135a10e71f7bfa4dcf2f/requests/req123456/participants
402
392
  // TODO make a synchronous chat21 version (with query parameter?) with request.support_group.created
403
393
  router.post('/:requestid/participants',
404
394
  [
405
395
  check('member').notEmpty(),
406
396
  ],
407
- function (req, res) {
397
+ async (req, res) => {
408
398
  winston.debug(req.body);
409
399
 
410
400
  const errors = validationResult(req);
@@ -432,7 +422,9 @@ error: uncaughtException: Cannot set property 'participants' of null
432
422
  2020-03-08T12:53:35.793660+00:00 app[web.1]: at /app/services/requestService.js:672:30
433
423
  2020-03-08T12:53:35.793661+00:00 app[web.1]: at /app/node_modules/mongoose/lib/model.js:4779:16
434
424
  */
435
- router.put('/:requestid/participants', function (req, res) {
425
+
426
+ // curl -v -X PUT -H 'Content-Type:application/json' -u andrea.leo@f21.it:123456 -d '{"member":"ciao"}' http://localhost:3000/68d4135a10e71f7bfa4dcf2f/requests/req123456/participants
427
+ router.put('/:requestid/participants', async (req, res) => {
436
428
  winston.debug("req.body", req.body);
437
429
 
438
430
  var participants = [];
@@ -512,7 +504,7 @@ router.put('/:requestid/replace', async (req, res) => {
512
504
  })
513
505
 
514
506
  // TODO make a synchronous chat21 version (with query parameter?) with request.support_group.created
515
- router.delete('/:requestid/participants/:participantid', function (req, res) {
507
+ router.delete('/:requestid/participants/:participantid', async (req, res) => {
516
508
  winston.debug(req.body);
517
509
  //removeParticipantByRequestId(request_id, id_project, member)
518
510
  return requestService.removeParticipantByRequestId(req.params.requestid, req.projectid, req.params.participantid).then(function (updatedRequest) {
@@ -775,6 +767,7 @@ router.post('/:requestid/notes', async function (req, res) {
775
767
  }
776
768
 
777
769
  // Check if the user is a participant
770
+ // disable this check?
778
771
  if (!request.participantsAgents.includes(req.user.id)) {
779
772
  winston.verbose("Trying to add a note from a non participating agent");
780
773
  return res.status(403).send({ success: false, error: "You are not participating in the conversation"})
@@ -821,6 +814,7 @@ router.delete('/:requestid/notes/:noteid', async function (req, res) {
821
814
  }
822
815
 
823
816
  // Check if the user is a participant
817
+ // disable this check?
824
818
  if (!request.participantsAgents.includes(req.user.id)) {
825
819
  winston.verbose("Trying to delete a note from a non participating agent");
826
820
  return res.status(403).send({ success: false, error: "You are not participating in the conversation"})
@@ -1052,8 +1046,8 @@ router.delete('/:requestid/tag/:tag_id', async (req, res) => {
1052
1046
  let id_project = req.projectid;
1053
1047
  let request_id = req.params.requestid;
1054
1048
  let tag_id = req.params.tag_id;
1055
-
1056
-
1049
+
1050
+
1057
1051
 
1058
1052
  Request.findOneAndUpdate({ id_project: id_project, request_id: request_id }, { $pull: { tags: { _id: tag_id } } }, { new: true }).then( async (updatedRequest) => {
1059
1053
 
@@ -1088,8 +1082,8 @@ router.delete('/:requestid', function (req, res) {
1088
1082
 
1089
1083
  var projectuser = req.projectuser;
1090
1084
 
1091
-
1092
- if (projectuser.role != "owner") {
1085
+ // request_role_check
1086
+ if (!projectuser.hasPermissionOrRole('request_delete', 'owner')){
1093
1087
  return res.status(403).send({ success: false, msg: 'Unauthorized.' });
1094
1088
  }
1095
1089
 
@@ -1144,8 +1138,8 @@ router.delete('/id/:id', function (req, res) {
1144
1138
 
1145
1139
  var projectuser = req.projectuser;
1146
1140
 
1147
-
1148
- if (projectuser.role != "owner") {
1141
+ // request_role_check
1142
+ if (!projectuser.hasPermissionOrRole('request_delete', 'owner')){
1149
1143
  return res.status(403).send({ success: false, msg: 'Unauthorized.' });
1150
1144
  }
1151
1145
 
@@ -1169,7 +1163,7 @@ router.delete('/id/:id', function (req, res) {
1169
1163
  });
1170
1164
 
1171
1165
 
1172
-
1166
+ // curl -v -X GET -H 'Content-Type:application/json' -u andrea.leo@f21.it:123456 http://localhost:3000/68d4135a10e71f7bfa4dcf2f/requests
1173
1167
 
1174
1168
  router.get('/', function (req, res, next) {
1175
1169
 
@@ -1207,16 +1201,24 @@ router.get('/', function (req, res, next) {
1207
1201
 
1208
1202
  if (req.user instanceof Subscription) {
1209
1203
  // All request
1210
- } else if (projectuser && (projectuser.role == "owner" || projectuser.role == "admin")) {
1204
+ winston.debug("Subscription All request ");
1205
+ } else if (projectuser.hasPermissionOrRole('request_read_all', ["owner", "admin"])) {
1211
1206
  // All request
1212
- // Per uni mostrare solo quelle proprie quindi solo participants
1213
- if (req.query.mine) {
1214
- query["$or"] = [{ "snapshot.agents.id_user": req.user.id }, { "participants": req.user.id }];
1215
- }
1216
- } else {
1207
+ winston.debug("hasPermissionOrRole All request ");
1208
+ } else if (projectuser.hasPermissionOrRole('request_read_group', ["agent"])) {
1209
+
1217
1210
  query["$or"] = [{ "snapshot.agents.id_user": req.user.id }, { "participants": req.user.id }];
1211
+
1212
+ }
1213
+ // else if (projectuser.hasPermissionOrRole('request_read_mine', ["????"])) {
1214
+ // query["participants"] = req.user.id;
1215
+ // }
1216
+ else {
1217
+ query["participants"] = req.user.id;
1218
+ // generate empty requests response
1218
1219
  }
1219
1220
 
1221
+
1220
1222
  if (req.query.dept_id) {
1221
1223
  query.department = req.query.dept_id;
1222
1224
  }
@@ -0,0 +1,151 @@
1
+ var express = require('express');
2
+ var router = express.Router();
3
+ var Role = require("../models/role");
4
+ var winston = require('../config/winston');
5
+ const roleEvent = require('../event/roleEvent');
6
+
7
+ router.post('/', function (req, res) {
8
+
9
+ winston.debug(req.body);
10
+ winston.debug("req.user", req.user);
11
+
12
+ var newRole = new Role({
13
+ name: req.body.name,
14
+ permissions: req.body.permissions,
15
+ id_project: req.projectid,
16
+ createdBy: req.user.id,
17
+ updatedBy: req.user.id
18
+ });
19
+
20
+ newRole.save(function(err, savedRole) {
21
+ if (err) {
22
+ winston.error('Error saving the role '+ JSON.stringify(newRole), err)
23
+ return res.status(500).send({ success: false, msg: 'Error inserting object.' });
24
+ }
25
+
26
+ roleEvent.emit('role.create', savedRole);
27
+
28
+ return res.json(savedRole);
29
+ })
30
+
31
+
32
+ });
33
+
34
+ router.put('/:roleid', function (req, res) {
35
+ winston.debug(req.body);
36
+ var update = {};
37
+
38
+ if (req.body.name!=undefined) {
39
+ update.name = req.body.name;
40
+ }
41
+
42
+ if (req.body.permissions!=undefined) {
43
+ update.permissions = req.body.permissions;
44
+ }
45
+
46
+
47
+ Role.findByIdAndUpdate(req.params.roleid, update, { new: true, upsert: true }, function (err, updatedRole) {
48
+ if (err) {
49
+ winston.error('--- > ERROR ', err);
50
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
51
+ }
52
+
53
+ roleEvent.emit('role.update', updatedRole);
54
+
55
+ res.json(updatedRole);
56
+ });
57
+ });
58
+
59
+
60
+
61
+ router.delete('/:roleid', function (req, res) {
62
+ winston.debug(req.body);
63
+
64
+ // Role.remove({ _id: req.params.roleid }, function (err, role) {
65
+ Role.findOneAndDelete({ _id: req.params.roleid }, (err, role) => {
66
+ if (err) {
67
+ winston.error('--- > ERROR ', err);
68
+ return res.status(500).send({ success: false, msg: 'Error deleting object.' });
69
+ }
70
+
71
+ roleEvent.emit('role.delete', role);
72
+
73
+ res.json(role);
74
+ });
75
+ });
76
+
77
+
78
+ router.get('/:roleid', function (req, res) {
79
+ winston.debug(req.body);
80
+
81
+ Role.findById(req.params.roleid, function (err, role) {
82
+ if (err) {
83
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
84
+ }
85
+ if (!role) {
86
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
87
+ }
88
+ res.json(role);
89
+ });
90
+ });
91
+
92
+
93
+ router.get('/', async(req, res) => {
94
+
95
+ var limit = 40; // Number of request per page
96
+
97
+ if (req.query.limit) {
98
+ limit = parseInt(req.query.limit);
99
+ winston.debug('LEAD ROUTE - limit: '+limit);
100
+ }
101
+
102
+ var page = 0;
103
+
104
+ if (req.query.page) {
105
+ page = req.query.page;
106
+ }
107
+
108
+ var skip = page * limit;
109
+ winston.debug('ROLE ROUTE - SKIP PAGE ', skip);
110
+
111
+
112
+ var query = {"id_project": req.projectid};
113
+
114
+
115
+
116
+ var direction = -1; //-1 descending , 1 ascending
117
+ if (req.query.direction) {
118
+ direction = req.query.direction;
119
+ }
120
+
121
+ var sortField = "createdAt";
122
+ if (req.query.sort) {
123
+ sortField = req.query.sort;
124
+ }
125
+
126
+ var sortQuery = {};
127
+ sortQuery[sortField] = direction;
128
+
129
+ winston.debug("sort query", sortQuery);
130
+
131
+
132
+
133
+ return Role.find(query).
134
+ skip(skip).limit(limit).
135
+ sort(sortQuery).
136
+ exec(function (err, roles) {
137
+ if (err) {
138
+ winston.error('ROLE ROUTE - REQUEST FIND ERR ', err)
139
+ return (err);
140
+ }
141
+
142
+
143
+ return res.json(roles);
144
+
145
+ });
146
+ });
147
+
148
+
149
+
150
+
151
+ module.exports = router;
@@ -6,7 +6,7 @@ var winston = require('../config/winston');
6
6
  // Add a new unanswered question
7
7
  router.post('/', async (req, res) => {
8
8
  try {
9
- const { namespace, question } = req.body;
9
+ const { namespace, question, request_id, sender } = req.body;
10
10
  const id_project = req.projectid;
11
11
 
12
12
  if (!namespace || !question) {
@@ -28,7 +28,9 @@ router.post('/', async (req, res) => {
28
28
  const unansweredQuestion = new UnansweredQuestion({
29
29
  id_project,
30
30
  namespace,
31
- question
31
+ question,
32
+ request_id,
33
+ sender
32
34
  });
33
35
 
34
36
  const savedQuestion = await unansweredQuestion.save();
@@ -67,21 +69,32 @@ router.get('/:namespace', async (req, res) => {
67
69
 
68
70
  const page = parseInt(req.query.page) || 0;
69
71
  const limit = parseInt(req.query.limit) || 20;
70
- const sortField = req.query.sortField || 'created_at';
72
+ const sortField = req.query.sortField || 'createdAt';
71
73
  const direction = parseInt(req.query.direction) || -1;
72
74
 
73
- const questions = await UnansweredQuestion.find({
74
- id_project,
75
- namespace
76
- })
77
- .sort({ [sortField]: direction })
78
- .skip(page * limit)
79
- .limit(limit);
75
+ const filter = { id_project, namespace };
80
76
 
81
- const count = await UnansweredQuestion.countDocuments({
82
- id_project,
83
- namespace
84
- });
77
+ let projection = undefined;
78
+
79
+ if (req.query.search) {
80
+ filter.$text = { $search: req.query.search };
81
+ // Add score to projection if it's a text search
82
+ projection = { score: { $meta: "textScore" } };
83
+ }
84
+
85
+ let sortObj;
86
+ if (projection && projection.score) {
87
+ sortObj = { score: { $meta: "textScore" } };
88
+ } else {
89
+ sortObj = { [sortField]: direction };
90
+ }
91
+
92
+ const questions = await UnansweredQuestion.find(filter, projection)
93
+ .sort(sortObj)
94
+ .skip(page * limit)
95
+ .limit(limit);
96
+
97
+ const count = await UnansweredQuestion.countDocuments(filter);
85
98
 
86
99
  res.status(200).json({
87
100
  count,
@@ -90,7 +103,8 @@ router.get('/:namespace', async (req, res) => {
90
103
  page,
91
104
  limit,
92
105
  sortField,
93
- direction
106
+ direction,
107
+ search: req.query.search || undefined
94
108
  }
95
109
  });
96
110
 
@@ -109,20 +123,19 @@ router.delete('/:id', async (req, res) => {
109
123
  const { id } = req.params;
110
124
  const id_project = req.projectid;
111
125
 
112
- const question = await UnansweredQuestion.findOne({ _id: id, id_project });
113
- if (!question) {
126
+ const deleted = await UnansweredQuestion.findOneAndDelete({ _id: id, id_project });
127
+ if (!deleted) {
114
128
  return res.status(404).json({
115
129
  success: false,
116
130
  error: "Question not found"
117
131
  });
118
132
  }
119
133
 
120
- await UnansweredQuestion.deleteOne({ _id: id });
121
134
  res.status(200).json({
122
135
  success: true,
123
136
  message: "Question deleted successfully"
124
137
  });
125
-
138
+
126
139
  } catch (error) {
127
140
  winston.error('Error deleting unanswered question:', error);
128
141
  res.status(500).json({
package/routes/widget.js CHANGED
@@ -82,7 +82,9 @@ router.get('/', async (req, res, next) => {
82
82
  operatingHoursService.projectIsOpenNow(req.projectid, function (isOpen, err) {
83
83
  winston.debug('isOpen:'+ isOpen);
84
84
  if (isOpen) {
85
- Project_user.find({ id_project: req.projectid, user_available: true, role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT]}, status: "active" }).
85
+ // rolequery
86
+ Project_user.find({ id_project: req.projectid, user_available: true, roleType: RoleConstants.TYPE_AGENTS, status: "active" }).
87
+ // Project_user.find({ id_project: req.projectid, user_available: true, role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT]}, status: "active" }).
86
88
  populate('id_user').
87
89
  exec(function (err, project_users) {
88
90
  winston.debug('project_users:'+ project_users);
@@ -47,15 +47,12 @@ class CacheEnabler {
47
47
  this.integrations = false;
48
48
  }
49
49
 
50
- // this.user = true;
51
- // if (process.env.CACHE_USER_ENABLED=="false" || process.env.CACHE_USER_ENABLED==false) {
52
- // this.user = false;
53
- // }
50
+ this.role = true;
51
+ if (process.env.CACHE_ROLE_ENABLED=="false" || process.env.CACHE_ROLE_ENABLED==false) {
52
+ this.role = false;
53
+ }
54
54
 
55
- // this.message = true;
56
- // if (process.env.CACHE_MESSAGE_ENABLED=="false" || process.env.CACHE_MESSAGE_ENABLED==false) {
57
- // this.message = false;
58
- // }
55
+
59
56
  }
60
57
  }
61
58