@tiledesk/tiledesk-server 2.3.13 → 2.3.16
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +9 -2
- package/app.js +7 -72
- package/channels/chat21/chat21WebHook.js +30 -21
- package/deploy.sh +2 -0
- package/middleware/ipFilter.js +220 -0
- package/middleware/passport.js +7 -1
- package/models/project.js +10 -0
- package/package.json +2 -1
- package/pubmodules/activities/activityArchiver.js +20 -1
- package/pubmodules/emailNotification/requestNotification.js +7 -0
- package/pubmodules/pubModulesManager.js +6 -1
- package/pubmodules/rasa/listener.js +4 -4
- package/pubmodules/tilebot/index.js +9 -1
- package/pubmodules/tilebot/listener.js +21 -3
- package/routes/project.js +66 -0
- package/routes/users.js +1 -1
- package/routes/widget.js +6 -2
- package/services/banUserNotifier.js +86 -0
- package/utils/orgUtil.js +3 -3
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# 2.3.14 -> PROD
|
2
|
+
- Added ip filter with Deny roles and ban User roles
|
3
|
+
- Ban notifier
|
4
|
+
- Middleware decodeJwt before passport with passport fallback
|
5
|
+
- Removed unused requestService.incrementMessagesCountByRequestId from chat21Webhook
|
6
|
+
- Enable agent to manage groups endpoint
|
7
|
+
- Added tilebot chat server
|
8
|
+
|
9
|
+
# 2.3.13
|
3
10
|
- Getting ip fix
|
4
11
|
|
5
12
|
# 2.3.10
|
package/app.js
CHANGED
@@ -146,10 +146,10 @@ pubModulesManager.init({express:express, mongoose:mongoose, passport:passport, d
|
|
146
146
|
var channelManager = require('./channels/channelManager');
|
147
147
|
channelManager.listen();
|
148
148
|
|
149
|
-
|
150
|
-
// const IpDeniedError = require('express-ipfilter').IpDeniedError;
|
151
|
-
|
149
|
+
var IPFilter = require('./middleware/ipFilter');
|
152
150
|
|
151
|
+
var BanUserNotifier = require('./services/banUserNotifier');
|
152
|
+
BanUserNotifier.listen();
|
153
153
|
|
154
154
|
var modulesManager = undefined;
|
155
155
|
try {
|
@@ -175,6 +175,7 @@ if (process.env.CREATE_INITIAL_DATA !== "false") {
|
|
175
175
|
|
176
176
|
|
177
177
|
|
178
|
+
|
178
179
|
var app = express();
|
179
180
|
|
180
181
|
|
@@ -335,71 +336,6 @@ var projectSetter = function (req, res, next) {
|
|
335
336
|
}
|
336
337
|
|
337
338
|
|
338
|
-
function customDetection (req) {
|
339
|
-
// const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
340
|
-
// const ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || //https://stackoverflow.com/questions/8107856/how-to-determine-a-users-ip-address-in-node
|
341
|
-
// req.socket.remoteAddress
|
342
|
-
|
343
|
-
|
344
|
-
let ip = req.socket.remoteAddress;
|
345
|
-
|
346
|
-
const xFor = req.headers['x-forwarded-for'];
|
347
|
-
if (xFor ) {
|
348
|
-
const xForArr = xFor.split(',');
|
349
|
-
if (xForArr && xForArr.length>0) {
|
350
|
-
ip = xForArr.shift();
|
351
|
-
}
|
352
|
-
}
|
353
|
-
// const ip =
|
354
|
-
// req.headers['x-forwarded-for']?.split(',').shift()
|
355
|
-
// || req.socket?.remoteAddress
|
356
|
-
|
357
|
-
winston.info("standard ip: "+ip); // ip address of the user
|
358
|
-
return ip;
|
359
|
-
}
|
360
|
-
|
361
|
-
|
362
|
-
var projectIpFilter = function (req, res, next) {
|
363
|
-
// var projectIpFilter = function (err, req, res, next) {
|
364
|
-
|
365
|
-
// var ip = require('ip');
|
366
|
-
// winston.info("projectIpFilter ip2: " + ip.address() );
|
367
|
-
|
368
|
-
|
369
|
-
const nextIp = function(err) {
|
370
|
-
winston.info("projectIpFilter next",err);
|
371
|
-
|
372
|
-
if (err && err.name === "IpDeniedError") {
|
373
|
-
winston.info("IpDeniedError");
|
374
|
-
return res.status(401).json({ err: "error project ip filter" });
|
375
|
-
// next(err)
|
376
|
-
}
|
377
|
-
|
378
|
-
next();
|
379
|
-
|
380
|
-
}
|
381
|
-
|
382
|
-
|
383
|
-
if (!req.project) {
|
384
|
-
return next();
|
385
|
-
}
|
386
|
-
|
387
|
-
var projectIpFilterEnabled = req.project.ipFilterEnabled;
|
388
|
-
winston.debug("project projectIpFilterEnabled: " +projectIpFilterEnabled)
|
389
|
-
|
390
|
-
var projectIpFilter = req.project.ipFilter
|
391
|
-
winston.debug("project ipFilter: " + projectIpFilter)
|
392
|
-
|
393
|
-
if (projectIpFilterEnabled === true && projectIpFilter && projectIpFilter.length > 0) {
|
394
|
-
var ip = ipfilter(projectIpFilter, { detectIp: customDetection, mode: 'allow' })
|
395
|
-
// var ip = ipfilter(projectIpFilter, { mode: 'allow' })
|
396
|
-
ip(req, res, nextIp);
|
397
|
-
} else {
|
398
|
-
next();
|
399
|
-
}
|
400
|
-
|
401
|
-
}
|
402
|
-
|
403
339
|
|
404
340
|
|
405
341
|
// app.use('/admin', admin);
|
@@ -445,8 +381,7 @@ if (modulesManager) {
|
|
445
381
|
modulesManager.use(app);
|
446
382
|
}
|
447
383
|
|
448
|
-
|
449
|
-
app.use('/:projectid/', [projectIdSetter, projectSetter, projectIpFilter]);
|
384
|
+
app.use('/:projectid/', [projectIdSetter, projectSetter, IPFilter.projectIpFilter, IPFilter.projectIpFilterDeny, IPFilter.decodeJwt, IPFilter.projectBanUserFilter]);
|
450
385
|
|
451
386
|
|
452
387
|
app.use('/:projectid/authtestWithRoleCheck', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken], authtestWithRoleCheck);
|
@@ -465,7 +400,7 @@ app.use('/:projectid/departments', department);
|
|
465
400
|
|
466
401
|
channelManager.useUnderProjects(app);
|
467
402
|
|
468
|
-
app.use('/:projectid/groups', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('
|
403
|
+
app.use('/:projectid/groups', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], group);
|
469
404
|
app.use('/:projectid/tags', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], tag);
|
470
405
|
app.use('/:projectid/subscriptions', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], resthook);
|
471
406
|
|
@@ -554,7 +489,7 @@ app.use(function (err, req, res, next) {
|
|
554
489
|
// error handler
|
555
490
|
app.use((err, req, res, next) => {
|
556
491
|
|
557
|
-
winston.
|
492
|
+
winston.debug("err.name", err.name)
|
558
493
|
if (err.name === "IpDeniedError") {
|
559
494
|
winston.info("IpDeniedError");
|
560
495
|
return res.status(401).json({ err: "error ip filter" });
|
@@ -209,7 +209,7 @@ router.post('/', function (req, res) {
|
|
209
209
|
departmentid:departmentid, sourcePage:sourcePage, language:language, userAgent:client, status:requestStatus, createdBy: undefined,
|
210
210
|
attributes:rAttributes, subject:undefined, preflight:false, channel:undefined, location:undefined,
|
211
211
|
lead:createdLead, requester:project_user
|
212
|
-
|
212
|
+
|
213
213
|
};
|
214
214
|
|
215
215
|
winston.debug("new_request", new_request);
|
@@ -229,10 +229,10 @@ router.post('/', function (req, res) {
|
|
229
229
|
// upsert(id, sender, senderFullname, recipient, text, id_project, createdBy, status, attributes, type, metadata, language)
|
230
230
|
return messageService.upsert(messageId, message.sender, message.sender_fullname, message.recipient, message.text,
|
231
231
|
projectid, null, MessageConstants.CHAT_MESSAGE_STATUS.RECEIVED, message.attributes, message.type, message.metadata, language).then(function(savedMessage){
|
232
|
-
|
233
|
-
return requestService.incrementMessagesCountByRequestId(savedRequest.request_id, savedRequest.id_project).then(function(savedRequestWithIncrement) {
|
234
|
-
return res.json(savedRequestWithIncrement);
|
235
|
-
});
|
232
|
+
return res.json(savedRequest);
|
233
|
+
// return requestService.incrementMessagesCountByRequestId(savedRequest.request_id, savedRequest.id_project).then(function(savedRequestWithIncrement) {
|
234
|
+
// return res.json(savedRequestWithIncrement);
|
235
|
+
// });
|
236
236
|
|
237
237
|
|
238
238
|
}).catch(function (err) {
|
@@ -289,23 +289,25 @@ router.post('/', function (req, res) {
|
|
289
289
|
|
290
290
|
// TOOD update also request attributes and sourcePage
|
291
291
|
|
292
|
-
return requestService.incrementMessagesCountByRequestId(request.request_id, request.id_project).then(function(savedRequest) {
|
292
|
+
// return requestService.incrementMessagesCountByRequestId(request.request_id, request.id_project).then(function(savedRequest) {
|
293
293
|
// winston.debug("savedRequest.participants.indexOf(message.sender)", savedRequest.participants.indexOf(message.sender));
|
294
294
|
|
295
295
|
// TODO it doesn't work for internal requests bacause participanets == message.sender⁄
|
296
|
-
if (
|
296
|
+
if (request.participants && request.participants.indexOf(message.sender) > -1) { //update waiitng time if write an agent (member of participants)
|
297
297
|
winston.debug("updateWaitingTimeByRequestId");
|
298
|
+
|
298
299
|
return requestService.updateWaitingTimeByRequestId(request.request_id, request.id_project).then(function(upRequest) {
|
299
300
|
return res.json(upRequest);
|
300
301
|
});
|
301
302
|
}else {
|
302
|
-
|
303
|
+
|
304
|
+
return res.json(upRequest);
|
303
305
|
}
|
304
|
-
});
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
306
|
+
// });
|
307
|
+
}).catch(function(err){
|
308
|
+
winston.error("Error creating chat21 webhook message: "+ JSON.stringify({err: err, message: message}));
|
309
|
+
return res.status(500).send({success: false, msg: 'Error creating message', err:err });
|
310
|
+
});
|
309
311
|
|
310
312
|
|
311
313
|
|
@@ -539,7 +541,7 @@ router.post('/', function (req, res) {
|
|
539
541
|
|
540
542
|
else if (req.body.event_type == "deleted-archivedconversation" || req.body.event_type == "conversation-unarchived") {
|
541
543
|
|
542
|
-
winston.
|
544
|
+
winston.debug("event_type","deleted-archivedconversation");
|
543
545
|
|
544
546
|
winston.debug("req.body",req.body);
|
545
547
|
|
@@ -549,37 +551,44 @@ router.post('/', function (req, res) {
|
|
549
551
|
}
|
550
552
|
|
551
553
|
|
552
|
-
var conversation = req.body.data;
|
554
|
+
var conversation = req.body.data;
|
553
555
|
// winston.debug("conversation",conversation);
|
554
556
|
|
555
557
|
var user_id = req.body.user_id;
|
556
|
-
winston.
|
558
|
+
winston.debug("user_id",user_id);
|
557
559
|
|
558
560
|
var recipient_id = req.body.recipient_id;
|
559
|
-
winston.
|
561
|
+
winston.debug("recipient_id",recipient_id);
|
560
562
|
|
561
563
|
|
562
564
|
// TODO leggi projectid from support-group
|
563
565
|
|
564
566
|
if (!recipient_id.startsWith("support-group")){
|
565
|
-
winston.
|
567
|
+
winston.debug("not a support conversation");
|
566
568
|
return res.status(400).send({success: false, msg: "not a support conversation" });
|
567
569
|
}
|
568
570
|
|
571
|
+
|
572
|
+
|
569
573
|
if (user_id!="system"){
|
570
|
-
winston.
|
574
|
+
winston.debug("not a system conversation");
|
571
575
|
return res.status(400).send({success: false, msg: "not a system conversation" });
|
572
576
|
}
|
573
577
|
|
574
578
|
|
579
|
+
|
580
|
+
// scrivo... nuova viene popolato projectid in attributes poi chiudo ed in archived c'è projectid
|
581
|
+
// quando scrivo viene cancellato archived e nuovo messaggio crea conv ma senza project id... lineare che è cosi
|
582
|
+
// si verifica solo se admin (da ionic ) archivia di nuovo senza che widget abbia scritto nulla (widget risetta projectid in properties)
|
583
|
+
|
575
584
|
var id_project;
|
576
585
|
if (conversation && conversation.attributes) {
|
577
586
|
id_project = conversation.attributes.projectId;
|
578
587
|
}else {
|
579
|
-
winston.
|
588
|
+
winston.debug( "not a support deleting archived conversation" );
|
580
589
|
return res.status(400).send({success: false, msg: "not a support deleting archived conversation" });
|
581
590
|
}
|
582
|
-
winston.
|
591
|
+
winston.debug("id_project", id_project);
|
583
592
|
|
584
593
|
|
585
594
|
return requestService.reopenRequestByRequestId(recipient_id, id_project).then(function(updatedRequest) {
|
package/deploy.sh
CHANGED
@@ -0,0 +1,220 @@
|
|
1
|
+
const ipfilter = require('express-ipfilter').IpFilter
|
2
|
+
var winston = require('../config/winston');
|
3
|
+
var jwt = require('jsonwebtoken');
|
4
|
+
|
5
|
+
|
6
|
+
var customDetection = function (req) {
|
7
|
+
// const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
8
|
+
// const ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || //https://stackoverflow.com/questions/8107856/how-to-determine-a-users-ip-address-in-node
|
9
|
+
// req.socket.remoteAddress
|
10
|
+
|
11
|
+
|
12
|
+
let ip = req.socket.remoteAddress;
|
13
|
+
|
14
|
+
const xFor = req.headers['x-forwarded-for'];
|
15
|
+
if (xFor ) {
|
16
|
+
const xForArr = xFor.split(',');
|
17
|
+
if (xForArr && xForArr.length>0) {
|
18
|
+
ip = xForArr.shift();
|
19
|
+
}
|
20
|
+
}
|
21
|
+
// const ip =
|
22
|
+
// req.headers['x-forwarded-for']?.split(',').shift()
|
23
|
+
// || req.socket?.remoteAddress
|
24
|
+
|
25
|
+
winston.info("standard ip: "+ip); // ip address of the user
|
26
|
+
return ip;
|
27
|
+
}
|
28
|
+
|
29
|
+
var getToken = function (headers) {
|
30
|
+
winston.debug("getToken",headers);
|
31
|
+
if (headers && headers.authorization) {
|
32
|
+
var parted = headers.authorization.split(' ');
|
33
|
+
if (parted.length === 2) {
|
34
|
+
return parted[1];
|
35
|
+
} else {
|
36
|
+
return null;
|
37
|
+
}
|
38
|
+
} else {
|
39
|
+
return null;
|
40
|
+
}
|
41
|
+
};
|
42
|
+
|
43
|
+
|
44
|
+
class IPFilter {
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
constructor() {
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
projectIpFilter (req, res, next) {
|
60
|
+
var that = this;
|
61
|
+
// console.log("that", that)
|
62
|
+
|
63
|
+
const nextIp = function(err) {
|
64
|
+
winston.debug("projectIpFilter next",err);
|
65
|
+
|
66
|
+
if (err && err.name === "IpDeniedError") {
|
67
|
+
winston.info("IpDeniedError for projectIpFilter");
|
68
|
+
return res.status(401).json({ err: "error project ip filter" });
|
69
|
+
// next(err)
|
70
|
+
}
|
71
|
+
|
72
|
+
next();
|
73
|
+
|
74
|
+
}
|
75
|
+
|
76
|
+
|
77
|
+
if (!req.project) {
|
78
|
+
return next();
|
79
|
+
}
|
80
|
+
|
81
|
+
var projectIpFilterEnabled = req.project.ipFilterEnabled;
|
82
|
+
winston.debug("project projectIpFilterEnabled: " +projectIpFilterEnabled)
|
83
|
+
|
84
|
+
var projectIpFilter = req.project.ipFilter
|
85
|
+
winston.debug("project ipFilter: " + projectIpFilter)
|
86
|
+
|
87
|
+
if (projectIpFilterEnabled === true && projectIpFilter && projectIpFilter.length > 0) {
|
88
|
+
winston.debug("filtering project IpFilter with ", projectIpFilter );
|
89
|
+
var ip = ipfilter(projectIpFilter, { detectIp: customDetection, mode: 'allow' })
|
90
|
+
// var ip = ipfilter(projectIpFilter, { mode: 'allow' })
|
91
|
+
ip(req, res, nextIp);
|
92
|
+
} else {
|
93
|
+
next();
|
94
|
+
}
|
95
|
+
|
96
|
+
}
|
97
|
+
|
98
|
+
projectIpFilterDeny (req, res, next) {
|
99
|
+
|
100
|
+
const nextIp = function(err) {
|
101
|
+
winston.debug("projectIpFilter next",err);
|
102
|
+
|
103
|
+
if (err && err.name === "IpDeniedError") {
|
104
|
+
winston.info("IpDeniedError for projectIpFilterDeny");
|
105
|
+
return res.status(401).json({ err: "error project deny ip filter" });
|
106
|
+
// next(err)
|
107
|
+
}
|
108
|
+
|
109
|
+
next();
|
110
|
+
|
111
|
+
}
|
112
|
+
|
113
|
+
if (!req.project) {
|
114
|
+
return next();
|
115
|
+
}
|
116
|
+
|
117
|
+
var projectIpFilterDenyEnabled = req.project.ipFilterDenyEnabled;
|
118
|
+
winston.debug("project projectIpFilterDenyEnabled: " +projectIpFilterDenyEnabled)
|
119
|
+
|
120
|
+
var projectIpFilterDeny = req.project.ipFilterDeny
|
121
|
+
winston.debug("project IpFilterDeny: " + projectIpFilterDeny)
|
122
|
+
|
123
|
+
|
124
|
+
if (projectIpFilterDenyEnabled === true && projectIpFilterDeny && projectIpFilterDeny.length > 0) {
|
125
|
+
winston.debug("filtering project projectIpFilterDeny with ", projectIpFilterDeny );
|
126
|
+
var ip = ipfilter(projectIpFilterDeny, { detectIp: customDetection, mode: 'deny' })
|
127
|
+
ip(req, res, nextIp);
|
128
|
+
} else {
|
129
|
+
next();
|
130
|
+
}
|
131
|
+
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
projectBanUserFilter(req, res, next) {
|
137
|
+
|
138
|
+
winston.debug("projectBanUserFilter hereee*********** ")
|
139
|
+
|
140
|
+
const nextIp = function(err) {
|
141
|
+
winston.debug("projectBanUserFilter next",err);
|
142
|
+
|
143
|
+
if (err && err.name === "IpDeniedError") {
|
144
|
+
winston.info("IpDeniedError for projectBanUserFilter");
|
145
|
+
return res.status(401).json({ err: "error projectBanUserFilter" });
|
146
|
+
// next(err)
|
147
|
+
}
|
148
|
+
|
149
|
+
next();
|
150
|
+
|
151
|
+
}
|
152
|
+
|
153
|
+
if (!req.project) {
|
154
|
+
return next();
|
155
|
+
}
|
156
|
+
|
157
|
+
var bannedUsers = req.project.bannedUsers
|
158
|
+
winston.debug("project bannedUsers: " + bannedUsers)
|
159
|
+
|
160
|
+
if (bannedUsers && bannedUsers.length > 0) {
|
161
|
+
|
162
|
+
let bannedUsersArr = [];
|
163
|
+
let bannedUsersIdUserArr = [];
|
164
|
+
for (var i =0; i < bannedUsers.length; i++) {
|
165
|
+
bannedUsersArr.push(bannedUsers[i].ip);
|
166
|
+
bannedUsersIdUserArr.push(bannedUsers[i].id);
|
167
|
+
}
|
168
|
+
|
169
|
+
winston.debug("project req.preDecodedJwt: ", req.preDecodedJwt)
|
170
|
+
// winston.debug("project req.preDecodedJwt._id: "+ req.preDecodedJwt._id)
|
171
|
+
|
172
|
+
|
173
|
+
if (req.preDecodedJwt && req.preDecodedJwt._id && bannedUsersIdUserArr.indexOf(req.preDecodedJwt._id) > -1) {
|
174
|
+
winston.info("filtering project bannedUsers with id: " + req.preDecodedJwt._id)
|
175
|
+
return res.status(401).json({ err: "error projectBanUserFilter by id" });
|
176
|
+
}
|
177
|
+
|
178
|
+
|
179
|
+
// winston.debug("filtering project bannedUsers with ", bannedUsersArr );
|
180
|
+
// var ip = ipfilter(bannedUsersArr, { detectIp: customDetection, mode: 'deny' })
|
181
|
+
// ip(req, res, nextIp);
|
182
|
+
next();
|
183
|
+
} else {
|
184
|
+
next();
|
185
|
+
}
|
186
|
+
|
187
|
+
}
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
decodeJwt(req, res, next) {
|
194
|
+
|
195
|
+
let token = getToken(req.headers);
|
196
|
+
winston.debug("filtering token " + token);
|
197
|
+
|
198
|
+
if (token) {
|
199
|
+
|
200
|
+
try {
|
201
|
+
var decoded = jwt.decode(token);
|
202
|
+
winston.debug("filtering decoded ", decoded);
|
203
|
+
req.preDecodedJwt = decoded;
|
204
|
+
}catch(e) {
|
205
|
+
winston.debug("Error decoding jwt");
|
206
|
+
}
|
207
|
+
|
208
|
+
}
|
209
|
+
|
210
|
+
|
211
|
+
next();
|
212
|
+
}
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
}
|
219
|
+
var iPFilter = new IPFilter();
|
220
|
+
module.exports = iPFilter;
|
package/middleware/passport.js
CHANGED
@@ -77,8 +77,14 @@ module.exports = function(passport) {
|
|
77
77
|
// winston.info("secretOrKeyProvider: "+request.project.name );
|
78
78
|
// winston.info("secretOrKeyProvider: "+rawJwtToken );
|
79
79
|
|
80
|
-
var decoded =
|
80
|
+
var decoded = request.preDecodedJwt
|
81
81
|
winston.debug("decoded: ", decoded );
|
82
|
+
if (!decoded) { //fallback
|
83
|
+
winston.debug("load decoded after: ");
|
84
|
+
decoded = jwt.decode(rawJwtToken);
|
85
|
+
}
|
86
|
+
|
87
|
+
winston.debug("decoded after: ", decoded );
|
82
88
|
|
83
89
|
// qui arriva questo
|
84
90
|
// decoded: {"_id":"5ce3ee855c520200176c189e","updatedAt":"2019-05-31T09:50:22.949Z","createdAt":"2019-05-21T12:26:45.192Z","name":"botext","url":"https://tiledesk-v2-simple--andrealeo83.repl.co","id_project":"5ce3d1ceb25ad30017274bc5","trashed":false,"createdBy":"5ce3d1c7b25ad30017274bc2","__v":0,"external":true,"iat":1559297130,"aud":"https://tiledesk.com","iss":"https://tiledesk.com","sub":"5ce3ee855c520200176c189e@tiledesk.com/bot"}
|
package/models/project.js
CHANGED
@@ -111,6 +111,16 @@ var ProjectSchema = new Schema({
|
|
111
111
|
ipFilter: [{
|
112
112
|
type: String
|
113
113
|
}],
|
114
|
+
ipFilterDenyEnabled:{
|
115
|
+
type: Boolean,
|
116
|
+
default: false
|
117
|
+
},
|
118
|
+
ipFilterDeny: [{
|
119
|
+
type: String
|
120
|
+
}],
|
121
|
+
bannedUsers: [{
|
122
|
+
id: String, ip: String
|
123
|
+
}],
|
114
124
|
// defaultLanguage: {
|
115
125
|
// type: String,
|
116
126
|
// required: true,
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tiledesk/tiledesk-server",
|
3
3
|
"description": "The Tiledesk server module",
|
4
|
-
"version": "2.3.
|
4
|
+
"version": "2.3.16",
|
5
5
|
"scripts": {
|
6
6
|
"start": "node ./bin/www",
|
7
7
|
"pretest": "mongodb-runner start",
|
@@ -44,6 +44,7 @@
|
|
44
44
|
"@tiledesk/tiledesk-chatbot-util": "^0.8.33",
|
45
45
|
"@tiledesk/tiledesk-json-rules-engine": "^4.0.3",
|
46
46
|
"@tiledesk/tiledesk-rasa-connector": "^1.0.10",
|
47
|
+
"@tiledesk/tiledesk-tybot-connector": "^0.1.4",
|
47
48
|
"app-root-path": "^3.0.0",
|
48
49
|
"bcrypt-nodejs": "0.0.3",
|
49
50
|
"body-parser": "^1.20.0",
|
@@ -76,7 +76,6 @@ class ActivityArchiver {
|
|
76
76
|
|
77
77
|
authEvent.on('project_user.update', function(event) {
|
78
78
|
setImmediate(() => {
|
79
|
-
// console.log("project_user.update");
|
80
79
|
/*
|
81
80
|
2019-11-20T10:40:52.686991+00:00 app[web.1]: TypeError: Cannot read property '_id' of undefined
|
82
81
|
*/
|
@@ -272,6 +271,26 @@ class ActivityArchiver {
|
|
272
271
|
});
|
273
272
|
|
274
273
|
|
274
|
+
requestEvent.on('request.close', function(request) {
|
275
|
+
setImmediate(() => {
|
276
|
+
|
277
|
+
try {
|
278
|
+
winston.error('ActivityArchiver close');
|
279
|
+
|
280
|
+
var activity = new Activity({actor: {type:"user", id: request.closed_by},
|
281
|
+
verb: "REQUEST_CLOSE", actionObj: request,
|
282
|
+
target: {type:"request", id:request._id, object: request },
|
283
|
+
id_project: request.id_project });
|
284
|
+
that.save(activity);
|
285
|
+
} catch(e) {
|
286
|
+
winston.error('ActivityArchiver error saving activity',e);
|
287
|
+
}
|
288
|
+
|
289
|
+
|
290
|
+
});
|
291
|
+
});
|
292
|
+
|
293
|
+
|
275
294
|
|
276
295
|
|
277
296
|
winston.info('ActivityArchiver listening');
|
@@ -355,6 +355,13 @@ async notifyFollowers(savedRequest, project, message) {
|
|
355
355
|
return winston.debug("not sending notifyFollowers for attributes.subtype info messages");
|
356
356
|
}
|
357
357
|
|
358
|
+
if (!savedRequest) {
|
359
|
+
return winston.debug("not sending notifyFollowers for direct messages");
|
360
|
+
}
|
361
|
+
|
362
|
+
// Cannot read property '_id' of undefined at RequestNotification.notifyFollowers (/usr/src/app/pubmodules/emailNotification/requestNotification.js:358:62) at /usr/src/app
|
363
|
+
// forse meglio .id
|
364
|
+
|
358
365
|
var reqWithFollowers = await Request.findById(savedRequest._id).populate('followers').exec();
|
359
366
|
winston.debug("reqWithFollowers");
|
360
367
|
winston.debug("reqWithFollowers",reqWithFollowers);
|
@@ -32,7 +32,7 @@ class PubModulesManager {
|
|
32
32
|
this.triggerRoute = undefined;
|
33
33
|
|
34
34
|
this.tilebot = undefined;
|
35
|
-
|
35
|
+
this.tilebotRoute = undefined;
|
36
36
|
}
|
37
37
|
|
38
38
|
|
@@ -43,6 +43,10 @@ class PubModulesManager {
|
|
43
43
|
app.use('/modules/rasa', this.rasaRoute);
|
44
44
|
winston.info("ModulesManager rasaRoute controller loaded");
|
45
45
|
}
|
46
|
+
if (this.tilebotRoute) {
|
47
|
+
app.use('/modules/tilebot', this.tilebotRoute);
|
48
|
+
winston.info("ModulesManager tilebot controller loaded");
|
49
|
+
}
|
46
50
|
|
47
51
|
}
|
48
52
|
useUnderProjects(app) {
|
@@ -266,6 +270,7 @@ class PubModulesManager {
|
|
266
270
|
this.tilebot = require('./tilebot');
|
267
271
|
winston.debug("this.tilebot:"+ this.tilebot);
|
268
272
|
this.tilebot.listener.listen(config);
|
273
|
+
this.tilebotRoute = this.tilebot.tilebotRoute;
|
269
274
|
|
270
275
|
winston.info("PubModulesManager initialized tilebot.");
|
271
276
|
} catch(err) {
|
@@ -23,7 +23,7 @@ class Listener {
|
|
23
23
|
listen(config) {
|
24
24
|
|
25
25
|
winston.info('Rasa Listener listen');
|
26
|
-
winston.debug("config databaseUri: " + config.databaseUri);
|
26
|
+
winston.debug("rasa config databaseUri: " + config.databaseUri);
|
27
27
|
|
28
28
|
|
29
29
|
var that = this;
|
@@ -34,7 +34,7 @@ class Listener {
|
|
34
34
|
KVBASE_COLLECTION : process.env.KVBASE_COLLECTION,
|
35
35
|
MONGODB_URI: config.databaseUri,
|
36
36
|
API_ENDPOINT: apiUrl,
|
37
|
-
log:
|
37
|
+
log: process.env.RASABOT_LOG
|
38
38
|
}, () => {
|
39
39
|
winston.info("RASA proxy server successfully started.");
|
40
40
|
});
|
@@ -44,10 +44,10 @@ class Listener {
|
|
44
44
|
botEvent.on('faqbot.create', function(bot) {
|
45
45
|
if (BOT_RASA_ENDPOINT) {
|
46
46
|
|
47
|
-
winston.
|
47
|
+
winston.debug('bot.type:'+bot.type);
|
48
48
|
if (bot.type==="rasa") {
|
49
49
|
|
50
|
-
winston.
|
50
|
+
winston.debug('qui.type:'+bot.type);
|
51
51
|
|
52
52
|
|
53
53
|
Faq_kb.findByIdAndUpdate(bot.id, {"url":BOT_RASA_ENDPOINT}, { new: true, upsert: true }, function (err, savedFaq_kb) {
|
@@ -1,3 +1,11 @@
|
|
1
1
|
const listener = require("./listener");
|
2
2
|
|
3
|
-
|
3
|
+
const tilebot = require("@tiledesk/tiledesk-tybot-connector");
|
4
|
+
const tilebotRoute = tilebot.router;
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
module.exports = { listener: listener, tilebotRoute: tilebotRoute };
|
11
|
+
|
@@ -1,25 +1,43 @@
|
|
1
1
|
const botEvent = require('../../event/botEvent');
|
2
2
|
var Faq_kb = require("../../models/faq_kb");
|
3
3
|
var winston = require('../../config/winston');
|
4
|
+
var configGlobal = require('../../config/global');
|
4
5
|
|
5
6
|
var port = process.env.PORT || '3000';
|
6
7
|
|
7
|
-
const TILEBOT_ENDPOINT = process.env.TILEBOT_ENDPOINT || "http://localhost:" + port+ "/modules/tilebot/";
|
8
|
+
const TILEBOT_ENDPOINT = process.env.TILEBOT_ENDPOINT || "http://localhost:" + port+ "/modules/tilebot/ext/";
|
8
9
|
winston.debug("TILEBOT_ENDPOINT: " + TILEBOT_ENDPOINT);
|
9
10
|
|
10
11
|
winston.info("Tilebot endpoint: " + TILEBOT_ENDPOINT);
|
11
12
|
|
13
|
+
|
14
|
+
const apiUrl = process.env.API_URL || configGlobal.apiUrl;
|
15
|
+
winston.info('Rasa apiUrl: '+ apiUrl);
|
16
|
+
|
17
|
+
const tybot = require("@tiledesk/tiledesk-tybot-connector");
|
18
|
+
|
19
|
+
|
12
20
|
class Listener {
|
13
21
|
|
14
22
|
listen(config) {
|
15
23
|
|
16
24
|
winston.info('Tilebot Listener listen');
|
17
|
-
|
25
|
+
winston.debug("Tilebot config databaseUri: " + config.databaseUri);
|
18
26
|
|
19
27
|
|
20
28
|
var that = this;
|
29
|
+
|
30
|
+
tybot.startApp(
|
31
|
+
{
|
32
|
+
MONGODB_URI: config.databaseUri,
|
33
|
+
API_ENDPOINT: apiUrl,
|
34
|
+
log: process.env.TILEBOT_LOG
|
35
|
+
}, () => {
|
36
|
+
winston.info("TileBot proxy server successfully started.");
|
37
|
+
}
|
38
|
+
);
|
39
|
+
|
21
40
|
|
22
|
-
|
23
41
|
botEvent.on('faqbot.create', function(bot) {
|
24
42
|
if (TILEBOT_ENDPOINT) {
|
25
43
|
|
package/routes/project.js
CHANGED
@@ -213,6 +213,22 @@ router.put('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: fa
|
|
213
213
|
update.ipFilter = req.body.ipFilter;
|
214
214
|
}
|
215
215
|
|
216
|
+
if (req.body.ipFilterDenyEnabled!=undefined) {
|
217
|
+
update.ipFilterDenyEnabled = req.body.ipFilterDenyEnabled;
|
218
|
+
}
|
219
|
+
|
220
|
+
if (req.body.ipFilterDeny!=undefined) {
|
221
|
+
update.ipFilterDeny = req.body.ipFilterDeny;
|
222
|
+
}
|
223
|
+
|
224
|
+
if (req.body.bannedUsers!=undefined) {
|
225
|
+
update.bannedUsers = req.body.bannedUsers;
|
226
|
+
}
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
|
216
232
|
|
217
233
|
// if (req.body.defaultLanguage!=undefined) {
|
218
234
|
// update.defaultLanguage = req.body.defaultLanguage;
|
@@ -360,6 +376,19 @@ router.patch('/:projectid', [passport.authenticate(['basic', 'jwt'], { session:
|
|
360
376
|
if (req.body.ipFilter!=undefined) {
|
361
377
|
update.ipFilter = req.body.ipFilter;
|
362
378
|
}
|
379
|
+
|
380
|
+
if (req.body.ipFilterDenyEnabled!=undefined) {
|
381
|
+
update.ipFilterDenyEnabled = req.body.ipFilterDenyEnabled;
|
382
|
+
}
|
383
|
+
|
384
|
+
if (req.body.ipFilterDeny!=undefined) {
|
385
|
+
update.ipFilterDeny = req.body.ipFilterDeny;
|
386
|
+
}
|
387
|
+
|
388
|
+
if (req.body.bannedUsers!=undefined) {
|
389
|
+
update.bannedUsers = req.body.bannedUsers;
|
390
|
+
}
|
391
|
+
|
363
392
|
|
364
393
|
// if (req.body.defaultLanguage!=undefined) {
|
365
394
|
// update.defaultLanguage = req.body.defaultLanguage;
|
@@ -378,6 +407,43 @@ router.patch('/:projectid', [passport.authenticate(['basic', 'jwt'], { session:
|
|
378
407
|
});
|
379
408
|
});
|
380
409
|
|
410
|
+
|
411
|
+
router.post('/:projectid/ban', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
|
412
|
+
winston.debug('PATCH PROJECT REQ BODY ', req.body);
|
413
|
+
|
414
|
+
var ban = {};
|
415
|
+
ban.id = req.body.id;
|
416
|
+
ban.ip = req.body.ip;
|
417
|
+
|
418
|
+
Project.findByIdAndUpdate(req.params.projectid, { $push: { bannedUsers: ban } }, { new: true, upsert: false }, function (err, updatedProject) {
|
419
|
+
if (err) {
|
420
|
+
winston.error('Error putting project ', err);
|
421
|
+
return res.status(500).send({ success: false, msg: 'Error patching object.' });
|
422
|
+
}
|
423
|
+
projectEvent.emit('project.update', updatedProject );
|
424
|
+
projectEvent.emit('project.update.user.ban', {banInfo: ban, project: updatedProject });
|
425
|
+
res.json(updatedProject);
|
426
|
+
});
|
427
|
+
|
428
|
+
});
|
429
|
+
router.delete('/:projectid/ban/:banid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
|
430
|
+
|
431
|
+
// winston.info('quiiiiii');
|
432
|
+
//cacheinvalidation
|
433
|
+
Project.findByIdAndUpdate(req.params.projectid, { $pull: { bannedUsers: { "_id": req.params.banid }}}, { new: true, upsert: false }, function (err, updatedProject) {
|
434
|
+
if (err) {
|
435
|
+
winston.error('Error putting project ', err);
|
436
|
+
return res.status(500).send({ success: false, msg: 'Error patching object.' });
|
437
|
+
}
|
438
|
+
projectEvent.emit('project.update', updatedProject );
|
439
|
+
projectEvent.emit('project.update.user.unban', {banInfo: req.params.banid, project: updatedProject});
|
440
|
+
res.json(updatedProject);
|
441
|
+
});
|
442
|
+
|
443
|
+
});
|
444
|
+
|
445
|
+
|
446
|
+
|
381
447
|
//roleChecker.hasRole('agent') works because req.params.projectid is valid using :projectid of this method
|
382
448
|
router.get('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], function (req, res) {
|
383
449
|
winston.debug(req.body);
|
package/routes/users.js
CHANGED
@@ -25,7 +25,7 @@ router.put('/', function (req, res) {
|
|
25
25
|
|
26
26
|
User.findByIdAndUpdate(req.user.id, update, { new: true, upsert: true }, function (err, updatedUser) {
|
27
27
|
if (err) {
|
28
|
-
winston.error(err);
|
28
|
+
winston.error("Error putting user",err);
|
29
29
|
return res.status(500).send({ success: false, msg: err });
|
30
30
|
}
|
31
31
|
|
package/routes/widget.js
CHANGED
@@ -146,8 +146,12 @@ router.get('/', function(req, res, next) {
|
|
146
146
|
//secondo me qui manca un parentesi tonda per gli or
|
147
147
|
if (project && project.profile && ((project.profile.type === 'free' && project.trialExpired === true) || (project.profile.type === 'payment' && project.isActiveSubscription === false))) {
|
148
148
|
winston.debug('getProject remove poweredBy tag', project);
|
149
|
-
|
150
|
-
project.widget
|
149
|
+
|
150
|
+
if (project.widget) {
|
151
|
+
project.widget.poweredBy = undefined;
|
152
|
+
project.widget.baloonImage = undefined;
|
153
|
+
}
|
154
|
+
|
151
155
|
}
|
152
156
|
|
153
157
|
return resolve(project);
|
@@ -0,0 +1,86 @@
|
|
1
|
+
var messageService = require("./messageService");
|
2
|
+
var projectEvent = require("../event/projectEvent");
|
3
|
+
|
4
|
+
var winston = require('../config/winston');
|
5
|
+
|
6
|
+
var MessageConstants = require("../models/messageConstants");
|
7
|
+
|
8
|
+
class BanUserNotifier {
|
9
|
+
|
10
|
+
listen() {
|
11
|
+
projectEvent.on("project.update.user.ban", function(data) {
|
12
|
+
var project=data.project;
|
13
|
+
var banInfo = data.banInfo;
|
14
|
+
|
15
|
+
winston.debug("User Banned");
|
16
|
+
|
17
|
+
var message = {
|
18
|
+
sender: 'system',
|
19
|
+
senderFullname: 'Bot',
|
20
|
+
recipient: banInfo.id,
|
21
|
+
recipientFullname: banInfo.id,
|
22
|
+
text: "User Banned",
|
23
|
+
id_project: project._id,
|
24
|
+
createdBy: "system",
|
25
|
+
attributes: {subtype:"info", messagelabel: {key: "USER_BANNED"} },
|
26
|
+
channel_type: MessageConstants.CHANNEL_TYPE.DIRECT,
|
27
|
+
status: MessageConstants.CHAT_MESSAGE_STATUS.SENDING,
|
28
|
+
// channel: {name: "chat21"}
|
29
|
+
};
|
30
|
+
messageService.save(message);
|
31
|
+
winston.info("User banned", message);
|
32
|
+
// messageService.send(
|
33
|
+
// 'system',
|
34
|
+
// 'Bot',
|
35
|
+
// banInfo.id,
|
36
|
+
// "User Banned",
|
37
|
+
// project._id,
|
38
|
+
// 'system',
|
39
|
+
// {subtype:"info"},
|
40
|
+
// undefined,
|
41
|
+
// undefined
|
42
|
+
// );
|
43
|
+
});
|
44
|
+
projectEvent.on("project.update.user.unban", function(data) {
|
45
|
+
var project=data.project;
|
46
|
+
var banInfo = data.banInfo;
|
47
|
+
|
48
|
+
winston.debug("User UnBanned: "+banInfo);
|
49
|
+
|
50
|
+
// var message = {
|
51
|
+
// sender: 'system',
|
52
|
+
// senderFullname: 'Bot',
|
53
|
+
// recipient: banInfo,
|
54
|
+
// recipientFullname: banInfo,
|
55
|
+
// text: "User Unbanned",
|
56
|
+
// id_project: project._id,
|
57
|
+
// createdBy: "system",
|
58
|
+
// attributes: {subtype:"info", messagelabel: {key: "USER_BANNED"}},
|
59
|
+
// channel_type: MessageConstants.CHANNEL_TYPE.DIRECT,
|
60
|
+
// status: MessageConstants.CHAT_MESSAGE_STATUS.SENDING,
|
61
|
+
// };
|
62
|
+
// messageService.save(message);
|
63
|
+
// winston.info("User UnBanned", message);
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
// messageService.send(
|
69
|
+
// 'system',
|
70
|
+
// 'Bot',
|
71
|
+
// banInfo.id,
|
72
|
+
// "User Unbanned",
|
73
|
+
// project._id,
|
74
|
+
// 'system',
|
75
|
+
// {subtype:"info"},
|
76
|
+
// undefined,
|
77
|
+
// undefined
|
78
|
+
// );
|
79
|
+
});
|
80
|
+
}
|
81
|
+
|
82
|
+
}
|
83
|
+
var banUserNotifier = new BanUserNotifier();
|
84
|
+
|
85
|
+
|
86
|
+
module.exports = banUserNotifier;
|
package/utils/orgUtil.js
CHANGED
@@ -36,10 +36,10 @@ class OrgUtil {
|
|
36
36
|
// winston.info("host: "+ host );
|
37
37
|
|
38
38
|
let origin = req.get('origin');
|
39
|
-
winston.
|
39
|
+
winston.debug("origin: "+ origin );
|
40
40
|
|
41
41
|
// winston.info("email: " + email.baseUrl);
|
42
|
-
winston.
|
42
|
+
winston.debug("this.ORGANIZATION_BASE_URL: " + this.ORGANIZATION_BASE_URL);
|
43
43
|
// global.organizationBaseUrl
|
44
44
|
// if (host !=email.baseUrl ) {
|
45
45
|
if (origin && origin.indexOf(this.ORGANIZATION_BASE_URL)>-1) {
|
@@ -49,7 +49,7 @@ class OrgUtil {
|
|
49
49
|
winston.info("origin found: "+ origin );
|
50
50
|
return origin;
|
51
51
|
}
|
52
|
-
winston.
|
52
|
+
winston.debug("origin not found: "+ origin );
|
53
53
|
|
54
54
|
// winston.info("host not found: "+ host );
|
55
55
|
// if (host.indexOf("localhost1")>-1) {
|