<commit_before>/**
 * @file Handles the login 'Remember Me' cookies
 * @module cookies
 */

var config      = require(__dirname + '/requireConfig.js');
var crypto      = require('crypto');
var cryptoUtils = require(__dirname + '/cryptoUtils.js');
var moment      = require('moment');
var MongoClient = require('mongodb').MongoClient;

/**
 * Clears all the expired cookies in the database
 * @function clearExpiredCookies
 *
 * @param {clearExpiredCookies} callback
 */

/**
 * Callback after the expired cookies are cleared
 * @callback clearExpiredCookies
 *
 * @param {Boolean} response
 */

function clearExpiredCookies(callback) {
	MongoClient.connect(config.mongodbURI, function(err, db) {
        if(!err) {
            var rememberdata = db.collection('remember');
            rememberdata.deleteMany({expires:''});
        } else {
            callback(false);
        }
	});
}

/**
 * Compares the
 * @function compareCookie
 *
 * @param {string} user - Username
 * @param {selector} selector - Selector, first part of cookie
 * @param {token} token - Token, second part of cookie, SHA-256 hashed version is stored in database
 * @param {compareCookieCallback}
 */

/**
 * Callback after cookie is compared against the database
 * @callback compareCookieCallback
 *
 * @param {string|Boolean} user - Username of cookie, false if error
 * @param {string|Boolean} token - New token to be placed in cookie or false if error
 * @param {Object|Boolean} expires - Javascript Date Object of expiring date, false if error
 */

function compareCookie(selector, token, callback) {
    cryptoUtils.shaHash(token, function(hashedToken) {
        MongoClient.connect(config.mongodbURI, function(dbErr, db) {

            if(!dbErr) {
                var rememberdata = db.collection('remember');
                rememberdata.find({selector: selector}).next(function(findErr, doc) {

                    if(!findErr && doc) {
                        var cookie  = doc;
                        var user    = cookie['user'];
                        var dbToken = cookie['token'];
                        var expires = cookie['expires'];

                        var today   = new Date();
                        if(expires.getTime() > today.getTime()) {

                            if(cryptoUtils.safeCompare(hashedToken, dbToken)) {

                                // Update token if successful

                                generateToken(user, selector, expires, function(newToken) {
                                    if(token) {
                                        // Update lastLogin
                                        var userdata = db.collection('users');
                                        userdata.update({user: user}, {$currentDate: {lastLogin: true}});
                                        db.close();

                                        callback(user, newToken, expires);
                                    } else {
                                        db.close();
                                        callback(false, false, false);
                                    }
                                });

                            } else {
                                db.close();
                                callback(false, false, false);
                            }

                        } else {
                            db.close();
                            callback(false, false, false);
                        }

                    } else {
                        db.close();
                        callback(false, false, false);
                    }

                });
            } else {
                callback(false, false, false);
            }
        });
    });
}

/**
 * Creates a selector and a token which can be used for the 'Remember Me' feature
 * @function createCookie
 *
 * @param {string} user - Username of cookie
 * @param {createCookieCallback}
 */

/**
 * Callback after creating a 'remember me' cookie
 * @callback createCookieCallback
 *
 * @param {string|Boolean} selector - Selector to be placed in cookie or false if error
 * @param {string|Boolean} token - Token to be placed in cookie or false if error
 * @param {Object|Boolean} expires - Javascript date object of when cookie expires, or false if error
 */

function createCookie(user, callback) {

    var expires = moment().add(30, 'days').toDate();
    crypto.randomBytes(16, function(err, selectorBuf) {

		if(!err) {

			var selector = selectorBuf.toString('hex');
			generateToken(user, selector, expires, function(token) {
				if(token) {
					callback(selector, token, expires);
				} else {
					callback(false, false, false);
				}
			});
		} else {
			callback(false, false, false);
		}
    });
}

/**
 * Upsert a new token into the database with the provided selector
 * @function generateToken
 *
 * @param {string} user - Username
 * @param {string} selector - Selector of existing cookie, or a new cookie to be created
 * @param {Object} expires - Javascript Date object of when the cookie expires
 * @param {generateTokenCallback}
 */

/**
 * Callback after a new token is generated
 * @callback generateTokenCallback
 *
 * @param {string|Boolean} token - New token to be given to client, false if error
 */

function generateToken(user, selector, expires, callback) {
    crypto.randomBytes(32, function(cryptoErr, tokenBuf) {
        if(!cryptoErr) {
            var token = tokenBuf.toString('hex');

            // Hash token for database
            cryptoUtils.shaHash(token, function(hashedToken) {

                // Insert token and hashed password in database
                MongoClient.connect(config.mongodbURI, function(dbErr, db) {
                    if(!dbErr) {
                        var rememberdata = db.collection('remember');
                        rememberdata.update({selector: selector}, {
                            user    : user,
                            selector: selector,
                            token   : hashedToken,
                            expires : expires,

                        }, {upsert: true}, function(updateErr) {

                            db.close();
                            if(!updateErr) {
                                callback(token);
                            } else {
                                callback(false);
                            }
                        });

                    } else {
                        callback(false);
                    }

                });
            });
        } else {
            callback(false);
        }

    });
}

/**
 * Checks to see if you have a 'remember me' login cookie. If so, automatically log in. This is Express Middleware, so the params are standard
 * @function remember
 *
 * @param {Object} req - Request
 * @param {Object} res - Response
 * @param {Object} next - Callback function
 */

function remember(req, res, next) {
    var cookie = req.cookies.rememberme;

    if(cookie && !req.session.user) {

        var values = cookie.split(':');
        var selector = values[0];
        var token    = values[1];

        compareCookie(selector, token, function(user, newToken, expires) {
            if(user) {
                req.session.user = user;
                res.cookie('rememberme', selector + ':' + newToken, {expires: expires});
            }
            next();
		});
    } else {
        next();
    }
}

module.exports.clearExpiredCookies = clearExpiredCookies;
module.exports.createCookie        = createCookie;
module.exports.remember            = remember;<commit_msg>Don't need this function, Mongo already has a feature<commit_after>/**
 * @file Handles the login 'Remember Me' cookies
 * @module cookies
 */

var config      = require(__dirname + '/requireConfig.js');
var crypto      = require('crypto');
var cryptoUtils = require(__dirname + '/cryptoUtils.js');
var moment      = require('moment');
var MongoClient = require('mongodb').MongoClient;

/**
 * Compares the
 * @function compareCookie
 *
 * @param {string} user - Username
 * @param {selector} selector - Selector, first part of cookie
 * @param {token} token - Token, second part of cookie, SHA-256 hashed version is stored in database
 * @param {compareCookieCallback}
 */

/**
 * Callback after cookie is compared against the database
 * @callback compareCookieCallback
 *
 * @param {string|Boolean} user - Username of cookie, false if error
 * @param {string|Boolean} token - New token to be placed in cookie or false if error
 * @param {Object|Boolean} expires - Javascript Date Object of expiring date, false if error
 */

function compareCookie(selector, token, callback) {
    cryptoUtils.shaHash(token, function(hashedToken) {
        MongoClient.connect(config.mongodbURI, function(dbErr, db) {

            if(!dbErr) {
                var rememberdata = db.collection('remember');
                rememberdata.find({selector: selector}).next(function(findErr, doc) {

                    if(!findErr && doc) {
                        var cookie  = doc;
                        var user    = cookie['user'];
                        var dbToken = cookie['token'];
                        var expires = cookie['expires'];

                        var today   = new Date();
                        if(expires.getTime() > today.getTime()) {

                            if(cryptoUtils.safeCompare(hashedToken, dbToken)) {

                                // Update token if successful

                                generateToken(user, selector, expires, function(newToken) {
                                    if(token) {
                                        // Update lastLogin
                                        var userdata = db.collection('users');
                                        userdata.update({user: user}, {$currentDate: {lastLogin: true}});
                                        db.close();

                                        callback(user, newToken, expires);
                                    } else {
                                        db.close();
                                        callback(false, false, false);
                                    }
                                });

                            } else {
                                db.close();
                                callback(false, false, false);
                            }

                        } else {
                            db.close();
                            callback(false, false, false);
                        }

                    } else {
                        db.close();
                        callback(false, false, false);
                    }

                });
            } else {
                callback(false, false, false);
            }
        });
    });
}

/**
 * Creates a selector and a token which can be used for the 'Remember Me' feature
 * @function createCookie
 *
 * @param {string} user - Username of cookie
 * @param {createCookieCallback}
 */

/**
 * Callback after creating a 'remember me' cookie
 * @callback createCookieCallback
 *
 * @param {string|Boolean} selector - Selector to be placed in cookie or false if error
 * @param {string|Boolean} token - Token to be placed in cookie or false if error
 * @param {Object|Boolean} expires - Javascript date object of when cookie expires, or false if error
 */

function createCookie(user, callback) {

    var expires = moment().add(30, 'days').toDate();
    crypto.randomBytes(16, function(err, selectorBuf) {

		if(!err) {

			var selector = selectorBuf.toString('hex');
			generateToken(user, selector, expires, function(token) {
				if(token) {
					callback(selector, token, expires);
				} else {
					callback(false, false, false);
				}
			});
		} else {
			callback(false, false, false);
		}
    });
}

/**
 * Upsert a new token into the database with the provided selector
 * @function generateToken
 *
 * @param {string} user - Username
 * @param {string} selector - Selector of existing cookie, or a new cookie to be created
 * @param {Object} expires - Javascript Date object of when the cookie expires
 * @param {generateTokenCallback}
 */

/**
 * Callback after a new token is generated
 * @callback generateTokenCallback
 *
 * @param {string|Boolean} token - New token to be given to client, false if error
 */

function generateToken(user, selector, expires, callback) {
    crypto.randomBytes(32, function(cryptoErr, tokenBuf) {
        if(!cryptoErr) {
            var token = tokenBuf.toString('hex');

            // Hash token for database
            cryptoUtils.shaHash(token, function(hashedToken) {

                // Insert token and hashed password in database
                MongoClient.connect(config.mongodbURI, function(dbErr, db) {
                    if(!dbErr) {
                        var rememberdata = db.collection('remember');
                        rememberdata.update({selector: selector}, {
                            user    : user,
                            selector: selector,
                            token   : hashedToken,
                            expires : expires,

                        }, {upsert: true}, function(updateErr) {

                            db.close();
                            if(!updateErr) {
                                callback(token);
                            } else {
                                callback(false);
                            }
                        });

                    } else {
                        callback(false);
                    }

                });
            });
        } else {
            callback(false);
        }

    });
}

/**
 * Checks to see if you have a 'remember me' login cookie. If so, automatically log in. This is Express Middleware, so the params are standard
 * @function remember
 *
 * @param {Object} req - Request
 * @param {Object} res - Response
 * @param {Object} next - Callback function
 */

function remember(req, res, next) {
    var cookie = req.cookies.rememberme;

    if(cookie && !req.session.user) {

        var values = cookie.split(':');
        var selector = values[0];
        var token    = values[1];

        compareCookie(selector, token, function(user, newToken, expires) {
            if(user) {
                req.session.user = user;
                res.cookie('rememberme', selector + ':' + newToken, {expires: expires});
            }
            next();
		});
    } else {
        next();
    }
}

module.exports.clearExpiredCookies = clearExpiredCookies;
module.exports.createCookie        = createCookie;
module.exports.remember            = remember;<|endoftext|>


<commit_before>/* globals game */

game.staticEntity = me.ObjectEntity.extend({

    /* -----

    constructor

    ------ */

    init: function(x, y, settings) {
        // call the constructor
        this.parent(x, y, settings);
        // set the default horizontal & vertical speed (accel vector)
        this.setVelocity(3, 3);

        this.gravity = 0;

        this.update();

    },

    /* -----

    update the player pos

    ------ */
    update: function(dt) {
        /*
        var dir = Math.floor(Math.random() * 4);
        if(dir === 0) {
            this.vel.x = 0;
            this.vel.y = 0;
            this.vel.x -= Math.floor(Math.random() * 4);
        } else if(dir === 1) {
            this.vel.x = 0;
            this.vel.y = 0;
            this.vel.x += Math.floor(Math.random() * 4);
        } else if(dir === 2) {
            this.vel.x = 0;
            this.vel.y = 0;
            this.vel.y -= Math.floor(Math.random() * 4);
        } else {
            this.vel.x = 0;
            this.vel.y = 0;
            this.vel.y += Math.floor(Math.random() * 4);
        }
        */

        // var player_loc = game.data.player_location;
        // me.plugin.astar.refresh();
        // var nodes = me.astar.search(player_loc.x, player_loc.y, this.pos.x, this.pos.y);
        // console.log(nodes);
        // if (typeof nodes[0] !== 'undefined'){
        //     this.vel.x = nodes[0].pos.x;
        //     this.vel.y = nodes[0].pos.y;
        // }
        // this.updateMovement();

        return true;
    },
    /* ---

       callback when everything is loaded

       ---  */

    loaded: function (){

    }
});<commit_msg>shakie has movement again<commit_after>/* globals game */

game.staticEntity = me.ObjectEntity.extend({

    /* -----

    constructor

    ------ */

    init: function(x, y, settings) {
        // call the constructor
        this.parent(x, y, settings);
        // set the default horizontal & vertical speed (accel vector)
        this.setVelocity(3, 3);

        this.gravity = 0;

        this.update();

    },

    /* -----

    update the player pos

    ------ */
    update: function(dt) {
        var dir = Math.floor(Math.random() * 4);
        if(dir === 0) {
            this.vel.x = 0;
            this.vel.y = 0;
            this.vel.x -= Math.floor(Math.random() * 4);
        } else if(dir === 1) {
            this.vel.x = 0;
            this.vel.y = 0;
            this.vel.x += Math.floor(Math.random() * 4);
        } else if(dir === 2) {
            this.vel.x = 0;
            this.vel.y = 0;
            this.vel.y -= Math.floor(Math.random() * 4);
        } else {
            this.vel.x = 0;
            this.vel.y = 0;
            this.vel.y += Math.floor(Math.random() * 4);
        }

        // var player_loc = game.data.player_location;
        // me.plugin.astar.refresh();
        // var nodes = me.astar.search(player_loc.x, player_loc.y, this.pos.x, this.pos.y);
        // console.log(nodes);
        // if (typeof nodes[0] !== 'undefined'){
        //     this.vel.x = nodes[0].pos.x;
        //     this.vel.y = nodes[0].pos.y;
        // }
        this.updateMovement();

        return true;
    },
    /* ---

       callback when everything is loaded

       ---  */

    loaded: function (){

    }
});<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Mansi Shah, Santosh Rajan
*/

var ast = {
        type: "Program",
        body: []
    }

module.exports = function(src) {

    var spaceRegEx = /^[ \t\r\n\b\f]+/,
        newLineRegEx = /\r?\n/g,
        nullRegEx = /^null\b/i,
        booleanRegEx = /^(true|false)\b/i,
        numberRegEx = /^[-+]?(\d+(\.\d*)?|\.\d+)([e][+-]?\d+)?/i,
        stringRegEx = /^('|").*?[^\\]\1/,
        identifierRegEx = /^[a-z\~]+[a-z0-9_\[\]\.\*]*/i,
        restParamRegEx = /^\.\.\.[a-z]+[a-z0-9_\[\]\.\*]*/i,
        openParanthesesRegEx = /^\(/,
        closingParanthesesRegEx = /^\)/,
        operatorRegEx = /^(\*|\+|\-|\/|\%|\=)/,
        unaryOperatorRegEx = /^(\!)/,
        functionKeywordRegEx = /^(\()(\s)*function/,
        macroKeywordRegEx = /^(\()(\s)*macro\b/,
        varKeywordRegEx = /^(\()?(\s)*var/,
        ifKeywordRegEx = /^\((\s)*if/,
        fatArrowRegEx = /^\(\=\>/,
        commentRegEx  = /^\#.*\n?/,
        line = 1
        macros = {}

    function consumer(regex, process) {
        return function() {
            var matches = regex.exec(src)
            if(!matches) return null
            // console.info("Matched "+regex)
            src = src.slice(matches[0].length)
            spaceParser()
            if(process)    return process(matches[0])
            return matches[0]
        }
    }

    function parserFactory() {
        var parsers = arguments
        return function() {
            for(index in parsers){
                var parser = parsers[index]
                spaceParser()
                var result = parser()
                if(result){
                    // console.info("Consumed as "+result.type)
                    return result
                }
            }
            return null
        }
    }

    var spaceParser = consumer(spaceRegEx, function(val){
            var match = val.match(newLineRegEx)
            var l = (match)? match.length : 0
            line+=l
            return true
        }),
        commentParser = consumer(commentRegEx, function(){
            line++
            return true
        }),
        nullParser = consumer(nullRegEx, function(){
            return {type: "Literal", value: null}
        }),
        booleanParser = consumer(booleanRegEx, function(val){
            if(val === 'true')
                return {type: "Literal", value: true}
            else
                return {type: "Literal", value: false}
        }),
        numberParser = consumer(numberRegEx, function(val){
            return {type: "Literal", value: Number(val)}
        }),
        stringParser = consumer(stringRegEx, function(val){
            return {type: "Literal", value: val.slice(1,val.length-1)}
        }),
        literalParser = parserFactory(nullParser, booleanParser, numberParser, stringParser),
        identifierParser = consumer(identifierRegEx, function(val) {
            return {type: "Identifier", name: val}
        }),
        restParamParser = consumer(restParamRegEx, function(val) {
            var temp = src
            src = val.slice(3)  //Stripping the '...'
            argument = statementParser()
            src = temp
            return {type: "RestElement", argument: argument}
        }),
        elementParser = parserFactory(literalParser, identifierParser, restParamParser),
        openParanthesesParser = consumer(openParanthesesRegEx, function(val){
            return true
        }),
        closingParanthesesParser = consumer(closingParanthesesRegEx, function(val){
            return true
        }),
        operatorParser = consumer(operatorRegEx),
        unaryOperatorParser = consumer(unaryOperatorRegEx),
        varKeywordParser = consumer(varKeywordRegEx),
        functionKeywordParser = consumer(functionKeywordRegEx),
        ifKeywordParser = consumer(ifKeywordRegEx),
        macroKeywordParser = consumer(macroKeywordRegEx),
        fatArrowParser = consumer(fatArrowRegEx)

    function argumentsParser() {
        var args = []
        spaceParser()
        if(src.length > 0){
            while(!closingParanthesesParser()){
                // console.info("Parsing args "+src)
                arg = argStatementParser()
                if (!arg)
                    throw new SyntaxError("argumentsParser : Unexpected character at line: "+line)
                args.push(arg)
                spaceParser()
            }
            spaceParser()
            if (args.length > 0)
                return args
        }
        return []
    }

    function expressionParser() {
        if (!openParanthesesParser()) return null
        // console.info("ExpressionParser "+src)
        return callExpressionParser() || unaryExpressionParser() || binaryExpressionParser() || statementParser()
    }

    function expressionStatementParser() {
        spaceParser()
        if (closingParanthesesParser())  return null
        // console.info("ExpressionStatementParser "+src)
        return combinator({type: "ExpressionStatement"}, ["expression", expressionParser])
    }

    function macroCallParser() {
        var temp = src
        if(!openParanthesesParser()) return null
        if (macroId = identifierParser()) {
        // console.info("MacroCallParser "+src)
            if (macro = macros[macroId.name]) {
                var macroArgs = getArguments() || []
                var macroBody = macro.body
                for(param in macro.params){
                    var regex = new RegExp('~'+param.replace(/\./g,'\\.'), 'gi')
                    if(!Array.isArray(macro.params[param]))
                        val = macroArgs.shift()
                    else
                        val = macroArgs.join(" ")
                    macroBody = macroBody.replace(regex,val)
                }
                var temp = src
                src = macroBody
                var macroExpr = []
                while(src.length > 0){
                    // console.info("Parsing Macro Body "+src)
                    var rslt = statementParser()
                    if(rslt)    macroExpr.push(rslt)
                    else    throw new SyntaxError("Cannot parse macro body")
                }
                src = temp
                return macroExpr
            }
        }
        src = temp
        return null
    }

    function callExpressionParser() {
        // console.info("callExpressionParser "+src)
        return combinator({type: "CallExpression"}, ["callee", statementParser], ["arguments", argumentsParser])
    }

    function unaryExpressionParser() {
        // console.info("unaryExpressionParser "+src)
        return combinator({type: "UnaryExpression"}, ["operator", unaryOperatorParser], ["argument", argStatementParser], ["prefix", true], ["", closingParanthesesParser])
    }

    function binaryExpressionParser() {
        // console.info("binaryExpressionParser "+src)
        return combinator({type: "BinaryExpression"}, ["operator", operatorParser], ["left", elementParser], ["right", elementParser], ["", closingParanthesesParser])
    }

    function extractExpression() {
        var found = false, parantheses = 1, i = 0
        // console.info("Inside extractExpression ")
        while(!found){
            if (src[i] == '(')
                parantheses++
            if (src[i] == ')')
                parantheses--
            if (parantheses == 0)
                found = true
            i++
        }

        return src.slice(0,i)
    }

    function getArguments(){
        var args = []
        // console.info("Inside getArguments ")
        while(!closingParanthesesParser()){
            if(matches = /^[a-z0-9]*\b/.exec(src) || stringRegEx.exec(src)){
                args.push(matches[0])
            }
            else if(openParanthesesParser()){
                matches = [extractExpression()]
                args.push('('+matches[0])
            }
            if(matches) src = src.slice(matches[0].length)
            else    throw new SyntaxError("Unknown character at line: "+line)
            spaceParser()
        }
        return args
    }

    function macroDeclarationParser() {
        if (!macroKeywordParser())    return null
        // console.info("macroDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        spaceParser()

        //id
        if (id = identifierParser())
            macroId = id.name
        else
            throw new SyntaxError("Expecting a macro identifier")
        spaceParser()

        //params
        if (!openParanthesesParser())
            throw new SyntaxError("Expecting '(' after " + macroId)

        var macro = {}
        macro.params = {}
        while(!closingParanthesesParser()){
            if (param = identifierParser().name) {
                macro.params[param.toString()] = null
            }
        }
        macro.params["...rest"] = []

        //body
        macro.body = src.slice(0,src.length-1)

        src = rest
        spaceParser()

        macros[macroId.toString()] = macro
        return true

    }

    function combinator(expr){
        for(var i=1; i<arguments.length; i++){
            var attr = arguments[i][0]
            var parser = arguments[i][1]
            var args = arguments[i][2]
            if(typeof parser == "function"){
                if(Array.isArray(args)){
                    var result = parser(args[0],args[1])
                }
                else
                    var result = parser()
                if(result == null) return null
            }
            else
                result = parser

            if(attr){
                expr[attr] = result
            }
        }
        return expr
    }

    function functionDeclarationParser() {
        if (!functionKeywordParser())    return null
        // console.info("functionDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "FunctionDeclaration"}, ["id", identifierParser], ["",openParanthesesParser], ["params",argumentsParser], ["defaults", []], ["body", functionBlockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function variableDeclarationParser() {
        if (!varKeywordParser()) return null
        // console.info("variableDeclarationParser "+src)
        var expr = {type: "VariableDeclaration", declarations: [], kind: "var"}
        while(!closingParanthesesParser()){
            var innerExpr = combinator({type: "VariableDeclarator"}, ["id", identifierParser])
            innerExpr.init = argStatementParser()
            expr.declarations.push(innerExpr)
        }
        return expr
    }

    function blockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", bodyParser])
    }

    function functionBlockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", functionBodyParser])
    }

    function arrowFunctionParser() {
        if (!fatArrowParser())   return null
        // console.info("arrowFunctionParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "ArrowFunctionExpression"}, ["id", null], ["", openParanthesesParser], ["params", argumentsParser], ["defaults", []], ["body", functionBlockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function ifStatementParser() {
        if (!ifKeywordParser())   return null
        // console.info("ifStatementParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "IfStatement"}, ["", openParanthesesParser], ["test", argStatementParser], ["", closingParanthesesParser], ["", openParanthesesParser], ["consequent", blockStatementParser], ["", openParanthesesParser], ["alternate", blockStatementParser])
        src = rest
        return expr
    }

    function functionBodyParser() {
        var stmts = []
        while(!closingParanthesesParser()){
            // console.info("Parsing Function Body "+src)
            var stmt = statementParser()
            if(stmt === true) {}
            else{
                if(Array.isArray(stmt)){
                    arrToObj(stmt).forEach(function(s){
                        stmts.push(s)
                    })
                }
                else
                    stmts.push(stmt)
            }
        }
        if(stmts[stmts.length-1].type === "ExpressionStatement"){
            stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1].expression}
        }
        else{
            stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1]}
        }

        return stmts
    }

    function statementParser() {
        // console.info("statementParser "+src)
        return commentParser() || ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionStatementParser()
    }

    function argStatementParser() {
        // console.info("argStatementParser "+src)
        return commentParser() || ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionParser()
    }

    function arrToObj(arr){
        return arr.reduce(function(flat, current) {
                if(Array.isArray(current)){
                    return flat.concat(arrToObj(current))
                }
                return flat.concat(current);
        }, [])
    }

    function bodyParser() {
        var body = []
        spaceParser()
        while(stmt = statementParser()){
            // console.info("Output: ",stmt)
            if (!stmt)
                throw new SyntaxError("Cannot parse statement at line: " + line)
            if(stmt === true) {}
            else{
                if(Array.isArray(stmt)){
                    arrToObj(stmt).forEach(function(s){
                        body.push(s)
                    })
                }
                else
                    body.push(stmt)
            }
            spaceParser()
        }
        return body
    }

    ast.body = bodyParser()
    return ast
}<commit_msg>Refactored argumentsParser<commit_after>/*
 * Copyright (c) 2015 Mansi Shah, Santosh Rajan
*/

var ast = {
        type: "Program",
        body: []
    }

module.exports = function(src) {

    var spaceRegEx = /^[ \t\r\n\b\f]+/,
        newLineRegEx = /\r?\n/g,
        nullRegEx = /^null\b/i,
        booleanRegEx = /^(true|false)\b/i,
        numberRegEx = /^[-+]?(\d+(\.\d*)?|\.\d+)([e][+-]?\d+)?/i,
        stringRegEx = /^('|").*?[^\\]\1/,
        identifierRegEx = /^[a-z\~]+[a-z0-9_\[\]\.\*]*/i,
        restParamRegEx = /^\.\.\.[a-z]+[a-z0-9_\[\]\.\*]*/i,
        openParanthesesRegEx = /^\(/,
        closingParanthesesRegEx = /^\)/,
        operatorRegEx = /^(\*|\+|\-|\/|\%|\=)/,
        unaryOperatorRegEx = /^(\!)/,
        functionKeywordRegEx = /^(\()(\s)*function/,
        macroKeywordRegEx = /^(\()(\s)*macro\b/,
        varKeywordRegEx = /^(\()?(\s)*var/,
        ifKeywordRegEx = /^\((\s)*if/,
        fatArrowRegEx = /^\(\=\>/,
        commentRegEx  = /^\#.*\n?/,
        line = 1
        macros = {}

    function consumer(regex, process) {
        return function() {
            var matches = regex.exec(src)
            if(!matches) return null
            // console.info("Matched "+regex)
            src = src.slice(matches[0].length)
            spaceParser()
            if(process)    return process(matches[0])
            return matches[0]
        }
    }

    function parserFactory() {
        var parsers = arguments
        return function() {
            for(index in parsers){
                var parser = parsers[index]
                spaceParser()
                var result = parser()
                if(result){
                    // console.info("Consumed as "+result.type)
                    return result
                }
            }
            return null
        }
    }

    var spaceParser = consumer(spaceRegEx, function(val){
            var match = val.match(newLineRegEx)
            var l = (match)? match.length : 0
            line+=l
            return true
        }),
        commentParser = consumer(commentRegEx, function(){
            line++
            return true
        }),
        nullParser = consumer(nullRegEx, function(){
            return {type: "Literal", value: null}
        }),
        booleanParser = consumer(booleanRegEx, function(val){
            if(val === 'true')
                return {type: "Literal", value: true}
            else
                return {type: "Literal", value: false}
        }),
        numberParser = consumer(numberRegEx, function(val){
            return {type: "Literal", value: Number(val)}
        }),
        stringParser = consumer(stringRegEx, function(val){
            return {type: "Literal", value: val.slice(1,val.length-1)}
        }),
        literalParser = parserFactory(nullParser, booleanParser, numberParser, stringParser),
        identifierParser = consumer(identifierRegEx, function(val) {
            return {type: "Identifier", name: val}
        }),
        restParamParser = consumer(restParamRegEx, function(val) {
            var temp = src
            src = val.slice(3)  //Stripping the '...'
            argument = statementParser()
            src = temp
            return {type: "RestElement", argument: argument}
        }),
        elementParser = parserFactory(literalParser, identifierParser, restParamParser),
        openParanthesesParser = consumer(openParanthesesRegEx, function(val){
            return true
        }),
        closingParanthesesParser = consumer(closingParanthesesRegEx, function(val){
            return true
        }),
        operatorParser = consumer(operatorRegEx),
        unaryOperatorParser = consumer(unaryOperatorRegEx),
        varKeywordParser = consumer(varKeywordRegEx),
        functionKeywordParser = consumer(functionKeywordRegEx),
        ifKeywordParser = consumer(ifKeywordRegEx),
        macroKeywordParser = consumer(macroKeywordRegEx),
        fatArrowParser = consumer(fatArrowRegEx)

    function argumentsParser() {
        var expr = bodyParser(argStatementParser)
        closingParanthesesParser()
        return expr
    }

    function expressionParser() {
        if (!openParanthesesParser()) return null
        // console.info("ExpressionParser "+src)
        return callExpressionParser() || unaryExpressionParser() || binaryExpressionParser() || statementParser()
    }

    function expressionStatementParser() {
        spaceParser()
        if (closingParanthesesParser())  return null
        // console.info("ExpressionStatementParser "+src)
        return combinator({type: "ExpressionStatement"}, ["expression", expressionParser])
    }

    function macroCallParser() {
        var temp = src
        if(!openParanthesesParser()) return null
        if (macroId = identifierParser()) {
        // console.info("MacroCallParser "+src)
            if (macro = macros[macroId.name]) {
                var macroArgs = getArguments() || []
                var macroBody = macro.body
                for(param in macro.params){
                    var regex = new RegExp('~'+param.replace(/\./g,'\\.'), 'gi')
                    if(!Array.isArray(macro.params[param]))
                        val = macroArgs.shift()
                    else
                        val = macroArgs.join(" ")
                    macroBody = macroBody.replace(regex,val)
                }
                var temp = src
                src = macroBody
                var macroExpr = []
                while(src.length > 0){
                    // console.info("Parsing Macro Body "+src)
                    var rslt = statementParser()
                    if(rslt)    macroExpr.push(rslt)
                    else    throw new SyntaxError("Cannot parse macro body")
                }
                src = temp
                return macroExpr
            }
        }
        src = temp
        return null
    }

    function callExpressionParser() {
        // console.info("callExpressionParser "+src)
        return combinator({type: "CallExpression"}, ["callee", statementParser], ["arguments", argumentsParser])
    }

    function unaryExpressionParser() {
        // console.info("unaryExpressionParser "+src)
        return combinator({type: "UnaryExpression"}, ["operator", unaryOperatorParser], ["argument", argStatementParser], ["prefix", true], ["", closingParanthesesParser])
    }

    function binaryExpressionParser() {
        // console.info("binaryExpressionParser "+src)
        return combinator({type: "BinaryExpression"}, ["operator", operatorParser], ["left", elementParser], ["right", elementParser], ["", closingParanthesesParser])
    }

    function extractExpression() {
        var found = false, parantheses = 1, i = 0
        // console.info("Inside extractExpression ")
        while(!found){
            if (src[i] == '(')
                parantheses++
            if (src[i] == ')')
                parantheses--
            if (parantheses == 0)
                found = true
            i++
        }

        return src.slice(0,i)
    }

    function getArguments(){
        var args = []
        // console.info("Inside getArguments ")
        while(!closingParanthesesParser()){
            if(matches = /^[a-z0-9]*\b/.exec(src) || stringRegEx.exec(src)){
                args.push(matches[0])
            }
            else if(openParanthesesParser()){
                matches = [extractExpression()]
                args.push('('+matches[0])
            }
            if(matches) src = src.slice(matches[0].length)
            else    throw new SyntaxError("Unknown character at line: "+line)
            spaceParser()
        }
        return args
    }

    function macroDeclarationParser() {
        if (!macroKeywordParser())    return null
        // console.info("macroDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        spaceParser()

        //id
        if (id = identifierParser())
            macroId = id.name
        else
            throw new SyntaxError("Expecting a macro identifier")
        spaceParser()

        //params
        if (!openParanthesesParser())
            throw new SyntaxError("Expecting '(' after " + macroId)

        var macro = {}
        macro.params = {}
        while(!closingParanthesesParser()){
            if (param = identifierParser().name) {
                macro.params[param.toString()] = null
            }
        }
        macro.params["...rest"] = []

        //body
        macro.body = src.slice(0,src.length-1)

        src = rest
        spaceParser()

        macros[macroId.toString()] = macro
        return true

    }

    function combinator(expr){
        for(var i=1; i<arguments.length; i++){
            var attr = arguments[i][0]
            var parser = arguments[i][1]
            var args = arguments[i][2]
            if(typeof parser == "function"){
                if(Array.isArray(args)){
                    var result = parser(args[0],args[1])
                }
                else
                    var result = parser()
                if(result == null) return null
            }
            else
                result = parser

            if(attr){
                expr[attr] = result
            }
        }
        return expr
    }

    function functionDeclarationParser() {
        if (!functionKeywordParser())    return null
        // console.info("functionDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "FunctionDeclaration"}, ["id", identifierParser], ["",openParanthesesParser], ["params",argumentsParser], ["defaults", []], ["body", functionBlockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function variableDeclarationParser() {
        if (!varKeywordParser()) return null
        // console.info("variableDeclarationParser "+src)
        var expr = {type: "VariableDeclaration", declarations: [], kind: "var"}
        while(!closingParanthesesParser()){
            var innerExpr = combinator({type: "VariableDeclarator"}, ["id", identifierParser])
            innerExpr.init = argStatementParser()
            expr.declarations.push(innerExpr)
        }
        return expr
    }

    function blockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", bodyParser])
    }

    function functionBlockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", functionBodyParser])
    }

    function arrowFunctionParser() {
        if (!fatArrowParser())   return null
        // console.info("arrowFunctionParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "ArrowFunctionExpression"}, ["id", null], ["", openParanthesesParser], ["params", argumentsParser], ["defaults", []], ["body", functionBlockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function ifStatementParser() {
        if (!ifKeywordParser())   return null
        // console.info("ifStatementParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "IfStatement"}, ["", openParanthesesParser], ["test", argStatementParser], ["", closingParanthesesParser], ["", openParanthesesParser], ["consequent", blockStatementParser], ["", openParanthesesParser], ["alternate", blockStatementParser])
        src = rest
        return expr
    }

    function functionBodyParser() {
        var stmts = []
        while(!closingParanthesesParser()){
            // console.info("Parsing Function Body "+src)
            var stmt = statementParser()
            if(stmt === true) {}
            else{
                if(Array.isArray(stmt)){
                    arrToObj(stmt).forEach(function(s){
                        stmts.push(s)
                    })
                }
                else
                    stmts.push(stmt)
            }
        }
        if(stmts[stmts.length-1].type === "ExpressionStatement"){
            stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1].expression}
        }
        else{
            stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1]}
        }

        return stmts
    }

    function statementParser() {
        // console.info("statementParser "+src)
        return commentParser() || ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionStatementParser()
    }

    function argStatementParser() {
        // console.info("argStatementParser "+src)
        return commentParser() || ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionParser()
    }

    function arrToObj(arr){
        return arr.reduce(function(flat, current) {
                if(Array.isArray(current)){
                    return flat.concat(arrToObj(current))
                }
                return flat.concat(current);
        }, [])
    }

    function bodyParser(parse) {
        if(!arguments[0])   parse = statementParser
        var body = []
        spaceParser()
        while(stmt = parse()){
            // console.info("Output: ",stmt)
            if (!stmt)
                throw new SyntaxError("Cannot parse statement at line: " + line)
            if(stmt === true) {}
            else{
                if(Array.isArray(stmt)){
                    arrToObj(stmt).forEach(function(s){
                        body.push(s)
                    })
                }
                else
                    body.push(stmt)
            }
            spaceParser()

        }
        return body
    }

    ast.body = bodyParser()
    return ast
}<|endoftext|>


<commit_before>var questions = require("./questions.json");

// constructor
function liarliar(room, io, end) {
  this.room = room;
  this.scores = {};
  this.rounds = {};
  this.players = {};
  this.io = io;
  this.end = end;
}

// methods

liarliar.prototype.addPlayer = function(id, name) {
  this.players[id] = name;
}

liarliar.prototype.submitAnswer = function(id, data, cb) {
  data.answer = data.answer.toLowerCase();
  if(this.activeQuestion.userAnswers[data.answer] === undefined) {
    this.activeQuestion.userAnswers[data.answer] = {};
    this.activeQuestion.userAnswers[data.answer].creators = [];
  }

  var userAnswer = data.answer.toLowerCase();
  var realAnswers = [this.activeQuestion.answer.toLowerCase()];
  for(ans in this.activeQuestion.alternate_spellings)
    realAnswers.push(ans.toLowerCase());

  if(realAnswers.indexOf(userAnswer) != -1) {
    cb(false);
    return;
  }

  if(this.activeQuestion.userAnswers[data.answer].creators.indexOf(id) == -1)
    this.activeQuestion.userAnswers[data.answer].creators.push(id);

  cb(true);

  if(Object.keys(this.activeQuestion.userAnswers).length >= Object.keys(io.sockets.adapter.rooms[this.room].sockets).length) {
    clearTimeout(this.endSubTimer);
    endSubmissionTime.bind(this)();
  }
}

liarliar.prototype.selectAnswer = function(id, data, cb) {
  if(this.activeQuestion.userAnswers[data.answer].votes === undefined)
    this.activeQuestion.userAnswers[data.answer].votes = [];

  this.activeQuestion.userVotes += 1;
  this.activeQuestion.userAnswers[data.answer].votes.push(id);

  if(this.activeQuestion.userVotes >= Object.keys(io.sockets.adapter.rooms[this.room].sockets).length - 1) {
    clearTimeout(this.endSelTimer);
    endSelectionTime.bind(this)();
  }

  // if(this.activeQuestion.userAnswers[data.answer] === undefined)
  //   this.activeQuestion.userAnswers[data.answer] = [];
  //
  // if(this.activeQuestion.userAnswers[data.answer].indexOf(id) == -1)
  //   this.activeQuestion.userAnswers[data.answer].push(id);
}

function transformQuestion(question) {
  return question.replace("<BLANK>", "________");
}

liarliar.prototype.start = function() {
  this.startRound();
  setTimeout(this.checkRoomStatus.bind(this), 5000);
}

liarliar.prototype.startRound = function() {
  this.questionID = parseInt(Math.random() * (Object.keys(questions).length - 1));
  this.activeQuestion = questions[this.questionID];
  this.activeQuestion.answer = this.activeQuestion.answer.toLowerCase();
  this.activeQuestion.userAnswers = {};
  this.activeQuestion.userVotes = 0;
  this.activeQuestion.userAnswers[this.activeQuestion.answer] = {correct: true};
  this.activeQuestion.userAnswers[this.activeQuestion.answer].creators = [];

  console.log(this.activeQuestion.answer);

  this.io.to(this.room).emit('question_selected', {question: transformQuestion(this.activeQuestion.question)});
  this.endSubTimer = setTimeout(endSubmissionTime.bind(this), 30000);
}

liarliar.prototype.checkRoomStatus = function() {
  if(this.io.sockets.adapter.rooms[this.room] === undefined) {
    this.end(this.room);
    return false;
  }

  return true;
}

liarliar.prototype.endGame = function() {
  setTimeout(function() {
    this.end(this.room)
  }.bind(this), 500);
}

function endSubmissionTime() {
  if(!this.checkRoomStatus()) {
    return;
  }

  if(this.activeQuestion.userAnswers[this.activeQuestion.answer] === undefined) {
    this.activeQuestion.userAnswers[this.activeQuestion.answer] = {};
  }

  var answers = Object.keys(this.activeQuestion.userAnswers);
  while(answers.length < 9) {
    var index = Math.floor(Math.random() * (this.activeQuestion.suggestions.length));
    var suggest = this.activeQuestion.suggestions[index];
    if(answers.indexOf(suggest) == -1) {
      answers.push(suggest);
      this.activeQuestion.userAnswers[suggest] = {};
    }
  }

  var shuffledAnswers = [];
  while(shuffledAnswers.length < 9) {
    var index = Math.floor(Math.random() * (answers.length));
    shuffledAnswers.push(answers[index]);
    answers.splice(index, 1);
  }

  var clients = io.sockets.adapter.rooms[this.room].sockets;
  for(client in clients) {
    var ans = [];
    for(a in shuffledAnswers) {
      a = shuffledAnswers[a];
      if(this.activeQuestion.userAnswers[a].creators === undefined || this.activeQuestion.userAnswers[a].correct) {
        ans.push(a);
      } else if(this.activeQuestion.userAnswers[a].creators.indexOf(client) == -1) {
        ans.push(a);
      }
    }
    this.io.to(client).emit('answers_posted', {answers: ans});
  }
  this.endSelTimer = setTimeout(endSelectionTime.bind(this), 30000);
}

function endSelectionTime() {
  if(!this.checkRoomStatus()) {
    return;
  }

  var scores = {};

  var roundAnswers = this.activeQuestion.userAnswers;

  var clients = io.sockets.adapter.rooms[this.room].sockets;

  for(client in clients) {
    if(this.players[client] !== undefined) {
      scores[client] = {
        id: client,
        nick: this.players[client],
        score: 0
      };
    }
    this.io.to(client).emit('scores_posted', {scores: scores});
  }

  for(ans in roundAnswers) {
    var ans = roundAnswers[ans];
    for(voter in ans.votes) {
      voter = ans.votes[voter];
      if(ans.correct) {
        scores[voter].score += 1000;
      } else {
        for(crtr in ans.creators) {
          crtr = ans.creators[crtr];
          scores[crtr].score += 500;
        }
        if(ans.creators === undefined) {
          scores[voter].score -= 250;
        }
      }
    }
  }

  this.io.to(this.room).emit('scores_posted', {scores: scores});
}

module.exports = liarliar;
<commit_msg>correct answer now pushes with scores<commit_after>var questions = require("./questions.json");

// constructor
function liarliar(room, io, end) {
  this.room = room;
  this.scores = {};
  this.rounds = {};
  this.players = {};
  this.io = io;
  this.end = end;
}

// methods

liarliar.prototype.addPlayer = function(id, name) {
  this.players[id] = name;
}

liarliar.prototype.submitAnswer = function(id, data, cb) {
  data.answer = data.answer.toLowerCase();
  if(this.activeQuestion.userAnswers[data.answer] === undefined) {
    this.activeQuestion.userAnswers[data.answer] = {};
    this.activeQuestion.userAnswers[data.answer].creators = [];
  }

  var userAnswer = data.answer.toLowerCase();
  var realAnswers = [this.activeQuestion.answer.toLowerCase()];
  for(ans in this.activeQuestion.alternate_spellings)
    realAnswers.push(ans.toLowerCase());

  if(realAnswers.indexOf(userAnswer) != -1) {
    cb(false);
    return;
  }

  if(this.activeQuestion.userAnswers[data.answer].creators.indexOf(id) == -1)
    this.activeQuestion.userAnswers[data.answer].creators.push(id);

  cb(true);

  if(Object.keys(this.activeQuestion.userAnswers).length >= Object.keys(io.sockets.adapter.rooms[this.room].sockets).length) {
    clearTimeout(this.endSubTimer);
    endSubmissionTime.bind(this)();
  }
}

liarliar.prototype.selectAnswer = function(id, data, cb) {
  if(this.activeQuestion.userAnswers[data.answer].votes === undefined)
    this.activeQuestion.userAnswers[data.answer].votes = [];

  this.activeQuestion.userVotes += 1;
  this.activeQuestion.userAnswers[data.answer].votes.push(id);

  if(this.activeQuestion.userVotes >= Object.keys(io.sockets.adapter.rooms[this.room].sockets).length - 1) {
    clearTimeout(this.endSelTimer);
    endSelectionTime.bind(this)();
  }
}

function transformQuestion(question) {
  return question.replace("<BLANK>", "________");
}

liarliar.prototype.start = function() {
  this.startRound();
  setTimeout(this.checkRoomStatus.bind(this), 5000);
}

liarliar.prototype.startRound = function() {
  this.questionID = parseInt(Math.random() * (Object.keys(questions).length - 1));
  this.activeQuestion = questions[this.questionID];
  this.activeQuestion.answer = this.activeQuestion.answer.toLowerCase();
  this.activeQuestion.userAnswers = {};
  this.activeQuestion.userVotes = 0;
  this.activeQuestion.userAnswers[this.activeQuestion.answer] = {correct: true};
  this.activeQuestion.userAnswers[this.activeQuestion.answer].creators = [];

  console.log(this.activeQuestion.answer);

  this.io.to(this.room).emit('question_selected', {question: transformQuestion(this.activeQuestion.question)});
  this.endSubTimer = setTimeout(endSubmissionTime.bind(this), 30000);
}

liarliar.prototype.checkRoomStatus = function() {
  if(this.io.sockets.adapter.rooms[this.room] === undefined) {
    this.end(this.room);
    return false;
  }

  return true;
}

liarliar.prototype.endGame = function() {
  setTimeout(function() {
    this.end(this.room)
  }.bind(this), 500);
}

function endSubmissionTime() {
  if(!this.checkRoomStatus()) {
    return;
  }

  if(this.activeQuestion.userAnswers[this.activeQuestion.answer] === undefined) {
    this.activeQuestion.userAnswers[this.activeQuestion.answer] = {};
  }

  var answers = Object.keys(this.activeQuestion.userAnswers);
  while(answers.length < 9) {
    var index = Math.floor(Math.random() * (this.activeQuestion.suggestions.length));
    var suggest = this.activeQuestion.suggestions[index];
    if(answers.indexOf(suggest) == -1) {
      answers.push(suggest);
      this.activeQuestion.userAnswers[suggest] = {};
    }
  }

  var shuffledAnswers = [];
  while(shuffledAnswers.length < 9) {
    var index = Math.floor(Math.random() * (answers.length));
    shuffledAnswers.push(answers[index]);
    answers.splice(index, 1);
  }

  var clients = io.sockets.adapter.rooms[this.room].sockets;
  for(client in clients) {
    var ans = [];
    for(a in shuffledAnswers) {
      a = shuffledAnswers[a];
      if(this.activeQuestion.userAnswers[a].creators === undefined || this.activeQuestion.userAnswers[a].correct) {
        ans.push(a);
      } else if(this.activeQuestion.userAnswers[a].creators.indexOf(client) == -1) {
        ans.push(a);
      }
    }
    this.io.to(client).emit('answers_posted', {answers: ans});
  }
  this.endSelTimer = setTimeout(endSelectionTime.bind(this), 30000);
}

function endSelectionTime() {
  if(!this.checkRoomStatus()) {
    return;
  }

  var scores = {};

  var roundAnswers = this.activeQuestion.userAnswers;

  var clients = io.sockets.adapter.rooms[this.room].sockets;

  for(client in clients) {
    if(this.players[client] !== undefined) {
      scores[client] = {
        id: client,
        nick: this.players[client],
        score: 0
      };
    }
    this.io.to(client).emit('scores_posted', {scores: scores});
  }

  for(ans in roundAnswers) {
    var ans = roundAnswers[ans];
    for(voter in ans.votes) {
      voter = ans.votes[voter];
      if(ans.correct) {
        scores[voter].score += 1000;
      } else {
        for(crtr in ans.creators) {
          crtr = ans.creators[crtr];
          scores[crtr].score += 500;
        }
        if(ans.creators === undefined) {
          scores[voter].score -= 250;
        }
      }
    }
  }

  this.io.to(this.room).emit('scores_posted', {scores: scores, correctAnswer: this.activeQuestion.answer});
}

module.exports = liarliar;
<|endoftext|>


<commit_before>'use strict';

var util = require('util');

var re4Integer = '-?(?:0|[1-9][0-9]*)';

var re = exports.re = {
    identifier: new RegExp('^[a-zA-Z_\$]+[a-zA-Z0-9_]*'),
    integer: new RegExp(re4Integer),
    range: new RegExp(util.format('^(%s)?\\:(%s)?(?:\\:(%s)?)?', re4Integer, re4Integer, re4Integer)),
    q_string: new RegExp('^\'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*\''),
    qq_string: new RegExp('^\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"')
};

var types = {
    ROOT: {
        type: 'root'
    },
    WILDCARD: {
        type: 'wildcard'
    },
    RECURSIVE_DESCENT: {
        type: 'recursive_descent'
    },
    PARENT: {
        type: 'parent'
    }
};

var propertyUpdate = {
    identifier: function (properties, reExecResult) {
        properties.push(reExecResult[0]);
    },
    integer: function (properties, reExecResult) {
        var i = parseInt(reExecResult[0], 10);
        properties.push(i);
    },
    q_string: function (properties, reExecResult) {
        properties.push(reExecResult[1]);
    },
    qq_string: function (properties, reExecResult) {
        properties.push(reExecResult[1]);
    },
    range: function (properties, reExecResult) {
        var start = (reExecResult[1] && parseInt(reExecResult[1], 10)) || 0;
        var end = (reExecResult[2] && parseInt(reExecResult[2], 10)) || null;
        var step = (reExecResult[3] && parseInt(reExecResult[3], 10)) || 1;
        properties.push({
            start: start,
            end: end,
            step: step
        });
    }
};

var expandSubscriptProperties = exports.expandSubscriptProperties = function expandSubscriptProperties(subscript, properties) {
    var reKeys = ['range', 'identifier', 'integer', 'q_string', 'qq_string'];
    var n = reKeys.length;
    for (var i = 0; i < n; ++i) {
        var key = reKeys[i];
        var r = re[key];
        var result = r.exec(subscript);
        if (result) {
            propertyUpdate[key](properties, result);
            var nResult = result[0].length;
            if (nResult === subscript.length) {
                return true;
            }
            if (subscript[nResult] !== ',') {
                var msg = util.format('Invalid character "%s" in %s.', subscript[nResult], subscript);
                throw new Error(msg);
            }
            subscript = subscript.substring(nResult + 1);
            return expandSubscriptProperties(subscript, properties);
        }
    }
    return false;
};

var subscriptToNode = function (subscript) {
    var n = subscript.length;
    if (n === 0) {
        throw new Error('Empty subscript in path.');
    }

    if (subscript === '*') {
        return types.WILDCARD;
    }

    var c = subscript.charAt(0);
    var ce = subscript.charAt(n - 1);

    if (c === '(') {
        if (ce !== ')') {
            throw new Error('Subscript starts with "(" but does not end with ")".');
        }
        return {
            type: 'script',
            parameter: subscript.substring(1, n - 1)
        };
    }

    if (c === '?') {
        if ((n < 2) || (subscript.charAt(1) !== '(')) {
            throw new Error('Subscript start with "?" but the second character is not "("');
        }
        if (ce !== ')') {
            throw new Error('Subscript starts with "?(" but does not end with ")".');
        }
        return {
            type: 'filter_script',
            parameter: subscript.substring(2, n - 1)
        };
    }

    if ((c === '$') && (n > 1) && (subscript.charAt(1) === '.')) {
        return {
            type: 'subpath',
            parameter: subscript
        };
    }

    var properties = [];
    var result = expandSubscriptProperties(subscript, properties);
    if (result) {
        return {
            type: 'properties',
            parameter: properties
        };
    }
    if (properties.length > 0) {
        throw new Error('Invalid subscript: ' + subscript);
    }

    return subscript;
};

var updateNodesWithProperty = function (property, nodes) {
    var n = property.length;
    if (property.substring(n - 2, n) === '()') {
        nodes.push({
            type: 'fn',
            parameter: property.substring(0, n - 2)
        });
        return;
    }
    nodes.push({
        type: 'property',
        parameter: property
    });
};

var normalize = exports.normalize = function (expr) {
    var exprList = [];
    var index = 0;
    var length = expr.length;
    var lastIndex = 0;
    while (index < length) {
        var c = expr.charAt(index);
        if (c === '.') {
            var cp1 = expr.charAt(index + 1);
            if (lastIndex !== index) {
                var subExpr = expr.substring(lastIndex, index);
                updateNodesWithProperty(subExpr, exprList);
            }
            if (cp1 === '.') {
                exprList.push(types.RECURSIVE_DESCENT);
                ++index;
            } else if (index + 1 === length) {
                throw new Error('Incomplete path.');
            }
            ++index;
            if (expr.charAt(index) === '.') {
                throw new Error('Invalid syntax "...".');
            }
            lastIndex = index;
            continue;
        }
        if (c === '[') {
            if (lastIndex !== index) {
                var subExprLB = expr.substring(lastIndex, index);
                updateNodesWithProperty(subExprLB, exprList);
            }
            var openBrackets = 1;
            ++index;
            lastIndex = index;
            while (index < length) {
                var cinside = expr.charAt(index);
                if (cinside === '[') {
                    ++openBrackets;
                    ++index;
                    continue;
                }
                if (cinside === ']') {
                    --openBrackets;
                    if (openBrackets === 0) {
                        var subExprInside = expr.substring(lastIndex, index);
                        var scriptResult = subscriptToNode(subExprInside);
                        exprList.push(scriptResult);
                        ++index;
                        lastIndex = index;
                        break;
                    }
                }
                ++index;
            }
            continue;
        }
        if (c === '*') {
            if (lastIndex === index) {
                exprList.push(types.WILDCARD);
                ++index;
                lastIndex = index;
                continue;
            }
        }
        if (c === '$') {
            if (lastIndex === index) {
                exprList.push(types.ROOT);
                ++index;
                lastIndex = index;
                continue;
            }
        }
        if (c === '^') {
            if (lastIndex === index) {
                exprList.push(types.PARENT);
                ++index;
                lastIndex = index;
                continue;
            }
        }
        ++index;
    }
    if (lastIndex < index) {
        var subExprFinal = expr.substring(lastIndex, index);
        updateNodesWithProperty(subExprFinal, exprList);
    }
    return exprList;
};
<commit_msg>code cleaning<commit_after>'use strict';

var util = require('util');

var re4Integer = '-?(?:0|[1-9][0-9]*)';

var re = exports.re = {
    identifier: new RegExp('^[a-zA-Z_\$]+[a-zA-Z0-9_]*'),
    integer: new RegExp(re4Integer),
    range: new RegExp(util.format('^(%s)?\\:(%s)?(?:\\:(%s)?)?', re4Integer, re4Integer, re4Integer)),
    q_string: new RegExp('^\'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*\''),
    qq_string: new RegExp('^\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"')
};

var types = {
    ROOT: {
        type: 'root'
    },
    WILDCARD: {
        type: 'wildcard'
    },
    RECURSIVE_DESCENT: {
        type: 'recursive_descent'
    },
    PARENT: {
        type: 'parent'
    }
};

var propertyUpdate = {
    identifier: function (properties, reExecResult) {
        properties.push(reExecResult[0]);
    },
    integer: function (properties, reExecResult) {
        var i = parseInt(reExecResult[0], 10);
        properties.push(i);
    },
    q_string: function (properties, reExecResult) {
        properties.push(reExecResult[1]);
    },
    qq_string: function (properties, reExecResult) {
        properties.push(reExecResult[1]);
    },
    range: function (properties, reExecResult) {
        var start = (reExecResult[1] && parseInt(reExecResult[1], 10)) || 0;
        var end = (reExecResult[2] && parseInt(reExecResult[2], 10)) || null;
        var step = (reExecResult[3] && parseInt(reExecResult[3], 10)) || 1;
        properties.push({
            start: start,
            end: end,
            step: step
        });
    }
};

var expandSubscriptProperties = exports.expandSubscriptProperties = function expandSubscriptProperties(subscript, properties) {
    var reKeys = ['range', 'identifier', 'integer', 'q_string', 'qq_string'];
    var n = reKeys.length;
    for (var i = 0; i < n; ++i) {
        var key = reKeys[i];
        var r = re[key];
        var result = r.exec(subscript);
        if (result) {
            propertyUpdate[key](properties, result);
            var nResult = result[0].length;
            if (nResult === subscript.length) {
                return true;
            }
            if (subscript[nResult] !== ',') {
                var msg = util.format('Invalid character "%s" in %s.', subscript[nResult], subscript);
                throw new Error(msg);
            }
            subscript = subscript.substring(nResult + 1);
            return expandSubscriptProperties(subscript, properties);
        }
    }
    return false;
};

var subscriptToNode = function (subscript) {
    var n = subscript.length;
    if (n === 0) {
        throw new Error('Empty subscript in path.');
    }

    if (subscript === '*') {
        return types.WILDCARD;
    }

    var c = subscript.charAt(0);
    var ce = subscript.charAt(n - 1);

    if (c === '(') {
        if (ce !== ')') {
            throw new Error('Subscript starts with "(" but does not end with ")".');
        }
        return {
            type: 'script',
            parameter: subscript.substring(1, n - 1)
        };
    }

    if (c === '?') {
        if ((n < 2) || (subscript.charAt(1) !== '(')) {
            throw new Error('Subscript start with "?" but the second character is not "("');
        }
        if (ce !== ')') {
            throw new Error('Subscript starts with "?(" but does not end with ")".');
        }
        return {
            type: 'filter_script',
            parameter: subscript.substring(2, n - 1)
        };
    }

    if ((c === '$') && (n > 1) && (subscript.charAt(1) === '.')) {
        return {
            type: 'subpath',
            parameter: subscript
        };
    }

    var properties = [];
    var result = expandSubscriptProperties(subscript, properties);
    if (result) {
        return {
            type: 'properties',
            parameter: properties
        };
    }
    if (properties.length > 0) {
        throw new Error('Invalid subscript: ' + subscript);
    }

    return subscript;
};

var updateNodesWithProperty = function (property, nodes) {
    var n = property.length;
    if (property.substring(n - 2, n) === '()') {
        nodes.push({
            type: 'fn',
            parameter: property.substring(0, n - 2)
        });
        return;
    }
    nodes.push({
        type: 'property',
        parameter: property
    });
};

var findMatchingSquareBracket = function (path, index) {
    var length = path.length;
    var openBrackets = 1;
    while (index < length) {
        var c = path.charAt(index);
        if (c === '[') {
            ++openBrackets;
            ++index;
        } else if (c === ']') {
            --openBrackets;
            if (openBrackets === 0) {
                return index;
            }
            ++index;
        } else {
            ++index;
        }
    }
    return index;
};

exports.normalize = function (expr) {
    var exprList = [];
    var index = 0;
    var length = expr.length;
    var lastIndex = 0;
    while (index < length) {
        var c = expr.charAt(index);
        if (c === '.') {
            var cp1 = expr.charAt(index + 1);
            if (lastIndex !== index) {
                var subExpr = expr.substring(lastIndex, index);
                updateNodesWithProperty(subExpr, exprList);
            }
            if (cp1 === '.') {
                exprList.push(types.RECURSIVE_DESCENT);
                ++index;
            } else if (index + 1 === length) {
                throw new Error('Incomplete path.');
            }
            ++index;
            if (expr.charAt(index) === '.') {
                throw new Error('Invalid syntax "...".');
            }
            lastIndex = index;
            continue;
        }
        if (c === '[') {
            if (lastIndex !== index) {
                var subExprLB = expr.substring(lastIndex, index);
                updateNodesWithProperty(subExprLB, exprList);
            }
            ++index;
            lastIndex = index;
            index = findMatchingSquareBracket(expr, index);
            if (index < length) {
                var subExprInside = expr.substring(lastIndex, index);
                var scriptResult = subscriptToNode(subExprInside);
                exprList.push(scriptResult);
                ++index;
                lastIndex = index;
            }
            continue;
        }
        if (c === '*') {
            if (lastIndex === index) {
                exprList.push(types.WILDCARD);
                ++index;
                lastIndex = index;
                continue;
            }
        }
        if (c === '$') {
            if (lastIndex === index) {
                exprList.push(types.ROOT);
                ++index;
                lastIndex = index;
                continue;
            }
        }
        if (c === '^') {
            if (lastIndex === index) {
                exprList.push(types.PARENT);
                ++index;
                lastIndex = index;
                continue;
            }
        }
        ++index;
    }
    if (lastIndex < index) {
        var subExprFinal = expr.substring(lastIndex, index);
        updateNodesWithProperty(subExprFinal, exprList);
    }
    return exprList;
};
<|endoftext|>


<commit_before>module.exports = function() {
  var parseVariables,
      gonzales = require('gonzales-pe'),
      gonzo = require('gonzales-ast'),
      _ = require('lodash');

  function astToSrc(ast, syntax) {
    return gonzales.astToSrc({
      ast: ast,
      syntax: syntax
    });
  }

  // Parse SASS variables to object
  parseVariables = function(string, syntax) {

    syntax = syntax || 'scss'

    var out = {},
      ast = gonzales.srcToAST({
        src: string,
        syntax: syntax
      });

    gonzo.traverse(ast, [{
      test: function(name, nodes) {
        return name === 'declaration' && nodes[1][0] === 'variable';
      },
      process: function(nodes) {
        var varName = nodes[1][1][1].filter(function(element) {
            return element != 'ident'
          })[0],
          varVal = astToSrc(nodes[4], syntax);

        out[varName] = varVal;
      }
    }, {
      test: function(name, nodes) {
        return name === 'atrules';
      },
      process: function(nodes) {
        var varName = nodes[1][1][1],
          varVal = '';

        /* Grabs all the listed values
         * Fix then https://github.com/tonyganch/gonzales-pe/issues/17 is fixed */
        nodes.forEach(function(element) {
          if (
            element == 'atrules' ||
            element[0] == 'atkeyword'
          ) {
            return
          };
          if (
            element[0] == 'operator' &&
            element[1] == ':'
          ) {
            return;
          }
          varVal += astToSrc(element, 'less');
        });
        varVal = varVal.trim();
        out[varName] = varVal;
      }
    }]);

    return out;
  }

  // Modifies string so that variables passed in object are updated
  setVariables = function(string, variables) {
    var sorted = [], lines = [],
      ast, result, changeVariable;

    changeVariable = function(ast, key, value) {
      return gonzo.traverse(ast, [
        {
          test: function(name, nodes) {
            return name === 'declaration' && nodes[1][0] === 'variable' && nodes[1][1].indexOf(key) !== -1;
          },
          process: function(node) {
            node[4][1] = value;
            return node;
          }
        }
      ]);
    }

    ast = gonzales.srcToAST({
      src: string,
      syntax: 'scss'
    });

    _.forEach(variables, function(value, key){
      ast = changeVariable(ast, key, value);
    });

    result = gonzales.astToSrc({
      ast: ast,
      syntax: 'scss'
    });
    return result;
  }

  return {
    parseVariables: parseVariables,
    setVariables: setVariables
  }
}
<commit_msg>Normal overwriting of multiple values<commit_after>module.exports = function() {
  var parseVariables,
      gonzales = require('gonzales-pe'),
      gonzo = require('gonzales-ast'),
      _ = require('lodash');

  function astToSrc(ast, syntax) {
    return gonzales.astToSrc({
      ast: ast,
      syntax: syntax
    });
  }

  // Parse SASS variables to object
  parseVariables = function(string, syntax) {

    syntax = syntax || 'scss'

    var out = {},
      ast = gonzales.srcToAST({
        src: string,
        syntax: syntax
      });

    gonzo.traverse(ast, [{
      test: function(name, nodes) {
        return name === 'declaration' && nodes[1][0] === 'variable';
      },
      process: function(nodes) {
        var varName = nodes[1][1][1].filter(function(element) {
            return element != 'ident'
          })[0],
          varVal = astToSrc(nodes[4], syntax);

        out[varName] = varVal;
      }
    }, {
      test: function(name, nodes) {
        return name === 'atrules';
      },
      process: function(nodes) {
        var varName = nodes[1][1][1],
          varVal = '';

        /* Grabs all the listed values
         * Fix then https://github.com/tonyganch/gonzales-pe/issues/17 is fixed */
        nodes.forEach(function(element) {
          if (
            element == 'atrules' ||
            element[0] == 'atkeyword'
          ) {
            return
          };
          if (
            element[0] == 'operator' &&
            element[1] == ':'
          ) {
            return;
          }
          varVal += astToSrc(element, 'less');
        });
        varVal = varVal.trim();
        out[varName] = varVal;
      }
    }]);

    return out;
  }

  // Modifies string so that variables passed in object are updated
  setVariables = function(string, variables) {
    var sorted = [], lines = [],
      ast, result, changeVariable;

    changeVariable = function(ast, key, value) {
      return gonzo.traverse(ast, [
        {
          test: function(name, nodes) {
            return name === 'declaration' && nodes[1][0] === 'variable' && nodes[1][1].indexOf(key) !== -1;
          },
          process: function(node) {
            node[4] = [
            'value',
             value
            ]
            return node;
          }
        }
      ]);
    }

    ast = gonzales.srcToAST({
      src: string,
      syntax: 'scss'
    });

    _.forEach(variables, function(value, key){
      ast = changeVariable(ast, key, value);
    });

    result = gonzales.astToSrc({
      ast: ast,
      syntax: 'scss'
    });
    return result;
  }

  return {
    parseVariables: parseVariables,
    setVariables: setVariables
  }
}
<|endoftext|>


<commit_before>import database from '../models';
import ResponseHandler from '../helpers/ResponseHandler';
import Authenticator from '../middlewares/Authenticator';
import ErrorHandler from '../helpers/ErrorHandler';
// declare the usersDB
const userDB = database.User;

/**
 * Class for the UsersController
 * to handle connections to our database
 */
class UserController {

  /**
   * Method to fetch save fields from a user object
   * @param {Object} user - User object
   * @param {String} token - token to be added to the User
   * Object sent (Optional)
   * @return {Object} - new User object containing fields
   * consider safe for public view
   */
  static getSafeUserFields(user, token) {
    return {
      id: user.id,
      email: user.email,
      firstName: user.firstName,
      lastName: user.lastName,
      createdAt: user.createdAt,
      token
    };
  }

  /**
   * Method to create a new User (POST)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static createUser(request, response) {
    const newUser = request.body;
    newUser.roleId = newUser.roleId || 2;
    userDB.create(newUser)
    .then((user) => {
      const token = Authenticator.generateToken(user);
      Authenticator.setUserActiveToken(user, token)
      .then(() => {
        ResponseHandler.sendResponse(
          response,
          201,
          Object.assign(
            {},
            UserController.getSafeUserFields(user, token),
            { roleId: user.roleId }
          )
        );
      });
    })
    .catch((error) => {
      ErrorHandler.handleRequestError(response, error);
    });
  }

  /**
   * Method to delete a specific user (DELETE)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static deleteUser(request, response) {
    const deleteId = Number(request.params.id);
    userDB.destroy({
      where: {
        id: deleteId
      }
    }).then((rowDeleted) => {
      if (rowDeleted === 1) {
        ResponseHandler.sendResponse(
          response,
          200,
          { message: 'User Deleted' }
        );
      } else {
        ResponseHandler.send404(response);
      }
    });
  }

  /**
   * Method to update a specific user (PUT)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static updateUser(request, response) {
    userDB.findById(request.params.id)
    .then((user) => {
      if (user) {
        user.update(request.body)
        .then((updatedUser) => {
          ResponseHandler.sendResponse(
            response,
            200,
            UserController.getSafeUserFields(updatedUser)
          );
        })
        .catch((error) => {
          ErrorHandler.handleRequestError(response, error);
        });
      } else {
        ResponseHandler.send404(response);
      }
    });
  }

  /**
   * Method to fetch a specific user (GET)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static fetchUser(request, response) {
    const searchId = Number(request.params.id);
    userDB.findById(searchId)
    .then((user) => {
      if (user) {
        ResponseHandler.sendResponse(
          response,
          200,
          UserController.getSafeUserFields(user)
        );
      } else {
        ResponseHandler.send404(response);
      }
    })
    .catch((error) => {
      ErrorHandler.handleRequestError(
        response,
        error
      );
    });
  }

  /**
   * Method to fetch all users (GET)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static fetchUsers(request, response) {
    const search = request.query.search;
    const limit = request.query.limit;
    const offset = request.query.offset;
    const page = request.query.page;
    const queryBuilder = {
      order: '"createdAt" DESC'
    };
    if (limit) {
      queryBuilder.limit = limit;
    }
    if (offset) {
      queryBuilder.offset = offset;
    }
    if (page) {
      // override offset if a page is specified, and default limit is 10
      const pageLimit = limit || 10;
      queryBuilder.offset = (page * pageLimit) - pageLimit;
      queryBuilder.limit = pageLimit;
    }
    if (search) {
      const searchList = search.split(/\s+/);
      queryBuilder.where = {
        $or: [{ firstName: { $iLike: { $any: searchList } } },
        { lastName: { $iLike: { $any: searchList } } },
        { email: { $iLike: { $any: searchList } } }]
      };
    }
    userDB.findAndCountAll(queryBuilder)
    .then((users) => {
      if (users.rows.length > 0) {
        ResponseHandler.sendResponse(
          response,
          200,
          {
            users: users.rows
              .map(user => UserController.getSafeUserFields(user)),
            total: users.count
          }
        );
      } else {
        ResponseHandler.send404(response);
      }
    });
  }

  /**
   * Method to login a specific user (POST)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static loginUser(request, response) {
    if (request.body.email && request.body.password) {
      userDB.findOne({
        where: {
          email: request.body.email
        }
      })
      .then((user) => {
        if (user) {
          if (user.verifyPassword(request.body.password)) {
            const token = Authenticator.generateToken(user);
            // update user activeToken
            user.update({ activeToken: token })
            .then(() => {
              // send the token here
              ResponseHandler.sendResponse(
                response,
                200,
                { token }
              );
            });
          } else {
            ResponseHandler.send401(
              response,
              { message: 'Wrong Password' }
            );
          }
        } else {
          ResponseHandler.send404(response);
        }
      });
    } else {
      ResponseHandler.send400(
        response,
        { message: 'Missing Login Credentials' }
      );
    }
  }

  /**
   * Method to logout a specific user (POST)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static logoutUser(request, response) {
    const id = request.decoded.userId;
    userDB.findById(id)
    .then((user) => {
      user.update({ activeToken: null })
      .then(() => {
        ResponseHandler.sendResponse(
          response,
          200,
          { message: 'Logout Successful' }
        );
      });
    });
  }

  /**
   * Method to fetch all documents of a specific user
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{Void} - returns void
   */
  static fetchUserDocuments(request, response) {
    const id = Number(request.params.id);
    const requesterRoleId = request.decoded.roleId;
    const requesterId = request.decoded.userId;
    userDB.findById(id, {
      attributes: ['id', 'firstName', 'lastName', 'email', 'roleId'],
      include: {
        model: database.Document,
        attributes: ['id', 'access', 'title', 'content', 'ownerId', 'createdAt']
      }
    })
    .then((user) => {
      if (user) {
        const documents = user.Documents.filter((document) => {
          if (Authenticator.verifyAdmin(requesterRoleId)) {
            return true;
          // for other users, ensure they have appropriate access rights
          } else if (
            (document.access === 'public' ||
            requesterRoleId === user.roleId)
            && document.access !== 'private') {
            return true;
          } else if (document.access === 'private'
            && document.ownerId === requesterId) {
            return true;
          }
          return false;
        });
        const safeUser = Object.assign(
          {},
          UserController.getSafeUserFields(user),
          { documents });
        ResponseHandler.sendResponse(
          response,
          200,
          safeUser
        );
      } else {
        ResponseHandler.send404(response);
      }
    });
  }
}

export default UserController;
<commit_msg>fix(user controller): return necessary user details along with token on user sign in<commit_after>import database from '../models';
import ResponseHandler from '../helpers/ResponseHandler';
import Authenticator from '../middlewares/Authenticator';
import ErrorHandler from '../helpers/ErrorHandler';
// declare the usersDB
const userDB = database.User;

/**
 * Class for the UsersController
 * to handle connections to our database
 */
class UserController {

  /**
   * Method to fetch save fields from a user object
   * @param {Object} user - User object
   * @param {String} token - token to be added to the User
   * Object sent (Optional)
   * @return {Object} - new User object containing fields
   * consider safe for public view
   */
  static getSafeUserFields(user, token) {
    return {
      id: user.id,
      email: user.email,
      firstName: user.firstName,
      lastName: user.lastName,
      createdAt: user.createdAt,
      token
    };
  }

  /**
   * Method to create a new User (POST)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static createUser(request, response) {
    const newUser = request.body;
    newUser.roleId = newUser.roleId || 2;
    userDB.create(newUser)
    .then((user) => {
      const token = Authenticator.generateToken(user);
      Authenticator.setUserActiveToken(user, token)
      .then(() => {
        ResponseHandler.sendResponse(
          response,
          201,
          Object.assign(
            {},
            UserController.getSafeUserFields(user, token),
            { roleId: user.roleId }
          )
        );
      });
    })
    .catch((error) => {
      ErrorHandler.handleRequestError(response, error);
    });
  }

  /**
   * Method to delete a specific user (DELETE)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static deleteUser(request, response) {
    const deleteId = Number(request.params.id);
    userDB.destroy({
      where: {
        id: deleteId
      }
    }).then((rowDeleted) => {
      if (rowDeleted === 1) {
        ResponseHandler.sendResponse(
          response,
          200,
          { message: 'User Deleted' }
        );
      } else {
        ResponseHandler.send404(response);
      }
    });
  }

  /**
   * Method to update a specific user (PUT)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static updateUser(request, response) {
    userDB.findById(request.params.id)
    .then((user) => {
      if (user) {
        user.update(request.body)
        .then((updatedUser) => {
          ResponseHandler.sendResponse(
            response,
            200,
            UserController.getSafeUserFields(updatedUser)
          );
        })
        .catch((error) => {
          ErrorHandler.handleRequestError(response, error);
        });
      } else {
        ResponseHandler.send404(response);
      }
    });
  }

  /**
   * Method to fetch a specific user (GET)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static fetchUser(request, response) {
    const searchId = Number(request.params.id);
    userDB.findById(searchId)
    .then((user) => {
      if (user) {
        ResponseHandler.sendResponse(
          response,
          200,
          UserController.getSafeUserFields(user)
        );
      } else {
        ResponseHandler.send404(response);
      }
    })
    .catch((error) => {
      ErrorHandler.handleRequestError(
        response,
        error
      );
    });
  }

  /**
   * Method to fetch all users (GET)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static fetchUsers(request, response) {
    const search = request.query.search;
    const limit = request.query.limit;
    const offset = request.query.offset;
    const page = request.query.page;
    const queryBuilder = {
      order: '"createdAt" DESC'
    };
    if (limit) {
      queryBuilder.limit = limit;
    }
    if (offset) {
      queryBuilder.offset = offset;
    }
    if (page) {
      // override offset if a page is specified, and default limit is 10
      const pageLimit = limit || 10;
      queryBuilder.offset = (page * pageLimit) - pageLimit;
      queryBuilder.limit = pageLimit;
    }
    if (search) {
      const searchList = search.split(/\s+/);
      queryBuilder.where = {
        $or: [{ firstName: { $iLike: { $any: searchList } } },
        { lastName: { $iLike: { $any: searchList } } },
        { email: { $iLike: { $any: searchList } } }]
      };
    }
    userDB.findAndCountAll(queryBuilder)
    .then((users) => {
      if (users.rows.length > 0) {
        ResponseHandler.sendResponse(
          response,
          200,
          {
            users: users.rows
              .map(user => UserController.getSafeUserFields(user)),
            total: users.count
          }
        );
      } else {
        ResponseHandler.send404(response);
      }
    });
  }

  /**
   * Method to login a specific user (POST)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static loginUser(request, response) {
    if (request.body.email && request.body.password) {
      userDB.findOne({
        where: {
          email: request.body.email
        }
      })
      .then((user) => {
        if (user) {
          if (user.verifyPassword(request.body.password)) {
            const token = Authenticator.generateToken(user);
            // update user activeToken
            user.update({ activeToken: token })
            .then(() => {
              // send the token here
              response.status(200).json({
                email: user.email,
                firstName: user.firstName,
                lastName: user.lastName,
                roleId: user.roleId,
                id: user.id,
                createdAt: user.createdAt,
                token
              });
            });
          } else {
            ResponseHandler.send401(
              response,
              { message: 'Wrong Password' }
            );
          }
        } else {
          ResponseHandler.send404(response);
        }
      });
    } else {
      ResponseHandler.send400(
        response,
        { message: 'Missing Login Credentials' }
      );
    }
  }

  /**
   * Method to logout a specific user (POST)
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{undefined} - returns undefined
   */
  static logoutUser(request, response) {
    const id = request.decoded.userId;
    userDB.findById(id)
    .then((user) => {
      user.update({ activeToken: null })
      .then(() => {
        ResponseHandler.sendResponse(
          response,
          200,
          { message: 'Logout Successful' }
        );
      });
    });
  }

  /**
   * Method to fetch all documents of a specific user
   * @param{Object} request - Request object
   * @param{Object} response - Response object
   * @return{Void} - returns void
   */
  static fetchUserDocuments(request, response) {
    const id = Number(request.params.id);
    const requesterRoleId = request.decoded.roleId;
    const requesterId = request.decoded.userId;
    userDB.findById(id, {
      attributes: ['id', 'firstName', 'lastName', 'email', 'roleId'],
      include: {
        model: database.Document,
        attributes: ['id', 'access', 'title', 'content', 'ownerId', 'createdAt']
      }
    })
    .then((user) => {
      if (user) {
        const documents = user.Documents.filter((document) => {
          if (Authenticator.verifyAdmin(requesterRoleId)) {
            return true;
          // for other users, ensure they have appropriate access rights
          } else if (
            (document.access === 'public' ||
            requesterRoleId === user.roleId)
            && document.access !== 'private') {
            return true;
          } else if (document.access === 'private'
            && document.ownerId === requesterId) {
            return true;
          }
          return false;
        });
        const safeUser = Object.assign(
          {},
          UserController.getSafeUserFields(user),
          { documents });
        ResponseHandler.sendResponse(
          response,
          200,
          safeUser
        );
      } else {
        ResponseHandler.send404(response);
      }
    });
  }
}

export default UserController;
<|endoftext|>