@tiledesk/tiledesk-server 2.17.3 → 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.
Files changed (50) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/app.js +2 -0
  3. package/archive.sh +92 -0
  4. package/channels/chat21/chat21WebHook.js +6 -1
  5. package/event/authEvent.js +16 -0
  6. package/event/projectUserEvent.js +39 -0
  7. package/event/roleEvent.js +9 -0
  8. package/middleware/has-role.js +160 -121
  9. package/middleware/passport.js +180 -179
  10. package/migrations/1757601159298-project_user_role_type.js +45 -0
  11. package/models/department.js +3 -0
  12. package/models/groupMemberSchama.js +19 -0
  13. package/models/kb_setting.js +6 -2
  14. package/models/permissionConstants.js +19 -0
  15. package/models/project_user.js +86 -8
  16. package/models/request.js +1 -0
  17. package/models/role.js +31 -0
  18. package/models/roleConstants.js +2 -0
  19. package/package.json +1 -1
  20. package/pubmodules/analytics/analytics.js +2 -2
  21. package/pubmodules/cache/mongoose-cachegoose-fn.js +37 -0
  22. package/pubmodules/canned/cannedResponseRoute.js +34 -6
  23. package/pubmodules/routing-queue/listener.js +7 -1
  24. package/pubmodules/trigger/rulesTrigger.js +1 -6
  25. package/routes/auth.js +3 -1
  26. package/routes/department.js +7 -1
  27. package/routes/kb.js +25 -1
  28. package/routes/message.js +4 -1
  29. package/routes/project.js +41 -3
  30. package/routes/project_user.js +62 -11
  31. package/routes/request.js +32 -30
  32. package/routes/roles.js +151 -0
  33. package/routes/unanswered.js +1 -1
  34. package/routes/webhook.js +18 -13
  35. package/routes/widget.js +3 -1
  36. package/services/cacheEnabler.js +5 -8
  37. package/services/departmentService.js +39 -11
  38. package/services/emailService.js +2 -2
  39. package/services/pendingInvitationService.js +2 -0
  40. package/services/projectService.js +3 -1
  41. package/services/projectUserService.js +67 -4
  42. package/services/subscriptionNotifierQueued.js +8 -0
  43. package/services/updateRequestSnapshotQueued.js +0 -3
  44. package/test/departmentService.js +5 -0
  45. package/test/messageRoute.js +7 -4
  46. package/test/projectUserRoute.js +116 -0
  47. package/test/requestService.js +7 -3
  48. package/test-int/bot.js +3 -2
  49. package/websocket/webSocketServer.js +273 -225
  50. package/routes/auth_newjwt.js +0 -648
@@ -81,13 +81,20 @@ winston.info('Authentication Oauth2 Signin enabled : ' + enableOauth2Signin);
81
81
 
82
82
  var jwthistory = undefined;
83
83
  try {
84
- jwthistory = require('@tiledesk-ent/tiledesk-server-jwthistory');
85
- } catch (err) {
86
- winston.debug("jwthistory not present");
84
+ jwthistory = require('@tiledesk-ent/tiledesk-server-jwthistory');
85
+ } catch(err) {
86
+ winston.info("jwthistory not present", err);
87
87
  }
88
88
 
89
- module.exports = function (passport) {
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
- winston.debug("passport opts: ", opts);
244
+ winston.debug("passport opts: ", opts);
238
245
 
239
- passport.use(new JwtStrategy(opts, async (req, jwt_payload, done) => {
240
- // passport.use(new JwtStrategy(opts, function(req, jwt_payload, done) {
241
- winston.debug("jwt_payload", jwt_payload);
242
- // console.log("req",req);
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
- if (jwt_payload._id == undefined && (jwt_payload._doc == undefined || (jwt_payload._doc && jwt_payload._doc._id == undefined))) {
249
- var err = "jwt_payload._id or jwt_payload._doc._id can t be undefined";
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
- // const subject = jwt_payload.sub || jwt_payload._id || jwt_payload._doc._id;
257
- winston.debug("passport identifier: " + identifier);
269
+ winston.debug("passport identifier: " + identifier + " subject " + subject);
258
270
 
259
- const subject = jwt_payload.sub;
260
- winston.debug("passport subject: " + subject);
271
+ var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
272
+ winston.debug("fullUrl:"+ fullUrl);
261
273
 
262
- winston.debug("passport identifier: " + identifier + " subject " + subject);
274
+ winston.debug("req.disablePassportEntityCheck:"+req.disablePassportEntityCheck);
263
275
 
264
- var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
265
- winston.debug("fullUrl:" + fullUrl);
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
- winston.debug("req.disablePassportEntityCheck:" + req.disablePassportEntityCheck);
294
+ if (subject == "bot") {
295
+ winston.debug("Passport JWT bot");
268
296
 
269
- if (req && req.disablePassportEntityCheck) { //req can be null
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
- //TODO check into DB if JWT is revoked
277
- if (jwthistory) {
278
- var jwtRevoked = await jwthistory.isJWTRevoked(jwt_payload.jti);
279
- winston.debug("passport jwt jwtRevoked: " + jwtRevoked);
280
- if (jwtRevoked) {
281
- winston.warn("passport jwt is revoked with jti: " + jwt_payload.jti);
282
- return done(null, false);
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
- if (subject == "bot") {
287
- winston.debug("Passport JWT bot");
338
+ } else if (subject=="userexternal") {
339
+
340
+
341
+ if (jwt_payload) {
288
342
 
289
- let qbot = Faq_kb.findOne({_id: identifier}); //TODO add cache_bot_here
343
+ // const audUrl = new URL(jwt_payload.aud);
344
+ // winston.info("audUrl: "+ audUrl );
290
345
 
291
- if (cacheEnabler.faq_kb) {
292
- let id_project = jwt_payload.id_project;
293
- winston.debug("jwt_payload.id_project:" + jwt_payload.id_project);
294
- qbot.cache(cacheUtil.defaultTTL, id_project + ":faq_kbs:id:" + identifier)
295
- winston.debug('faq_kb cache enabled');
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
- qbot.exec(function (err, faq_kb) {
352
+ // const AudienceId = path.split("/")[2];
353
+ // winston.info("audUrl AudienceId: " + AudienceId );
299
354
 
300
- if (err) {
301
- winston.error("Passport JWT bot err", err);
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
- Subscription.findOne({_id: identifier}, function (err, subscription) {
317
- if (err) {
318
- winston.error("Passport JWT subscription err", err);
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
- } else if (subject == "userexternal") {
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
- if (jwt_payload) {
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
- // const audUrl = new URL(jwt_payload.aud);
336
- // winston.info("audUrl: "+ audUrl );
408
+ }
409
+
337
410
 
338
- // const path = audUrl.pathname;
339
- // winston.info("audUrl path: " + path );
340
411
 
341
- // const AudienceType = path.split("/")[1];
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
- winston.debug("Passport JWT userexternal", jwt_payload);
351
- var userM = UserUtil.decorateUser(jwt_payload);
352
- winston.debug("Passport JWT userexternal userM", userM);
421
+ var email = userid.toLowerCase();
422
+ winston.debug("email lowercase: " + email);
353
423
 
354
- return done(null, userM);
355
- } else {
356
- var err = {msg: "No jwt_payload passed. Its required"};
357
- winston.error("Passport JWT userexternal err", err);
358
- return done(err, false);
359
- }
360
-
361
- } else if (subject == "guest") {
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
- var err = {msg: "No jwt_payload passed. Its required"};
371
- winston.error("Passport JWT guest err", err);
372
- return done(err, false);
442
+ return done(err);
373
443
  }
374
-
375
- } else {
376
- winston.debug("Passport JWT generic user");
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
+
@@ -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;
@@ -1,7 +1,11 @@
1
1
  let mongoose = require('mongoose');
2
2
  let Schema = mongoose.Schema;
3
3
  let winston = require('../config/winston');
4
- let expireAfterSeconds = process.env.UNANSWERED_QUESTION_EXPIRATION_TIME || 7 * 24 * 60 * 60; // 7 days
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({ created_at: 1 }, { expireAfterSeconds: expireAfterSeconds }); // 30 days
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 }
@@ -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
- Project_userSchema.virtual('events', {
90
- ref: 'event', // The model to use
91
- localField: '_id', // Find people where `localField`
92
- foreignField: 'project_user', // is equal to `foreignField`
93
- justOne: false,
94
- // options: { getters: true }
95
- options: { sort: { createdAt: -1 }, limit: 5 } // Query options, see http://bit.ly/mongoose-query-options
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");