@tiledesk/tiledesk-server 2.10.3 → 2.10.4

Sign up to get free protection for your applications and to get access to all the features.
package/routes/images.js CHANGED
@@ -15,6 +15,9 @@ const sharp = require('sharp');
15
15
 
16
16
 
17
17
  const FileGridFsService = require('../services/fileGridFsService.js');
18
+ const faq_kb = require('../models/faq_kb');
19
+ const project_user = require('../models/project_user');
20
+ const roleConstants = require('../models/roleConstants');
18
21
 
19
22
  const fileService = new FileGridFsService("images");
20
23
 
@@ -173,27 +176,57 @@ curl -v -X PUT -u andrea.leo@f21.it:123456 \
173
176
  */
174
177
  router.put('/users/photo', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken],
175
178
  // bodymiddleware,
176
- uploadAvatar.single('file'), (req, res, next) => {
179
+ uploadAvatar.single('file'), async (req, res, next) => {
177
180
  try {
178
181
  winston.debug("/users/photo");
179
- // winston.info("req.query.folder1:"+req.body.folder);
180
-
181
- // var folder = req.folder || "error";
182
- // winston.info("folder:"+folder);
183
182
 
184
183
  if (req.upload_file_already_exists) {
185
184
  winston.warn('Error uploading photo image, file already exists',req.file.filename );
186
185
  return res.status(409).send({success: false, msg: 'Error uploading photo image, file already exists'});
187
186
  }
188
187
 
189
- var userid = req.user.id;
188
+ let userid = req.user.id;
189
+ let bot_id;
190
+ let entity_id = userid;
190
191
 
191
- if (req.query.user_id) {
192
- userid = req.query.user_id;
193
- }
192
+ // if (req.query.user_id) {
193
+ // userid = req.query.user_id;
194
+ // }
194
195
 
196
+ if (req.query.bot_id) {
197
+ bot_id = req.query.bot_id;
198
+
199
+ let chatbot = await faq_kb.findById(bot_id).catch((err) => {
200
+ winston.error("Error finding bot ", err);
201
+ res.status(500).send({ success: false, error: "Unable to find chatbot with id " + bot_id });
202
+ })
203
+
204
+ if (!chatbot) {
205
+ res.status(404).send({ success: false, error: "Chatbot not found" })
206
+ }
195
207
 
196
- var destinationFolder = 'uploads/users/' + userid + "/images/";
208
+ let id_project = chatbot.id_project;
209
+
210
+ let puser = await project_user.findOne({ id_user: userid, id_project: id_project }).catch((err) => {
211
+ winston.error("Error finding project user: ", err);
212
+ return res.status(500).send({ success: false, error: "Unable to find project user for user " + userid + "in project " + id_project });
213
+ })
214
+
215
+ if (!puser) {
216
+ winston.warn("User" + userid + "don't belongs the project " + id_project);
217
+ return res.status(401).send({ success: false, error: "You don't belong the chatbot's project" })
218
+ }
219
+
220
+ if ((puser.role !== roleConstants.ADMIN) && (puser.role !== roleConstants.OWNER)) {
221
+ winston.warn("User with role " + puser.role + "can't modify the chatbot");
222
+ return res.status(403).send({ success: false, error: "You don't have the role required to modify the chatbot" });
223
+ }
224
+
225
+ entity_id = bot_id;
226
+ }
227
+
228
+
229
+ var destinationFolder = 'uploads/users/' + entity_id + "/images/";
197
230
  winston.debug("destinationFolder:"+destinationFolder);
198
231
 
199
232
  var thumFilename = destinationFolder+'thumbnails_200_200-photo.jpg';
package/routes/request.js CHANGED
@@ -29,6 +29,7 @@ csv = require('csv-express');
29
29
  csv.separator = ';';
30
30
 
31
31
  const { check, validationResult } = require('express-validator');
32
+ const RoleConstants = require('../models/roleConstants');
32
33
 
33
34
  // var messageService = require('../services/messageService');
34
35
 
@@ -222,9 +223,9 @@ router.patch('/:requestid', function (req, res) {
222
223
  update.tags = req.body.tags;
223
224
  }
224
225
 
225
- if (req.body.notes) {
226
- update.notes = req.body.notes;
227
- }
226
+ // if (req.body.notes) {
227
+ // update.notes = req.body.notes;
228
+ // }
228
229
 
229
230
  if (req.body.rating) {
230
231
  update.rating = req.body.rating;
@@ -302,21 +303,39 @@ router.patch('/:requestid', function (req, res) {
302
303
 
303
304
 
304
305
  // TODO make a synchronous chat21 version (with query parameter?) with request.support_group.created
305
- router.put('/:requestid/close', function (req, res) {
306
+ router.put('/:requestid/close', async function (req, res) {
306
307
  winston.debug(req.body);
308
+ let request_id = req.params.requestid;
309
+ let user_role = req.projectuser.role;
307
310
 
308
311
  // closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
309
312
  const closed_by = req.user.id;
310
- return requestService.closeRequestByRequestId(req.params.requestid, req.projectid, false, true, closed_by, req.body.force).then(function (closedRequest) {
311
313
 
312
- winston.verbose("request closed", closedRequest);
314
+ if (user_role !== RoleConstants.OWNER && user_role !== RoleConstants.ADMIN) {
315
+ let request = await Request.findOne({ id_project: req.projectid, request_id: request_id }).catch((err) => {
316
+ winston.error("Error finding request: ", err);
317
+ return res.status(500).send({ success: false, error: "Error finding request with request_id " + request_id })
318
+ })
319
+
320
+ if (!request) {
321
+ winston.verbose("Request with request_id " + request_id)
322
+ return res.status(404).send({ success: false, error: "Request not found"})
323
+ }
324
+
325
+ if (!request.participantsAgents.includes(req.user.id)) {
326
+ winston.verbose("Request can't be closed by a non participant. Attempt made by " + req.user.id);
327
+ return res.status(403).send({ success: false, error: "You must be among the participants to close a conversation."})
328
+ }
329
+ }
330
+
313
331
 
332
+ return requestService.closeRequestByRequestId(req.params.requestid, req.projectid, false, true, closed_by, req.body.force).then(function (closedRequest) {
333
+ winston.verbose("request closed", closedRequest);
314
334
  return res.json(closedRequest);
315
-
316
335
  });
317
336
 
318
-
319
337
  });
338
+
320
339
  // TODO make a synchronous chat21 version (with query parameter?) with request.support_group.created
321
340
  router.put('/:requestid/reopen', function (req, res) {
322
341
  winston.debug(req.body);
@@ -609,14 +628,34 @@ router.patch('/:requestid/attributes', function (req, res) {
609
628
 
610
629
  });
611
630
 
612
- router.post('/:requestid/notes', function (req, res) {
631
+ router.post('/:requestid/notes', async function (req, res) {
632
+
633
+ let request_id = req.params.requestid
613
634
  var note = {};
614
635
  note.text = req.body.text;
615
- // note.id_project = req.projectid;
616
636
  note.createdBy = req.user.id;
617
637
 
618
- //cacheinvalidation
619
- return Request.findOneAndUpdate({ request_id: req.params.requestid, id_project: req.projectid }, { $push: { notes: note } }, { new: true, upsert: false })
638
+ let project_user = req.projectuser;
639
+
640
+ if (project_user.role === RoleConstants.AGENT) {
641
+ let request = await Request.findOne({ request_id: request_id }).catch((err) => {
642
+ winston.error("Error finding request ", err);
643
+ return res.status(500).send({ success: false, error: "Error finding request with id " + request_id });
644
+ })
645
+
646
+ if (!request) {
647
+ winston.warn("Request with id " + request_id + " not found.");
648
+ return res.status(404).send({ success: false, error: "Request with id " + request_id + " not found."});
649
+ }
650
+
651
+ // Check if the user is a participant
652
+ if (!request.participantsAgents.includes(req.user.id)) {
653
+ winston.verbose("Trying to add a note from a non participating agent");
654
+ return res.status(403).send({ success: false, error: "You are not participating in the conversation"})
655
+ }
656
+ }
657
+
658
+ return Request.findOneAndUpdate({ request_id: request_id, id_project: req.projectid }, { $push: { notes: note } }, { new: true, upsert: false })
620
659
  .populate('lead')
621
660
  .populate('department')
622
661
  .populate('participatingBots')
@@ -638,10 +677,32 @@ router.post('/:requestid/notes', function (req, res) {
638
677
  });
639
678
 
640
679
 
641
- router.delete('/:requestid/notes/:noteid', function (req, res) {
680
+ router.delete('/:requestid/notes/:noteid', async function (req, res) {
681
+
682
+ let request_id = req.params.requestid
683
+ let note_id = req.params.noteid;
684
+ let project_user = req.projectuser;
685
+
686
+ if (project_user.role === RoleConstants.AGENT) {
687
+ let request = await Request.findOne({ request_id: request_id }).catch((err) => {
688
+ winston.error("Error finding request ", err);
689
+ return res.status(500).send({ success: false, error: "Error finding request with id " + request_id });
690
+ })
691
+
692
+ if (!request) {
693
+ winston.warn("Request with id " + request_id + " not found.");
694
+ return res.status(404).send({ success: false, error: "Request with id " + request_id + " not found."});
695
+ }
696
+
697
+ // Check if the user is a participant
698
+ if (!request.participantsAgents.includes(req.user.id)) {
699
+ winston.verbose("Trying to delete a note from a non participating agent");
700
+ return res.status(403).send({ success: false, error: "You are not participating in the conversation"})
701
+ }
702
+ }
642
703
 
643
704
  //cacheinvalidation
644
- return Request.findOneAndUpdate({ request_id: req.params.requestid, id_project: req.projectid }, { $pull: { notes: { "_id": req.params.noteid } } }, { new: true, upsert: false })
705
+ return Request.findOneAndUpdate({ request_id: request_id, id_project: req.projectid }, { $pull: { notes: { "_id": note_id } } }, { new: true, upsert: false })
645
706
  .populate('lead')
646
707
  .populate('department')
647
708
  .populate('participatingBots')
@@ -903,7 +964,7 @@ router.get('/', function (req, res, next) {
903
964
  skip = page * limit;
904
965
 
905
966
  // Default query
906
- var query = { "id_project": req.projectid, "status": { $lt: 1000, $ne: 150 }, preflight: false };
967
+ var query = { "id_project": req.projectid, "status": { $lt: 1000, $nin: [50, 150] }, preflight: false };
907
968
 
908
969
  if (req.user instanceof Subscription) {
909
970
  // All request
package/routes/users.js CHANGED
@@ -6,6 +6,7 @@ var emailService = require("../services/emailService");
6
6
  var winston = require('../config/winston');
7
7
  const authEvent = require('../event/authEvent');
8
8
  const uuidv4 = require('uuid/v4');
9
+ var uniqid = require('uniqid');
9
10
 
10
11
  router.put('/', function (req, res) {
11
12
 
@@ -131,6 +132,16 @@ router.put('/changepsw', function (req, res) {
131
132
  winston.debug('* THE PSW MATCH CURRENT PSW * PROCEED WITH THE UPDATE')
132
133
  winston.debug('CHANGE PSW - NEW PSW: ', req.body.newpsw);
133
134
 
135
+ if (req.body.newpsw === req.body.oldpsw) {
136
+ winston.warn("New password can't match the old one");
137
+ return res.status(403).send({ success: false, message: "The new password must be different from the previous one."})
138
+ }
139
+
140
+ const regex = new RegExp(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,}$/);
141
+ if (!regex.test(req.body.newpsw)) {
142
+ return res.status(403).send({ success: false, message: "The password does not meet the minimum vulnerability requirements"})
143
+ }
144
+
134
145
  user.password = req.body.newpsw
135
146
 
136
147
  user.save(function (err, saveUser) {
@@ -157,9 +168,17 @@ router.put('/changepsw', function (req, res) {
157
168
 
158
169
  router.get('/resendverifyemail', function (req, res) {
159
170
  winston.debug('RE-SEND VERIFY EMAIL - LOGGED USER ', req.user);
171
+ console.log("resendverifyemail req.user", req.user)
172
+ let user = req.user;
160
173
  try {
161
174
  // TODO req.user.email is null for bot visitor
162
- emailService.sendVerifyEmailAddress(req.user.email, req.user);
175
+ let verify_email_code = uniqid();
176
+ let redis_client = req.app.get('redis_client');
177
+ let key = "emailverify:verify-" + verify_email_code;
178
+ let obj = { _id: user._id, email: user.email}
179
+ let value = JSON.stringify(obj);
180
+ redis_client.set(key, value, { EX: 900} )
181
+ emailService.sendVerifyEmailAddress(user.email, user, verify_email_code);
163
182
  res.status(200).json({ success: true, message: 'Verify email successfully sent' });
164
183
  } catch (e) {
165
184
  winston.debug("RE-SEND VERIFY EMAIL error", e);
@@ -1685,7 +1685,7 @@ class EmailService {
1685
1685
  }
1686
1686
 
1687
1687
  // ok
1688
- async sendVerifyEmailAddress(to, savedUser) {
1688
+ async sendVerifyEmailAddress(to, savedUser, code) {
1689
1689
 
1690
1690
 
1691
1691
  var that = this;
@@ -1705,7 +1705,8 @@ class EmailService {
1705
1705
 
1706
1706
  var replacements = {
1707
1707
  savedUser: savedUser,
1708
- baseScope: baseScope
1708
+ baseScope: baseScope,
1709
+ code: code
1709
1710
  };
1710
1711
 
1711
1712
  var html = template(replacements);
@@ -2828,7 +2828,7 @@ class RequestService {
2828
2828
 
2829
2829
  async getConversationsCount(id_project, status, preflight, hasBot, startDate, endDate) {
2830
2830
  return new Promise( async (resolve, reject) => {
2831
- let query = { id_project: id_project, status: status, preflight: preflight};
2831
+ let query = { id_project: id_project, status: status, preflight: preflight, draft: { $in: [false, null] }};
2832
2832
  if (hasBot != null) {
2833
2833
  query.hasBot = hasBot;
2834
2834
  }
@@ -160,7 +160,7 @@
160
160
  <!-- <br> welcome on Tiledesk.com. -->
161
161
  <br><br> Thank you for signin up with Tiledesk.
162
162
  <br><br> To complete the setup, <span><a
163
- href="{{baseScope.baseUrl}}/#/verify/email/{{savedUser._id}}"> click here to verify your email
163
+ href="{{baseScope.baseUrl}}/#/verify/email/{{savedUser._id}}/{{code}}"> click here to verify your email
164
164
  address. </a> </span>
165
165
  <br><br>Give us your feedback! We need your advice. Send an email to <a
166
166
  href="mailto:info@tiledesk.com">info@tiledesk.com</a>
@@ -186,12 +186,12 @@ describe('/signup', () => {
186
186
  // this.timeout();
187
187
 
188
188
  var email = "test-signuook-" + Date.now() + "@email.com";
189
- var pwd = "pwd";
189
+ var pwd = "Pwd1234!";
190
190
 
191
191
 
192
192
  chai.request(server)
193
193
  .post('/auth/signup' )
194
- .send({email:email, password:pwd, lastname:"lastname", firstname: "firstname", disableEmail: true})
194
+ .send({email:email, password:pwd, lastname:"lastname", firstname: "firstname", disableEmail: true}) // whi disableEmail true?
195
195
  .end((err, res) => {
196
196
  //console.log("res", res);
197
197
  console.log("res.body", res.body);
@@ -208,6 +208,28 @@ describe('/signup', () => {
208
208
 
209
209
  });
210
210
 
211
+
212
+ // it('verifyemail', (done) => {
213
+
214
+ // let user_id = "670e55c8187b430e793d644e";
215
+ // let code = "4fx6e1hfcm2admb4a";
216
+ // chai.request(server)
217
+ // .put('/auth/verifyemail/' + user_id + '/' + code)
218
+ // .send({ emailVerified: true })
219
+ // .end((err, res) => {
220
+
221
+ // console.error("err: ", err)
222
+ // console.log("res.body: ", res.body)
223
+ // done();
224
+ // })
225
+
226
+
227
+
228
+ // });
229
+
230
+
231
+
232
+
211
233
  // it('signUpAdminNoVerificationEmail', (done) => {
212
234
 
213
235
  // var email = "test-signup-" + Date.now() + "@email.com";
@@ -244,7 +266,7 @@ describe('/signup', () => {
244
266
  // this.timeout();
245
267
  var now = Date.now();
246
268
  var email = "test-signupUpperCaseEmail-" + now + "@email.com";
247
- var pwd = "pwd";
269
+ var pwd = "Pwd1234!";
248
270
 
249
271
 
250
272
  chai.request(server)
@@ -272,7 +294,7 @@ describe('/signup', () => {
272
294
  // this.timeout();
273
295
 
274
296
  var email = "test-signuoOk-" + Date.now() + "@email";
275
- var pwd = "pwd";
297
+ var pwd = "Pwd1234!";
276
298
 
277
299
 
278
300
  chai.request(server)
@@ -32,7 +32,7 @@ describe('Authorization', () => {
32
32
  // this.timeout();
33
33
 
34
34
  var email = "test-signup-" + Date.now() + "@email.com";
35
- var pwd = "pwd";
35
+ var pwd = "Pwd1234!";
36
36
 
37
37
  userService.signup( email ,pwd, "Test Firstname", "Test lastname").then(function(savedUser) {
38
38
  projectService.createAndReturnProjectAndProjectUser("test-auth", savedUser._id).then(function(savedProjectAndPU) {
@@ -7,7 +7,7 @@ var userService = require('../services/userService');
7
7
  var faqService = require('../services/faqService');
8
8
 
9
9
  let chatbot_mock = require('./chatbot-mock');
10
- let log = true;
10
+ let log = false;
11
11
 
12
12
 
13
13
  //Require the dev-dependencies
@@ -17,6 +17,8 @@ let server = require('../app');
17
17
  let should = chai.should();
18
18
  var fs = require('fs');
19
19
  const path = require('path');
20
+ const Project_user = require('../models/project_user');
21
+ const roleConstants = require('../models/roleConstants');
20
22
 
21
23
  // chai.config.includeStack = true;
22
24
 
@@ -29,12 +31,80 @@ describe('FaqKBRoute', () => {
29
31
 
30
32
  describe('/create', () => {
31
33
 
34
+ it('create-new-chatbot', (done) => {
32
35
 
36
+ var email = "test-signup-" + Date.now() + "@email.com";
37
+ var pwd = "pwd";
33
38
 
34
- it('create', (done) => {
39
+ userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
40
+ projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
41
+
42
+ chai.request(server)
43
+ .post('/' + savedProject._id + '/faq_kb')
44
+ .auth(email, pwd)
45
+ .send({ "name": "testbot", type: "external", language: 'fr' })
46
+ .end((err, res) => {
35
47
 
48
+ if (err) { console.error("err: ", err); }
49
+ if (log) { console.log("res.body", res.body); }
36
50
 
37
- // this.timeout();
51
+ res.should.have.status(200);
52
+ res.body.should.be.a('object');
53
+ expect(res.body.name).to.equal("testbot");
54
+ expect(res.body.language).to.equal("fr");
55
+
56
+ chai.request(server)
57
+ .get('/' + savedProject._id + '/faq_kb/' + res.body._id)
58
+ .auth(email, pwd)
59
+ .end((err, res) => {
60
+
61
+ if (err) { console.error("err: ", err); }
62
+ if (log) { console.log("res.body", res.body); }
63
+
64
+ res.should.have.status(200);
65
+
66
+ done();
67
+
68
+ });
69
+ });
70
+ });
71
+ });
72
+
73
+ })
74
+
75
+ it('create-new-chatbot-agent-role', (done) => {
76
+
77
+ var email = "test-signup-" + Date.now() + "@email.com";
78
+ var pwd = "pwd";
79
+
80
+ userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
81
+ projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
82
+ Project_user.findOneAndUpdate({ id_project: savedProject._id, id_user: savedUser._id }, { role: roleConstants.AGENT }, (err, savedProject_user) => {
83
+
84
+ chai.request(server)
85
+ .post('/' + savedProject._id + '/faq_kb')
86
+ .auth(email, pwd)
87
+ .send({ "name": "testbot", type: "external", language: 'fr' })
88
+ .end((err, res) => {
89
+
90
+ if (err) { console.error("err: ", err); }
91
+ if (log) { console.log("res.body", res.body); }
92
+
93
+ res.should.have.status(403);
94
+ expect(res.body.success).to.equal(false);
95
+ expect(res.body.msg).to.equal("you dont have the required role.");
96
+
97
+ done();
98
+
99
+ });
100
+ })
101
+ });
102
+ });
103
+
104
+ })
105
+
106
+
107
+ it('get-all-chatbot-with-role-admin-or-owner', (done) => {
38
108
 
39
109
  var email = "test-signup-" + Date.now() + "@email.com";
40
110
  var pwd = "pwd";
@@ -46,21 +116,23 @@ describe('FaqKBRoute', () => {
46
116
  .auth(email, pwd)
47
117
  .send({ "name": "testbot", type: "external", language: 'fr' })
48
118
  .end((err, res) => {
49
- if (log) {
50
- console.log("res.body", res.body);
51
- }
119
+
120
+ if (err) { console.error("err: ", err); }
121
+ if (log) { console.log("res.body", res.body); }
122
+
52
123
  res.should.have.status(200);
53
124
  res.body.should.be.a('object');
54
125
  expect(res.body.name).to.equal("testbot");
55
126
  expect(res.body.language).to.equal("fr");
56
127
 
57
128
  chai.request(server)
58
- .get('/' + savedProject._id + '/faq_kb/' + res.body._id)
129
+ .get('/' + savedProject._id + '/faq_kb')
59
130
  .auth(email, pwd)
60
131
  .end((err, res) => {
61
- if (log) {
62
- console.log("res.body", res.body);
63
- }
132
+
133
+ if (err) { console.error("err: ", err); }
134
+ if (log) { console.log("res.body", res.body); }
135
+
64
136
  res.should.have.status(200);
65
137
 
66
138
  done();
@@ -73,6 +145,50 @@ describe('FaqKBRoute', () => {
73
145
 
74
146
  }).timeout(20000);
75
147
 
148
+ it('get-all-chatbot-with-role-agent', (done) => {
149
+
150
+ var email = "test-signup-" + Date.now() + "@email.com";
151
+ var pwd = "pwd";
152
+
153
+ userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
154
+ projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
155
+ chai.request(server)
156
+ .post('/' + savedProject._id + '/faq_kb')
157
+ .auth(email, pwd)
158
+ .send({ "name": "testbot", type: "external", language: 'fr' })
159
+ .end((err, res) => {
160
+
161
+ if (err) { console.error("err: ", err); }
162
+ if (log) { console.log("res.body", res.body); }
163
+
164
+ res.should.have.status(200);
165
+ res.body.should.be.a('object');
166
+ expect(res.body.name).to.equal("testbot");
167
+ expect(res.body.language).to.equal("fr");
168
+
169
+ Project_user.findOneAndUpdate({ id_project: savedProject._id, id_user: savedUser._id }, { role: roleConstants.AGENT }, (err, savedProject_user) => {
170
+ chai.request(server)
171
+ .get('/' + savedProject._id + '/faq_kb')
172
+ .auth(email, pwd)
173
+ .end((err, res) => {
174
+
175
+ if (err) { console.error("err: ", err); }
176
+ if (log) { console.log("res.body", res.body); }
177
+ console.log("res.body", res.body);
178
+ res.should.have.status(200);
179
+
180
+ done();
181
+ });
182
+ })
183
+
184
+ });
185
+
186
+
187
+ });
188
+ });
189
+
190
+ }).timeout(20000);
191
+
76
192
  /**
77
193
  * This test will be no longer available after merge with master because
78
194
  * the profile section can no longer be modified via api.
@@ -85,6 +85,56 @@ describe('RequestRoute', () => {
85
85
  });
86
86
  });
87
87
 
88
+ it('create-simple-new-note', function (done) {
89
+ // this.timeout(10000);
90
+
91
+ var email = "test-request-create-" + Date.now() + "@email.com";
92
+ var pwd = "pwd";
93
+
94
+ userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
95
+ projectService.create("request-create", savedUser._id, { email: { template: { assignedRequest: "123" } } }).then(function (savedProject) {
96
+
97
+
98
+ chai.request(server)
99
+ .post('/' + savedProject._id + '/requests/')
100
+ .auth(email, pwd)
101
+ .set('content-type', 'application/json')
102
+ .send({ "first_text": "first_text" })
103
+ .end(function (err, res) {
104
+
105
+ if (err) { console.error("err: ", err); }
106
+ if (log) { console.log("res.body", res.body); }
107
+
108
+ res.should.have.status(200);
109
+ res.body.should.be.a('object');
110
+
111
+ let request_id = res.body.request_id;
112
+ chai.request(server)
113
+ .post('/' + savedProject._id + '/requests/' + request_id + "/notes")
114
+ .auth(email, pwd)
115
+ .send({ text: "test note 1"})
116
+ .end((err, res) => {
117
+
118
+ if (err) { console.error("err: ", err); }
119
+ if (log) { console.log("res.body", res.body); }
120
+
121
+ res.should.have.status(200);
122
+ res.body.should.be.a('object');
123
+ expect(res.body.notes.length).to.equal(1);
124
+ expect(res.body.notes[0].text).to.equal("test note 1");
125
+ expect(res.body.notes[0].createdBy).to.equal(savedUser._id.toString());
126
+
127
+ done();
128
+ // Project_user.findOneAndUpdate({id_project: savedProject._id, id_user: savedUser._id }, { role: RoleConstants.AGENT }, function(err, savedProject_user){
129
+ // done();
130
+ // })
131
+ })
132
+
133
+ });
134
+ });
135
+ });
136
+ });
137
+
88
138
 
89
139
  it('createSimpleAndCloseForDuration', function (done) {
90
140
  // this.timeout(10000);