@tiledesk/tiledesk-server 2.11.7 → 2.11.9

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 CHANGED
@@ -5,6 +5,13 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
+ # 2.11.9
9
+ - Changed: oauth2 endpoints in auth route
10
+ - Updated: improved project users management (soft delete)
11
+
12
+ # 2.11.8
13
+ - Added: migration file to migrate namespace engine
14
+
8
15
  # 2.11.7
9
16
  - Hotfix: solved bug on findProjectUsersAllAndAvailableWithOperatingHours_group on searching group
10
17
 
@@ -1,11 +1,17 @@
1
1
  var winston = require('../config/winston');
2
2
 
3
- var Recaptcha = require('express-recaptcha').RecaptchaV3
4
- var recaptcha = new Recaptcha('6Lf1khcpAAAAABMNHJfnJm43vVTxFzXM7ADqDAp5', '6Lf1khcpAAAAAG6t7LuOfl9vThGPFOOJIiAoMIhs')
3
+ var Recaptcha = require('express-recaptcha').RecaptchaV3;
5
4
 
6
- const RECAPTCHA_ENABLED = false;
5
+ const recaptcha_key = process.env.RECAPTCHA_KEY;
6
+ const recaptcha_secret = process.env.RECAPTCHA_SECRET;
7
+
8
+ winston.info("Recaptcha key: " + recaptcha_key + " and secret: " + recaptcha_secret );
9
+ let recaptcha;
10
+
11
+ let RECAPTCHA_ENABLED = false;
7
12
 
8
13
  if (process.env.RECAPTCHA_ENABLED === true || process.env.RECAPTCHA_ENABLED ==="true") {
14
+ recaptcha = new Recaptcha(recaptcha_key, recaptcha_secret);
9
15
  RECAPTCHA_ENABLED = true;
10
16
  }
11
17
 
@@ -21,7 +27,7 @@ module.exports =
21
27
  next();
22
28
  // success code
23
29
  } else {
24
- winston.error("Signup recaptcha ko");
30
+ winston.error("Signup recaptcha ko: "+ error);
25
31
  // next({status:"Signup recaptcha ko"});
26
32
  res.status(403).send({success: false, msg: 'Recaptcha error.'});
27
33
 
@@ -29,4 +35,4 @@ module.exports =
29
35
  }
30
36
  })
31
37
 
32
- }
38
+ }
@@ -0,0 +1,31 @@
1
+ var winston = require('../config/winston');
2
+ const { Namespace } = require('../models/kb_setting');
3
+
4
+ async function up () {
5
+
6
+ if (!process.env.PINECONE_INDEX || !process.env.PINECONE_TYPE) {
7
+ winston.error("Namespace engine migration STOPPED. PINECONE_TYPE or PINECONE_INDEX undefined.");
8
+ return;
9
+ }
10
+
11
+ let engine = {
12
+ name: "pinecone",
13
+ type: process.env.PINECONE_TYPE,
14
+ apikey: "",
15
+ vector_size: 1536,
16
+ index_name: process.env.PINECONE_INDEX
17
+ };
18
+
19
+ try {
20
+ const updates = await Namespace.updateMany(
21
+ { engine: { $exists: false } },
22
+ { engine: engine }
23
+ );
24
+ winston.info("Schema updated for " + updates.nModified + " namespace");
25
+ } catch (err) {
26
+ winston.error("Error updating namespaces in migration:", err);
27
+ throw err;
28
+ }
29
+ }
30
+
31
+ module.exports = { up };
@@ -74,6 +74,11 @@ var TagSchema = require("../models/tag");
74
74
  index: true,
75
75
  required: true
76
76
  },
77
+ trashed: {
78
+ type: Boolean,
79
+ default: false,
80
+ required: false
81
+ }
77
82
  }, {
78
83
  timestamps: true,
79
84
  toJSON: { virtuals: true } //used to polulate messages in toJSON// https://mongoosejs.com/docs/populate.html
@@ -116,7 +121,24 @@ Project_userSchema.virtual('isAuthenticated').get(function () {
116
121
  Project_userSchema.index({ id_project: 1, role: 1, status: 1, createdAt: 1 });
117
122
 
118
123
 
119
-
124
+ Project_userSchema.pre('findOneAndUpdate', async function(next) {
125
+ // Get the update object
126
+ const update = this.getUpdate();
127
+
128
+ // Check if 'trashed' is being set to true
129
+ if (update && (
130
+ (update.trashed === true) ||
131
+ (update.$set && update.$set.trashed === true)
132
+ )) {
133
+ // Set status to "disabled"
134
+ if (!update.$set) {
135
+ update.$set = {};
136
+ }
137
+ update.$set.status = "disabled";
138
+ this.setUpdate(update);
139
+ }
140
+ next();
141
+ });
120
142
 
121
143
 
122
144
  module.exports = mongoose.model('project_user', Project_userSchema);;
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.11.7",
4
+ "version": "2.11.9",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
package/routes/auth.js CHANGED
@@ -773,78 +773,72 @@ router.get("/google/callback", passport.authenticate("google", { session: false
773
773
 
774
774
 
775
775
 
776
- router.get("/oauth2", function(req,res,next){
777
- winston.debug("redirect_url: "+ req.query.redirect_url );
776
+ router.get("/oauth2", function (req, res, next) {
777
+ winston.debug("(oauth2) redirect_url: " + req.query.redirect_url);
778
778
  req.session.redirect_url = req.query.redirect_url;
779
779
 
780
- winston.debug("forced_redirect_url: "+ req.query.forced_redirect_url );
780
+ winston.debug("(oauth2) forced_redirect_url: " + req.query.forced_redirect_url);
781
781
  req.session.forced_redirect_url = req.query.forced_redirect_url;
782
782
 
783
783
  passport.authenticate(
784
784
  'oauth2'
785
- )(req,res,next);
785
+ )(req, res, next);
786
786
  });
787
787
 
788
788
  // router.get('/oauth2',
789
789
  // passport.authenticate('oauth2'));
790
790
 
791
- router.get('/oauth2/callback',
792
- passport.authenticate('oauth2', { session: false}),
793
- function(req, res) {
794
- winston.debug("'/oauth2/callback: ", req.query);
795
- winston.debug("/oauth2/callback --> req.session.redirect_url", req.session.redirect_url);
796
- winston.debug("/oauth2/callback --> req.session.forced_redirect_url", req.session.forced_redirect_url);
797
-
798
- var user = req.user;
799
- winston.debug("user", user);
800
- winston.debug("req.session.redirect_url: "+ req.session.redirect_url);
801
- var userJson = user.toObject();
802
-
803
- delete userJson.password;
804
-
805
-
806
- var signOptions = {
807
- issuer: 'https://tiledesk.com',
808
- subject: 'user',
809
- audience: 'https://tiledesk.com',
810
- jwtid: uuidv4()
811
-
812
- };
813
-
814
- var alg = process.env.GLOBAL_SECRET_ALGORITHM;
815
- if (alg) {
816
- signOptions.algorithm = alg;
817
- }
818
-
819
-
820
- var token = jwt.sign(userJson, configSecret, signOptions); //priv_jwt pp_jwt
821
-
822
-
823
- // return the information including token as JSON
824
- // res.json(returnObject);
825
-
826
- let dashboard_base_url = process.env.EMAIL_BASEURL || config.baseUrl;
827
- winston.debug("Google Redirect dashboard_base_url: ", dashboard_base_url);
828
-
829
- let homeurl = "/#/";
830
-
831
- if (req.session.redirect_url) {
832
- homeurl = req.session.redirect_url;
833
- }
834
-
835
- var url = dashboard_base_url+homeurl+"?token=JWT "+token;
836
-
837
- if (req.session.forced_redirect_url) {
838
- url = req.session.forced_redirect_url+"?jwt=JWT "+token; //attention we use jwt= (ionic) instead token=(dashboard) for ionic
839
- }
840
-
841
- winston.debug("Google Redirect: "+ url);
842
-
843
- res.redirect(url);
844
-
791
+ router.get('/oauth2/callback', passport.authenticate('oauth2', { session: false }), function (req, res) {
792
+ winston.debug("'/oauth2/callback: ", req.query);
793
+ winston.debug("/oauth2/callback --> req.session.redirect_url", req.session.redirect_url);
794
+ winston.debug("/oauth2/callback --> req.session.forced_redirect_url", req.session.forced_redirect_url);
845
795
 
846
-
847
- });
796
+ var user = req.user;
797
+ winston.debug("(/oauth2/callback) user", user);
798
+ winston.debug("(/oauth2/callback) req.session.redirect_url: " + req.session.redirect_url);
799
+ var userJson = user.toObject();
800
+
801
+ delete userJson.password;
802
+
803
+ var signOptions = {
804
+ issuer: 'https://tiledesk.com',
805
+ subject: 'user',
806
+ audience: 'https://tiledesk.com',
807
+ jwtid: uuidv4()
808
+
809
+ };
810
+
811
+ var alg = process.env.GLOBAL_SECRET_ALGORITHM;
812
+ if (alg) {
813
+ signOptions.algorithm = alg;
814
+ }
815
+
816
+ var token = jwt.sign(userJson, configSecret, signOptions); //priv_jwt pp_jwt
817
+
818
+ // return the information including token as JSON
819
+ // res.json(returnObject);
820
+
821
+ let dashboard_base_url = process.env.EMAIL_BASEURL || config.baseUrl;
822
+ winston.debug("(/oauth2/callback) Google Redirect dashboard_base_url: ", dashboard_base_url);
823
+
824
+ let homeurl = "/#/";
825
+
826
+ if (req.session.redirect_url) {
827
+ homeurl = req.session.redirect_url;
828
+ }
829
+
830
+ const separator = homeurl.includes('?') ? '&' : '?';
831
+ var url = dashboard_base_url + homeurl + separator + "token=JWT " + token;
832
+
833
+ if (req.session.forced_redirect_url) {
834
+ const separator = req.session.forced_redirect_url.includes('?') ? '&' : '?';
835
+ url = req.session.forced_redirect_url + separator + "jwt=JWT " + token; //attention we use jwt= (ionic) instead token=(dashboard) for ionic
836
+ }
837
+
838
+ winston.debug("(/oauth2/callback) Google Redirect: " + url);
839
+
840
+ res.redirect(url);
841
+ });
848
842
 
849
843
  router.get(
850
844
  "/keycloak",
package/routes/kb.js CHANGED
@@ -1538,10 +1538,12 @@ router.post('/sitemap', async (req, res) => {
1538
1538
 
1539
1539
  const sitemap = new Sitemapper({
1540
1540
  url: sitemap_url,
1541
- timeout: 15000
1541
+ timeout: 15000,
1542
+ debug: true
1542
1543
  });
1543
1544
 
1544
1545
  sitemap.fetch().then((data) => {
1546
+ // TODO - check on data.errors to catch error
1545
1547
  winston.debug("data: ", data);
1546
1548
  res.status(200).send(data);
1547
1549
  }).catch((err) => {
@@ -12,176 +12,118 @@ var RoleConstants = require("../models/roleConstants");
12
12
  var ProjectUserUtil = require("../utils/project_userUtil");
13
13
  const uuidv4 = require('uuid/v4');
14
14
 
15
-
16
15
  var passport = require('passport');
17
16
  require('../middleware/passport')(passport);
18
17
  var validtoken = require('../middleware/valid-token')
19
18
  var roleChecker = require('../middleware/has-role');
20
19
 
21
20
 
22
-
23
- // NEW: INVITE A USER
24
21
  router.post('/invite', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
25
22
 
26
- winston.debug('-> INVITE USER ', req.body);
23
+ winston.debug('Invite ProjectUser body ', req.body);
27
24
 
28
- var email = req.body.email;
25
+ let id_project = req.projectid;
26
+ let email = req.body.email;
29
27
  if (email) {
30
28
  email = email.toLowerCase();
31
29
  }
32
30
 
33
- winston.debug('»»» INVITE USER EMAIL', email);
34
- winston.debug('»»» CURRENT USER ID', req.user._id);
35
- winston.debug('»»» PROJECT ID', req.projectid);
36
- // authType
37
- User.findOne({ email: email, status: 100
38
- // , authType: 'email_password'
39
- }, function (err, user) {
40
- if (err) throw err;
31
+ winston.debug('Invite ProjectUser with email ' + email + ' on project ' + req.projectid);
32
+
33
+ User.findOne({ email: email, status: 100 }, (err, user) => {
34
+
35
+ if (err) {
36
+ winston.error("Error in searching for a possible existing project user with email " + email);
37
+ return res.status(500).send({ success: false, error: "An error occurred during the invite process" });
38
+ }
41
39
 
42
40
  if (!user) {
43
- /*
44
- * *** USER NOT FOUND > SAVE EMAIL AND PROJECT ID IN PENDING INVITATION *** */
41
+ // User not registered on Tiledesk Platform -> Save email and project_id in pending invitation
45
42
  // TODO req.user.firstname is null for bot visitor
46
- return pendinginvitation.saveInPendingInvitation(req.projectid, req.project.name, email, req.body.role, req.user._id, req.user.firstname, req.user.lastname)
47
- .then(function (savedPendingInvitation) {
48
-
49
- var eventData = {req: req, savedPendingInvitation: savedPendingInvitation};
50
- winston.debug("eventData",eventData);
51
- authEvent.emit('project_user.invite.pending', eventData);
52
-
53
- return res.json({ msg: "User not found, save invite in pending ", pendingInvitation: savedPendingInvitation });
54
- })
55
- .catch(function (err) {
56
- return res.send(err);
57
- // return res.status(500).send(err);
58
- });
59
- // return res.status(404).send({ success: false, msg: 'User not found.' });
43
+ return pendinginvitation.saveInPendingInvitation(req.projectid, req.project.name, email, req.body.role, req.user._id, req.user.firstname, req.user.lastname).then(function (savedPendingInvitation) {
44
+ var eventData = { req: req, savedPendingInvitation: savedPendingInvitation };
45
+ winston.debug("eventData", eventData);
46
+ authEvent.emit('project_user.invite.pending', eventData);
47
+ return res.json({ msg: "User not found, save invite in pending ", pendingInvitation: savedPendingInvitation });
48
+ }).catch(function (err) {
49
+ return res.send(err);
50
+ });
60
51
 
61
52
  } else if (req.user.id == user._id) {
62
- winston.debug('-> -> FOUND USER ID', user._id)
63
- winston.debug('-> -> CURRENT USER ID', req.user.id);
64
- // if the current user id is = to the id of found user return an error:
65
- // (to a user is not allowed to invite oneself)
66
-
67
- winston.debug('XXX XXX FORBIDDEN')
53
+ // If the current user id is = to the id of found user return an error. To a user is not allowed to invite oneself.
54
+ winston.debug('Invite User: found user ' + user._id + ' is equal to current user ' + req.user.id + '. Is not allowed to invite oneself.')
68
55
  return res.status(403).send({ success: false, msg: 'Forbidden. It is not allowed to invite oneself', code: 4000 });
69
56
 
70
57
  } else {
71
58
 
72
- /**
73
- * *** IT IS NOT ALLOWED TO INVITE A USER WHO IS ALREADY A MEMBER OF THE PROJECT ***
74
- * FIND THE PROJECT USERS FOR THE PROJECT ID PASSED BY THE CLIENT IN THE BODY OF THE REQUEST
75
- * IF THE ID OF THE USER FOUND FOR THE EMAIL (PASSED IN THE BODY OF THE REQUEST - see above)
76
- * MATCHES ONE OF THE USER ID CONTENTS IN THE PROJECTS USER OBJECT STOP THE WORKFLOW AND RETURN AN ERROR */
77
-
78
- var role = [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT];
79
- winston.debug("role", role);
80
-
81
- // winston.debug("PROJECT USER ROUTES - req projectid", req.projectid);
59
+ let roles = [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT];
82
60
 
83
- return Project_user.find({ id_project: req.projectid, role: { $in : role }, status: "active"}, function (err, projectuser) {
84
-
85
-
86
- winston.debug('PRJCT-USERS FOUND (FILTERED FOR THE PROJECT ID) ', projectuser)
61
+ Project_user.findOne({ id_project: id_project, id_user: user._id, role: { $in: roles }}, (err, puser) => {
87
62
  if (err) {
88
- winston.error("Error gettting project_user for invite", err);
89
- return res.status(500).send(err);
63
+ winston.error("Error inviting an already existing user: ", err);
64
+ return res.status(500).send({ success: false, msg: "An error occurred on inviting user " + email + " on project " + id_project })
90
65
  }
91
66
 
92
- if (!projectuser) {
93
- // winston.debug('*** PRJCT-USER NOT FOUND ***')
94
- return res.status(404).send({ success: false, msg: 'Project user not found.' });
67
+ if (!roles.includes(req.body.role)) {
68
+ return res.status(400).send({ success: false, msg: 'Invalid role specified: ' + req.body.role });
95
69
  }
70
+
71
+ let user_available = typeof req.body.user_available === 'boolean' ? req.body.user_available : true
96
72
 
97
- if (projectuser) {
98
- try {
99
- projectuser.forEach(p_user => {
100
- if (p_user) {
101
- // winston.debug('»»»» FOUND USER ID: ', user._id, ' TYPE OF ', typeof (user._id))
102
- // winston.debug('»»»» PRJCT USER > USER ID: ', p_user.id_user, ' TYPE OF ', typeof (p_user.id_user));
103
- var projectUserId = p_user.id_user.toString();
104
- var foundUserId = user._id.toString()
105
-
106
- winston.debug('»»»» FOUND USER ID: ', foundUserId, ' TYPE OF ', typeof (foundUserId))
107
- winston.debug('»»»» PRJCT USER > USER ID: ', projectUserId, ' TYPE OF ', typeof (projectUserId));
108
-
109
- // var n = projectuser.includes('5ae6c62c61c7d54bf119ac73');
110
- // winston.debug('USER IS ALREADY A MEMBER OF THE PROJECT ', n)
111
- if (projectUserId == foundUserId) {
112
- // if ('5ae6c62c61c7d54bf119ac73' == '5ae6c62c61c7d54bf119ac73') {
113
-
114
- winston.debug('»»»» THE PRJCT-USER ID ', p_user.id_user, ' MATCHES THE FOUND USER-ID', user._id)
115
- winston.warn("User " + projectUserId+ " is already a member of the project: " + req.projectid)
116
-
117
- // cannot use continue or break inside a JavaScript Array.prototype.forEach loop. However, there are other options:
118
- throw new Error('User is already a member'); // break
119
- // return res.status(403).send({ success: false, msg: 'Forbidden. User is already a member' });
120
- }
121
- }
122
- });
123
- }
124
- catch (e) {
125
- winston.error('»»» ERROR ', e)
73
+ if (puser) {
74
+ if (puser.trashed !== true) {
75
+ winston.warn("Trying to invite an already project member user")
126
76
  return res.status(403).send({ success: false, msg: 'Forbidden. User is already a member', code: 4001 });
127
77
  }
128
78
 
129
- winston.debug('NO ERROR, SO CREATE AND SAVE A NEW PROJECT USER ')
130
-
131
- var user_available = true;
132
- if (req.body.user_available!=undefined) {
133
- user_available = req.body.user_available;
134
- }
135
- var newProject_user = new Project_user({
136
- // _id: new mongoose.Types.ObjectId(),
137
- id_project: req.projectid,
138
- id_user: user._id,
139
- role: req.body.role,
140
- user_available: user_available,
141
- createdBy: req.user.id,
142
- updatedBy: req.user.id
143
- });
144
-
145
- return newProject_user.save(function (err, savedProject_user) {
79
+ Project_user.findByIdAndUpdate(puser._id, { role: req.body.role, user_available: user_available, trashed: false, status: 'active' }, { new: true}, (err, updatedPuser) => {
146
80
  if (err) {
147
- winston.error('--- > ERROR ', err)
148
- return res.status(500).send({ success: false, msg: 'Error saving object.' });
81
+ winston.error("Error update existing project user before inviting it ", err)
82
+ return res.status(500).send({ success: false, msg: "An error occurred on inviting user " + email + " on project " + id_project })
149
83
  }
150
84
 
85
+ emailService.sendYouHaveBeenInvited(email, req.user.firstname, req.user.lastname, req.project.name, id_project, user.firstname, user.lastname, req.body.role)
151
86
 
87
+ updatedPuser.populate({path:'id_user', select:{'firstname':1, 'lastname':1}},function (err, updatedPuserPopulated){
88
+ var pu = updatedPuserPopulated.toJSON();
89
+ pu.isBusy = ProjectUserUtil.isBusy(savedProject_userPopulated, req.project.settings && req.project.settings.max_agent_assigned_chat);
90
+ var eventData = {req:req, updatedPuserPopulated: pu};
91
+ winston.debug("eventData",eventData);
92
+ authEvent.emit('project_user.invite', eventData);
93
+ });
152
94
 
153
- winston.debug('INVITED USER (IS THE USER FOUND BY EMAIL) ', user);
154
- winston.debug('EMAIL of THE INVITED USER ', email);
155
- winston.debug('ROLE of THE INVITED USER ', req.body.role);
156
- winston.debug('PROJECT NAME ', req.body.role);
157
- winston.debug('LOGGED USER ID ', req.user.id);
158
- winston.debug('LOGGED USER NAME ', req.user.firstname);
159
- winston.debug('LOGGED USER NAME ', req.user.lastname);
95
+ return res.status(200).send(updatedPuser);
96
+ })
160
97
 
98
+ } else {
161
99
 
162
- var invitedUserFirstname = user.firstname
163
- var invitedUserLastname = user.lastname
100
+ let newProject_user = new Project_user({
101
+ id_project: id_project,
102
+ id_user: user._id,
103
+ role: req.body.role,
104
+ user_available: user_available,
105
+ createdBy: req.user.id,
106
+ updatedBy: req.user.id
107
+ })
164
108
 
165
- emailService.sendYouHaveBeenInvited(email, req.user.firstname, req.user.lastname, req.project.name, req.projectid, invitedUserFirstname, invitedUserLastname, req.body.role)
166
-
167
- // try {
168
- //test it
169
- savedProject_user.populate({path:'id_user', select:{'firstname':1, 'lastname':1}},function (err, savedProject_userPopulated){
170
- var pu = savedProject_userPopulated.toJSON();
171
- pu.isBusy = ProjectUserUtil.isBusy(savedProject_userPopulated, req.project.settings && req.project.settings.max_agent_assigned_chat);
172
-
173
-
174
- var eventData = {req:req, savedProject_userPopulated: pu};
175
- winston.debug("eventData",eventData);
176
- authEvent.emit('project_user.invite', eventData);
177
- });
178
- // } catch(e) {winston.error('Error emitting activity');}
179
-
180
- return res.json(savedProject_user);
109
+ newProject_user.save((err, savedProject_user) => {
110
+ if (err) {
111
+ winston.error("Error saving new project user: ", err)
112
+ return res.status(500).send({ success: false, msg: "An error occurred on inviting user " + email + " on project " + id_project })
113
+ }
181
114
 
182
-
183
- });
115
+ emailService.sendYouHaveBeenInvited(email, req.user.firstname, req.user.lastname, req.project.name, id_project, user.firstname, user.lastname, req.body.role)
116
+
117
+ savedProject_user.populate({path:'id_user', select:{'firstname':1, 'lastname':1}},function (err, savedProject_userPopulated){
118
+ var pu = savedProject_userPopulated.toJSON();
119
+ pu.isBusy = ProjectUserUtil.isBusy(savedProject_userPopulated, req.project.settings && req.project.settings.max_agent_assigned_chat);
120
+ var eventData = {req:req, savedProject_userPopulated: pu};
121
+ winston.debug("eventData",eventData);
122
+ authEvent.emit('project_user.invite', eventData);
123
+ });
184
124
 
125
+ return res.status(200).send(savedProject_user);
126
+ })
185
127
  }
186
128
  })
187
129
  }
@@ -264,7 +206,6 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
264
206
  });
265
207
  });
266
208
 
267
-
268
209
  router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('admin', ['subscription'])], function (req, res) {
269
210
 
270
211
  winston.debug("project_userid update", req.body);
@@ -334,23 +275,48 @@ router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
334
275
  });
335
276
  });
336
277
 
337
-
338
-
339
278
  // TODO fai servizio di patch degli attributi come request
340
279
  // TODO blocca cancellazione owner?
341
280
  router.delete('/:project_userid', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
342
281
 
282
+ const { hard, soft } = req.query;
283
+ const pu_id = req.params.project_userid;
284
+
343
285
  winston.debug(req.body);
344
-
345
- if (req.query.force === "true") {
346
286
 
347
- Project_user.findByIdAndRemove(req.params.project_userid, { new: false }, function (err, project_user) {
287
+ if (soft === "true") {
288
+ // Soft Delete
289
+ Project_user.findByIdAndUpdate(pu_id, { trashed: true }, { new: true }, (err, project_user) => {
348
290
  if (err) {
349
- winston.error("Error gettting project_user for delete", err);
350
- return res.status(500).send({ success: false, msg: 'Error deleting object.' });
291
+ winston.error("Error gettting project_user for soft delete", err);
292
+ return res.status(500).send({ success: false, msg: 'Error deleting Project User with id ' + pu_id });
351
293
  }
352
294
 
353
- winston.debug("Physically removed project_user", project_user);
295
+ winston.debug("Soft deleted project_user", project_user);
296
+ if (!project_user) {
297
+ winston.warn("Project user not found for soft delete with id " + pu_id);
298
+ return res.status(404).send({ success: false, error: 'Project user not found with id ' + pu_id });
299
+ }
300
+
301
+ // Event 'project_user.delete' not working - Check it and improve it to manage soft/hard delete
302
+ return res.status(200).send(project_user);
303
+
304
+ })
305
+ }
306
+ else if (hard === "true") {
307
+ // Hard Delete
308
+ Project_user.findByIdAndRemove(pu_id, { new: false }, (err, project_user) => {
309
+ if (err) {
310
+ winston.error("Error gettting project_user for hard delete", err);
311
+ return res.status(500).send({ success: false, msg: 'Error deleting Project user with id ' + pu_id });
312
+ }
313
+
314
+ if (!project_user) {
315
+ winston.warn("Project user not found for soft delete with id " + pu_id);
316
+ return res.status(404).send({ success: false, error: 'Project user not found with id ' + pu_id });
317
+ }
318
+
319
+ winston.debug("Hard deleted project_user", project_user);
354
320
 
355
321
  if (project_user) {
356
322
  project_user.populate({ path: 'id_user', select: { 'firstname': 1, 'lastname': 1 } }, function (err, project_userPopulated) {
@@ -358,25 +324,26 @@ router.delete('/:project_userid', [passport.authenticate(['basic', 'jwt'], { ses
358
324
  });
359
325
  }
360
326
 
361
- res.json(project_user);
327
+ return res.status(200).send(project_user);
362
328
  });
363
- } else {
364
-
365
- Project_user.findByIdAndUpdate(req.params.project_userid, { status: "disabled", user_available: false }, { new: true }, function (err, project_user) {
329
+ }
330
+ else {
331
+ // Disable
332
+ Project_user.findByIdAndUpdate(pu_id, { status: "disabled", user_available: false }, { new: true }, (err, project_user) => {
366
333
  if (err) {
367
- winston.error("Error gettting project_user for logical delete", err);
368
- return res.status(500).send({ success: false, msg: 'Error disabling object.' });
334
+ winston.error("Error gettting project_user for disable user", err);
335
+ return res.status(500).send({ success: false, msg: 'Error disabling Project User with id ' + pu_id });
369
336
  }
370
337
 
371
- winston.debug("Logically disabled project_user", project_user);
372
-
373
- if (project_user) {
374
- project_user.populate({ path: 'id_user', select: { 'firstname': 1, 'lastname': 1 } }, function (err, project_userPopulated) {
375
- authEvent.emit('project_user.delete', { req: req, project_userPopulated: project_userPopulated });
376
- });
338
+ if (!project_user) {
339
+ winston.warn("Project user not found for soft delete with id " + pu_id);
340
+ return res.status(404).send({ success: false, error: 'Project user not found with id ' + pu_id });
377
341
  }
378
342
 
379
- res.json(project_user);
343
+ winston.debug("Disabled project_user", project_user);
344
+
345
+ // Event 'project_user.delete' not working - Check it and improve it to manage disable project user
346
+ return res.status(200).send(project_user);
380
347
  }
381
348
  );
382
349
  }
@@ -403,7 +370,6 @@ router.get('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
403
370
 
404
371
  });
405
372
 
406
-
407
373
  router.get('/users/search', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('user', ['subscription'])], async (req, res, next) => { //changed for smtp
408
374
  // router.get('/users/search', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], async (req, res, next) => {
409
375
  winston.debug("--> users search ");
@@ -440,8 +406,6 @@ router.get('/users/search', [passport.authenticate(['basic', 'jwt'], { session:
440
406
  /**
441
407
  * GET PROJECT-USER BY PROJECT ID AND CURRENT USER ID
442
408
  // */
443
-
444
-
445
409
  router.get('/users/:user_id', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], function (req, res, next) {
446
410
  winston.debug("--> users USER ID ", req.params.user_id);
447
411
 
@@ -518,7 +482,7 @@ router.get('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
518
482
  }
519
483
  winston.debug("role", role);
520
484
 
521
- var query = { id_project: req.projectid, role: { $in : role } }; //, status: 'active'
485
+ var query = { id_project: req.projectid, role: { $in : role }, trashed: { $ne: true } };
522
486
 
523
487
  if (req.query.presencestatus) {
524
488
  query["presence.status"] = req.query.presencestatus;
package/test/kbRoute.js CHANGED
@@ -3,9 +3,9 @@ process.env.NODE_ENV = 'test';
3
3
  process.env.GPTKEY = "fakegptkey";
4
4
  process.env.LOG_LEVEL = 'critical'
5
5
  process.env.KB_WEBHOOK_TOKEN = "testtoken"
6
- process.env.PINECONE_INDEX = "test_index";
6
+ process.env.PINECONE_INDEX = "test-index";
7
7
  process.env.PINECONE_TYPE = "pod";
8
- process.env.PINECONE_INDEX_HYBRID = "test_index_hybrid";
8
+ process.env.PINECONE_INDEX_HYBRID = "test-index-hybrid";
9
9
  process.env.PINECONE_TYPE_HYBRID = "serverless";
10
10
  process.env.ADMIN_EMAIL = "admin@tiledesk.com";
11
11
 
@@ -69,7 +69,7 @@ describe('KbRoute', () => {
69
69
 
70
70
  res.should.have.status(200);
71
71
  expect(res.body.length).to.equal(1);
72
- expect(res.body[0].engine.index_name).to.equal('test_index')
72
+ expect(res.body[0].engine.index_name).to.equal('test-index')
73
73
 
74
74
  let namespace_id = res.body[0].id;
75
75
 
@@ -1149,7 +1149,7 @@ describe('KbRoute', () => {
1149
1149
  expect(res.body.name).to.equal('MyCustomNamespace');
1150
1150
  should.exist(res.body.engine)
1151
1151
  expect(res.body.engine.name).to.equal('pinecone');
1152
- expect(res.body.engine.type).to.equal('pod');
1152
+ expect(res.body.engine.type).to.equal('serverless');
1153
1153
 
1154
1154
  // Get again all namespace. A new default namespace should not be created.
1155
1155
  chai.request(server)