<commit_before>//var db = require("../database");
var $util = require("../utilities");
var bcrypt = require("bcrypt");
var db = require("../database");

var registrationLock = {};
var blackHole = function () { };

module.exports = {
    /**
     * Initialize the accounts table
     */
    init: function () {
        db.query("CREATE TABLE IF NOT EXISTS `users` (" +
                    "`id` INT NOT NULL AUTO_INCREMENT," +
                    "`name` VARCHAR(20) NOT NULL," +
                    "`password` VARCHAR(64) NOT NULL," +
                    "`global_rank` INT NOT NULL," +
                    "`email` VARCHAR(255) NOT NULL," +
                    "`profile` TEXT NOT NULL," +
                    "`ip` VARCHAR(39) NOT NULL," +
                    "`time` BIGINT NOT NULL, " +
                 "PRIMARY KEY(`id`), INDEX(`name`)) " +
                 "CHARACTER SET utf8");
    },

    /**
     * Check if a username is taken
     */
    isUsernameTaken: function (name, callback) {
        db.query("SELECT name FROM `users` WHERE name=?", [name],
        function (err, rows) {
            if (err) {
                callback(err, true);
                return;
            }
            callback(null, rows.length > 0);
        });
    },

    /**
     * Search for a user by name
     */
    search: function (name, fields, callback) {
        /* This bit allows it to accept varargs
           Function can be called as (name, callback) or
           (name, fields, callback)
        */
        if (typeof callback !== "function") {
            if (typeof fields === "function") {
                callback = fields;
                fields = ["name"];
            } else {
                return;
            }
        }

        // Don't allow search to return password hashes
        if (fields.indexOf("password") !== -1) {
            fields.splice(fields.indexOf("password"));
        }

        db.query("SELECT " + fields.join(",") + " FROM `users` WHERE name LIKE ?",
                 ["%"+name+"%"],
        function (err, rows) {
            if (err) {
                callback(err, true);
                return;
            }
            callback(null, rows);
        });
    },

    /**
     * Registers a new user account
     */
    register: function (name, pw, email, ip, callback) {
        // Start off with a boatload of error checking
        if (typeof callback !== "function") {
            callback = blackHole;
        }

        if (typeof name !== "string" || typeof pw !== "string") {
            callback("You must provide a nonempty username and password", null);
            return;
        }
        var lname = name.toLowerCase();

        if (registrationLock[lname]) {
            callback("There is already a registration in progress for "+name,
                     null);
            return;
        }

        if (!$util.isValidUserName(name)) {
            callback("Invalid username.  Usernames may consist of 1-20 " +
                     "characters a-z, A-Z, 0-9, -, _, and accented letters.",
                     null);
            return;
        }

        if (typeof email !== "string") {
            email = "";
        }

        if (typeof ip !== "string") {
            ip = "";
        }

        // From this point forward, actual registration happens
        // registrationLock prevents concurrent database activity
        // on the same user account
        registrationLock[lname] = true;

        this.isUsernameTaken(name, function (err, taken) {
            if (err) {
                delete registrationLock[lname];
                callback(err, null);
                return;
            }

            if (taken) {
                delete registrationLock[lname];
                callback("Username is already registered", null);
                return;
            }

            bcrypt.hash(pw, 10, function (err, hash) {
                if (err) {
                    delete registrationLock[lname];
                    callback(err, null);
                    return;
                }

                db.query("INSERT INTO `users` " +
                         "(`name`, `password`, `global_rank`, `email`, `ip`, `time`)" +
                         " VALUES " +
                         "(?, ?, ?, ?, ?, ?)",
                         [name, hash, 1, email, ip, Date.now()],
                function (err, res) {
                    delete registrationLock[lname];
                    if (err) {
                        callback(err, null);
                    } else {
                        callback(null, {
                            name: name,
                            hash: hash
                        });
                    }<commit_msg>Fix register<commit_after>//var db = require("../database");
var $util = require("../utilities");
var bcrypt = require("bcrypt");
var db = require("../database");

var registrationLock = {};
var blackHole = function () { };

module.exports = {
    /**
     * Initialize the accounts table
     */
    init: function () {
        db.query("CREATE TABLE IF NOT EXISTS `users` (" +
                    "`id` INT NOT NULL AUTO_INCREMENT," +
                    "`name` VARCHAR(20) NOT NULL," +
                    "`password` VARCHAR(64) NOT NULL," +
                    "`global_rank` INT NOT NULL," +
                    "`email` VARCHAR(255) NOT NULL," +
                    "`profile` TEXT NOT NULL," +
                    "`ip` VARCHAR(39) NOT NULL," +
                    "`time` BIGINT NOT NULL, " +
                 "PRIMARY KEY(`id`), INDEX(`name`)) " +
                 "CHARACTER SET utf8");
    },

    /**
     * Check if a username is taken
     */
    isUsernameTaken: function (name, callback) {
        db.query("SELECT name FROM `users` WHERE name=?", [name],
        function (err, rows) {
            if (err) {
                callback(err, true);
                return;
            }
            callback(null, rows.length > 0);
        });
    },

    /**
     * Search for a user by name
     */
    search: function (name, fields, callback) {
        /* This bit allows it to accept varargs
           Function can be called as (name, callback) or
           (name, fields, callback)
        */
        if (typeof callback !== "function") {
            if (typeof fields === "function") {
                callback = fields;
                fields = ["name"];
            } else {
                return;
            }
        }

        // Don't allow search to return password hashes
        if (fields.indexOf("password") !== -1) {
            fields.splice(fields.indexOf("password"));
        }

        db.query("SELECT " + fields.join(",") + " FROM `users` WHERE name LIKE ?",
                 ["%"+name+"%"],
        function (err, rows) {
            if (err) {
                callback(err, true);
                return;
            }
            callback(null, rows);
        });
    },

    /**
     * Registers a new user account
     */
    register: function (name, pw, email, ip, callback) {
        // Start off with a boatload of error checking
        if (typeof callback !== "function") {
            callback = blackHole;
        }

        if (typeof name !== "string" || typeof pw !== "string") {
            callback("You must provide a nonempty username and password", null);
            return;
        }
        var lname = name.toLowerCase();

        if (registrationLock[lname]) {
            callback("There is already a registration in progress for "+name,
                     null);
            return;
        }

        if (!$util.isValidUserName(name)) {
            callback("Invalid username.  Usernames may consist of 1-20 " +
                     "characters a-z, A-Z, 0-9, -, _, and accented letters.",
                     null);
            return;
        }

        if (typeof email !== "string") {
            email = "";
        }

        if (typeof ip !== "string") {
            ip = "";
        }

        // From this point forward, actual registration happens
        // registrationLock prevents concurrent database activity
        // on the same user account
        registrationLock[lname] = true;

        this.isUsernameTaken(name, function (err, taken) {
            if (err) {
                delete registrationLock[lname];
                callback(err, null);
                return;
            }

            if (taken) {
                delete registrationLock[lname];
                callback("Username is already registered", null);
                return;
            }

            bcrypt.hash(pw, 10, function (err, hash) {
                if (err) {
                    delete registrationLock[lname];
                    callback(err, null);
                    return;
                }

                db.query("INSERT INTO `users` " +
                         "(`name`, `password`, `global_rank`, `email`, `profile`, `ip`, `time`)" +
                         " VALUES " +
                         "(?, ?, ?, ?, '', ?, ?)",
                         [name, hash, 1, email, ip, Date.now()],
                function (err, res) {
                    delete registrationLock[lname];
                    if (err) {
                        callback(err, null);
                    } else {
                        callback(null, {
                            name: name,
                            hash: hash
                        });
                    }
{'fraction_non_alphanumeric': 0.12602739726027398, 'fraction_numerical': 0.004214963119072708, 'mean_word_length': 1.2394997640396412, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4789500', 'n_tokens_mistral': 2482, 'n_tokens_neox': 2306, 'n_words': 680}