arnaucube
arnaucube/socketioMEANseedPublic Self-hosted repository
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};