diff --git a/config.template.yaml b/config.template.yaml index c3bc995b..a4a883a6 100644 --- a/config.template.yaml +++ b/config.template.yaml @@ -57,6 +57,8 @@ youtube-v2-key: '' channel-save-interval: 5 # Limit for the number of channels a user can register max-channels-per-user: 5 +# Limit for the number of accounts an IP address can register +max-accounts-per-ip: 5 # Minimum number of seconds between guest logins from the same IP guest-login-delay: 60 # Block known Tor IP addresses diff --git a/lib/config.js b/lib/config.js index ddfbe640..0255bfeb 100644 --- a/lib/config.js +++ b/lib/config.js @@ -50,6 +50,7 @@ var defaults = { "youtube-v2-key": "", "channel-save-interval": 5, "max-channels-per-user": 5, + "max-accounts-per-ip": 5, "guest-login-delay": 60, "enable-tor-blocker": true, stats: { diff --git a/lib/database/accounts.js b/lib/database/accounts.js index 2672b1ff..b7039cd0 100644 --- a/lib/database/accounts.js +++ b/lib/database/accounts.js @@ -2,6 +2,7 @@ var $util = require("../utilities"); var bcrypt = require("bcrypt"); var db = require("../database"); +var Config = require("../config"); var registrationLock = {}; var blackHole = function () { }; @@ -98,41 +99,56 @@ module.exports = { // on the same user account registrationLock[lname] = true; - this.isUsernameTaken(name, function (err, taken) { + this.getAccounts(ip, function (err, accts) { if (err) { delete registrationLock[lname]; callback(err, null); return; } - - if (taken) { + + if (accts.length >= Config.get("max-accounts-per-ip")) { delete registrationLock[lname]; - callback("Username is already registered", null); + callback("You have registered too many accounts from this "+ + "computer.", null); return; } - bcrypt.hash(pw, 10, function (err, hash) { + module.exports.isUsernameTaken(name, function (err, taken) { 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) { + 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); - } else { - callback(null, { - name: name, - hash: hash - }); + 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 + }); + } + }); }); }); }); @@ -496,5 +512,17 @@ module.exports = { } db.query("SELECT * FROM `channels` WHERE owner=?", [name], callback); + }, + + /** + * Retrieves all names registered from a given IP + */ + getAccounts: function (ip, callback) { + if (typeof callback !== "function") { + return; + } + + db.query("SELECT name,global_rank FROM `users` WHERE `ip`=?", [ip], + callback); } }; diff --git a/lib/web/auth.js b/lib/web/auth.js index aaa4bafa..98f03a10 100644 --- a/lib/web/auth.js +++ b/lib/web/auth.js @@ -139,6 +139,7 @@ function handleRegisterPage(req, res) { return; } } + sendJade(res, "register", { registered: false, registerError: false