@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.
- package/CHANGELOG.md +8 -3
- package/app.js +4 -0
- package/channels/chat21/chat21WebHook.js +6 -1
- package/docs/routes-answered.md +153 -0
- package/event/authEvent.js +16 -0
- package/event/projectUserEvent.js +39 -0
- package/event/roleEvent.js +9 -0
- package/middleware/has-role.js +160 -121
- package/middleware/passport.js +180 -179
- package/migrations/1757601159298-project_user_role_type.js +104 -0
- package/models/department.js +3 -0
- package/models/groupMemberSchama.js +19 -0
- package/models/kb_setting.js +74 -4
- package/models/permissionConstants.js +19 -0
- package/models/project_user.js +86 -8
- package/models/request.js +1 -0
- package/models/role.js +31 -0
- package/models/roleConstants.js +2 -0
- package/package.json +1 -1
- package/pubmodules/analytics/analytics.js +2 -2
- package/pubmodules/cache/mongoose-cachegoose-fn.js +37 -0
- package/pubmodules/canned/cannedResponseRoute.js +34 -6
- package/pubmodules/routing-queue/listener.js +7 -1
- package/pubmodules/trigger/rulesTrigger.js +1 -6
- package/routes/answered.js +227 -0
- package/routes/auth.js +3 -1
- package/routes/department.js +7 -1
- package/routes/message.js +4 -1
- package/routes/project.js +41 -3
- package/routes/project_user.js +62 -11
- package/routes/request.js +32 -30
- package/routes/roles.js +151 -0
- package/routes/unanswered.js +32 -19
- package/routes/widget.js +3 -1
- package/services/cacheEnabler.js +5 -8
- package/services/departmentService.js +39 -11
- package/services/emailService.js +2 -2
- package/services/pendingInvitationService.js +2 -0
- package/services/projectService.js +3 -1
- package/services/projectUserService.js +67 -4
- package/services/subscriptionNotifierQueued.js +8 -0
- package/services/updateRequestSnapshotQueued.js +0 -3
- package/test/departmentService.js +5 -0
- package/test/messageRoute.js +7 -4
- package/test/projectUserRoute.js +116 -0
- package/test/requestService.js +7 -3
- package/test-int/bot.js +3 -2
- package/websocket/webSocketServer.js +273 -225
- 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
|
-
|
|
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 ,
|
|
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
|
-
|
|
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 })
|
package/routes/project_user.js
CHANGED
|
@@ -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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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',
|
|
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.
|
|
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.
|
|
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
|
-
|
|
1204
|
+
winston.debug("Subscription All request ");
|
|
1205
|
+
} else if (projectuser.hasPermissionOrRole('request_read_all', ["owner", "admin"])) {
|
|
1211
1206
|
// All request
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
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
|
}
|
package/routes/roles.js
ADDED
|
@@ -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;
|
package/routes/unanswered.js
CHANGED
|
@@ -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 || '
|
|
72
|
+
const sortField = req.query.sortField || 'createdAt';
|
|
71
73
|
const direction = parseInt(req.query.direction) || -1;
|
|
72
74
|
|
|
73
|
-
const
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
|
113
|
-
if (!
|
|
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
|
-
|
|
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);
|
package/services/cacheEnabler.js
CHANGED
|
@@ -47,15 +47,12 @@ class CacheEnabler {
|
|
|
47
47
|
this.integrations = false;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
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
|
|