From 651596c6a61f14e5773f1f24e512e90deec37124 Mon Sep 17 00:00:00 2001 From: Railag Date: Mon, 17 Dec 2018 15:37:53 +0300 Subject: [PATCH] bug(fix) fixed deprecation warnings (EWC-422) --- src/controllers/user-controller.js | 17 +-- src/helpers/app-helper.js | 19 +++- src/services/connector-service.js | 4 +- src/services/user-service.js | 12 +- test/src/controllers/user-controller.test.js | 112 ++++++------------- test/src/helpers/app-helpers.test.js | 83 +++++++------- 6 files changed, 100 insertions(+), 147 deletions(-) diff --git a/src/controllers/user-controller.js b/src/controllers/user-controller.js index 43badf767..4eb75a30f 100644 --- a/src/controllers/user-controller.js +++ b/src/controllers/user-controller.js @@ -42,14 +42,11 @@ const userLoginEndPoint = async function (req) { await Validator.validate(user, Validator.schemas.login); - const encryptedPassword = AppHelper.encryptText(user.password, user.email); const credentials = { email: user.email, - password: encryptedPassword + password: user.password }; - logger.info("Parameters:" + JSON.stringify(credentials)); - return await UserService.login(credentials, false); }; @@ -96,17 +93,7 @@ const updateUserPasswordEndPoint = async function (req, user) { await Validator.validate(passwordUpdates, Validator.schemas.updatePassword); - const encryptedOldPassword = AppHelper.encryptText(passwordUpdates.oldPassword, user.email); - const encryptedNewPassword = AppHelper.encryptText(passwordUpdates.newPassword, user.email); - - const encryptedPasswordUpdates = { - oldPassword: encryptedOldPassword, - newPassword: encryptedNewPassword - }; - - logger.info("Parameters:" + JSON.stringify(encryptedPasswordUpdates)); - - return await UserService.updateUserPassword(encryptedPasswordUpdates, user, false); + return await UserService.updateUserPassword(passwordUpdates, user, false); }; const resetUserPasswordEndPoint = async function (req) { diff --git a/src/helpers/app-helper.js b/src/helpers/app-helper.js index ff7056322..5f9d2cde7 100644 --- a/src/helpers/app-helper.js +++ b/src/helpers/app-helper.js @@ -21,19 +21,30 @@ const portscanner = require('portscanner'); const format = require('string-format'); const ALGORITHM = 'aes-256-ctr'; +const IV_LENGTH = 16; + const Transaction = require('sequelize/lib/transaction'); function encryptText(text, salt) { - const cipher = crypto.createCipher(ALGORITHM, salt); + const iv = crypto.randomBytes(IV_LENGTH); + const processedSalt = crypto.createHash('md5').update(salt).digest("hex"); + + const cipher = crypto.createCipheriv(ALGORITHM, processedSalt, iv); let crypted = cipher.update(text, 'utf8', 'hex'); crypted += cipher.final('hex'); - return crypted + return iv.toString('hex') + ':' + crypted.toString('hex'); } function decryptText(text, salt) { - const decipher = crypto.createDecipher(ALGORITHM, salt); - let dec = decipher.update(text, 'hex', 'utf8'); + const processedSalt = crypto.createHash('md5').update(salt).digest("hex"); + + const textParts = text.split(':'); + const iv = new Buffer(textParts.shift(), 'hex'); + let encryptedText = new Buffer(textParts.join(':'), 'hex'); + + const decipher = crypto.createDecipheriv(ALGORITHM, processedSalt, iv); + let dec = decipher.update(encryptedText, 'hex', 'utf8'); dec += decipher.final('utf8'); return dec } diff --git a/src/services/connector-service.js b/src/services/connector-service.js index dd10c8a04..2f1ceab98 100644 --- a/src/services/connector-service.js +++ b/src/services/connector-service.js @@ -168,7 +168,7 @@ async function openPortsOnConnector(connector, isPublicAccess, transaction) { }; if (!connector.devMode && connector.cert && connector.isSelfSignedCert === true) { const ca = fs.readFileSync(connector.cert); - options.ca = new Buffer(ca); + options.ca = new Buffer.from(ca); } const ports = await _makeRequest(connector, options, data); @@ -205,7 +205,7 @@ async function closePortOnConnector(connector, ports, transaction) { }; if (!connector.devMode && connector.cert && connector.isSelfSignedCert === true) { const ca = fs.readFileSync(connector.cert); - options.ca = new Buffer(ca); + options.ca = new Buffer.from(ca); } diff --git a/src/services/user-service.js b/src/services/user-service.js index 85e30c08e..affc2b40b 100644 --- a/src/services/user-service.js +++ b/src/services/user-service.js @@ -66,7 +66,9 @@ const login = async function (credentials, isCLI, transaction) { throw new Errors.InvalidCredentialsError(); } - const validPassword = credentials.password === user.password || credentials.password === user.tempPassword; + const pass = AppHelper.decryptText(user.password, user.email); + + const validPassword = credentials.password === pass || credentials.password === user.tempPassword; if (!validPassword) { throw new Errors.InvalidCredentialsError(); } @@ -174,14 +176,18 @@ const deleteUser = async function (user, isCLI, transaction) { }; const updateUserPassword = async function (passwordUpdates, user, isCLI, transaction) { - if (user.password !== passwordUpdates.oldPassword && user.tempPassword !== passwordUpdates.oldPassword) { + const pass = AppHelper.decryptText(user.password, user.email); + + if (pass !== passwordUpdates.oldPassword && user.tempPassword !== passwordUpdates.oldPassword) { throw new Errors.ValidationError(ErrorMessages.INVALID_OLD_PASSWORD); } const emailData = await _getEmailData(); const transporter = await _userEmailSender(emailData); - await UserManager.updatePassword(user.id, passwordUpdates.newPassword, transaction); + const newPass = AppHelper.encryptText(passwordUpdates.newPassword, user.email); + + await UserManager.updatePassword(user.id, newPass, transaction); await _notifyUserAboutPasswordChange(user, emailData, transporter); }; diff --git a/test/src/controllers/user-controller.test.js b/test/src/controllers/user-controller.test.js index 815a45b0a..6fe296bd1 100644 --- a/test/src/controllers/user-controller.test.js +++ b/test/src/controllers/user-controller.test.js @@ -113,14 +113,11 @@ describe('User Controller', () => { } })); def('response', () => Promise.resolve()); - def('encryptedPassword', () => 'encryptedPassword'); def('validatorResponse', () => Promise.resolve(true)); - def('encryptTextResponse', () => $encryptedPassword); def('subject', () => $subject.userLoginEndPoint($req)); beforeEach(() => { $sandbox.stub(Validator, 'validate').returns($validatorResponse); - $sandbox.stub(AppHelper, 'encryptText').returns($encryptTextResponse); $sandbox.stub(UserService, 'login').returns($response); }); @@ -141,43 +138,30 @@ describe('User Controller', () => { }); context('when Validator#validate() succeeds', () => { - it('calls AppHelper#encryptText() with correct args', async () => { + it('calls UserService.login with correct args', async () => { await $subject; - expect(AppHelper.encryptText).to.have.been.calledWith($password, $email); + expect(UserService.login).to.have.been.calledWith({ + email: $email, + password: $password + }, false) }); - context('when AppHelper#encryptText() fails', () => { - it('fails', () => { - return expect($subject).to.eventually.equal(undefined); - }); - }); + context('when UserService#login fails', () => { + const error = 'Error!'; - context('when AppHelper#encryptText() succeeds', () => { - it('calls UserService.login with correct args', async () => { - await $subject; - expect(UserService.login).to.have.been.calledWith({ - email: $email, - password: $encryptedPassword - }, false) - }); - - context('when UserService#login fails', () => { - const error = 'Error!'; - - def('response', () => Promise.reject(error)); - - it(`fails with "${error}"`, () => { - return expect($subject).to.be.rejectedWith(error) - }) - }); + def('response', () => Promise.reject(error)); - context('when UserService#login succeeds', () => { - it(`succeeds`, () => { - return expect($subject).to.eventually.equal(undefined) - }) + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) }) }); + context('when UserService#login succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); }); @@ -399,13 +383,10 @@ describe('User Controller', () => { })); def('response', () => Promise.resolve()); def('validatorResponse', () => Promise.resolve(true)); - def('encryptedPassword', () => 'encryptedPassword'); - def('encryptTextResponse', () => $encryptedPassword); def('subject', () => $subject.updateUserPasswordEndPoint($req, $user)); beforeEach(() => { $sandbox.stub(Validator, 'validate').returns($validatorResponse); - $sandbox.stub(AppHelper, 'encryptText').returns($encryptTextResponse); $sandbox.stub(UserService, 'updateUserPassword').returns($response); }); @@ -426,56 +407,29 @@ describe('User Controller', () => { }); context('when Validator#validate() succeeds', () => { - it('calls AppHelper#encryptText() for old password with correct args', async () => { + it('calls UserService.updateUserPassword with correct args', async () => { await $subject; - expect(AppHelper.encryptText).to.have.been.calledWith($oldPassword, $user.email); - }); - - context('when AppHelper#encryptText() for old password fails', () => { - it('fails', () => { - return expect($subject).to.eventually.equal(undefined); - }); + expect(UserService.updateUserPassword).to.have.been.calledWith({ + oldPassword: $oldPassword, + newPassword: $newPassword + }, $user, false); }); - context('when AppHelper#encryptText() for old password succeeds', () => { - it('calls AppHelper#encryptText() for new password with correct args', async () => { - await $subject; - expect(AppHelper.encryptText).to.have.been.calledWith($newPassword, $user.email); - }); - - context('when AppHelper#encryptText() for new password fails', () => { - it('fails', () => { - return expect($subject).to.eventually.equal(undefined); - }); - }); + context('when UserService#updateUserPassword fails', () => { + const error = 'Error!'; - context('when AppHelper#encryptText() for new password succeeds', () => { - it('calls UserService.updateUserPassword with correct args', async () => { - await $subject; - expect(UserService.updateUserPassword).to.have.been.calledWith({ - oldPassword: $encryptedPassword, - newPassword: $encryptedPassword - }, $user, false); - }); - - context('when UserService#updateUserPassword fails', () => { - const error = 'Error!'; - - def('response', () => Promise.reject(error)); - - it(`fails with "${error}"`, () => { - return expect($subject).to.be.rejectedWith(error) - }) - }); - - context('when UserService#updateUserPassword succeeds', () => { - it(`succeeds`, () => { - return expect($subject).to.eventually.equal(undefined) - }) - }) - }); + def('response', () => Promise.reject(error)); + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) }); + + context('when UserService#updateUserPassword succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) }); }); diff --git a/test/src/helpers/app-helpers.test.js b/test/src/helpers/app-helpers.test.js index 69935d8d2..f832ef517 100644 --- a/test/src/helpers/app-helpers.test.js +++ b/test/src/helpers/app-helpers.test.js @@ -1,93 +1,88 @@ -const crypto = require('crypto') -const { expect } = require('chai') -const fs = require('fs') -const path = require('path') -const portscanner = require('portscanner') -const sinon = require('sinon') +const crypto = require('crypto'); +const { expect } = require('chai'); +const fs = require('fs'); +const path = require('path'); +const portscanner = require('portscanner'); +const sinon = require('sinon'); -const AppHelpers = require('../../../src/helpers/app-helper') -const Config = require('../../../src/config') +const AppHelpers = require('../../../src/helpers/app-helper'); +const Config = require('../../../src/config'); describe('App Helpers', () => { - const text = 'some-text' - const salt = 'kosher-salt' - const encrypted = '17f4faa5c532708c8f' - - def('subject', () => AppHelpers) - def('sandbox', () => sinon.createSandbox()) + const text = 'some-text'; + const salt = 'kosher-salt'; + const encrypted = '18f4faa5c532708c8f'; + const processedSalt = 'c2cd22c1a8133704f09fc8a218088b1b'; + const encryptedPasswordLine = '17f4faa5c532708c8f:18f4faa5c532708c8f'; + + def('subject', () => AppHelpers); + def('sandbox', () => sinon.createSandbox()); def('cipher', () => ({ update: $sandbox.stub().returns(''), final: $sandbox.stub().returns(encrypted) - })) + })); def('decipher', () => ({ update: $sandbox.stub().returns(''), final: $sandbox.stub().returns(text) - })) + })); - afterEach(() => $sandbox.restore()) + afterEach(() => $sandbox.restore()); describe('.encryptText()', () => { - def('subject', () => $subject.encryptText(text, salt)) + def('subject', () => $subject.encryptText(text, salt)); + def('iv', () => '17f4faa5c532708c8f'); beforeEach(() => { - $sandbox.stub(crypto, 'createCipher').returns($cipher) - }) + $sandbox.stub(crypto, 'randomBytes').returns($iv); + $sandbox.stub(crypto, 'createCipheriv').returns($cipher); + }); - it('calls crypto#createCipher() with correct args', () => { + it('calls crypto#createCipheriv() with correct args', () => { $subject - expect(crypto.createCipher).to.have.been.calledWith('aes-256-ctr', salt) - }) + expect(crypto.createCipheriv).to.have.been.calledWith('aes-256-ctr', processedSalt, $iv) + }); it('calls crypto.cipher#update() with correct args', () => { $subject expect($cipher.update).to.have.been.calledWith(text, 'utf8', 'hex') - }) + }); it('calls crypto.cipher#final() with correct args', () => { $subject expect($cipher.final).to.have.been.calledWith('hex') - }) + }); it('returns the encrypted text', () => { - expect($subject).to.equal(encrypted) + expect($subject).to.equal(encryptedPasswordLine) }) - }) + }); describe('.decryptText()', () => { - def('subject', () => $subject.decryptText(encrypted, salt)) + def('iv', () => '17f4faa5c532708c8f'); + def('subject', () => $subject.decryptText(encryptedPasswordLine, salt)); beforeEach(() => { - $sandbox.stub(crypto, 'createDecipher').returns($decipher) - }) - - it('calls crypto#createDecipher() with correct args', () => { - $subject - expect(crypto.createDecipher).to.have.been.calledWith('aes-256-ctr', salt) - }) - - it('calls crypto.decipher#update() with correct args', () => { - $subject - expect($decipher.update).to.have.been.calledWith(encrypted, 'hex', 'utf8') - }) + $sandbox.stub(crypto, 'createDecipheriv').returns($decipher); + }); it('calls crypto.decipher#final() with correct args', () => { $subject expect($decipher.final).to.have.been.calledWith('utf8') - }) + }); it('returns the decrypted text', () => { expect($subject).to.equal(text) }) - }) + }); describe('.generateRandomString()', () => { - def('size', () => 12) + def('size', () => 12); context('when size is greater than zero', () => { it('returns a random string with length of size', () => { expect(AppHelpers.generateRandomString($size)).to.have.lengthOf($size) }) - }) + }); context('when size is zero', () => { def('size', () => 0)