loginRoutes.js

var jwt = require("jsonwebtoken");
var async = require("async");
var dbCollections = require('../../config/db/dbCollections');

function loginRoutes(app, routeOptions) {
    // List of collections available
    var DB = dbCollections(routeOptions.database);

    // route for logging in
    app.put('/auth/user/checkinvite', function(req, res) {
        // Check if email already exists in RegisterClln
        DB.RegisterClln.findOne({'invite.code':req.body.code}, {_id: 0, 'invite.code': 1}, function (err, result) {
            console.log(result);
            if (result !== null) {
                // If invite exists, approve registeration for email id associated to that invite code
                DB.RegisterClln.update({'invite.code':req.body.code}, {$set: {'invite.isRegistrationAllowed': true, 'invite.enabledAt': new Date().getTime()}},
                function(err, result) {
                    if (result !== null) {
                        res.json({
                            success: true,
                            message: 'Validation successful'
                        });
                    }
                    else {
                        console.log(err);
                    }
                });
            } else {
                res.json({
                    success: false,
                    message: 'Validation failed'
                });
            }
        });
    });

    app.post('/auth/user/login', function(req, res) {
        var user = {};
        var userinfo = {
            username: req.body.username,
            password: req.body.password
        };
        DB.UserClln.findOne(userinfo, {_id: 0, token: 1}, function(err, result) {
            if (result !== null) {
                res.json({
                    success: true,
                    message: 'Authentication successful',
                    token: result.token
                });
            }
            else {
                res.json({
                    success: false,
                    message: 'Authentication failed'
                });
            }
        });
    });

    // route for user registration for getting invite code
    app.post('/auth/user/register', function(req, res) {
        var user = {
            fullname: req.body.fullname,
            email:  req.body.email
        };

        var error =
        {
            isInEmailRegClln: false,
            isInEmailUserClln: false
        };

        async.parallel([
            function(callback) {
                // Check if email already exists in RegisterClln
                DB.RegisterClln.findOne({email: user.email}, {_id: 0, email: 1}, function (err, result) {
                    if (result !== null) {
                        error.isInEmailRegClln = true;
                    } else {
                        error.isInEmailRegClln = false;
                    }
                    console.log('Email exists in RegisterClln: ' + error.isInEmailRegClln);
                    callback(null, 'one');
                });
            },
            function(callback) {
                // Check if email already exists in UserClln
                DB.UserClln.findOne({email: user.email}, {_id: 0, email: 1}, function (err, result) {
                    if (result !== null) {
                        error.isInEmailUserClln = true;
                    } else {
                        error.isInEmailUserClln = false;
                    }
                    console.log('Email exists in UserClln: ' + error.isInEmailUserClln);
                    callback(null, 'two');
                });
            }
        ],
        function(err, results) {
            if(!(error.isInEmailRegClln || error.isInEmailUserClln)) {
                // Insert user if no existing record already exists
                console.log('Inserted user: ' + user.email);
                DB.RegisterClln.insert({'fullname': user.fullname, 'email': user.email, 'modifiedAt': new Date().getTime()},
                function (err, data) {
                    res.json({
                        success: true,
                        message: 'Inserted user: ' + user.fullname
                    });
                });
            }
            else {
                console.log('Email exist already');
                // Send error details in case email already exist
                console.log(error);
                res.json({
                    success: false,
                    message: 'Email id already registered'
                });
            }
        });
    });

    // route for user signup completion
    app.post('/auth/user/signup', function(req, res) {
        var user = {
            username: req.body.username,
            password: req.body.password,
            email:  req.body.email
        };
        var userinfo = {
            username: req.body.username,
            password: req.body.password,
            email: req.body.email,
            firstName: req.body.firstName,
            lastName: req.body.lastName,
            token: jwt.sign(user, process.env.JWT_SECRET),
            registeredAt: new Date().getTime()
        };

        var error =
        {
            email: false,
            username: false,
            invite: false
        };

        async.series([
            function (callback) {
                // Check if invite code validated
                DB.RegisterClln.findOne({email: user.email}, {_id: 0, 'invite.isRegistrationAllowed': 1},
                function (err, result) {
                    console.log(result);
                    if (result !== null) {
                        result.invite = result.invite || {};
                        error.invite = result.invite.isRegistrationAllowed ? false : true;
                    } else {
                        error.invite = false;
                    }
                    console.log('Email approved: ' + error.invite);
                    callback(null, 'one');
                });
            }
        ], function (err, results) {
            if(!(error.invite)) {
                async.parallel([
                    function(callback) {
                        // Check if email already exists
                        DB.UserClln.findOne({email: user.email}, {_id: 0, email: 1}, function (err, result) {
                            if (result !== null) {
                                error.email = true;
                            } else {
                                error.email = false;
                            }
                            console.log('email already exists: ' + error.email);
                            callback(null, 'one');
                        });
                    },
                    function(callback) {
                        DB.UserClln.findOne({username: user.username}, {_id: 0, username: 1}, function (err, result) {
                            if (result !== null) {
                                error.username = true;
                            } else {
                                error.username = false;
                            }
                            console.log('username already exists: ' + error.username);
                            callback(null, 'two');
                        });
                    }
                ],
                function(err, results) {
                    if(!(error.email && error.username)) {
                        console.log('Username and Email doesnt exist already');
                        // Insert user if no existing record already exists
                        DB.UserClln.insert(userinfo, function (err, data) {
                            res.json({
                                success: true,
                                message: 'Registeration successful'
                            });
                        });
                    }
                    else {
                        console.log('Error in Username/Email');
                        // Send error details in case email or username already exist
                        console.log(error);
                        var message;
                        if(error.email && error.username) {
                            message = 'email and username already exist';
                        }
                        else if(error.email) {
                            message = 'email already exist';
                        }
                        else {
                            message = 'username already exist';
                        }

                        res.json({
                            success: false,
                            message: 'Invite code not valid'
                        });
                    }
                });
            }
            else {
                res.json({
                    success: false,
                    message: 'Invite code not valid'
                });
            }
        });
    });

    // NOTE: This has to be after unprotected routes
    // route middleware to verify a token
    app.use(function(req, res, next) {
        // check header or url parameters or post parameters for token
        var token = req.body.token || req.query.token || req.headers['x-auth-token'];

        if (token) {
            // verifies secret and checks exp
            jwt.verify(token, process.env.JWT_SECRET, function(err, decoded) {
                if (err) {
                    console.log('Failed to authenticate token.');
                    return res.json({ success: false, message: 'Failed to authenticate token.' });
                } else {
                    console.log('Token verifed successfully');
                    // if everything is good, save to request for use in next middleware
                    req.decoded = decoded;
                    next();
                }
            });
        } else {
            // if there is no token
            // return an error
            return res.status(403).send({
                success: false,
                message: 'No token provided.'
            });
        }
    });

    // route for logging out
    app.get('/auth/user/logout', function(req, res) {
        res.redirect('/');
    });
}

module.exports = loginRoutes;