diff --git a/src/password.js b/src/password.js new file mode 100644 index 000000000..e11ff9338 --- /dev/null +++ b/src/password.js @@ -0,0 +1,46 @@ +/* jslint node:true */ + +'use strict'; + +// From https://www.npmjs.com/package/password-generator + +exports = module.exports = { + generate: generate, + validate: validate +}; + +var assert = require('assert'), + generatePassword = require('password-generator'); + +// http://www.w3resource.com/javascript/form/example4-javascript-form-validation-password.html +var gPasswordTestRegExp = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,20}$/; + +var UPPERCASE_RE = /([A-Z])/g; +var LOWERCASE_RE = /([a-z])/g; +var NUMBER_RE = /([\d])/g; +var SPECIAL_CHAR_RE = /([\?\-])/g; + +function isStrongEnough(password) { + var uc = password.match(UPPERCASE_RE); + var lc = password.match(LOWERCASE_RE); + var n = password.match(NUMBER_RE); + var sc = password.match(SPECIAL_CHAR_RE); + + return uc && lc && n && sc; +} + +function generate() { + var password = ''; + + while (!isStrongEnough(password)) password = generatePassword(8, false, /[\w\d\?\-]/); + + return password; +} + +function validate(password) { + assert.strictEqual(typeof password, 'string'); + + if (!password.match(gPasswordTestRegExp)) return new Error('Password must be 8-20 character with at least one uppercase, one numeric and one special character'); + + return null; +} diff --git a/src/routes/user.js b/src/routes/user.js index 1dd5d72fe..29666bbf9 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -17,7 +17,7 @@ exports = module.exports = { }; var assert = require('assert'), - generatePassword = require('password-generator'), + generatePassword = require('../password.js').generate, HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, user = require('../user.js'), @@ -49,7 +49,7 @@ function createUser(req, res, next) { if ('displayName' in req.body && typeof req.body.displayName !== 'string') return next(new HttpError(400, 'displayName must be string')); var username = req.body.username; - var password = generatePassword(8, true /* memorable */); + var password = generatePassword(); var email = req.body.email; var sendInvite = req.body.invite; var displayName = req.body.displayName || ''; diff --git a/src/user.js b/src/user.js index 3c7f99fe4..b21c51c4e 100644 --- a/src/user.js +++ b/src/user.js @@ -31,6 +31,7 @@ var assert = require('assert'), userdb = require('./userdb.js'), tokendb = require('./tokendb.js'), clientdb = require('./clientdb.js'), + validatePassword = require('./password.js').validate, util = require('util'), validator = require('validator'), _ = require('underscore'); @@ -71,9 +72,6 @@ UserError.BAD_PASSWORD = 'Bad password'; UserError.BAD_TOKEN = 'Bad token'; UserError.NOT_ALLOWED = 'Not Allowed'; -// http://www.w3resource.com/javascript/form/example4-javascript-form-validation-password.html -var gPasswordTestRegExp = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,20}$/; - function listUsers(callback) { assert.strictEqual(typeof callback, 'function'); @@ -93,14 +91,6 @@ function validateUsername(username) { return null; } -function validatePassword(password) { - assert.strictEqual(typeof password, 'string'); - - if(!password.match(gPasswordTestRegExp)) return new UserError(UserError.BAD_PASSWORD, 'Password must be 8-20 character with at least one uppercase, one numeric and one special character'); - - return null; -} - function validateEmail(email) { assert.strictEqual(typeof email, 'string');