diff --git a/config_sample.json b/config_sample.json index e6da2d1..35ea54c 100644 --- a/config_sample.json +++ b/config_sample.json @@ -112,6 +112,7 @@ "*@a.com" ], "password":{ + "validateOldPassword": false, "regexValidation": "(?=.*\\d)(?=.*[A-Z])(?=.*[a-z]).{8}", "message": "Your password must be at least 8 characters and must contain at least one capital, one lower and one number.", "generatedRegex": "([a-z][\\d][A-Z]){3,4}", diff --git a/scripts/add_users.js b/scripts/add_users.js new file mode 100644 index 0000000..984aebe --- /dev/null +++ b/scripts/add_users.js @@ -0,0 +1,98 @@ +var async = require('async'), + fs = require('fs'), + nock = require('nock'), + userMng = require('../src/managers/user'), + config = require('../config.json'), + userDao = require('../src/managers/dao.js'); +/* + * Objects for `async.eachSeries` + */ + +// Function to apply to each fixture +var addFixture = function(fixture, callback) { + + var data = fixture; + + // Define user object to be passed to userMng + var pin = null; + var profileBody = { + id: data._id.$oid || data._id, + email: data.email, + password: data.password || (process.env.DEFAULT_PASS ? process.env.DEFAULT_PASS : "qwerty") + }; + + if(!profileBody.id || !profileBody.email || !profileBody.password) { + console.log("Missing mandatory parameter(s)"); + return callback(); + } + // Nock the createUser URL + nock('http://' + config.private_host + ':' + config.private_port + config.passThroughEndpoint.path, { reqheaders: { + 'Content-Type': 'application/json; charset=utf-8' + }}) + .post(config.passThroughEndpoint.path) + .reply(201,profileBody); + + // Save user data to database + userMng().createUser(profileBody, pin, function(err) { + if(err) { + + if (err.err === 'auth_proxy_user_error') { + console.log(profileBody.email + " " + err.des); + return callback(); + } + return callback(err); + } + console.log(profileBody.email + " added"); + return callback(); + }); + +}; + +/* + * Main part of the script: + * - Exports the function, or + * - Executes the function if running from CLI + */ +var runLoadFixtures = module.exports = function(fixtureFile, callback) { + + console.log("running Load Fixtures"); + + + async.eachSeries(fixtureFile, addFixture, callback); + +}; + +if (!module.parent) { // Run as CLI command exec + async.series([ + + // Start cipherLayer components (mongodb, redis...) + function connect(done) { + userDao.connect(done); + }, + + function drop(done) { + if(!process.env.DROP_DB) return done(); + console.log("Dropping database"); + userDao.deleteAllUsers(done); + }, + + function load(done) { + fixtureFile = require(__dirname + '/' + '../tests/fixtures/' + 'User.json'); + runLoadFixtures(fixtureFile,done); + }, + + function disconnect(done) { + userDao.disconnect(done); + } + + ], function(err) { + if (err) { + console.error(err); + process.exit(1); + } + + console.info('Fixtures loaded'); + process.exit(); + }); + +} diff --git a/src/managers/user.js b/src/managers/user.js index 21e2536..6f8f616 100644 --- a/src/managers/user.js +++ b/src/managers/user.js @@ -309,6 +309,28 @@ function setPassword(id, body, cbk){ } } +function validateOldPassword(username, oldPassword, cbk) { + + userDao.getAllUserFields(username, function(err, user) { + if (err) { + res.send(401, err); + return next(); + } + + cryptoMng.encrypt(oldPassword, function(encrypted){ + if (user.password !== encrypted) { + return cbk({ + err: 'invalid_old_password', + des: 'invalid password', + code: 401 + }); + } + + return cbk(); + }); + }); +} + //Aux functions function random (howMany, chars) { chars = chars || "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789"; @@ -352,6 +374,7 @@ module.exports = function(settings) { setPlatformData : setPlatformData, createUser : createUser, createUserByToken : createUserByToken, - setPassword: setPassword + setPassword: setPassword, + validateOldPassword: validateOldPassword }; }; diff --git a/src/middlewares/propagateRequest.js b/src/middlewares/propagateRequest.js index f31cfff..5fd99a1 100644 --- a/src/middlewares/propagateRequest.js +++ b/src/middlewares/propagateRequest.js @@ -34,6 +34,9 @@ function propagateRequest(req, res, next) { // if url is a direct proxy request, use http-proxy if (useDirectProxy) { + // add user id to proxy request headers + req.headers['x-user-id'] = req.options.headers['x-user-id']; + proxy.web(req, res, { target: 'http://' + config.private_host + ':' + config.private_port }); diff --git a/src/routes/user.js b/src/routes/user.js index 7fdeab3..6fdc76e 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -140,6 +140,46 @@ function createUserByToken(req, res, next) { }); } +function checkBody(req, res, next) { + var err; + if (!req.body){ + err = { + err: 'invalid_body', + des: 'The call to this url must have body.' + }; + res.send(400, err); + return next(false); + } + + return next(); +} + +function validateOldPassword(req, res, next) { + var err; + if (!config.password.validateOldPassword) { + return next(); + } + + if (!req.body.oldPassword) { + err = { + err: 'missing_password', + des: 'Missing old password validation' + }; + res.send(400, err); + return next(false); + } + + debug('validating old password', req.user.password, req.body); + + userMng().validateOldPassword(req.user.username, req.body.oldPassword, function(err){ + if (err) { + res.send(401, err); + return next(false); + } + return next(); + }); + +} function setPassword(req, res, next){ if(!req.body){ res.send(400, { @@ -172,7 +212,7 @@ function addRoutes(service){ service.post(config.passThroughEndpoint.path, createUserEndpoint); service.get('/user/activate', createUserByToken); - service.put('/user/me/password', checkAccessTokenParam, checkAuthHeader, decodeToken, findUser, setPassword); + service.put('/user/me/password', checkAccessTokenParam, checkAuthHeader, decodeToken, checkBody, findUser, validateOldPassword, setPassword); } module.exports = addRoutes; diff --git a/tests/fixtures/User.json b/tests/fixtures/User.json new file mode 100644 index 0000000..b2631f3 --- /dev/null +++ b/tests/fixtures/User.json @@ -0,0 +1,23 @@ +[ + { + "_id": {"$oid": "01f0000000000000003f0004"}, + "phone": "555-7891-2365", + "email": "nick@intelygenz.com", + "password": "1234", + "country": "PL" + }, + { + "_id": {"$oid": "01f0000000000000003f0002"}, + "phone": "555-8899-1324", + "email": "gustavo@intelygenz.com", + "password": "asdf", + "country": "AR" + }, + { + "_id": {"$oid": "01f0000000000000003f0003"}, + "phone": "555-0012-7453", + "email": "josemanuel@intelygenz.com", + "password": "abcd", + "country": "ES" + } +] \ No newline at end of file