diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 48b6c0ccab..dbf6c56925 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -30,6 +30,7 @@ "username-too-short": "Username too short", "username-too-long": "Username too long", + "password-too-long": "Password too long", "user-banned": "User banned", "user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post", diff --git a/src/controllers/authentication.js b/src/controllers/authentication.js index 47249b18e5..5894ff0784 100644 --- a/src/controllers/authentication.js +++ b/src/controllers/authentication.js @@ -216,25 +216,28 @@ function continueLogin(req, res, next) { } authenticationController.localLogin = function(req, username, password, next) { - if (!username || !password) { - return next(new Error('[[error:invalid-password]]')); + if (!username) { + return next(new Error('[[error:invalid-username]]')); } var userslug = utils.slugify(username); var uid, userData = {}; async.waterfall([ - function(next) { + function (next) { + user.isPasswordValid(password, next); + }, + function (next) { user.getUidByUserslug(userslug, next); }, - function(_uid, next) { + function (_uid, next) { if (!_uid) { return next(new Error('[[error:no-user]]')); } uid = _uid; user.auth.logAttempt(uid, req.ip, next); }, - function(next) { + function (next) { async.parallel({ userData: function(next) { db.getObjectFields('user:' + uid, ['password', 'banned', 'passwordExpiry'], next); @@ -244,7 +247,7 @@ authenticationController.localLogin = function(req, username, password, next) { } }, next); }, - function(result, next) { + function (result, next) { userData = result.userData; userData.uid = uid; userData.isAdmin = result.isAdmin; @@ -261,7 +264,7 @@ authenticationController.localLogin = function(req, username, password, next) { } Password.compare(password, userData.password, next); }, - function(passwordMatch, next) { + function (passwordMatch, next) { if (!passwordMatch) { return next(new Error('[[error:invalid-password]]')); } diff --git a/src/socket.io/user/profile.js b/src/socket.io/user/profile.js index ba5e46986c..8f8811ef06 100644 --- a/src/socket.io/user/profile.js +++ b/src/socket.io/user/profile.js @@ -74,7 +74,7 @@ module.exports = function(SocketUser) { } SocketUser.changePassword = function(socket, data, callback) { - if (!data || !data.uid || data.newPassword.length < meta.config.minimumPasswordLength) { + if (!data || !data.uid) { return callback(new Error('[[error:invalid-data]]')); } if (!socket.uid) { diff --git a/src/user/create.js b/src/user/create.js index 1f8656c040..c455b61e82 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -185,6 +185,11 @@ module.exports = function(User) { if (password.length < meta.config.minimumPasswordLength) { return callback(new Error('[[user:change_password_error_length]]')); } + + if (password.length > 4096) { + return callback(new Error('[[error:password-too-long]]')); + } + callback(); }; diff --git a/src/user/password.js b/src/user/password.js index b326313be4..e116edb867 100644 --- a/src/user/password.js +++ b/src/user/password.js @@ -1,5 +1,6 @@ 'use strict'; +var async = require('async'); var nconf = require('nconf'); var db = require('../database'); @@ -16,13 +17,21 @@ module.exports = function(User) { }; User.isPasswordCorrect = function(uid, password, callback) { - db.getObjectField('user:' + uid, 'password', function(err, hashedPassword) { - if (err || !hashedPassword) { - return callback(err); + password = password || ''; + async.waterfall([ + function (next) { + User.isPasswordValid(password, next); + }, + function (next) { + db.getObjectField('user:' + uid, 'password', next); + }, + function (hashedPassword, next) { + if (!hashedPassword) { + return callback(); + } + Password.compare(password, hashedPassword, next); } - - Password.compare(password || '', hashedPassword, callback); - }); + ], callback); }; User.hasPassword = function(uid, callback) { diff --git a/src/user/profile.js b/src/user/profile.js index e588d147d0..1c0a1564f1 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -1,17 +1,13 @@ 'use strict'; -var async = require('async'), - validator = require('validator'), - url = require('url'), - S = require('string'), - - utils = require('../../public/src/utils'), - meta = require('../meta'), - events = require('../events'), - db = require('../database'), - Password = require('../password'), - plugins = require('../plugins'); +var async = require('async'); +var S = require('string'); + +var utils = require('../../public/src/utils'); +var meta = require('../meta'); +var db = require('../database'); +var plugins = require('../plugins'); module.exports = function(User) { @@ -246,39 +242,32 @@ module.exports = function(User) { return callback(new Error('[[error:invalid-uid]]')); } - function hashAndSetPassword(callback) { - User.hashPassword(data.newPassword, function(err, hash) { - if (err) { - return callback(err); + async.waterfall([ + function (next) { + User.isPasswordValid(data.newPassword, next); + }, + function (next) { + if (parseInt(uid, 10) !== parseInt(data.uid, 10)) { + User.isAdministrator(uid, next); + } else { + User.isPasswordCorrect(uid, data.currentPassword, next); + } + }, + function (isAdminOrPasswordMatch, next) { + if (!isAdminOrPasswordMatch) { + return next(new Error('[[error:change_password_error_wrong_current]]')); } + User.hashPassword(data.newPassword, next); + }, + function (hashedPassword, next) { async.parallel([ - async.apply(User.setUserField, data.uid, 'password', hash), + async.apply(User.setUserField, data.uid, 'password', hashedPassword), async.apply(User.reset.updateExpiry, data.uid) - ], callback); - }); - } - - if (!utils.isPasswordValid(data.newPassword)) { - return callback(new Error('[[user:change_password_error]]')); - } - - if (parseInt(uid, 10) !== parseInt(data.uid, 10)) { - User.isAdministrator(uid, function(err, isAdmin) { - if (err || !isAdmin) { - return callback(err || new Error('[[user:change_password_error_privileges')); - } - - hashAndSetPassword(callback); - }); - } else { - User.isPasswordCorrect(uid, data.currentPassword, function(err, correct) { - if (err || !correct) { - return callback(err || new Error('[[user:change_password_error_wrong_current]]')); - } - - hashAndSetPassword(callback); - }); - } + ], function(err) { + next(err); + }); + } + ], callback); }; };