@tiledesk/tiledesk-server 2.17.4 → 2.18.1
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 +4 -3
- package/app.js +2 -0
- package/channels/chat21/chat21WebHook.js +6 -1
- 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 +45 -0
- package/models/department.js +3 -0
- package/models/groupMemberSchama.js +19 -0
- package/models/kb_setting.js +6 -2
- 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/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 +1 -1
- 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/middleware/passport.js
CHANGED
|
@@ -81,13 +81,20 @@ winston.info('Authentication Oauth2 Signin enabled : ' + enableOauth2Signin);
|
|
|
81
81
|
|
|
82
82
|
var jwthistory = undefined;
|
|
83
83
|
try {
|
|
84
|
-
|
|
85
|
-
} catch
|
|
86
|
-
|
|
84
|
+
jwthistory = require('@tiledesk-ent/tiledesk-server-jwthistory');
|
|
85
|
+
} catch(err) {
|
|
86
|
+
winston.info("jwthistory not present", err);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
let JWT_HISTORY_ENABLED = false;
|
|
90
|
+
if (process.env.JWT_HISTORY_ENABLED==true || process.env.JWT_HISTORY_ENABLED=="true") {
|
|
91
|
+
JWT_HISTORY_ENABLED = true;
|
|
92
|
+
}
|
|
93
|
+
winston.debug("JWT_HISTORY_ENABLED: " + JWT_HISTORY_ENABLED);
|
|
94
|
+
|
|
95
|
+
|
|
90
96
|
|
|
97
|
+
module.exports = function(passport) {
|
|
91
98
|
// passport.serializeUser(function(user, done) {
|
|
92
99
|
// console.log("serializeUser");
|
|
93
100
|
|
|
@@ -231,218 +238,212 @@ module.exports = function (passport) {
|
|
|
231
238
|
done(null, configSecret); //pub_jwt pp_jwt
|
|
232
239
|
}
|
|
233
240
|
}
|
|
234
|
-
}
|
|
241
|
+
};
|
|
235
242
|
|
|
236
243
|
|
|
237
|
-
|
|
244
|
+
winston.debug("passport opts: ", opts);
|
|
238
245
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
246
|
+
passport.use(new JwtStrategy(opts, async(req, jwt_payload, done) => {
|
|
247
|
+
// passport.use(new JwtStrategy(opts, function(req, jwt_payload, done) {
|
|
248
|
+
winston.debug("jwt_payload",jwt_payload);
|
|
249
|
+
// console.log("req",req);
|
|
250
|
+
|
|
243
251
|
|
|
252
|
+
// console.log("jwt_payload._doc._id",jwt_payload._doc._id);
|
|
244
253
|
|
|
245
|
-
// console.log("jwt_payload._doc._id",jwt_payload._doc._id);
|
|
246
254
|
|
|
255
|
+
if (jwt_payload._id == undefined && (jwt_payload._doc == undefined || (jwt_payload._doc && jwt_payload._doc._id==undefined))) {
|
|
256
|
+
var err = "jwt_payload._id or jwt_payload._doc._id can t be undefined" ;
|
|
257
|
+
winston.error(err);
|
|
258
|
+
return done(null, false);
|
|
259
|
+
}
|
|
260
|
+
//JWT OLD format
|
|
261
|
+
const identifier = jwt_payload._id || jwt_payload._doc._id;
|
|
262
|
+
|
|
263
|
+
// const subject = jwt_payload.sub || jwt_payload._id || jwt_payload._doc._id;
|
|
264
|
+
winston.debug("passport identifier: " + identifier);
|
|
247
265
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
winston.error(err);
|
|
251
|
-
return done(null, false);
|
|
252
|
-
}
|
|
253
|
-
//JWT OLD format
|
|
254
|
-
const identifier = jwt_payload._id || jwt_payload._doc._id;
|
|
266
|
+
const subject = jwt_payload.sub;
|
|
267
|
+
winston.debug("passport subject: " + subject);
|
|
255
268
|
|
|
256
|
-
|
|
257
|
-
winston.debug("passport identifier: " + identifier);
|
|
269
|
+
winston.debug("passport identifier: " + identifier + " subject " + subject);
|
|
258
270
|
|
|
259
|
-
|
|
260
|
-
|
|
271
|
+
var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
|
|
272
|
+
winston.debug("fullUrl:"+ fullUrl);
|
|
261
273
|
|
|
262
|
-
|
|
274
|
+
winston.debug("req.disablePassportEntityCheck:"+req.disablePassportEntityCheck);
|
|
263
275
|
|
|
264
|
-
|
|
265
|
-
|
|
276
|
+
if (req && req.disablePassportEntityCheck) { //req can be null
|
|
277
|
+
// jwt_payload.id = jwt_payload._id; //often req.user.id is used inside code. req.user.id is a mongoose getter of _id
|
|
278
|
+
// is better to rename req.user.id to req.user._id in all files
|
|
279
|
+
winston.debug("req.disablePassportEntityCheck enabled");
|
|
280
|
+
return done(null, jwt_payload);
|
|
281
|
+
}
|
|
282
|
+
winston.debug("jwthistory passport",jwthistory);
|
|
283
|
+
|
|
284
|
+
//TODO check into DB if JWT is revoked
|
|
285
|
+
if (jwthistory && JWT_HISTORY_ENABLED==true) {
|
|
286
|
+
var jwtRevoked = await jwthistory.isJWTRevoked(jwt_payload.jti);
|
|
287
|
+
winston.debug("passport jwt jwtRevoked: "+ jwtRevoked);
|
|
288
|
+
if (jwtRevoked) {
|
|
289
|
+
winston.warn("passport jwt is revoked with jti: "+ jwt_payload.jti);
|
|
290
|
+
return done(null, false);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
266
293
|
|
|
267
|
-
|
|
294
|
+
if (subject == "bot") {
|
|
295
|
+
winston.debug("Passport JWT bot");
|
|
268
296
|
|
|
269
|
-
|
|
270
|
-
// jwt_payload.id = jwt_payload._id; //often req.user.id is used inside code. req.user.id is a mongoose getter of _id
|
|
271
|
-
// is better to rename req.user.id to req.user._id in all files
|
|
272
|
-
winston.debug("req.disablePassportEntityCheck enabled");
|
|
273
|
-
return done(null, jwt_payload);
|
|
274
|
-
}
|
|
297
|
+
let qbot = Faq_kb.findOne({_id: identifier}); //TODO add cache_bot_here
|
|
275
298
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
299
|
+
if (cacheEnabler.faq_kb) {
|
|
300
|
+
let id_project = jwt_payload.id_project;
|
|
301
|
+
winston.debug("jwt_payload.id_project:"+jwt_payload.id_project);
|
|
302
|
+
qbot.cache(cacheUtil.defaultTTL, id_project+":faq_kbs:id:"+identifier)
|
|
303
|
+
winston.debug('faq_kb cache enabled');
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
qbot.exec(function(err, faq_kb) {
|
|
307
|
+
|
|
308
|
+
if (err) {
|
|
309
|
+
winston.error("Passport JWT bot err", err);
|
|
310
|
+
return done(err, false);
|
|
311
|
+
}
|
|
312
|
+
if (faq_kb) {
|
|
313
|
+
winston.debug("Passport JWT bot user", faq_kb);
|
|
314
|
+
return done(null, faq_kb);
|
|
315
|
+
} else {
|
|
316
|
+
winston.warn("Passport JWT bot not user");
|
|
317
|
+
return done(null, false);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
// } else if (subject=="projects") {
|
|
321
|
+
|
|
322
|
+
} else if (subject=="subscription") {
|
|
323
|
+
|
|
324
|
+
Subscription.findOne({_id: identifier}, function(err, subscription) {
|
|
325
|
+
if (err) {
|
|
326
|
+
winston.error("Passport JWT subscription err", err);
|
|
327
|
+
return done(err, false);
|
|
328
|
+
}
|
|
329
|
+
if (subscription) {
|
|
330
|
+
winston.debug("Passport JWT subscription user", subscription);
|
|
331
|
+
return done(null, subscription);
|
|
332
|
+
} else {
|
|
333
|
+
winston.warn("Passport JWT subscription not user", subscription);
|
|
334
|
+
return done(null, false);
|
|
284
335
|
}
|
|
336
|
+
});
|
|
285
337
|
|
|
286
|
-
|
|
287
|
-
|
|
338
|
+
} else if (subject=="userexternal") {
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
if (jwt_payload) {
|
|
288
342
|
|
|
289
|
-
|
|
343
|
+
// const audUrl = new URL(jwt_payload.aud);
|
|
344
|
+
// winston.info("audUrl: "+ audUrl );
|
|
290
345
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
346
|
+
// const path = audUrl.pathname;
|
|
347
|
+
// winston.info("audUrl path: " + path );
|
|
348
|
+
|
|
349
|
+
// const AudienceType = path.split("/")[1];
|
|
350
|
+
// winston.info("audUrl AudienceType: " + AudienceType );
|
|
297
351
|
|
|
298
|
-
|
|
352
|
+
// const AudienceId = path.split("/")[2];
|
|
353
|
+
// winston.info("audUrl AudienceId: " + AudienceId );
|
|
299
354
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
return done(err, false);
|
|
303
|
-
}
|
|
304
|
-
if (faq_kb) {
|
|
305
|
-
winston.debug("Passport JWT bot user", faq_kb);
|
|
306
|
-
return done(null, faq_kb);
|
|
307
|
-
} else {
|
|
308
|
-
winston.warn("Passport JWT bot not user");
|
|
309
|
-
return done(null, false);
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
// } else if (subject=="projects") {
|
|
355
|
+
// jwt_payload._id = AudienceId + "-" + jwt_payload._id;
|
|
356
|
+
|
|
313
357
|
|
|
314
|
-
} else if (subject == "subscription") {
|
|
315
358
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return done(err, false);
|
|
320
|
-
}
|
|
321
|
-
if (subscription) {
|
|
322
|
-
winston.debug("Passport JWT subscription user", subscription);
|
|
323
|
-
return done(null, subscription);
|
|
324
|
-
} else {
|
|
325
|
-
winston.warn("Passport JWT subscription not user", subscription);
|
|
326
|
-
return done(null, false);
|
|
327
|
-
}
|
|
328
|
-
});
|
|
359
|
+
winston.debug("Passport JWT userexternal", jwt_payload);
|
|
360
|
+
var userM = UserUtil.decorateUser(jwt_payload);
|
|
361
|
+
winston.debug("Passport JWT userexternal userM", userM);
|
|
329
362
|
|
|
330
|
-
|
|
363
|
+
return done(null, userM );
|
|
364
|
+
} else {
|
|
365
|
+
var err = {msg: "No jwt_payload passed. Its required"};
|
|
366
|
+
winston.error("Passport JWT userexternal err", err);
|
|
367
|
+
return done(err, false);
|
|
368
|
+
}
|
|
331
369
|
|
|
370
|
+
} else if (subject=="guest") {
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
if (jwt_payload) {
|
|
374
|
+
winston.debug("Passport JWT guest", jwt_payload);
|
|
375
|
+
var userM = UserUtil.decorateUser(jwt_payload);
|
|
376
|
+
winston.debug("Passport JWT guest userM", userM);
|
|
377
|
+
return done(null, userM );
|
|
378
|
+
} else {
|
|
379
|
+
var err = {msg: "No jwt_payload passed. Its required"};
|
|
380
|
+
winston.error("Passport JWT guest err", err);
|
|
381
|
+
return done(err, false);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
} else {
|
|
385
|
+
winston.debug("Passport JWT generic user");
|
|
386
|
+
let quser = User.findOne({_id: identifier, status: 100}) //TODO user_cache_here
|
|
387
|
+
//@DISABLED_CACHE .cache(cacheUtil.defaultTTL, "users:id:"+identifier)
|
|
388
|
+
|
|
389
|
+
if (cacheEnabler.user) {
|
|
390
|
+
quser.cache(cacheUtil.defaultTTL, "users:id:"+identifier)
|
|
391
|
+
winston.debug('user cache enabled');
|
|
392
|
+
}
|
|
332
393
|
|
|
333
|
-
|
|
394
|
+
quser.exec(function(err, user) {
|
|
395
|
+
if (err) {
|
|
396
|
+
winston.error("Passport JWT generic err ", err);
|
|
397
|
+
return done(err, false);
|
|
398
|
+
}
|
|
399
|
+
if (user) {
|
|
400
|
+
winston.debug("Passport JWT generic user ", user);
|
|
401
|
+
return done(null, user);
|
|
402
|
+
} else {
|
|
403
|
+
winston.debug("Passport JWT generic not user");
|
|
404
|
+
return done(null, false);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
334
407
|
|
|
335
|
-
|
|
336
|
-
|
|
408
|
+
}
|
|
409
|
+
|
|
337
410
|
|
|
338
|
-
// const path = audUrl.pathname;
|
|
339
|
-
// winston.info("audUrl path: " + path );
|
|
340
411
|
|
|
341
|
-
|
|
342
|
-
// winston.info("audUrl AudienceType: " + AudienceType );
|
|
412
|
+
}));
|
|
343
413
|
|
|
344
|
-
// const AudienceId = path.split("/")[2];
|
|
345
|
-
// winston.info("audUrl AudienceId: " + AudienceId );
|
|
346
414
|
|
|
347
|
-
// jwt_payload._id = AudienceId + "-" + jwt_payload._id;
|
|
348
415
|
|
|
416
|
+
passport.use(new BasicStrategy(function(userid, password, done) {
|
|
417
|
+
|
|
418
|
+
winston.debug("BasicStrategy: " + userid);
|
|
419
|
+
|
|
349
420
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
winston.debug("Passport JWT userexternal userM", userM);
|
|
421
|
+
var email = userid.toLowerCase();
|
|
422
|
+
winston.debug("email lowercase: " + email);
|
|
353
423
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
424
|
+
User.findOne({ email: email, status: 100}, 'email firstname lastname password emailverified id') //TODO user_cache_here. NOT used frequently. ma attento select. ATTENTO QUI NN USEREI LA SELECT altrimenti con JWT ho tuttto USER mentre con basich auth solo aluni campi
|
|
425
|
+
//@DISABLED_CACHE .cache(cacheUtil.defaultTTL, "users:email:"+email)
|
|
426
|
+
.exec(function (err, user) {
|
|
427
|
+
|
|
428
|
+
if (err) {
|
|
429
|
+
// console.log("BasicStrategy err.stop");
|
|
430
|
+
return done(err);
|
|
431
|
+
}
|
|
432
|
+
if (!user) { return done(null, false); }
|
|
433
|
+
|
|
434
|
+
user.comparePassword(password, function (err, isMatch) {
|
|
435
|
+
if (isMatch && !err) {
|
|
362
436
|
|
|
437
|
+
// if user is found and password is right create a token
|
|
438
|
+
// console.log("BasicStrategy ok");
|
|
439
|
+
return done(null, user);
|
|
363
440
|
|
|
364
|
-
if (jwt_payload) {
|
|
365
|
-
winston.debug("Passport JWT guest", jwt_payload);
|
|
366
|
-
var userM = UserUtil.decorateUser(jwt_payload);
|
|
367
|
-
winston.debug("Passport JWT guest userM", userM);
|
|
368
|
-
return done(null, userM);
|
|
369
441
|
} else {
|
|
370
|
-
|
|
371
|
-
winston.error("Passport JWT guest err", err);
|
|
372
|
-
return done(err, false);
|
|
442
|
+
return done(err);
|
|
373
443
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
let quser = User.findOne({_id: identifier, status: 100}) //TODO user_cache_here
|
|
378
|
-
//@DISABLED_CACHE .cache(cacheUtil.defaultTTL, "users:id:"+identifier)
|
|
379
|
-
|
|
380
|
-
if (cacheEnabler.user) {
|
|
381
|
-
quser.cache(cacheUtil.defaultTTL, "users:id:" + identifier)
|
|
382
|
-
winston.debug('user cache enabled');
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
quser.exec(function (err, user) {
|
|
386
|
-
if (err) {
|
|
387
|
-
winston.error("Passport JWT generic err ", err);
|
|
388
|
-
return done(err, false);
|
|
389
|
-
}
|
|
390
|
-
if (user) {
|
|
391
|
-
winston.debug("Passport JWT generic user ", user);
|
|
392
|
-
return done(null, user);
|
|
393
|
-
} else {
|
|
394
|
-
winston.debug("Passport JWT generic not user");
|
|
395
|
-
return done(null, false);
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}));
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
passport.use(new BasicStrategy(function (userid, password, done) {
|
|
406
|
-
|
|
407
|
-
winston.debug("BasicStrategy: " + userid);
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
var email = userid.toLowerCase();
|
|
411
|
-
winston.debug("email lowercase: " + email);
|
|
412
|
-
|
|
413
|
-
User.findOne({
|
|
414
|
-
email: email,
|
|
415
|
-
status: 100
|
|
416
|
-
}, 'email firstname lastname password emailverified id') //TODO user_cache_here. NOT used frequently. ma attento select. ATTENTO QUI NN USEREI LA SELECT altrimenti con JWT ho tuttto USER mentre con basich auth solo aluni campi
|
|
417
|
-
//@DISABLED_CACHE .cache(cacheUtil.defaultTTL, "users:email:"+email)
|
|
418
|
-
.exec(function (err, user) {
|
|
419
|
-
|
|
420
|
-
if (err) {
|
|
421
|
-
// console.log("BasicStrategy err.stop");
|
|
422
|
-
return done(err);
|
|
423
|
-
}
|
|
424
|
-
if (!user) {
|
|
425
|
-
return done(null, false);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
user.comparePassword(password, function (err, isMatch) {
|
|
429
|
-
if (isMatch && !err) {
|
|
430
|
-
|
|
431
|
-
// if user is found and password is right create a token
|
|
432
|
-
// console.log("BasicStrategy ok");
|
|
433
|
-
return done(null, user);
|
|
434
|
-
|
|
435
|
-
} else {
|
|
436
|
-
return done(err);
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
// if (user) { return done(null, user); }
|
|
442
|
-
// if (!user) { return done(null, false); }
|
|
443
|
-
// if (!user.verifyPassword(password)) { return done(null, false); }
|
|
444
|
-
});
|
|
445
|
-
}));
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
}));
|
|
446
447
|
|
|
447
448
|
|
|
448
449
|
if (enableGoogleSignin == true) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var Project_user = require("../models/project_user");
|
|
2
|
+
var winston = require('../config/winston');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Make any changes you need to make to the database here
|
|
6
|
+
*/
|
|
7
|
+
async function up () {
|
|
8
|
+
let p = await Project_user.find({}).exec()
|
|
9
|
+
// Write migration here
|
|
10
|
+
await new Promise((resolve, reject) => {
|
|
11
|
+
Project_user.updateMany({"$or":[{ "role": "agent" }, { "role": "supervisor" }, { "role": "admin" }, { "role": "owner" }]}, {"$set": {"roleType": 1 }}, function (err, updates) {
|
|
12
|
+
if (err) {
|
|
13
|
+
winston.error("Error appling the migration script", err);
|
|
14
|
+
}
|
|
15
|
+
winston.info("Schema updated for " + updates.nModified + " project_user of type agents")
|
|
16
|
+
winston.debug("updates",updates)
|
|
17
|
+
// return resolve('ok');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return Project_user.updateMany({"$or":[{ "role": "user" }, { "role": "guest" }]}, {"$set": {"roleType": 2 }}, function (err, updates) {
|
|
21
|
+
if (err) {
|
|
22
|
+
winston.error("Error appling the migration script", err);
|
|
23
|
+
}
|
|
24
|
+
winston.info("Schema updated for " + updates.nModified + " project_user of type user"),
|
|
25
|
+
winston.debug("updates",updates)
|
|
26
|
+
return resolve('ok');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Make any changes that UNDO the up function side effects here (if possible)
|
|
37
|
+
*/
|
|
38
|
+
async function down () {
|
|
39
|
+
|
|
40
|
+
// Write migration here
|
|
41
|
+
// console.log("down*********");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { up, down };
|
|
45
|
+
|
package/models/department.js
CHANGED
|
@@ -3,6 +3,8 @@ var Schema = mongoose.Schema;
|
|
|
3
3
|
var routingConstants = require('../models/routingConstants');
|
|
4
4
|
var winston = require('../config/winston');
|
|
5
5
|
var TagSchema = require("../models/tag");
|
|
6
|
+
var GroupMemberSchema = require("../models/groupMemberSchama");
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
var DepartmentSchema = new Schema({
|
|
8
10
|
id_bot: {
|
|
@@ -34,6 +36,7 @@ var DepartmentSchema = new Schema({
|
|
|
34
36
|
id_group: {
|
|
35
37
|
type: String,
|
|
36
38
|
},
|
|
39
|
+
groups: [GroupMemberSchema],
|
|
37
40
|
// used??
|
|
38
41
|
online_msg: {
|
|
39
42
|
type: String,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
var mongoose = require('mongoose');
|
|
2
|
+
var Schema = mongoose.Schema;
|
|
3
|
+
var winston = require('../config/winston');
|
|
4
|
+
|
|
5
|
+
var GroupMemberSchema = new Schema({
|
|
6
|
+
|
|
7
|
+
group_id: {
|
|
8
|
+
type: String,
|
|
9
|
+
required: true
|
|
10
|
+
},
|
|
11
|
+
percentage: {
|
|
12
|
+
type: Number,
|
|
13
|
+
required: true,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
module.exports = GroupMemberSchema;
|
package/models/kb_setting.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
let mongoose = require('mongoose');
|
|
2
2
|
let Schema = mongoose.Schema;
|
|
3
3
|
let winston = require('../config/winston');
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
const expireAfterSeconds = (() => {
|
|
6
|
+
const n = Number(process.env.UNANSWERED_QUESTION_EXPIRATION_TIME);
|
|
7
|
+
return !isNaN(n) && n >= 0 ? n : 7 * 24 * 60 * 60; // default 7 days
|
|
8
|
+
})();
|
|
5
9
|
|
|
6
10
|
const EngineSchema = new Schema({
|
|
7
11
|
name: {
|
|
@@ -205,7 +209,7 @@ const UnansweredQuestionSchema = new Schema({
|
|
|
205
209
|
});
|
|
206
210
|
|
|
207
211
|
// Add TTL index to automatically delete documents after 30 days
|
|
208
|
-
UnansweredQuestionSchema.index({
|
|
212
|
+
UnansweredQuestionSchema.index({ createdAt: 1 }, { expireAfterSeconds: expireAfterSeconds }); // 30 days
|
|
209
213
|
|
|
210
214
|
// DEPRECATED !! - Start
|
|
211
215
|
const KBSettingSchema = new Schema({
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const OWNER_ROLE = [
|
|
2
|
+
];
|
|
3
|
+
|
|
4
|
+
const ADMIN_ROLE = [
|
|
5
|
+
"request_read_all"
|
|
6
|
+
];
|
|
7
|
+
const AGENT_ROLE= [
|
|
8
|
+
"request_read_group"
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
// console.log("ADMIN_ROLE", ADMIN_ROLE.concat(AGENT_ROLE));
|
|
12
|
+
module.exports = {
|
|
13
|
+
"agent": AGENT_ROLE,
|
|
14
|
+
"admin": ADMIN_ROLE.concat(AGENT_ROLE),
|
|
15
|
+
"owner": OWNER_ROLE.concat(ADMIN_ROLE).concat(AGENT_ROLE)
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
// const ADMIN_ROLE = Object.assign({}, ADMIN_ROLE, AGENT_ROLE)
|
|
19
|
+
// const ADMIN_ROLE = { ...ADMIN_ROLE, ...AGENT_ROLE }
|
package/models/project_user.js
CHANGED
|
@@ -31,6 +31,10 @@ var TagSchema = require("../models/tag");
|
|
|
31
31
|
index: true
|
|
32
32
|
// required: true
|
|
33
33
|
},
|
|
34
|
+
roleType: {
|
|
35
|
+
type: Number, //1 for agents 2 for users
|
|
36
|
+
index: true
|
|
37
|
+
},
|
|
34
38
|
user_available: {
|
|
35
39
|
type: Boolean,
|
|
36
40
|
default: true,
|
|
@@ -63,6 +67,7 @@ var TagSchema = require("../models/tag");
|
|
|
63
67
|
type: Object,
|
|
64
68
|
},
|
|
65
69
|
tags: [TagSchema],
|
|
70
|
+
permissions: [String],
|
|
66
71
|
createdBy: {
|
|
67
72
|
type: String,
|
|
68
73
|
required: true
|
|
@@ -86,14 +91,16 @@ var TagSchema = require("../models/tag");
|
|
|
86
91
|
);
|
|
87
92
|
|
|
88
93
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
94
|
+
|
|
95
|
+
//TODO COMMENT IT unused. Now events are not saved to the db
|
|
96
|
+
// Project_userSchema.virtual('events', {
|
|
97
|
+
// ref: 'event', // The model to use
|
|
98
|
+
// localField: '_id', // Find people where `localField`
|
|
99
|
+
// foreignField: 'project_user', // is equal to `foreignField`
|
|
100
|
+
// justOne: false,
|
|
101
|
+
// // options: { getters: true }
|
|
102
|
+
// options: { sort: { createdAt: -1 }, limit: 5 } // Query options, see http://bit.ly/mongoose-query-options
|
|
103
|
+
// });
|
|
97
104
|
|
|
98
105
|
Project_userSchema.virtual('isAuthenticated').get(function () {
|
|
99
106
|
if (this.role === RoleConstants.GUEST ) {
|
|
@@ -103,6 +110,77 @@ Project_userSchema.virtual('isAuthenticated').get(function () {
|
|
|
103
110
|
}
|
|
104
111
|
});
|
|
105
112
|
|
|
113
|
+
Project_userSchema.methods.getAllPermissions = function () {
|
|
114
|
+
// console.log("this", this);
|
|
115
|
+
winston.debug("this.permissions", this.permissions);
|
|
116
|
+
|
|
117
|
+
// console.log("this.rolePermissions", this.rolePermissions);
|
|
118
|
+
winston.debug("this._doc.rolePermissions", this._doc.rolePermissions);
|
|
119
|
+
|
|
120
|
+
let all = this.permissions;
|
|
121
|
+
|
|
122
|
+
if (this._doc.rolePermissions) {
|
|
123
|
+
all = [...new Set([...this.permissions, ...this._doc.rolePermissions])]; //https://medium.com/@rivoltafilippo/javascript-merge-arrays-without-duplicates-3fbd8f4881be
|
|
124
|
+
}
|
|
125
|
+
// const all = this.permissions.concat(this._doc.rolePermissions);
|
|
126
|
+
winston.verbose("getAllPermissions all", all);
|
|
127
|
+
|
|
128
|
+
return all;
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
Project_userSchema.methods.hasPermissionOrRole = function (permission, roles) {
|
|
135
|
+
var all_permissions = this.getAllPermissions();
|
|
136
|
+
// var all_permissions = this.getAllPermissions();
|
|
137
|
+
// console.log("hasPermissionOrRole", all_permissions, permission, this.role, roles)
|
|
138
|
+
if (all_permissions && all_permissions.length>0 ) {
|
|
139
|
+
if (all_permissions.includes(permission)) {
|
|
140
|
+
// console.log("hasPermissionOrRole found", permission)
|
|
141
|
+
return true;
|
|
142
|
+
} else {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}else {
|
|
146
|
+
if (roles instanceof Array) {
|
|
147
|
+
// console.log("hasPermissionOrRole roles instanceof Array");
|
|
148
|
+
for (var i = 0; i < roles.length; i++) {
|
|
149
|
+
if (roles[i]==this.role) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
|
|
155
|
+
} else {
|
|
156
|
+
// console.log("roles instanceof ", roles instanceof );
|
|
157
|
+
// console.log("this.role instanceof ", this.role instanceof );
|
|
158
|
+
|
|
159
|
+
// console.log("hasPermissionOrRole role ", this.role, roles);
|
|
160
|
+
if (this.role==roles) {
|
|
161
|
+
// console.log("role ok");
|
|
162
|
+
return true;
|
|
163
|
+
} else {
|
|
164
|
+
// console.log("role ko");
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
Project_userSchema.methods.hasPermission = function (permission) {
|
|
174
|
+
if (this.permissions && this.permissions.length>0 ) {
|
|
175
|
+
if (this.permissions.includes(permission)) {
|
|
176
|
+
return true;
|
|
177
|
+
} else {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}else {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
106
184
|
|
|
107
185
|
|
|
108
186
|
// var query = { id_project: req.params.projectid, id_user: req.user._id};
|
package/models/request.js
CHANGED
|
@@ -11,6 +11,7 @@ var ProjectUserSchema = require("../models/project_user").schema;
|
|
|
11
11
|
var RequestStatus = require("../models/requestStatus");
|
|
12
12
|
var LeadSchema = require("../models/lead").schema; //it's not used but i you run test like (mocha departmentService.js) it throws this not blocking exception: error: error getting requestSchema hasn't been registered for model "lead".
|
|
13
13
|
var NoteSchema = require("../models/note").schema;
|
|
14
|
+
|
|
14
15
|
var TagSchema = require("../models/tag");
|
|
15
16
|
var LocationSchema = require("../models/location");
|
|
16
17
|
var RequestSnapshotSchema = require("../models/requestSnapshot");
|