@tiledesk/tiledesk-server 2.3.6 → 2.3.7-1.2
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/.github/workflows/docker-community-worker-push-latest.yml +23 -0
- package/.github/workflows/docker-image-tag-worker-community-tag-push.yml +22 -0
- package/CHANGELOG.md +361 -3
- package/Dockerfile-jobs +31 -0
- package/app.js +62 -69
- package/channels/chat21/chat21Handler.js +37 -6
- package/channels/chat21/chat21WebHook.js +62 -34
- package/channels/chat21/package-lock.json +663 -706
- package/channels/chat21/package.json +2 -2
- package/config/labels/widget.json +337 -136
- package/deploy.sh +2 -0
- package/event/messageEvent.js +110 -9
- package/jobs.js +80 -0
- package/jobsManager.js +47 -0
- package/middleware/has-role.js +10 -3
- package/middleware/ipFilter.js +220 -0
- package/middleware/passport.js +8 -2
- package/models/department.js +1 -1
- package/models/faq.js +77 -25
- package/models/faq_kb.js +19 -0
- package/models/message.js +10 -8
- package/models/project.js +10 -0
- package/models/project_user.js +10 -0
- package/models/request.js +12 -1
- package/package.json +12 -11
- package/pubmodules/activities/activityArchiver.js +216 -90
- package/pubmodules/activities/routes/activity.js +1 -1
- package/pubmodules/apps/index.js +8 -0
- package/pubmodules/apps/listener.js +27 -0
- package/pubmodules/cache/index.js +2 -0
- package/pubmodules/cache/mongoose-cachegoose-fn.js +630 -0
- package/pubmodules/canned/cannedResponse.js +4 -0
- package/pubmodules/canned/cannedResponseRoute.js +10 -5
- package/pubmodules/dialogflow/index.js +10 -0
- package/pubmodules/dialogflow/listener.js +66 -0
- package/pubmodules/emailNotification/requestNotification.js +58 -28
- package/pubmodules/events/eventRoute.js +49 -24
- package/pubmodules/messageTransformer/messageHandlebarsTransformerInterceptor.js +6 -1
- package/pubmodules/messageTransformer/messageTransformerInterceptor.js +10 -4
- package/pubmodules/pubModulesManager.js +173 -7
- package/pubmodules/queue/index.js +4 -0
- package/pubmodules/queue/reconnect.js +331 -0
- package/pubmodules/queue/reconnectFanout.js +256 -0
- package/pubmodules/rasa/listener.js +5 -5
- package/pubmodules/routing-queue/index.js +3 -0
- package/pubmodules/routing-queue/listener.js +328 -0
- package/pubmodules/rules/conciergeBot.js +2 -2
- package/pubmodules/scheduler/tasks/closeAgentUnresponsiveRequestTask.js +6 -1
- package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +7 -1
- package/pubmodules/tilebot/index.js +11 -0
- package/pubmodules/tilebot/listener.js +85 -0
- package/pubmodules/trigger/rulesTrigger.js +137 -14
- package/pubmodules/trigger/start.js +5 -1
- package/pubmodules/whatsapp/index.js +7 -0
- package/pubmodules/whatsapp/listener.js +32 -0
- package/routes/auth.js +7 -2
- package/routes/campaigns.js +3 -3
- package/routes/department.js +3 -2
- package/routes/email.js +32 -2
- package/routes/faq.js +37 -2
- package/routes/faq_kb.js +496 -133
- package/routes/faqpub.js +5 -0
- package/routes/lead.js +56 -0
- package/routes/message.js +196 -14
- package/routes/messagesRoot.js +39 -0
- package/routes/project.js +76 -4
- package/routes/project_user.js +11 -1
- package/routes/project_user_test.js +19 -0
- package/routes/request.js +134 -30
- package/routes/troubleshooting.js +12 -0
- package/routes/users-util.js +39 -0
- package/routes/users.js +1 -1
- package/routes/widget.js +64 -2
- package/services/BotSubscriptionNotifier.js +5 -0
- package/services/banUserNotifier.js +86 -0
- package/services/cacheEnabler.js +56 -0
- package/services/chatbotService.js +101 -0
- package/services/departmentService.js +25 -3
- package/services/emailService.js +170 -28
- package/services/faqBotHandler.js +2 -3
- package/services/faqService.js +28 -3
- package/services/geoService.js +36 -6
- package/services/labelService.js +1 -1
- package/services/leadService.js +3 -2
- package/services/messageService.js +4 -2
- package/services/modulesManager.js +23 -76
- package/services/operatingHoursService.js +9 -4
- package/services/requestService.js +75 -39
- package/services/subscriptionNotifier.js +9 -4
- package/services/trainingService.js +106 -0
- package/template/email/assignedEmailMessage.html +21 -11
- package/template/email/assignedRequest.html +21 -11
- package/template/email/beenInvitedExistingUser.html +16 -6
- package/template/email/beenInvitedNewUser.html +16 -6
- package/template/email/emailDirect.html +130 -0
- package/template/email/newMessage.html +18 -8
- package/template/email/newMessageFollower.html +22 -12
- package/template/email/passwordChanged.html +15 -5
- package/template/email/pooledEmailMessage.html +21 -11
- package/template/email/pooledRequest.html +20 -10
- package/template/email/resetPassword.html +15 -5
- package/template/email/sendTranscript.html +7 -4
- package/template/email/ticket.html +17 -7
- package/template/email/verify.html +15 -5
- package/test/cannedRoute.js +157 -0
- package/test/chatbot-mock.js +127 -0
- package/test/example-json-intents.txt +1 -0
- package/test/example-json.txt +1 -0
- package/test/example.json +1 -0
- package/test/faqRoute.js +353 -208
- package/test/faqkbRoute.js +669 -64
- package/test/imageRoute.js +1 -1
- package/test/messageRoute.js +387 -5
- package/test/requestRoute.js +6 -6
- package/test/requestService.js +55 -4
- package/test-int/cache-project.js +90 -0
- package/test-int/cache-project_user.js +88 -0
- package/utils/UIDGenerator.js +20 -0
- package/utils/cacheUtil.js +2 -2
- package/utils/orgUtil.js +3 -3
- package/utils/promiseUtil.js +31 -0
- package/utils/recipientEmailUtil.js +66 -0
- package/utils/sendEmailUtil.js +34 -0
- package/utils/sendMessageUtil.js +1 -1
- package/utils/stringUtil.js +12 -0
- package/websocket/webSocketServer.js +33 -10
package/deploy.sh
CHANGED
package/event/messageEvent.js
CHANGED
|
@@ -7,7 +7,7 @@ var MessageConstants = require("../models/messageConstants");
|
|
|
7
7
|
var message2Event = require("../event/message2Event");
|
|
8
8
|
|
|
9
9
|
var cacheUtil = require('../utils/cacheUtil');
|
|
10
|
-
|
|
10
|
+
var cacheEnabler = require("../services/cacheEnabler");
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class MessageEvent extends EventEmitter {
|
|
@@ -34,13 +34,18 @@ function emitCompleteMessage(message) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
messageEvent.on('message.create', emitCompleteMessage);
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
// messageEvent.on('message.update.simple', emitCompleteMessage); //if populateMessageUpdate is disabled then you must forward message.update event from message.update.simple
|
|
39
|
+
messageEvent.on('message.update', emitCompleteMessage); // i must restore populateMessageWithRequest. see below
|
|
38
40
|
|
|
39
41
|
function populateMessageCreate(message) {
|
|
40
42
|
return populateMessageWithRequest(message, 'message.create');
|
|
41
43
|
}
|
|
42
44
|
function populateMessageUpdate(message) {
|
|
43
45
|
return populateMessageWithRequest(message, 'message.update');
|
|
46
|
+
// return; // do not populate message.update it's not used by anyone.
|
|
47
|
+
///it is used by \agent interceptor. Without populateMessageWithRequest \agent sent by bot doesn't work. i must restore populateMessageWithRequest
|
|
48
|
+
// Not used by webhook. populate for message.update is slow.
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
|
|
@@ -48,32 +53,42 @@ function populateMessageWithRequest(message, eventPrefix) {
|
|
|
48
53
|
|
|
49
54
|
|
|
50
55
|
winston.debug("populateMessageWithRequest "+eventPrefix, message.toObject());
|
|
56
|
+
winston.debug("populateMessageWithRequest "+eventPrefix +" "+ message.text);
|
|
51
57
|
|
|
52
58
|
var messageJson = message.toJSON();
|
|
53
59
|
|
|
54
60
|
|
|
55
61
|
// cacherequest // requestcachefarequi populaterequired cacheveryhightpriority
|
|
56
62
|
|
|
57
|
-
Request.findOne({request_id: message.recipient, id_project: message.id_project}).
|
|
63
|
+
let q = Request.findOne({request_id: message.recipient, id_project: message.id_project}).
|
|
58
64
|
populate('lead').
|
|
59
65
|
populate('department').
|
|
60
66
|
populate('participatingBots').
|
|
61
67
|
populate('participatingAgents').
|
|
62
68
|
populate({path:'requester',populate:{path:'id_user'}}).
|
|
63
|
-
lean()
|
|
69
|
+
lean();
|
|
70
|
+
|
|
71
|
+
|
|
64
72
|
//perche lean?
|
|
65
73
|
// TODO availableAgentsCount nn c'è per il lean problema trigger
|
|
66
74
|
// request.department._id DA CORREGGERE ANCHE PER REQUEST.CREATE
|
|
67
75
|
// request.department.hasBot
|
|
68
76
|
// request.isOpen
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
winston.debug('message Event populate');
|
|
78
|
+
if (cacheEnabler.request) {
|
|
79
|
+
q.cache(cacheUtil.defaultTTL, message.id_project+":requests:request_id:"+message.recipient) //request_cache ma con lean????attento metti a parte
|
|
80
|
+
winston.debug('request cache enabled');
|
|
81
|
+
}
|
|
82
|
+
q.exec(function (err, request) {
|
|
71
83
|
|
|
72
84
|
if (err) {
|
|
73
85
|
winston.error("Error getting request on messageEvent.populateMessage",err );
|
|
74
86
|
return messageEvent.emit(eventPrefix, message);
|
|
75
87
|
}
|
|
76
88
|
|
|
89
|
+
winston.debug('message Event populate after query');
|
|
90
|
+
|
|
91
|
+
|
|
77
92
|
if (request) {
|
|
78
93
|
winston.debug("request is defined in messageEvent",request );
|
|
79
94
|
|
|
@@ -82,9 +97,14 @@ function populateMessageWithRequest(message, eventPrefix) {
|
|
|
82
97
|
|
|
83
98
|
if (request.department && request.department.id_bot) {
|
|
84
99
|
// if (request.department) {
|
|
85
|
-
Faq_kb.findById(request.department.id_bot)
|
|
86
|
-
|
|
87
|
-
.
|
|
100
|
+
let qbot = Faq_kb.findById(request.department.id_bot)
|
|
101
|
+
|
|
102
|
+
if (cacheEnabler.faq_kb) {
|
|
103
|
+
qbot.cache(cacheUtil.defaultTTL, message.id_project+":faq_kbs:id:"+request.department.id_bot)
|
|
104
|
+
winston.debug('faq_kb cache enabled');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
qbot.exec(function(err, bot) {
|
|
88
108
|
winston.debug('bot', bot);
|
|
89
109
|
requestJson.department.bot = bot
|
|
90
110
|
|
|
@@ -159,4 +179,85 @@ messageEvent.on('message.create.simple', populateMessageCreate);
|
|
|
159
179
|
messageEvent.on('message.update.simple', populateMessageUpdate);
|
|
160
180
|
|
|
161
181
|
|
|
182
|
+
|
|
183
|
+
// // riattiva commentato per performance
|
|
184
|
+
|
|
185
|
+
// // spostare su classe
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
// var messageCreateKey = 'message.create';
|
|
190
|
+
// if (messageEvent.queueEnabled) {
|
|
191
|
+
// messageCreateKey = 'message.create.queue';
|
|
192
|
+
// }
|
|
193
|
+
// winston.debug("messageEvent.queueEnabled: "+messageEvent.queueEnabled);
|
|
194
|
+
|
|
195
|
+
// winston.debug("messageCreateKey: "+messageCreateKey);
|
|
196
|
+
|
|
197
|
+
// messageEvent.on(messageCreateKey, function(message) {
|
|
198
|
+
// setImmediate(() => {
|
|
199
|
+
// winston.debug("message.create before");
|
|
200
|
+
// if (!message.request) {
|
|
201
|
+
// return;
|
|
202
|
+
// }
|
|
203
|
+
// let request_id = message.request.request_id;
|
|
204
|
+
// let id_project = message.request.id_project;
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
// //update waiitng time if write an agent (member of participants)
|
|
208
|
+
// let visitor_sent_last_message = false;
|
|
209
|
+
// // winston.info(" message.request.snapshot.lead.lead_id: "+ message.request.snapshot.lead.lead_id);
|
|
210
|
+
// // winston.info(" message.sender: "+ message.sender);
|
|
211
|
+
|
|
212
|
+
// if (message.request.snapshot && message.request.snapshot.lead.lead_id == message.sender) {
|
|
213
|
+
// visitor_sent_last_message = true;
|
|
214
|
+
// }
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
// // don't work for recursive call
|
|
219
|
+
// // requestService.incrementMessagesCountByRequestId(message.request._id, message.request.id_project).then(function (savedRequest) {
|
|
220
|
+
// // winston.info("incremented request", savedRequest);
|
|
221
|
+
// // });
|
|
222
|
+
// let clonedmessage = Object.assign({}, message);
|
|
223
|
+
// delete clonedmessage.request
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
// let data = {
|
|
227
|
+
// $push: {
|
|
228
|
+
// "snapshot.messages.data": {
|
|
229
|
+
// $each: [ clonedmessage ],
|
|
230
|
+
// $slice: -30
|
|
231
|
+
// }
|
|
232
|
+
// },
|
|
233
|
+
// $inc : {'snapshot.messages.messages_count' : 1},
|
|
234
|
+
// "snapshot.messages.visitor_sent_last_message": visitor_sent_last_message,
|
|
235
|
+
// "snapshot.messages.last_message_timestamp": message.createdAt
|
|
236
|
+
// };
|
|
237
|
+
|
|
238
|
+
// // db.getCollection('requests').find({"$expr": { "$gt": [ "$snapshot.messages.visitor_last_message_timestamp", "$snapshot.messages.agent_last_message_timestamp"]}})
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
// if (visitor_sent_last_message) {
|
|
242
|
+
// data["snapshot.messages.visitor_last_message_timestamp"]= message.createdAt;
|
|
243
|
+
// } else {
|
|
244
|
+
// data["snapshot.messages.agent_last_message_timestamp"]= message.createdAt;
|
|
245
|
+
// }
|
|
246
|
+
// // db.getCollection('requests').updateOne({"request_id":"support-group-630600bfaf7cd942116bc993-3da378ec63924bb9b4934b2835b37a7c"},{"$push":{"snapshot.messages.data":{"$each":["s"],"$slice":-5}}}}})
|
|
247
|
+
// winston.debug("data", data);
|
|
248
|
+
|
|
249
|
+
// return Request
|
|
250
|
+
// .findOneAndUpdate({request_id: request_id, id_project: id_project}, data, {new: true, upsert:false}, function(err, updatedRequest) {
|
|
251
|
+
// if (err) {
|
|
252
|
+
// winston.error(err);
|
|
253
|
+
// return reject(err);
|
|
254
|
+
// }
|
|
255
|
+
// winston.info("Message count +1");
|
|
256
|
+
|
|
257
|
+
// });
|
|
258
|
+
|
|
259
|
+
// });
|
|
260
|
+
// });
|
|
261
|
+
|
|
262
|
+
|
|
162
263
|
module.exports = messageEvent;
|
package/jobs.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
|
|
2
|
+
var dotenvPath = undefined;
|
|
3
|
+
|
|
4
|
+
if (process.env.DOTENV_PATH) {
|
|
5
|
+
dotenvPath = process.env.DOTENV_PATH;
|
|
6
|
+
console.log("load dotenv form DOTENV_PATH", dotenvPath);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (process.env.LOAD_DOTENV_SUBFOLDER ) {
|
|
10
|
+
console.log("load dotenv form LOAD_DOTENV_SUBFOLDER");
|
|
11
|
+
dotenvPath = __dirname+'/confenv/.env';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
require('dotenv').config({ path: dotenvPath});
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
var mongoose = require('mongoose');
|
|
18
|
+
|
|
19
|
+
let winston = require('./config/winston');
|
|
20
|
+
let JobsManager = require('./jobsManager');
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
let geoService = require('./services/geoService');
|
|
24
|
+
var config = require('./config/database');
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
//override JOB_WORKER_ENABLED to false when you start jobs.js
|
|
28
|
+
process.env.JOB_WORKER_ENABLED=false
|
|
29
|
+
|
|
30
|
+
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI || config.database;
|
|
31
|
+
var autoIndex = true;
|
|
32
|
+
|
|
33
|
+
if (!databaseUri) { //TODO??
|
|
34
|
+
winston.warn('DATABASE_URI not specified, falling back to localhost.');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var connection = mongoose.connect(databaseUri, { "useNewUrlParser": true, "autoIndex": autoIndex }, function(err) {
|
|
38
|
+
if (err) {
|
|
39
|
+
winston.error('Failed to connect to MongoDB on ' + databaseUri + " ", err);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// winston.info("mongoose.connection",mongoose.connection);
|
|
45
|
+
// module.exports = jobsManager;
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
async function main()
|
|
50
|
+
{
|
|
51
|
+
|
|
52
|
+
require('./pubmodules/queue');
|
|
53
|
+
// require('@tiledesk-ent/tiledesk-server-queue');
|
|
54
|
+
|
|
55
|
+
let jobsManager = new JobsManager(undefined, geoService);
|
|
56
|
+
|
|
57
|
+
jobsManager.listen();
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
let emailNotification = require('./pubmodules/emailNotification');
|
|
61
|
+
jobsManager.listenEmailNotification(emailNotification);
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
let activityArchiver = require('./pubmodules/activities').activityArchiver;
|
|
65
|
+
jobsManager.listenActivityArchiver(activityArchiver);
|
|
66
|
+
|
|
67
|
+
winston.info("Jobs started");
|
|
68
|
+
|
|
69
|
+
await new Promise(function () {});
|
|
70
|
+
console.log('This text will never be printed');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function panic(error)
|
|
74
|
+
{
|
|
75
|
+
console.error(error);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// https://stackoverflow.com/a/46916601/1478566
|
|
80
|
+
main().catch(panic).finally(clearInterval.bind(null, setInterval(a=>a, 1E9)));
|
package/jobsManager.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
var winston = require('./config/winston');
|
|
3
|
+
|
|
4
|
+
class JobsManager {
|
|
5
|
+
constructor(jobWorkerEnabled, geoService) {
|
|
6
|
+
this.geoService = geoService;
|
|
7
|
+
this.emailNotificatio = undefined;
|
|
8
|
+
this.activityArchiver = undefined;
|
|
9
|
+
|
|
10
|
+
this.jobWorkerEnabled = jobWorkerEnabled;
|
|
11
|
+
// this.jobWorkerEnabled = false;
|
|
12
|
+
// if (process.env.JOB_WORKER_ENABLED=="true" || process.env.JOB_WORKER_ENABLED == true) {
|
|
13
|
+
// this.jobWorkerEnabled = true;
|
|
14
|
+
// }
|
|
15
|
+
// winston.info("JobsManager jobWorkerEnabled: "+ this.jobWorkerEnabled);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
listen() {
|
|
20
|
+
winston.info("JobsManager listener started");
|
|
21
|
+
if ( this.jobWorkerEnabled == true) {
|
|
22
|
+
return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listeners");
|
|
23
|
+
}
|
|
24
|
+
this.geoService.listen();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
listenEmailNotification(emailNotification) {
|
|
28
|
+
winston.info("JobsManager listenEmailNotification started");
|
|
29
|
+
if ( this.jobWorkerEnabled == true) {
|
|
30
|
+
return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listener for Email Notification");
|
|
31
|
+
}
|
|
32
|
+
this.emailNotification = emailNotification;
|
|
33
|
+
this.emailNotification.requestNotification.listen();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
listenActivityArchiver(activityArchiver) {
|
|
37
|
+
winston.info("JobsManager listenActivityArchiver started");
|
|
38
|
+
if ( this.jobWorkerEnabled == true) {
|
|
39
|
+
return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listener for Activity Archiver");
|
|
40
|
+
}
|
|
41
|
+
this.activityArchiver = activityArchiver;
|
|
42
|
+
this.activityArchiver.listen();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
module.exports = JobsManager;
|
package/middleware/has-role.js
CHANGED
|
@@ -4,6 +4,7 @@ var Subscription = require("../models/subscription");
|
|
|
4
4
|
var winston = require('../config/winston');
|
|
5
5
|
|
|
6
6
|
var cacheUtil = require('../utils/cacheUtil');
|
|
7
|
+
var cacheEnabler = require("../services/cacheEnabler");
|
|
7
8
|
|
|
8
9
|
class RoleChecker {
|
|
9
10
|
|
|
@@ -131,15 +132,21 @@ class RoleChecker {
|
|
|
131
132
|
|
|
132
133
|
// JWT_HERE
|
|
133
134
|
var query = { id_project: req.params.projectid, id_user: req.user._id, status: "active"};
|
|
135
|
+
let cache_key = req.params.projectid+":project_users:iduser:"+req.user._id
|
|
134
136
|
|
|
135
137
|
if (req.user.sub && (req.user.sub=="userexternal" || req.user.sub=="guest")) {
|
|
136
138
|
query = { id_project: req.params.projectid, uuid_user: req.user._id, status: "active"};
|
|
139
|
+
cache_key = req.params.projectid+":project_users:uuid_user:"+req.user._id
|
|
137
140
|
}
|
|
138
141
|
winston.debug("hasRoleOrType query " + JSON.stringify(query));
|
|
139
142
|
|
|
140
|
-
Project_user.findOne(query)
|
|
141
|
-
|
|
142
|
-
.
|
|
143
|
+
let q = Project_user.findOne(query);
|
|
144
|
+
if (cacheEnabler.project_user) {
|
|
145
|
+
q.cache(cacheUtil.defaultTTL, cache_key);
|
|
146
|
+
winston.debug("cacheEnabler.project_user enabled");
|
|
147
|
+
|
|
148
|
+
}
|
|
149
|
+
q.exec(function (err, project_user) {
|
|
143
150
|
if (err) {
|
|
144
151
|
winston.error("Error getting project_user for hasrole",err);
|
|
145
152
|
return next(err);
|
|
@@ -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"}
|
|
@@ -132,7 +138,7 @@ module.exports = function(passport) {
|
|
|
132
138
|
|
|
133
139
|
winston.debug("project id: "+ AudienceId );
|
|
134
140
|
Project.findOne({_id: AudienceId, status: 100}).select('+jwtSecret')
|
|
135
|
-
//@DISABLED_CACHE .cache(cacheUtil.queryTTL, "projects:query:id:status:100:"+AudienceId+":select:+jwtSecret")
|
|
141
|
+
//@DISABLED_CACHE .cache(cacheUtil.queryTTL, "projects:query:id:status:100:"+AudienceId+":select:+jwtSecret") //project_cache
|
|
136
142
|
.exec(function (err, project){
|
|
137
143
|
if (err) {
|
|
138
144
|
winston.error("auth Project err: ", {error:err, decoded: decoded} );
|
package/models/department.js
CHANGED