socketioMEANseed/server/controllers/userController.js
server/controllers/userController.jsRaw
1var express = require('express');
2var app = express();
3var router = express.Router();
4var jwt = require('jsonwebtoken');
5var config = require('../config/config');
6var crypto = require('crypto');
7var formidable = require('formidable');
8var fs = require('fs');
9var https = require('https');
10app.set('superSecret', config.secret);
11
12/*******MODELS*********/
13var publicationModel = require('../models/publicationModel');
14var userModel = require('../models/userModel');
15var dietModel = require('../models/dietModel');
16var routineModel = require('../models/routineModel');
17
18
19/** POST '/users/register' **/
20exports.register = function (req, res) {
21 console.log(req.body);
22 var user = new userModel({
23 name: req.body.name,
24 role: req.body.role,
25 password: crypto.createHash('sha256').update(req.body.password).digest('base64'),
26 email: req.body.email,
27 description: "Hi, i'm here to train.",
28 avatar: 'img/user.png',
29 background: 'img/background.png',
30 attributes: {
31 height: req.body.height,
32 weight: req.body.weight,
33 gender: req.body.gender,
34 age: req.body.age
35 },
36 points: {
37 total: 0
38 }
39 });
40 /* gamification */
41 var reward = {
42 concept: "account created",
43 date: Date(),
44 value: +1
45 };
46 user.points.history.push(reward);
47 user.points.total = user.points.total + 1;
48 /* end of gamification */
49 /*notification*/
50 var notification = {
51 state: "pendent",
52 message: "Wellcome! this is your profile, update the Profile picture to let other members recognize you",
53 link: "editUser/" + user._id,
54 icon: "newpetition.png",
55 date: Date()
56 };
57 user.notifications.push(notification);
58 /* end of notification*/
59 user.save(function (err, user) {
60 if (err) {
61 console.log(err.message);
62 return res.status(500).send(err.message);
63 }
64 //res.status(200).jsonp(user); en comptes de retoranr la data del signup, fem el login directament
65 console.log("signup fet correctament, redirigint al login internament automàtic");
66 exports.login(req, res);
67 });
68};
69
70var SECRET = "6LcyxhIUAAAAAPkCdz5HoBPN5--RhP7mpIE-V2CL";
71
72function verifyRecaptcha(key, callback) {
73 https.get("https://www.google.com/recaptcha/api/siteverify?secret=" + SECRET + "&response=" + key, function(res) {
74 var data = "";
75 res.on('data', function (chunk) {
76 data += chunk.toString();
77 });
78 res.on('end', function() {
79 try {
80 var parsedData = JSON.parse(data);
81 callback(parsedData.success);
82 } catch (e) {
83 callback(false);
84 }
85 });
86 });
87}
88
89/** POST '/users/login' **/
90exports.login = function (req, res) {
91 verifyRecaptcha(req.body["g-recaptcha-response"], function() {
92 userModel.findOne({
93 email: req.body.email
94 })
95 .select('+password')
96 .exec(function (err, user) {
97 if (err) throw err;
98 if (!user) {
99 res.json({success: false, message: 'Authentication failed. User not found.'});
100 } else if (user) {
101 req.body.password = crypto.createHash('sha256').update(req.body.password).digest('base64');
102 if (user.password != req.body.password) {
103 res.json({success: false, message: 'Authentication failed. Wrong password.'});
104 } else {
105 var indexToken = -1;
106 for (var i = 0; i < user.tokens.length; i++) {
107 if (user.tokens[i].userAgent == req.body.userAgent) {
108 indexToken = JSON.parse(JSON.stringify(i));//stringify i parse pq es faci una còpia de la variable i, enlloc de una referència
109 }
110 }
111 console.log(indexToken);
112 if (indexToken == -1) {//userAgent no exist
113 var tokenGenerated = jwt.sign({foo: 'bar'}, app.get('superSecret'), {
114 // expiresIn: 86400 // expires in 24 hours
115 });
116 var newToken = {
117 userAgent: req.body.userAgent,
118 token: tokenGenerated,
119 os: req.body.os,
120 browser: req.body.browser,
121 device: req.body.device,
122 os_version: req.body.os_version,
123 browser_version: req.body.browser_version,
124 ip: req.body.ip,
125 lastLogin: Date()
126 };
127 user.tokens.push(newToken);
128 } else {//userAgent already exist
129 user.tokens[indexToken].token = "";
130 var tokenGenerated = jwt.sign({foo: 'bar'}, app.get('superSecret'), {
131 // expiresIn: 86400 // expires in 24 hours
132 });
133 user.tokens[indexToken].token = tokenGenerated;
134 user.tokens[indexToken].ip = req.body.ip;
135 user.tokens[indexToken].lastLogin = Date();
136 }
137 user.save(function (err, user) {
138 if (err) return res.send(500, err.message);
139 // return the information including token as JSON
140 user.password = "";
141 res.json({
142 user: user,
143 success: true,
144 message: 'Enjoy your token!',
145 token: tokenGenerated
146 });
147 });
148 }
149 }
150 });
151})};
152
153/** POST '/logout' **/
154exports.logout = function (req, res, callback) {
155 var token = req.headers.authorization;
156 var decoded = verify(token);
157 if (decoded) {
158 db.get(decoded.auth, function (err, record) {
159 if (err) throw err;
160 var updated = JSON.parse(record);
161 updated.valid = false;
162 db.put(decoded.auth, updated, function (err) {
163 if (err) throw err;
164 res.writeHead(200, {'content-type': 'text/plain'});
165 res.end('Logged Out!');
166 return callback(res);
167 });
168 });
169 } else {
170 authFail(res, done);
171 return callback(res);
172 }
173};
174
175/*** Building a File Uploader with NodeJs
176 * https://coligo.io/building-ajax-file-uploader-with-node/
177 */
178/** POST '/users/upload' **/
179exports.avatarUpload = function (req, res) {/* no sé si s'ha provat si funciona, per ara almenys no està linkat ni es fa servir */
180 // create an incoming form object
181 var form = new formidable.IncomingForm();
182 // specify that we want to allow the user to upload multiple files in a single request
183 form.multiples = true;
184 // store all uploads in the /uploads directory
185 form.uploadDir = path.join(__dirname, '/uploads');
186 // every time a file has been uploaded successfully,
187 // rename it to it's orignal name
188 form.on('file', function (field, file) {
189 fs.rename(file.path, path.join(form.uploadDir, file.name));
190 });
191 // log any errors that occur
192 form.on('error', function (err) {
193 console.log('An error has occured: \n' + err);
194 });
195 // once all the files have been uploaded, send a response to the client
196 form.on('end', function () {
197 res.end('success');
198 });
199 // parse the incoming request containing the form data
200 form.parse(req);
201};
202
203/** PUT '/users/:userid' **/
204exports.updateUser = function (req, res) {//funciona
205 var id = req.params.userid;
206 var user = req.body;
207 userModel.update({'tokens.token': req.headers['x-access-token']}, user,
208 function (err) {
209 if (err) return console.log(err);
210 console.log(user);
211 res.status(200).jsonp(user);
212 });
213};
214
215/** DELETE '/users/:userid' **/
216exports.deleteUserById = function (req, res) {
217 userModel.findByIdAndRemove({_id: req.params.userid}, function (err) {
218 if (err) return res.send(500, err.message);
219 res.status(200).send("Deleted");
220 });
221};
222
223/** GET '/users/' **/
224exports.getUsers = function (req, res) {
225 userModel.find({role: 'user'})
226 .limit(Number(req.query.pageSize))
227 .skip(Number(req.query.pageSize) * Number(req.query.page))
228 .exec(function (err, users) {
229 if (err) return res.send(500, err.message);
230 res.status(200).jsonp(users);
231 });
232};
233
234/** GET '/users/:userid' **/
235exports.getUserById = function (req, res) {
236 userModel.findOne({_id: req.params.userid})
237 .lean()
238 .populate('diets', 'title description')
239 .populate('routines', 'title description')
240 .populate('trainers', 'name avatar description disciplines')
241 .populate('clients.client', 'name avatar')
242 .populate('publications')
243 .exec(function (err, user) {
244 if (err) return res.send(500, err.message);
245 if (!user) {
246 res.json({success: false, message: 'User not found.'});
247 } else if (user) {
248 /* aquí va el carro de bucle per acabar retornant només les peticions pendents */
249 var pendentNumber=0;
250 for (var i = 0; i < user.notifications.length; i++) {
251 if (user.notifications[i].state == "pendent") {
252 pendentNumber++;
253 }
254 }
255 user.pendentNotificationsNumber=pendentNumber;
256 /* fi del carro de bucle de peticions pendents */
257 res.status(200).jsonp(user);
258 }
259 });
260};
261exports.getUserByToken = function (req, res) {
262 console.log(req.params.tok);
263 userModel.findOne({'tokens.token': req.params.tok})
264 .lean()
265 .populate('diets', 'title description')
266 .populate('routines', 'title description')
267 .populate('trainers', 'name avatar description disciplines')
268 .populate('clients.client', 'name avatar')
269 .populate('publications')
270 .exec(function (err, user) {
271 if (err) return res.send(500, err.message);
272 if (!user) {
273 res.json({success: false, message: 'User not found.'});
274 } else if (user) {
275 /* aquí va el carro de bucle per acabar retornant només les peticions pendents */
276 var pendentNumber=0;
277 for (var i = 0; i < user.notifications.length; i++) {
278 if (user.notifications[i].state == "pendent") {
279 pendentNumber++;
280 }
281 }
282 user.pendentNotificationsNumber=pendentNumber;
283 /* fi del carro de bucle de peticions pendents */
284 res.status(200).jsonp(user);
285 }
286 });
287};
288
289/** GET '/users/:userid/network' **/
290exports.getUserNetworkById = function (req, res) {
291 userModel.findOne({_id: req.params.userid})
292 .lean()
293 .populate('followers', 'name avatar description')
294 .populate('following', 'name avatar description')
295 .exec(function (err, user) {
296 if (err) return res.send(500, err.message);
297 res.status(200).jsonp(user);
298 });
299};
300
301/** GET '/users/:userid/suggestions' **/
302exports.getUserSuggestionsById = function (req, res) {
303 userModel.findOne({'tokens.token': req.headers['x-access-token']})
304 .exec(function (err, user) {
305 if (err) return res.send(500, err.message);
306
307 userModel.find({
308 $and: [
309 {_id: { $nin: user._id}},
310 {_id: { $nin: user.following}}
311 ],
312 city: user.city})
313 .limit(Number(req.query.pageSize))
314 .skip(Number(req.query.pageSize) * Number(req.query.page))
315 .select('name role email description avatar')
316 .exec(function (err, users) {
317 if (err) return res.send(500, err.message);
318 console.log(users);
319 if (users.length>0) {
320 res.status(200).jsonp(users);
321 } else {
322 //si no té users a la ciutat, li tornem users igualment (tot i no ser de la mateixa ciutat)
323 userModel.find({
324 $and: [
325 {_id: { $nin: user._id}},
326 {_id: { $nin: user.following}}
327 ]})
328 .limit(Number(req.query.pageSize))
329 .skip(Number(req.query.pageSize) * Number(req.query.page))
330 .select('name role email description avatar')
331 .exec(function (err, users) {
332 res.status(200).jsonp(users);
333 });
334 }
335 });
336 });
337};
338
339/** GET '/users/:userid/diets' **/
340exports.getDietsFromUserId = function (req, res) {
341 userModel.findOne({_id: req.params.userid})
342 .populate('diets')
343 .exec(function (err, user) {
344 if (err) return res.send(500, err.message);
345 res.status(200).jsonp(user.diets);
346 });
347};
348
349/** GET '/users/:userid/routines' **/
350exports.getRoutinesFromUserId = function (req, res) {
351 userModel.findOne({_id: req.params.userid})
352 .populate('routines')
353 .exec(function (err, user) {
354 if (err) return res.send(500, err.message);
355 res.status(200).jsonp(user.routines);
356 });
357};
358
359/** POST '/users/sendPetitionToTrainer/:trainerid' **/
360exports.sendPetitionToTrainer = function (req, res) {
361 userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) {
362 if (err) return res.send(500, err.message);
363 if (!user) {
364 res.json({success: false, message: 'sending petition failed. user not found.'});
365 } else if (user) {
366 console.log(user.name);//aquí potser caldria comprovar que la routine és la que han creat per l'user
367 //ara busquem el trainer
368 userModel.findOne({_id: req.params.trainerid}, function (err, trainer) {
369 if (err) return res.send(500, err.message);
370 if (!trainer) {
371 res.json({success: false, message: 'sending petition failed. trainer not found.'});
372 } else if (trainer) {
373 var newPetition = {
374 clientid: user._id,
375 message: req.body.message,
376 state: "pendent"
377 };
378 trainer.clientsPetitions.push(newPetition);
379 /*notification*/
380 var notification = {
381 state: "pendent",
382 message: "client has sent a petition to you",
383 link: "dashboard",
384 icon: "newpetition.png",
385 date: Date()
386 };
387 trainer.notifications.push(notification);
388 /* end of notification*/
389 trainer.save(function (err) {
390 if (err) return res.send(500, err.message);
391 res.status(200).jsonp(trainer);
392 });
393 }//end else if
394 });
395 }//end else if
396 });
397};
398
399exports.getNumberOfNotifications = function (req, res) {
400 userModel.findOne({'tokens.token': req.headers['x-access-token']})
401 .exec(function (err, user) {
402 if (err) return res.send(500, err.message);
403 if (!user) {
404 res.json({success: false, message: 'User not found.'});
405 } else if (user) {
406 /* aquí va el carro de bucle per acabar retornant només les peticions pendents */
407 var pendentNumber=0;
408 for (var i = 0; i < user.notifications.length; i++) {
409 if (user.notifications[i].state == "pendent") {
410 pendentNumber++;
411 }
412 }
413 /* fi del carro de bucle de peticions pendents */
414 res.status(200).jsonp(pendentNumber);
415 }
416 });
417};
418
419/** GET '/users/:userid/getNotifications' **/
420exports.getNotifications = function (req, res) {
421 userModel.findOne({'tokens.token': req.headers['x-access-token']})
422 .exec(function (err, user) {
423 if (err) return res.send(500, err.message);
424 if (!user) {
425 res.json({success: false, message: 'User not found.'});
426 } else if (user) {
427 var viewed=[];
428 var pendent=[];
429 for (var i = 0; i < user.notifications.length; i++) {
430 if (user.notifications[i].state == "pendent") {
431 pendent.push(user.notifications[i]);
432 user.notifications[i].state = "viewed";
433 user.notifications[i].dateviewed = Date();
434 }else{
435 viewed.push(user.notifications[i]);
436 }
437 }
438 user.save(function (err) {
439 if (err) return res.send(500, err.message);
440 res.status(200).jsonp({
441 pendent: pendent,
442 viewed: viewed
443 });
444 });
445 }
446 });
447};
448
449/** POST '/users/:userid/deleteSelectedTokens' **/
450exports.deleteSelectedTokens = function (req, res) {
451 userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) {
452 if (err) return res.send(500, err.message);
453 if (!user) {
454 res.json({success: false, message: 'user not found.'});
455 } else if (user) {
456 console.log(user);
457 for (var i = 0; i < req.body.devicesToDelete.length; i++) {
458 for (var j = 0; j < user.tokens.length; j++) {
459 if (user.tokens[j].userAgent == req.body.devicesToDelete[i].userAgent) {
460 user.tokens.splice(j, 1);
461 }
462 }
463 }
464 user.save(function (err) {
465 if (err) return res.send(500, err.message);
466 res.status(200).jsonp(user);
467 });
468 }//end else if
469 });
470};
471
472/**
473 userA: el que fa l'acció de seguir --> se li posa userB a following
474 userB: el que reb el seguiment --> se li posa el userA al followers
475 **/
476/** POST '/users/follow' **/
477exports.follow = function (req, res) {
478 userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, userA) {
479 if (err) return res.send(500, err.message);
480 if (!userA) {
481 res.json({success: false, message: 'userA not found.'});
482 } else if (userA) {
483 //ara busquem el userB
484 userModel.findOne({_id: req.body.userid}, function (err, userB) {
485 if (err) return res.send(500, err.message);
486 if (!userB) {
487 res.json({success: false, message: 'userB not found.'});
488 } else if (userB) {
489 userB.followers.push(userA._id);
490 /*notification*/
491 var notification = {
492 state: "pendent",
493 message: userA.name + " followed you",
494 link: "dashboard",
495 icon: "follower.png",
496 date: Date()
497 };
498 userB.notifications.push(notification);
499 /* end of notification*/
500 /* gamification */
501 var reward = {
502 concept: userA.name + " followed you",
503 date: Date(),
504 value: +1
505 };
506 userB.points.history.push(reward);
507 userB.points.total = userB.points.total + 1;
508 /* end of gamification */
509 userB.save(function (err) {
510 if (err) return res.send(500, err.message);
511 userA.following.push(userB._id);
512 /* gamification */
513 var reward = {
514 concept: "followed " + userB.name,
515 date: Date(),
516 value: +1
517 };
518 userA.points.history.push(reward);
519 userA.points.total = userA.points.total + 1;
520 /* end of gamification */
521 userA.save(function (err) {
522 if (err) return res.send(500, err.message);
523 userModel.findOne({_id: userA._id}).lean().populate('following', 'name avatar')
524 .exec(function (err, userA) {
525 if (err) return res.send(500, err.message);
526 console.log("user followed" + userB.name);
527 res.status(200).jsonp(userB);
528 });
529 });
530 });
531 }//end else if
532 });
533 }//end else if
534 });
535};
536
537/**
538 userA: el que fa l'acció de deixar de seguir --> se li treu userB de following
539 userB: el que deixa de tenir el seguiment --> se li treu l'userA del followers
540 **/
541/** POST '/users/unfollow' **/
542exports.unfollow = function (req, res) {
543 userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, userA) {
544 if (err) return res.send(500, err.message);
545 if (!userA) {
546 res.json({success: false, message: 'userA not found.'});
547 } else if (userA) {
548 //ara busquem el userB
549 userModel.findOne({_id: req.body.userid}, function (err, userB) {
550 if (err) return res.send(500, err.message);
551 if (!userB) {
552 res.json({success: false, message: 'userB not found.'});
553 } else if (userB) {
554 var indexFollower = -1;
555 for (var i = 0; i < userB.followers.length; i++) {
556 if (userB.followers[i].equals(userA._id)) {
557 indexFollower = JSON.parse(JSON.stringify(i));
558 }
559 }
560 if (indexFollower > -1) {
561 userB.followers.splice(indexFollower, 1);
562 /*notification*/
563 var notification = {
564 state: "pendent",
565 message: userA.name + " unfollowed you",
566 link: "dashboard",
567 icon: "unfollower.png",
568 date: Date()
569 };
570 userB.notifications.push(notification);
571 /* end of notification*/
572 /* gamification */
573 var reward = {
574 concept: userA.name + " unfollowed you",
575 date: Date(),
576 value: -1
577 };
578 userB.points.history.push(reward);
579 userB.points.total = userB.points.total - 1;
580 /* end of gamification */
581 userB.save(function (err) {
582 if (err) return res.send(500, err.message);
583 var indexFollower = -1;
584 for (var i = 0; i < userA.following.length; i++) {
585 if (userA.following[i].equals(userB._id)) {
586 indexFollower = JSON.parse(JSON.stringify(i));
587 }
588 }
589 if (indexFollower > -1) {
590 userA.following.splice(indexFollower, 1);
591 /* gamification */
592 var reward = {
593 concept: "unfollowed " + userB.name,
594 date: Date(),
595 value: -1
596 };
597 userA.points.history.push(reward);
598 userA.points.total = userA.points.total - 1;
599 /* end of gamification */
600 userA.save(function (err) {
601 if (err) return res.send(500, err.message);
602 userModel.findOne(userA).lean().populate('following', 'name avatar')
603 .exec(function (err, userA) {
604 if (err) return res.send(500, err.message);
605 console.log("user followed" + userB.name);
606 res.status(200).jsonp(userB);
607 });
608 });
609 } else {//else de indexFollower>-1
610 res.status(200).jsonp({message: 'not found'});
611 }
612 });
613 } else {//else de indexFollower>-1
614 res.status(200).jsonp({message: 'not found'});
615 }
616 }//end else if
617 });
618 }//end else if
619 });
620};
621
622/**GET '/search/:searchstring' **/
623exports.search = function (req, res) {
624 userModel.find({
625 name: new RegExp(req.params.searchstring, "i"),
626 role: 'user'
627 })//perquè retorni tots els objectes que continguin l'string sense necessitat de que sigui exactament la mateixa string
628 .limit(Number(req.query.pageSize))
629 .skip(Number(req.query.pageSize) * Number(req.query.page))
630 .exec(function (err, users) {
631 if (err) return res.send(500, err.message);
632 userModel.find({
633 name: new RegExp(req.params.searchstring, "i"),
634 role: 'trainer'
635 })//perquè retorni tots els objectes que continguin l'string sense necessitat de que sigui exactament la mateixa string
636 .limit(Number(req.query.pageSize))
637 .skip(Number(req.query.pageSize) * Number(req.query.page))
638 .exec(function (err, trainers) {
639 if (err) return res.send(500, err.message);
640 routineModel.find({title: new RegExp(req.params.searchstring, "i")})//perquè retorni tots els objectes que continguin l'string sense necessitat de que sigui exactament la mateixa string
641 .limit(Number(req.query.pageSize))
642 .skip(Number(req.query.pageSize) * Number(req.query.page))
643 .exec(function (err, routines) {
644 if (err) return res.send(500, err.message);
645 dietModel.find({title: new RegExp(req.params.searchstring, "i")})//perquè retorni tots els objectes que continguin l'string sense necessitat de que sigui exactament la mateixa string
646 .limit(Number(req.query.pageSize))
647 .skip(Number(req.query.pageSize) * Number(req.query.page))
648 .exec(function (err, diets) {
649 if (err) return res.send(500, err.message);
650 res.json({
651 users: users,
652 trainers: trainers,
653 routines: routines,
654 diets: diets
655 });
656 });//diets
657 });//routines
658 });//trainers
659 });//users
660};
661
662/** POST '/users/newMark' **/
663exports.newMark = function (req, res) {
664 userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) {
665 if (err) return res.send(500, err.message);
666 if (!user) {
667 res.json({success: false, message: 'user not found.'});
668 } else if (user) {
669 var newmark = {
670 title: req.body.title,
671 unit: req.body.unit
672 };
673 user.marks.push(newmark);
674 /* gamification */
675 var reward = {
676 concept: "new mark created: " + newmark.title,
677 date: Date(),
678 value: +3
679 };
680 user.points.history.push(reward);
681 user.points.total = user.points.total + 3;
682 /* end of gamification */
683 user.save(function (err) {
684 if (err) return res.send(500, err.message);
685 res.status(200).jsonp(user.marks);
686 });
687 }//end else if user
688 });
689};
690
691/** DELETE /users/markid'**/
692exports.deleteUserMark = function (req, res) {
693 userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) {
694 if (err) return res.send(500, err.message);
695 if (!user) {
696 res.json({success: false, message: 'user not found.'});
697 } else if (user) {
698 var indexMark=-1;
699 for (var i = 0; i < user.marks.length; i++) {
700 if (user.marks[i]._id == req.params.markid) {
701 indexMark = JSON.parse(JSON.stringify(i));
702 }
703 }
704 if(indexMark>-1)
705 {
706 user.marks.splice(indexMark, 1);
707 /* gamification */
708 var reward = {
709 concept: "mark deleted",
710 date: Date(),
711 value: -3
712 };
713 user.points.history.push(reward);
714 user.points.total = user.points.total - 3;
715 /* end of gamification */
716 user.save(function (err, user) {//guardem el trainer amb la rutina treta
717 if (err) return res.send(500, err.message);
718 userModel.findOne({_id: user._id})
719 .lean()
720 .populate('diets', 'title description')
721 .populate('routines', 'title description')
722 .populate('trainers', 'name avatar description disciplines')
723 .populate('clients.client', 'name avatar')
724 .populate('publications')
725 .exec(function (err, user) {
726 if (err) return res.send(500, err.message);
727 res.status(200).jsonp(user);
728 });
729 });
730 }else{
731 res.status(200).jsonp({message: 'mark not found'});
732 }
733 }
734 });
735}
736
737/**
738 cal rebre:
739 _id
740 value: 10
741 **/
742/** POST '/users/:markid/addDayToMark' **/
743exports.addDayToMark = function (req, res) {
744 userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) {
745 if (err) return res.send(500, err.message);
746 if (!user) {
747 res.json({success: false, message: 'user not found.'});
748 } else if (user) {
749 var indexMark = -1;
750 var indexDay = -1;
751 for (var i = 0; i < user.marks.length; i++) {
752 if (user.marks[i]._id == req.params.markid) {
753 indexMark = JSON.parse(JSON.stringify(i));
754 for (var j = 0; j < user.marks[i].days.length; j++) {
755 if (user.marks[i].days[j].date == Date()) {
756 indexDay = JSON.parse(JSON.stringify(j));
757 }
758 }
759 }
760 }
761 if (indexMark > -1)//si la mark existeix
762 {
763 if (indexDay == -1)//però el dia no existeix encara
764 {
765 var newday = {
766 date: Date(),
767 value: req.body.value
768 };
769 user.marks[indexMark].days.push(newday);
770 /* gamification */
771 var reward = {
772 concept: "day value added to mark: " + user.marks[indexMark].title,
773 date: Date(),
774 value: +1
775 };
776 user.points.history.push(reward);
777 user.points.total = user.points.total + 1;
778 /* end of gamification */
779 user.save(function (err) {
780 if (err) return res.send(500, err.message);
781 res.status(200).jsonp(user.marks);
782 });
783 } else {
784 res.status(200).jsonp({message: 'mark of day already registered'});
785 }
786 } else {
787 res.status(200).jsonp({message: 'mark not registered'});
788 }
789 }//end else if user
790 });
791};