diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c193ae0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.py] +indent_size = 4 diff --git a/example/lesspass.html b/example/lesspass.html index c4519c8..25320c5 100644 --- a/example/lesspass.html +++ b/example/lesspass.html @@ -1,31 +1,31 @@ - - + + - \ No newline at end of file + diff --git a/src/lesspass.js b/src/lesspass.js index 3c24127..9d3c1da 100644 --- a/src/lesspass.js +++ b/src/lesspass.js @@ -4,59 +4,59 @@ var pbkdf2 = require('./pbkdf2'); var objectAssign = require('object-assign'); module.exports = { - encryptLogin: v1.encryptLogin, - renderPassword: v1.renderPassword, - createFingerprint: v1.createFingerprint, - _deriveEncryptedLogin: v1._deriveEncryptedLogin, - _getPasswordTemplate: v1._getPasswordTemplate, - _prettyPrint: v1._prettyPrint, - _string2charCodes: v1._string2charCodes, - _getCharType: v1._getCharType, - _getPasswordChar: v1._getPasswordChar, - _createHmac: v1._createHmac, + encryptLogin: v1.encryptLogin, + renderPassword: v1.renderPassword, + createFingerprint: v1.createFingerprint, + _deriveEncryptedLogin: v1._deriveEncryptedLogin, + _getPasswordTemplate: v1._getPasswordTemplate, + _prettyPrint: v1._prettyPrint, + _string2charCodes: v1._string2charCodes, + _getCharType: v1._getCharType, + _getPasswordChar: v1._getPasswordChar, + _createHmac: v1._createHmac, - generatePassword: generatePassword, - _calcEntropy: v2._calcEntropy, - _consumeEntropy: v2._consumeEntropy, - _getSetOfCharacters: v2._getSetOfCharacters, - _getConfiguredRules: v2._getConfiguredRules, - _insertStringPseudoRandomly: v2._insertStringPseudoRandomly, - _getOneCharPerRule: v2._getOneCharPerRule, - _renderPassword: v2._renderPassword, + generatePassword: generatePassword, + _calcEntropy: v2._calcEntropy, + _consumeEntropy: v2._consumeEntropy, + _getSetOfCharacters: v2._getSetOfCharacters, + _getConfiguredRules: v2._getConfiguredRules, + _insertStringPseudoRandomly: v2._insertStringPseudoRandomly, + _getOneCharPerRule: v2._getOneCharPerRule, + _renderPassword: v2._renderPassword, - pbkdf2: pbkdf2 + pbkdf2: pbkdf2 }; var defaultPasswordProfile = { - version: 2, - lowercase: true, - numbers: true, - uppercase: true, - symbols: true, - keylen: 32, - digest: 'sha256', - length: 16, - index: 1, - iterations: 100000 + version: 2, + lowercase: true, + numbers: true, + uppercase: true, + symbols: true, + keylen: 32, + digest: 'sha256', + length: 16, + index: 1, + iterations: 100000 }; function generatePassword(site, login, masterPassword, passwordProfile) { - var _passwordProfile = objectAssign({}, defaultPasswordProfile, passwordProfile); - if (_passwordProfile.version === 1) { - var options = { - counter: _passwordProfile.counter, - length: _passwordProfile.length, - lowercase: _passwordProfile.lowercase, - uppercase: _passwordProfile.uppercase, - numbers: _passwordProfile.numbers, - symbols: _passwordProfile.symbols - }; - return v1.encryptLogin(login, masterPassword) - .then(function (encryptedLogin) { - return v1.renderPassword(encryptedLogin, site, options).then(function (generatedPassword) { - return generatedPassword - }); - }); - } - return v2.generatePassword(site, login, masterPassword, _passwordProfile); -} \ No newline at end of file + var _passwordProfile = objectAssign({}, defaultPasswordProfile, passwordProfile); + if (_passwordProfile.version === 1) { + var options = { + counter: _passwordProfile.counter, + length: _passwordProfile.length, + lowercase: _passwordProfile.lowercase, + uppercase: _passwordProfile.uppercase, + numbers: _passwordProfile.numbers, + symbols: _passwordProfile.symbols + }; + return v1.encryptLogin(login, masterPassword) + .then(function(encryptedLogin) { + return v1.renderPassword(encryptedLogin, site, options).then(function(generatedPassword) { + return generatedPassword + }); + }); + } + return v2.generatePassword(site, login, masterPassword, _passwordProfile); +} diff --git a/src/pbkdf2.js b/src/pbkdf2.js index 2400e8c..560b826 100644 --- a/src/pbkdf2.js +++ b/src/pbkdf2.js @@ -3,49 +3,49 @@ var Promise = require('pinkie-promise'); function shouldUseNative() { - return !!(typeof window !== 'undefined' && window.crypto && window.crypto.subtle); + return !!(typeof window !== 'undefined' && window.crypto && window.crypto.subtle); } function pbkdf2Native(password, salt, iterations, keylen, digest) { - var algorithms = { - 'sha1': 'SHA-1', - 'sha-1': 'SHA-1', - 'sha256': 'SHA-256', - 'sha-256': 'SHA-256', - 'sha512': 'SHA-512', - 'sha-512': 'SHA-512', - }; - return window.crypto.subtle.importKey('raw', new Buffer(password), 'PBKDF2', false, ['deriveKey']) - .then(function (key) { - var algo = { - name: 'PBKDF2', - salt: new Buffer(salt), - iterations: iterations, - hash: algorithms[digest.toLowerCase()], - }; - return window.crypto.subtle.deriveKey(algo, key, { - name: 'AES-CTR', - length: keylen * 8 - }, true, ['encrypt', 'decrypt']); - }) - .then(function (derivedKey) { - return window.crypto.subtle.exportKey('raw', derivedKey).then(function (keyArray) { - return new Buffer(keyArray).toString('hex'); - }); - }); + var algorithms = { + 'sha1': 'SHA-1', + 'sha-1': 'SHA-1', + 'sha256': 'SHA-256', + 'sha-256': 'SHA-256', + 'sha512': 'SHA-512', + 'sha-512': 'SHA-512', + }; + return window.crypto.subtle.importKey('raw', new Buffer(password), 'PBKDF2', false, ['deriveKey']) + .then(function(key) { + var algo = { + name: 'PBKDF2', + salt: new Buffer(salt), + iterations: iterations, + hash: algorithms[digest.toLowerCase()], + }; + return window.crypto.subtle.deriveKey(algo, key, { + name: 'AES-CTR', + length: keylen * 8 + }, true, ['encrypt', 'decrypt']); + }) + .then(function(derivedKey) { + return window.crypto.subtle.exportKey('raw', derivedKey).then(function(keyArray) { + return new Buffer(keyArray).toString('hex'); + }); + }); } function pbkdf2Browserified(password, salt, iterations, keylen, digest) { - return new Promise(function (resolve, reject) { - pbkdf2.pbkdf2(password, salt, iterations, keylen, digest, function (error, key) { - if (error) { - reject('error in pbkdf2'); - } else { - resolve(key.toString('hex')); - } - }); + return new Promise(function(resolve, reject) { + pbkdf2.pbkdf2(password, salt, iterations, keylen, digest, function(error, key) { + if (error) { + reject('error in pbkdf2'); + } else { + resolve(key.toString('hex')); + } }); + }); } -module.exports = shouldUseNative() ? pbkdf2Native : pbkdf2Browserified; \ No newline at end of file +module.exports = shouldUseNative() ? pbkdf2Native : pbkdf2Browserified; diff --git a/src/v1.js b/src/v1.js index 9c263da..6901581 100644 --- a/src/v1.js +++ b/src/v1.js @@ -4,106 +4,106 @@ var Promise = require('pinkie-promise'); module.exports = { - encryptLogin: encryptLogin, - renderPassword: renderPassword, - createFingerprint: createFingerprint, - _deriveEncryptedLogin: deriveEncryptedLogin, - _getPasswordTemplate: getPasswordTemplate, - _prettyPrint: prettyPrint, - _string2charCodes: string2charCodes, - _getCharType: getCharType, - _getPasswordChar: getPasswordChar, - _createHmac: createHmac, + encryptLogin: encryptLogin, + renderPassword: renderPassword, + createFingerprint: createFingerprint, + _deriveEncryptedLogin: deriveEncryptedLogin, + _getPasswordTemplate: getPasswordTemplate, + _prettyPrint: prettyPrint, + _string2charCodes: string2charCodes, + _getCharType: getCharType, + _getPasswordChar: getPasswordChar, + _createHmac: createHmac, }; function encryptLogin(login, masterPassword, options) { - var _options = options !== undefined ? options : {}; - var iterations = _options.iterations || 8192; - var keylen = _options.keylen || 32; - return pbkdf2(masterPassword, login, iterations, keylen, 'sha256'); + var _options = options !== undefined ? options : {}; + var iterations = _options.iterations || 8192; + var keylen = _options.keylen || 32; + return pbkdf2(masterPassword, login, iterations, keylen, 'sha256'); } function renderPassword(encryptedLogin, site, passwordOptions) { - return deriveEncryptedLogin(encryptedLogin, site, passwordOptions).then(function (derivedEncryptedLogin) { - var template = passwordOptions.template || getPasswordTemplate(passwordOptions); - return prettyPrint(derivedEncryptedLogin, template); - }); + return deriveEncryptedLogin(encryptedLogin, site, passwordOptions).then(function(derivedEncryptedLogin) { + var template = passwordOptions.template || getPasswordTemplate(passwordOptions); + return prettyPrint(derivedEncryptedLogin, template); + }); } function createHmac(encryptedLogin, salt) { - return new Promise(function (resolve) { - resolve(createHMAC('sha256', new Buffer(encryptedLogin)).update(salt).digest('hex')); - }); + return new Promise(function(resolve) { + resolve(createHMAC('sha256', new Buffer(encryptedLogin)).update(salt).digest('hex')); + }); } function deriveEncryptedLogin(encryptedLogin, site, options) { - var _options = options !== undefined ? options : {}; - var length = _options.length || 12; - var counter = _options.counter || 1; + var _options = options !== undefined ? options : {}; + var length = _options.length || 12; + var counter = _options.counter || 1; - var salt = site + counter.toString(); - return createHmac(encryptedLogin, salt).then(function (derivedHash) { - return derivedHash.substring(0, length); - }); + var salt = site + counter.toString(); + return createHmac(encryptedLogin, salt).then(function(derivedHash) { + return derivedHash.substring(0, length); + }); } function getPasswordTemplate(passwordTypes) { - var templates = { - lowercase: 'vc', - uppercase: 'VC', - numbers: 'n', - symbols: 's', - }; - var returnedTemplate = ''; - Object.keys(templates).forEach(function (template) { - if (passwordTypes.hasOwnProperty(template) && passwordTypes[template]) { - returnedTemplate += templates[template] - } - }); - return returnedTemplate; + var templates = { + lowercase: 'vc', + uppercase: 'VC', + numbers: 'n', + symbols: 's', + }; + var returnedTemplate = ''; + Object.keys(templates).forEach(function(template) { + if (passwordTypes.hasOwnProperty(template) && passwordTypes[template]) { + returnedTemplate += templates[template] + } + }); + return returnedTemplate; } function prettyPrint(hash, template) { - var password = ''; + var password = ''; - string2charCodes(hash).forEach(function (charCode, index) { - var charType = getCharType(template, index); - password += getPasswordChar(charType, charCode); - }); - return password; + string2charCodes(hash).forEach(function(charCode, index) { + var charType = getCharType(template, index); + password += getPasswordChar(charType, charCode); + }); + return password; } function string2charCodes(text) { - var charCodes = []; - for (var i = 0; i < text.length; i++) { - charCodes.push(text.charCodeAt(i)); - } - return charCodes; + var charCodes = []; + for (var i = 0; i < text.length; i++) { + charCodes.push(text.charCodeAt(i)); + } + return charCodes; } function getCharType(template, index) { - return template[index % template.length]; + return template[index % template.length]; } function getPasswordChar(charType, index) { - var passwordsChars = { - V: 'AEIOUY', - C: 'BCDFGHJKLMNPQRSTVWXZ', - v: 'aeiouy', - c: 'bcdfghjklmnpqrstvwxz', - A: 'AEIOUYBCDFGHJKLMNPQRSTVWXZ', - a: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz', - n: '0123456789', - s: '@&%?,=[]_:-+*$#!\'^~;()/.', - x: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz0123456789@&%?,=[]_:-+*$#!\'^~;()/.' - }; - var passwordChar = passwordsChars[charType]; - return passwordChar[index % passwordChar.length]; + var passwordsChars = { + V: 'AEIOUY', + C: 'BCDFGHJKLMNPQRSTVWXZ', + v: 'aeiouy', + c: 'bcdfghjklmnpqrstvwxz', + A: 'AEIOUYBCDFGHJKLMNPQRSTVWXZ', + a: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz', + n: '0123456789', + s: '@&%?,=[]_:-+*$#!\'^~;()/.', + x: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz0123456789@&%?,=[]_:-+*$#!\'^~;()/.' + }; + var passwordChar = passwordsChars[charType]; + return passwordChar[index % passwordChar.length]; } function createFingerprint(str) { - return new Promise(function (resolve) { - resolve(createHMAC('sha256', new Buffer(str)).digest('hex')) - }); -} \ No newline at end of file + return new Promise(function(resolve) { + resolve(createHMAC('sha256', new Buffer(str)).digest('hex')) + }); +} diff --git a/src/v2.js b/src/v2.js index d770fd2..3c6995f 100644 --- a/src/v2.js +++ b/src/v2.js @@ -2,83 +2,83 @@ var pbkdf2 = require('./pbkdf2'); var bigInt = require("big-integer"); module.exports = { - generatePassword: generatePassword, - _calcEntropy: calcEntropy, - _consumeEntropy: consumeEntropy, - _getSetOfCharacters: getSetOfCharacters, - _getConfiguredRules: getConfiguredRules, - _insertStringPseudoRandomly: insertStringPseudoRandomly, - _getOneCharPerRule: getOneCharPerRule, - _renderPassword: renderPassword + generatePassword: generatePassword, + _calcEntropy: calcEntropy, + _consumeEntropy: consumeEntropy, + _getSetOfCharacters: getSetOfCharacters, + _getConfiguredRules: getConfiguredRules, + _insertStringPseudoRandomly: insertStringPseudoRandomly, + _getOneCharPerRule: getOneCharPerRule, + _renderPassword: renderPassword }; function generatePassword(site, login, masterPassword, passwordProfile) { - return calcEntropy(site, login, masterPassword, passwordProfile).then(function (entropy) { - return renderPassword(entropy, passwordProfile); - }); + return calcEntropy(site, login, masterPassword, passwordProfile).then(function(entropy) { + return renderPassword(entropy, passwordProfile); + }); } function calcEntropy(site, login, masterPassword, passwordProfile) { - var salt = site + login + passwordProfile.counter.toString(16); - return pbkdf2(masterPassword, salt, passwordProfile.iterations, passwordProfile.keylen, passwordProfile.digest); + var salt = site + login + passwordProfile.counter.toString(16); + return pbkdf2(masterPassword, salt, passwordProfile.iterations, passwordProfile.keylen, passwordProfile.digest); } var characterSubsets = { - lowercase: 'abcdefghijklmnopqrstuvwxyz', - uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', - numbers: '0123456789', - symbols: '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' + lowercase: 'abcdefghijklmnopqrstuvwxyz', + uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + numbers: '0123456789', + symbols: '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' }; function getSetOfCharacters(rules) { - if (typeof rules === 'undefined') { - return characterSubsets.lowercase + characterSubsets.uppercase + characterSubsets.numbers + characterSubsets.symbols; - } - var setOfChars = ''; - rules.forEach(function (rule) { - setOfChars += characterSubsets[rule]; - }); - return setOfChars; + if (typeof rules === 'undefined') { + return characterSubsets.lowercase + characterSubsets.uppercase + characterSubsets.numbers + characterSubsets.symbols; + } + var setOfChars = ''; + rules.forEach(function(rule) { + setOfChars += characterSubsets[rule]; + }); + return setOfChars; } function consumeEntropy(generatedPassword, quotient, setOfCharacters, maxLength) { - if (generatedPassword.length >= maxLength) { - return {value: generatedPassword, entropy: quotient}; - } - var longDivision = quotient.divmod(setOfCharacters.length); - generatedPassword += setOfCharacters[longDivision.remainder]; - return consumeEntropy(generatedPassword, longDivision.quotient, setOfCharacters, maxLength); + if (generatedPassword.length >= maxLength) { + return {value: generatedPassword, entropy: quotient}; + } + var longDivision = quotient.divmod(setOfCharacters.length); + generatedPassword += setOfCharacters[longDivision.remainder]; + return consumeEntropy(generatedPassword, longDivision.quotient, setOfCharacters, maxLength); } function insertStringPseudoRandomly(generatedPassword, entropy, string) { - for (var i = 0; i < string.length; i++) { - var longDivision = entropy.divmod(generatedPassword.length); - generatedPassword = generatedPassword.slice(0, longDivision.remainder) + string[i] + generatedPassword.slice(longDivision.remainder); - entropy = longDivision.quotient; - } - return generatedPassword; + for (var i = 0; i < string.length; i++) { + var longDivision = entropy.divmod(generatedPassword.length); + generatedPassword = generatedPassword.slice(0, longDivision.remainder) + string[i] + generatedPassword.slice(longDivision.remainder); + entropy = longDivision.quotient; + } + return generatedPassword; } function getOneCharPerRule(entropy, rules) { - var oneCharPerRules = ''; - rules.forEach(function (rule) { - var password = consumeEntropy('', entropy, characterSubsets[rule], 1); - oneCharPerRules += password.value; - entropy = password.entropy; - }); - return {value: oneCharPerRules, entropy: entropy}; + var oneCharPerRules = ''; + rules.forEach(function(rule) { + var password = consumeEntropy('', entropy, characterSubsets[rule], 1); + oneCharPerRules += password.value; + entropy = password.entropy; + }); + return {value: oneCharPerRules, entropy: entropy}; } function getConfiguredRules(passwordProfile) { - return ['lowercase', 'uppercase', 'numbers', 'symbols'].filter(function (rule) { - return passwordProfile[rule]; - }); + return ['lowercase', 'uppercase', 'numbers', 'symbols'].filter(function(rule) { + return passwordProfile[rule]; + }); } function renderPassword(entropy, passwordProfile) { - var rules = getConfiguredRules(passwordProfile); - var setOfCharacters = getSetOfCharacters(rules); - var password = consumeEntropy('', bigInt(entropy, 16), setOfCharacters, passwordProfile.length - rules.length); - var charactersToAdd = getOneCharPerRule(password.entropy, rules); - return insertStringPseudoRandomly(password.value, charactersToAdd.entropy, charactersToAdd.value); + var rules = getConfiguredRules(passwordProfile); + var setOfCharacters = getSetOfCharacters(rules); + var password = consumeEntropy('', bigInt(entropy, 16), setOfCharacters, passwordProfile.length - rules.length); + var charactersToAdd = getOneCharPerRule(password.entropy, rules); + return insertStringPseudoRandomly(password.value, charactersToAdd.entropy, charactersToAdd.value); } diff --git a/tests/karma.config.js b/tests/karma.config.js index 6ba61c5..8cd0675 100644 --- a/tests/karma.config.js +++ b/tests/karma.config.js @@ -1,29 +1,29 @@ -module.exports = function (config) { - var configuration = { - basePath: '..', - frameworks: ['mocha', 'chai'], - files: [ - 'node_modules/big-integer/BigInteger.min.js', - 'dist/lesspass.js', - 'tests/**/*.js' - ], - exclude: [ - 'tests/node.js', - 'tests/helper.js', - 'tests/karma.webcrypto.config.js', - ], - preprocessors: {}, - reporters: ['progress'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome', 'Firefox'], - singleRun: true, - concurrency: Infinity - }; - if (process.env.TRAVIS) { - configuration.browsers = ['PhantomJS']; - } - config.set(configuration) +module.exports = function(config) { + var configuration = { + basePath: '..', + frameworks: ['mocha', 'chai'], + files: [ + 'node_modules/big-integer/BigInteger.min.js', + 'dist/lesspass.js', + 'tests/**/*.js' + ], + exclude: [ + 'tests/node.js', + 'tests/helper.js', + 'tests/karma.webcrypto.config.js', + ], + preprocessors: {}, + reporters: ['progress'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome', 'Firefox'], + singleRun: true, + concurrency: Infinity + }; + if (process.env.TRAVIS) { + configuration.browsers = ['PhantomJS']; + } + config.set(configuration) }; diff --git a/tests/node.js b/tests/node.js index e2a3a34..cba9e73 100644 --- a/tests/node.js +++ b/tests/node.js @@ -5,19 +5,19 @@ const site = 'lesspass.com'; const login = 'contact@lesspass.com'; const masterPassword = 'password'; const passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - length: 16, - counter: 1, - version: 2 + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + length: 16, + counter: 1, + version: 2 }; LessPass.generatePassword(site, login, masterPassword, passwordProfile) - .then(function (generatedPassword) { - assert.equal(generatedPassword, '\\g-A1-.OHEwrXjT#'); - console.log('generated password ok'); - }) - .catch(function (e) { - console.log(e); - }); \ No newline at end of file + .then(function(generatedPassword) { + assert.equal(generatedPassword, '\\g-A1-.OHEwrXjT#'); + console.log('generated password ok'); + }) + .catch(function(e) { + console.log(e); + }); diff --git a/tests/pbkdf2.tests.js b/tests/pbkdf2.tests.js index c3f692d..c2f9dbf 100644 --- a/tests/pbkdf2.tests.js +++ b/tests/pbkdf2.tests.js @@ -1,13 +1,13 @@ var assert = chai.assert; -describe('LessPass', function () { - describe('pbkdf2', function () { - it('should secret, salt, 2, 32, sha256', function () { - return LessPass.pbkdf2('secret', 'salt', 2, 32, 'sha256').then(function (key) { - assert.equal('f92f45f9df4c2aeabae1ed3c16f7b64660c1f8e377fa9b4699b23c2c3a29f569', key); - }) - }); +describe('LessPass', function() { + describe('pbkdf2', function() { + it('should secret, salt, 2, 32, sha256', function() { + return LessPass.pbkdf2('secret', 'salt', 2, 32, 'sha256').then(function(key) { + assert.equal('f92f45f9df4c2aeabae1ed3c16f7b64660c1f8e377fa9b4699b23c2c3a29f569', key); + }) }); + }); }); diff --git a/tests/v1/api.tests.js b/tests/v1/api.tests.js index a455edb..648955e 100644 --- a/tests/v1/api.tests.js +++ b/tests/v1/api.tests.js @@ -1,584 +1,545 @@ var assert = chai.assert; -describe('LessPass v1', function () { - describe('encryptLogin', function () { - it('should use pbkdf2 with 8192 iterations and sha256', function (done) { - LessPass.encryptLogin('test@example.org', 'password').then(function (encryptedLogin) { - assert.equal('d8af5f918db6b65b1db3d3984e5a400e39e1dbb19462220e4431de283809f472', encryptedLogin); - done(); - }); - }); - - it('should allow to customize number of iterations', function (done) { - LessPass.encryptLogin('test@example.org', 'password', {iterations: 4096}).then(function (encryptedLogin) { - assert.equal('0a91208545e3aa4935d3a22984ca097a7669259a04d261ac16361bdc1a2e960f', encryptedLogin); - done(); - }); - }); - - it('should allow to customize key length', function (done) { - LessPass.encryptLogin('test@example.org', 'password', {keylen: 16}).then(function (encryptedLogin) { - assert.equal('d8af5f918db6b65b1db3d3984e5a400e', encryptedLogin); - done(); - }); - }); - - it('should allow to customize iterations and key length', function (done) { - LessPass.encryptLogin('test@example.org', 'password', { - iterations: 4096, - keylen: 16 - }).then(function (encryptedLogin) { - assert.equal('0a91208545e3aa4935d3a22984ca097a', encryptedLogin); - done(); - }); - }); - - it('should allow utf8 parameter', function () { - return LessPass.encryptLogin('test@example.org', '♥ LessPass ♥').then(function (encryptedLogin) { - assert.equal('997fe81d3d0db236e039c75efdb487f17a902fdf94f9dacaa9884329c85d9651', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 0', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 1', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 2', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 3', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 4', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 5', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 6', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 7', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 8', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function (encryptedLogin) { - assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 9', function () { - return LessPass.encryptLogin('lesspass', 'password').then(function (encryptedLogin) { - assert.equal('7d05ee25597dcc3ac16d082aa910e7707f75be620ed8db5bef7245e2a8579116', encryptedLogin); - }); - }); - - it('encryptLogin auto generated test 10', function () { - return LessPass.encryptLogin('contact@lesspass.com', 'password2').then(function (encryptedLogin) { - assert.equal('ce853092fc54fe88c281e38df97bd5826d64e6bee315dc94939cbba8930df0e4', encryptedLogin); - }); - }); +describe('LessPass v1', function() { + describe('encryptLogin', function() { + it('should use pbkdf2 with 8192 iterations and sha256', function(done) { + LessPass.encryptLogin('test@example.org', 'password').then(function(encryptedLogin) { + assert.equal('d8af5f918db6b65b1db3d3984e5a400e39e1dbb19462220e4431de283809f472', encryptedLogin); + done(); + }); }); - - describe('renderPassword', function () { - it('render password', function (done) { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true - }; - LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('azYS7,olOL2]', generatedPassword); - done(); - }) - }); - - it('render password with a custom template', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - template: 'n' - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - var i = generatedPassword.length; - while (i--) { - assert('0123456789'.indexOf(generatedPassword[i]) !== -1) - } - }) - }); - - it('render password with a custom template too short', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - template: 'CvcnCVsn' - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('Sor4WU:8Wad5', generatedPassword); - }) - }); - - it('render password with a custom template too long', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 6, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - template: 'CvcnCVsn' - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('Sor4WU', generatedPassword); - }) - }); - - it('render password auto generated test 0', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('azYS7,olOL2]', generatedPassword); - }) - }); - - it('render password auto generated test 1', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 14, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('azYS7,olOL2]iz', generatedPassword); - }) - }); - - it('render password auto generated test 2', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: false, - numbers: false, - symbols: false, - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('azyseqololat', generatedPassword); - }) - }); - - it('render password auto generated test 3', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: false, - uppercase: true, - numbers: true, - symbols: true - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('AZ3[EQ7@OL2]', generatedPassword); - }) - }); - - it('render password auto generated test 4', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: false, - uppercase: false, - numbers: true, - symbols: true - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('4?3[7,7@7@2]', generatedPassword); - }) - }); - - it('render password auto generated test 5', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: false, - uppercase: false, - numbers: false, - symbols: true - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('[?=[&,:@:@[]', generatedPassword); - }) - }); - - it('render password auto generated test 6', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: false - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('azYS7uwAW8at', generatedPassword); - }) - }); - - it('render password auto generated test 7', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: false, - symbols: false - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('azYSeqOLolAT', generatedPassword); - }) - }); - - it('render password auto generated test 8', function () { - var site = 'lesspass.com'; - var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; - var passwordOptions = { - counter: 2, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('obYT2=olOV9=', generatedPassword); - }) - }); - - it('render password auto generated test 9', function () { - var site = 'lesspass.com'; - var encryptedLogin = '7d05ee25597dcc3ac16d082aa910e7707f75be620ed8db5bef7245e2a8579116'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('erOC1%imIW3,', generatedPassword); - }) - }); - - it('render password auto generated test 10', function () { - var site = 'lesspass.com'; - var encryptedLogin = 'ce853092fc54fe88c281e38df97bd5826d64e6bee315dc94939cbba8930df0e4'; - var passwordOptions = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true - }; - return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function (generatedPassword) { - assert.equal('uvUM5_ucUP5=', generatedPassword); - }) - }); - - + it('should allow to customize number of iterations', function(done) { + LessPass.encryptLogin('test@example.org', 'password', {iterations: 4096}).then(function(encryptedLogin) { + assert.equal('0a91208545e3aa4935d3a22984ca097a7669259a04d261ac16361bdc1a2e960f', encryptedLogin); + done(); + }); }); - describe('fingerprint', function () { - it('createFingerprint', function () { - return LessPass.createFingerprint('password').then(function (fingerprint) { - assert.equal('e56a207acd1e6714735487c199c6f095844b7cc8e5971d86c003a7b6f36ef51e', fingerprint); - }) - }); + it('should allow to customize key length', function(done) { + LessPass.encryptLogin('test@example.org', 'password', {keylen: 16}).then(function(encryptedLogin) { + assert.equal('d8af5f918db6b65b1db3d3984e5a400e', encryptedLogin); + done(); + }); + }); + it('should allow to customize iterations and key length', function(done) { + LessPass.encryptLogin('test@example.org', 'password', { + iterations: 4096, + keylen: 16 + }).then(function(encryptedLogin) { + assert.equal('0a91208545e3aa4935d3a22984ca097a', encryptedLogin); + done(); + }); + }); + it('should allow utf8 parameter', function() { + return LessPass.encryptLogin('test@example.org', '♥ LessPass ♥').then(function(encryptedLogin) { + assert.equal('997fe81d3d0db236e039c75efdb487f17a902fdf94f9dacaa9884329c85d9651', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 0', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 1', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 2', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 3', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 4', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 5', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 6', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 7', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 8', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password').then(function(encryptedLogin) { + assert.equal('63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 9', function() { + return LessPass.encryptLogin('lesspass', 'password').then(function(encryptedLogin) { + assert.equal('7d05ee25597dcc3ac16d082aa910e7707f75be620ed8db5bef7245e2a8579116', encryptedLogin); + }); + }); + it('encryptLogin auto generated test 10', function() { + return LessPass.encryptLogin('contact@lesspass.com', 'password2').then(function(encryptedLogin) { + assert.equal('ce853092fc54fe88c281e38df97bd5826d64e6bee315dc94939cbba8930df0e4', encryptedLogin); + }); + }); + }); + + describe('renderPassword', function() { + it('render password', function(done) { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true + }; + LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('azYS7,olOL2]', generatedPassword); + done(); + }) + }); + it('render password with a custom template', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + template: 'n' + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + var i = generatedPassword.length; + while (i--) { + assert('0123456789'.indexOf(generatedPassword[i]) !== -1) + } + }) + }); + it('render password with a custom template too short', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + template: 'CvcnCVsn' + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('Sor4WU:8Wad5', generatedPassword); + }) + }); + it('render password with a custom template too long', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 6, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + template: 'CvcnCVsn' + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('Sor4WU', generatedPassword); + }) + }); + it('render password auto generated test 0', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('azYS7,olOL2]', generatedPassword); + }) + }); + it('render password auto generated test 1', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 14, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('azYS7,olOL2]iz', generatedPassword); + }) + }); + it('render password auto generated test 2', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: false, + numbers: false, + symbols: false, + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('azyseqololat', generatedPassword); + }) + }); + it('render password auto generated test 3', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: false, + uppercase: true, + numbers: true, + symbols: true + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('AZ3[EQ7@OL2]', generatedPassword); + }) + }); + it('render password auto generated test 4', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: false, + uppercase: false, + numbers: true, + symbols: true + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('4?3[7,7@7@2]', generatedPassword); + }) + }); + it('render password auto generated test 5', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: false, + uppercase: false, + numbers: false, + symbols: true + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('[?=[&,:@:@[]', generatedPassword); + }) + }); + it('render password auto generated test 6', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: false + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('azYS7uwAW8at', generatedPassword); + }) + }); + it('render password auto generated test 7', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: false, + symbols: false + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('azYSeqOLolAT', generatedPassword); + }) + }); + it('render password auto generated test 8', function() { + var site = 'lesspass.com'; + var encryptedLogin = '63d850713d0b2f7f2c4396fe93f4ac0c6bc7485f9e7473c4b8c4a33ec12199c0'; + var passwordOptions = { + counter: 2, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('obYT2=olOV9=', generatedPassword); + }) + }); + it('render password auto generated test 9', function() { + var site = 'lesspass.com'; + var encryptedLogin = '7d05ee25597dcc3ac16d082aa910e7707f75be620ed8db5bef7245e2a8579116'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('erOC1%imIW3,', generatedPassword); + }) + }); + it('render password auto generated test 10', function() { + var site = 'lesspass.com'; + var encryptedLogin = 'ce853092fc54fe88c281e38df97bd5826d64e6bee315dc94939cbba8930df0e4'; + var passwordOptions = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true + }; + return LessPass.renderPassword(encryptedLogin, site, passwordOptions).then(function(generatedPassword) { + assert.equal('uvUM5_ucUP5=', generatedPassword); + }) }); - describe('generatePassword', function () { - it('generate password', function () { - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('izIS5@ozYM2?', generatedPassword); - }); - }); - it('generate password auto generated test 0', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('azYS7,olOL2]', generatedPassword); - }); - }); - - it('generate password auto generated test 1', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - length: 14, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('azYS7,olOL2]iz', generatedPassword); - }); - }); - - it('generate password auto generated test 2', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: false, - numbers: false, - symbols: false, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('azyseqololat', generatedPassword); - }); - }); - - it('generate password auto generated test 3', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: false, - uppercase: true, - numbers: true, - symbols: true, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('AZ3[EQ7@OL2]', generatedPassword); - }); - }); - - it('generate password auto generated test 4', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: false, - uppercase: false, - numbers: true, - symbols: true, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('4?3[7,7@7@2]', generatedPassword); - }); - }); - - it('generate password auto generated test 5', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: false, - uppercase: false, - numbers: false, - symbols: true, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('[?=[&,:@:@[]', generatedPassword); - }); - }); - - it('generate password auto generated test 6', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: false, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('azYS7uwAW8at', generatedPassword); - }); - }); - - it('generate password auto generated test 7', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: false, - symbols: false, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('azYSeqOLolAT', generatedPassword); - }); - }); - - it('generate password auto generated test 8', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - length: 12, - counter: 2, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('obYT2=olOV9=', generatedPassword); - }); - }); - - it('generate password auto generated test 9', function () { - var site = 'lesspass.com'; - var login = 'lesspass'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('erOC1%imIW3,', generatedPassword); - }); - }); - it('generate password auto generated test 10', function () { - var site = 'lesspass.com'; - var login = 'contact@lesspass.com'; - var masterPassword = 'password2'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - length: 12, - counter: 1, - version: 1, - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('uvUM5_ucUP5=', generatedPassword); - }); - }); + }); + describe('fingerprint', function() { + it('createFingerprint', function() { + return LessPass.createFingerprint('password').then(function(fingerprint) { + assert.equal('e56a207acd1e6714735487c199c6f095844b7cc8e5971d86c003a7b6f36ef51e', fingerprint); + }) + }); + }); + + describe('generatePassword', function() { + it('generate password', function() { + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('izIS5@ozYM2?', generatedPassword); + }); + }); + it('generate password auto generated test 0', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('azYS7,olOL2]', generatedPassword); + }); + }); + it('generate password auto generated test 1', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + length: 14, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('azYS7,olOL2]iz', generatedPassword); + }); + }); + it('generate password auto generated test 2', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: false, + numbers: false, + symbols: false, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('azyseqololat', generatedPassword); + }); + }); + it('generate password auto generated test 3', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: false, + uppercase: true, + numbers: true, + symbols: true, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('AZ3[EQ7@OL2]', generatedPassword); + }); + }); + it('generate password auto generated test 4', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: false, + uppercase: false, + numbers: true, + symbols: true, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('4?3[7,7@7@2]', generatedPassword); + }); + }); + it('generate password auto generated test 5', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: false, + uppercase: false, + numbers: false, + symbols: true, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('[?=[&,:@:@[]', generatedPassword); + }); + }); + it('generate password auto generated test 6', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: false, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('azYS7uwAW8at', generatedPassword); + }); + }); + it('generate password auto generated test 7', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: false, + symbols: false, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('azYSeqOLolAT', generatedPassword); + }); + }); + it('generate password auto generated test 8', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + length: 12, + counter: 2, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('obYT2=olOV9=', generatedPassword); + }); + }); + it('generate password auto generated test 9', function() { + var site = 'lesspass.com'; + var login = 'lesspass'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('erOC1%imIW3,', generatedPassword); + }); + }); + it('generate password auto generated test 10', function() { + var site = 'lesspass.com'; + var login = 'contact@lesspass.com'; + var masterPassword = 'password2'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + length: 12, + counter: 1, + version: 1, + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('uvUM5_ucUP5=', generatedPassword); + }); }); + }); }); diff --git a/tests/v1/deriveEncryptedLogin.tests.js b/tests/v1/deriveEncryptedLogin.tests.js index 7395946..ca5045f 100644 --- a/tests/v1/deriveEncryptedLogin.tests.js +++ b/tests/v1/deriveEncryptedLogin.tests.js @@ -1,84 +1,84 @@ var assert = chai.assert; -describe('LessPass v1', function () { - describe('deriveEncryptedLogin', function () { - it('should createHmac', function () { - var encryptedLogin = '9f505f3a95fe0485da3242cb81c9fe25c2f400d8399737655a8dad2b52778d88'; - var salt = 'lesspass.com1'; - return LessPass._createHmac(encryptedLogin, salt).then(function (hmac) { - assert.equal('be00f942fc8aa67d8e76fc2456862b9d66d166ebfdd3dc2f0116e278209532ed', hmac); - }); - }); - it('should derive encrypted login with default options 1', function () { - const encryptedLogin = '90cff82b8847525370a8f29a59ecf45db62c719a535788ad0df58d32304e925d'; - const site = 'lesspass.com'; - return LessPass._deriveEncryptedLogin(encryptedLogin, site).then(function (generatedPassword) { - assert.equal('ecd16aefc7e5', generatedPassword); - }); - }); - it('should derive encrypted login with default options 2', function () { - const encryptedLogin = '90cff82b8847525370a8f29a59ecf45db62c719a535788ad0df58d32304e925d'; - const site = 'lesspass.com'; - const option = { - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - }; - return LessPass._deriveEncryptedLogin(encryptedLogin, site, option).then(function (generatedPassword) { - assert.equal('ecd16aefc7e5', generatedPassword); - }); - }); - it('should derive encrypted login with defined length', function () { - var encryptedLogin = 'd79d8482f708122288af7b259393a58fe05840f4555cc935cdd3f062b9aa75ed'; - var site = 'lesspass.com'; - var option = { - counter: 1, - length: 10, - }; - return LessPass._deriveEncryptedLogin(encryptedLogin, site, option).then(function (generatedPassword) { - assert.equal(10, generatedPassword.length); - }); - }); - it('should return two different passwords if site different 1', function () { - const encryptedLogin = 'f4fd3885fb70085f2285c3382e2d9adb4c2553285fc45dd896791aa5e79070a9'; - const site = 'google.com'; - return LessPass._deriveEncryptedLogin(encryptedLogin, site).then(function (derivedEncryptedLogin) { - assert.equal('a957c3a459ec', derivedEncryptedLogin) - }); - }); - it('should return two different passwords if site different 2', function () { - const encryptedLogin = 'f4fd3885fb70085f2285c3382e2d9adb4c2553285fc45dd896791aa5e79070a9'; - const site = 'facebook.com'; - return LessPass._deriveEncryptedLogin(encryptedLogin, site).then(function (derivedEncryptedLogin) { - assert.equal('d9f3a918c34b', derivedEncryptedLogin) - }); - }); - it('should return two different passwords if counter different 1', function () { - const encryptedLogin = 'dfba06278c9aa24d992bc2d390a53efef482788859455875f72015335d085fcd'; - const site = 'lesspass.com'; - const option = {counter: 1}; - return LessPass._deriveEncryptedLogin(encryptedLogin, site, option).then(function (derivedEncryptedLogins) { - assert.equal('bb2e0b34036d', derivedEncryptedLogins) - }); - }); - it('should return two different passwords if counter different 2', function () { - const encryptedLogin = 'dfba06278c9aa24d992bc2d390a53efef482788859455875f72015335d085fcd'; - const site = 'lesspass.com'; - const option2 = {counter: 2}; - return LessPass._deriveEncryptedLogin(encryptedLogin, site, option2).then(function (derivedEncryptedLogins) { - assert.equal('67fe8c05a248', derivedEncryptedLogins) - }); - }); - it('should derive encrypted login with sha 256', function () { - const encryptedLogin = '9f505f3a95fe0485da3242cb81c9fe25c2f400d8399737655a8dad2b52778d88'; - const site = 'lesspass.com'; - LessPass._deriveEncryptedLogin(encryptedLogin, site).then(function (encryptedLogin) { - assert.equal('be00f942fc8a', encryptedLogin); - }); - }); +describe('LessPass v1', function() { + describe('deriveEncryptedLogin', function() { + it('should createHmac', function() { + var encryptedLogin = '9f505f3a95fe0485da3242cb81c9fe25c2f400d8399737655a8dad2b52778d88'; + var salt = 'lesspass.com1'; + return LessPass._createHmac(encryptedLogin, salt).then(function(hmac) { + assert.equal('be00f942fc8aa67d8e76fc2456862b9d66d166ebfdd3dc2f0116e278209532ed', hmac); + }); }); + it('should derive encrypted login with default options 1', function() { + const encryptedLogin = '90cff82b8847525370a8f29a59ecf45db62c719a535788ad0df58d32304e925d'; + const site = 'lesspass.com'; + return LessPass._deriveEncryptedLogin(encryptedLogin, site).then(function(generatedPassword) { + assert.equal('ecd16aefc7e5', generatedPassword); + }); + }); + it('should derive encrypted login with default options 2', function() { + const encryptedLogin = '90cff82b8847525370a8f29a59ecf45db62c719a535788ad0df58d32304e925d'; + const site = 'lesspass.com'; + const option = { + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + }; + return LessPass._deriveEncryptedLogin(encryptedLogin, site, option).then(function(generatedPassword) { + assert.equal('ecd16aefc7e5', generatedPassword); + }); + }); + it('should derive encrypted login with defined length', function() { + var encryptedLogin = 'd79d8482f708122288af7b259393a58fe05840f4555cc935cdd3f062b9aa75ed'; + var site = 'lesspass.com'; + var option = { + counter: 1, + length: 10, + }; + return LessPass._deriveEncryptedLogin(encryptedLogin, site, option).then(function(generatedPassword) { + assert.equal(10, generatedPassword.length); + }); + }); + it('should return two different passwords if site different 1', function() { + const encryptedLogin = 'f4fd3885fb70085f2285c3382e2d9adb4c2553285fc45dd896791aa5e79070a9'; + const site = 'google.com'; + return LessPass._deriveEncryptedLogin(encryptedLogin, site).then(function(derivedEncryptedLogin) { + assert.equal('a957c3a459ec', derivedEncryptedLogin) + }); + }); + it('should return two different passwords if site different 2', function() { + const encryptedLogin = 'f4fd3885fb70085f2285c3382e2d9adb4c2553285fc45dd896791aa5e79070a9'; + const site = 'facebook.com'; + return LessPass._deriveEncryptedLogin(encryptedLogin, site).then(function(derivedEncryptedLogin) { + assert.equal('d9f3a918c34b', derivedEncryptedLogin) + }); + }); + it('should return two different passwords if counter different 1', function() { + const encryptedLogin = 'dfba06278c9aa24d992bc2d390a53efef482788859455875f72015335d085fcd'; + const site = 'lesspass.com'; + const option = {counter: 1}; + return LessPass._deriveEncryptedLogin(encryptedLogin, site, option).then(function(derivedEncryptedLogins) { + assert.equal('bb2e0b34036d', derivedEncryptedLogins) + }); + }); + it('should return two different passwords if counter different 2', function() { + const encryptedLogin = 'dfba06278c9aa24d992bc2d390a53efef482788859455875f72015335d085fcd'; + const site = 'lesspass.com'; + const option2 = {counter: 2}; + return LessPass._deriveEncryptedLogin(encryptedLogin, site, option2).then(function(derivedEncryptedLogins) { + assert.equal('67fe8c05a248', derivedEncryptedLogins) + }); + }); + it('should derive encrypted login with sha 256', function() { + const encryptedLogin = '9f505f3a95fe0485da3242cb81c9fe25c2f400d8399737655a8dad2b52778d88'; + const site = 'lesspass.com'; + LessPass._deriveEncryptedLogin(encryptedLogin, site).then(function(encryptedLogin) { + assert.equal('be00f942fc8a', encryptedLogin); + }); + }); + }); }); diff --git a/tests/v1/getPasswordTemplate.tests.js b/tests/v1/getPasswordTemplate.tests.js index 1e39beb..1072173 100644 --- a/tests/v1/getPasswordTemplate.tests.js +++ b/tests/v1/getPasswordTemplate.tests.js @@ -1,63 +1,63 @@ var assert = chai.assert; -describe('Lessass v1', function () { - describe('getPasswordTemplate', function () { - it('should get default template', function () { - assert.equal('vcVCns', LessPass._getPasswordTemplate({ - counter: 1, - length: 12, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true - })); - }); - it('should get lowercase template', function () { - assert.equal('vc', LessPass._getPasswordTemplate({ - lowercase: true, - uppercase: false, - numbers: false, - symbols: false - })); - }); - it('should get uppercase template', function () { - assert.equal('VC', LessPass._getPasswordTemplate({ - lowercase: false, - uppercase: true, - numbers: false, - symbols: false - })); - }); - it('should get numbers template', function () { - assert.equal('n', LessPass._getPasswordTemplate({ - lowercase: false, - uppercase: false, - numbers: true, - symbols: false - })); - }); - it('should get symbols template', function () { - assert.equal('s', LessPass._getPasswordTemplate({ - lowercase: false, - uppercase: false, - numbers: false, - symbols: true - })); - }); - it('should concatenate template if two password settings', function () { - assert.equal('vcVC', LessPass._getPasswordTemplate({ - lowercase: true, - uppercase: true, - numbers: false, - symbols: false - })); - assert.equal('vcns', LessPass._getPasswordTemplate({ - lowercase: true, - uppercase: false, - numbers: true, - symbols: true - })); - }); +describe('Lessass v1', function() { + describe('getPasswordTemplate', function() { + it('should get default template', function() { + assert.equal('vcVCns', LessPass._getPasswordTemplate({ + counter: 1, + length: 12, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true + })); }); + it('should get lowercase template', function() { + assert.equal('vc', LessPass._getPasswordTemplate({ + lowercase: true, + uppercase: false, + numbers: false, + symbols: false + })); + }); + it('should get uppercase template', function() { + assert.equal('VC', LessPass._getPasswordTemplate({ + lowercase: false, + uppercase: true, + numbers: false, + symbols: false + })); + }); + it('should get numbers template', function() { + assert.equal('n', LessPass._getPasswordTemplate({ + lowercase: false, + uppercase: false, + numbers: true, + symbols: false + })); + }); + it('should get symbols template', function() { + assert.equal('s', LessPass._getPasswordTemplate({ + lowercase: false, + uppercase: false, + numbers: false, + symbols: true + })); + }); + it('should concatenate template if two password settings', function() { + assert.equal('vcVC', LessPass._getPasswordTemplate({ + lowercase: true, + uppercase: true, + numbers: false, + symbols: false + })); + assert.equal('vcns', LessPass._getPasswordTemplate({ + lowercase: true, + uppercase: false, + numbers: true, + symbols: true + })); + }); + }); }); diff --git a/tests/v1/prettyPrint.js b/tests/v1/prettyPrint.js index d7ef563..ff259db 100644 --- a/tests/v1/prettyPrint.js +++ b/tests/v1/prettyPrint.js @@ -1,35 +1,35 @@ var assert = chai.assert; -describe('LessPass v1', function () { - describe('prettyPrint', function () { - it('should print different password if templates different', function () { - var encryptedLogin = '78ae5892055ab59fdd54489ae30928d322841a27590b65cf875fcfdd083f7c32'; - assert.notEqual(LessPass._prettyPrint(encryptedLogin, 'cv'), LessPass._prettyPrint(encryptedLogin, 'vc')); - }); - it('must return a string of the same length as the input', function () { - var hash = 'f5785e569ab5d38b02e2248c798ac17df90f57a85f34a9d5382408c2f0d9532d'; - assert.equal(hash.length, LessPass._prettyPrint(hash, 'cv').length); - }); - it('should return char inside a string based on modulo of the index', function () { - var template = 'cv'; - assert.equal('c', LessPass._getCharType(template, 0)); - assert.equal('v', LessPass._getCharType(template, 1)); - assert.equal('c', LessPass._getCharType(template, 10)); - }); - it('should convert a string into an array of char code', function () { - var charCodes = LessPass._string2charCodes('ab40f6ee71'); - assert.equal(97, charCodes[0]); - assert.equal(98, charCodes[1]); - assert.equal(10, charCodes.length); - }); - it('should get password char based on its type and index', function () { - var typeVowel = 'V'; - assert.equal('A', LessPass._getPasswordChar(typeVowel, 0)); - }); - it('should modulo if overflow', function () { - var typeVowel = 'V'; - assert.equal('E', LessPass._getPasswordChar(typeVowel, 1)); - assert.equal('E', LessPass._getPasswordChar(typeVowel, 7)); - }); +describe('LessPass v1', function() { + describe('prettyPrint', function() { + it('should print different password if templates different', function() { + var encryptedLogin = '78ae5892055ab59fdd54489ae30928d322841a27590b65cf875fcfdd083f7c32'; + assert.notEqual(LessPass._prettyPrint(encryptedLogin, 'cv'), LessPass._prettyPrint(encryptedLogin, 'vc')); }); + it('must return a string of the same length as the input', function() { + var hash = 'f5785e569ab5d38b02e2248c798ac17df90f57a85f34a9d5382408c2f0d9532d'; + assert.equal(hash.length, LessPass._prettyPrint(hash, 'cv').length); + }); + it('should return char inside a string based on modulo of the index', function() { + var template = 'cv'; + assert.equal('c', LessPass._getCharType(template, 0)); + assert.equal('v', LessPass._getCharType(template, 1)); + assert.equal('c', LessPass._getCharType(template, 10)); + }); + it('should convert a string into an array of char code', function() { + var charCodes = LessPass._string2charCodes('ab40f6ee71'); + assert.equal(97, charCodes[0]); + assert.equal(98, charCodes[1]); + assert.equal(10, charCodes.length); + }); + it('should get password char based on its type and index', function() { + var typeVowel = 'V'; + assert.equal('A', LessPass._getPasswordChar(typeVowel, 0)); + }); + it('should modulo if overflow', function() { + var typeVowel = 'V'; + assert.equal('E', LessPass._getPasswordChar(typeVowel, 1)); + assert.equal('E', LessPass._getPasswordChar(typeVowel, 7)); + }); + }); }); diff --git a/tests/v2/api.tests.js b/tests/v2/api.tests.js index a7231bd..d6e988d 100644 --- a/tests/v2/api.tests.js +++ b/tests/v2/api.tests.js @@ -1,79 +1,79 @@ var assert = chai.assert; -describe('LessPass v2', function () { - describe('API', function () { - it('render password', function () { - this.timeout(10000); - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - length: 16, - counter: 1, - version: 2 - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('WHLpUL)e00[iHR+w', generatedPassword); - }); - }); - it('render password no symbols', function () { - this.timeout(10000); - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: true, - symbols: false, - length: 14, - counter: 2, - version: 2 - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('MBAsB7b1Prt8Sl', generatedPassword); - }); - }); - it('render password only digit', function () { - this.timeout(10000); - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: false, - uppercase: false, - numbers: true, - symbols: false, - length: 6, - counter: 3, - version: 2 - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal('117843', generatedPassword); - }); - }); - it('render password no number', function () { - this.timeout(10000); - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile = { - lowercase: true, - uppercase: true, - numbers: false, - symbols: true, - length: 14, - counter: 1, - version: 2 - }; - return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function (generatedPassword) { - assert.equal("sB>{qF}wN%/-fm", generatedPassword); - }); - }); +describe('LessPass v2', function() { + describe('API', function() { + it('render password', function() { + this.timeout(10000); + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + length: 16, + counter: 1, + version: 2 + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('WHLpUL)e00[iHR+w', generatedPassword); + }); }); + it('render password no symbols', function() { + this.timeout(10000); + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: true, + symbols: false, + length: 14, + counter: 2, + version: 2 + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('MBAsB7b1Prt8Sl', generatedPassword); + }); + }); + it('render password only digit', function() { + this.timeout(10000); + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: false, + uppercase: false, + numbers: true, + symbols: false, + length: 6, + counter: 3, + version: 2 + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal('117843', generatedPassword); + }); + }); + it('render password no number', function() { + this.timeout(10000); + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile = { + lowercase: true, + uppercase: true, + numbers: false, + symbols: true, + length: 14, + counter: 1, + version: 2 + }; + return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(function(generatedPassword) { + assert.equal("sB>{qF}wN%/-fm", generatedPassword); + }); + }); + }); }); diff --git a/tests/v2/entropy.tests.js b/tests/v2/entropy.tests.js index cfc2814..30c25f2 100644 --- a/tests/v2/entropy.tests.js +++ b/tests/v2/entropy.tests.js @@ -1,58 +1,58 @@ var assert = chai.assert; -describe('LessPass v2', function () { - describe('entropy', function () { - it('calc entropy pbkdf2 with default params (100000 iterations, 32 bytes length, sha256 digest)', function () { - this.timeout(10000); - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile = { - iterations: 100000, - keylen: 32, - digest: 'sha256', - counter: 1 - }; - return LessPass._calcEntropy(site, login, masterPassword, passwordProfile).then(function (entropy) { - assert.equal('dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e', entropy); - }); - }); - it('calc entropy with different options (8192 iterations, 16 bytes length, sha512 digest)', function () { - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile = { - iterations: 8192, - keylen: 16, - digest: 'sha512', - counter: 1 - }; - return LessPass._calcEntropy(site, login, masterPassword, passwordProfile).then(function (entropy) { - assert.equal('fff211c16a4e776b3574c6a5c91fd252', entropy); - }); - }); - it('calc entropy different if counter different 1', function () { - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile1 = {iterations: 1, keylen: 16, digest: 'sha256', counter: 1}; - return LessPass._calcEntropy(site, login, masterPassword, passwordProfile1).then(function (entropy) { - assert.equal('d3ec1e988dd0b3640c7491cd2c2a88b5', entropy) - }); - }); - it('calc entropy different if counter different 2', function () { - var site = 'example.org'; - var login = 'contact@example.org'; - var masterPassword = 'password'; - var passwordProfile2 = {iterations: 1, keylen: 16, digest: 'sha256', counter: 2}; - return LessPass._calcEntropy(site, login, masterPassword, passwordProfile2).then(function (entropy) { - assert.equal('ddfb1136260f930c21f6d72f6eddbd40', entropy) - }); - }); - it('consume entropy', function () { - var password = LessPass._consumeEntropy('', bigInt(4 * 4 + 2), "abcd", 2); - assert.equal('ca', password.value); - assert.equal(1, password.entropy) - }); +describe('LessPass v2', function() { + describe('entropy', function() { + it('calc entropy pbkdf2 with default params (100000 iterations, 32 bytes length, sha256 digest)', function() { + this.timeout(10000); + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile = { + iterations: 100000, + keylen: 32, + digest: 'sha256', + counter: 1 + }; + return LessPass._calcEntropy(site, login, masterPassword, passwordProfile).then(function(entropy) { + assert.equal('dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e', entropy); + }); }); + it('calc entropy with different options (8192 iterations, 16 bytes length, sha512 digest)', function() { + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile = { + iterations: 8192, + keylen: 16, + digest: 'sha512', + counter: 1 + }; + return LessPass._calcEntropy(site, login, masterPassword, passwordProfile).then(function(entropy) { + assert.equal('fff211c16a4e776b3574c6a5c91fd252', entropy); + }); + }); + it('calc entropy different if counter different 1', function() { + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile1 = {iterations: 1, keylen: 16, digest: 'sha256', counter: 1}; + return LessPass._calcEntropy(site, login, masterPassword, passwordProfile1).then(function(entropy) { + assert.equal('d3ec1e988dd0b3640c7491cd2c2a88b5', entropy) + }); + }); + it('calc entropy different if counter different 2', function() { + var site = 'example.org'; + var login = 'contact@example.org'; + var masterPassword = 'password'; + var passwordProfile2 = {iterations: 1, keylen: 16, digest: 'sha256', counter: 2}; + return LessPass._calcEntropy(site, login, masterPassword, passwordProfile2).then(function(entropy) { + assert.equal('ddfb1136260f930c21f6d72f6eddbd40', entropy) + }); + }); + it('consume entropy', function() { + var password = LessPass._consumeEntropy('', bigInt(4 * 4 + 2), "abcd", 2); + assert.equal('ca', password.value); + assert.equal(1, password.entropy) + }); + }); }); diff --git a/tests/v2/renderPassword.tests.js b/tests/v2/renderPassword.tests.js index ee671ac..2de96f1 100644 --- a/tests/v2/renderPassword.tests.js +++ b/tests/v2/renderPassword.tests.js @@ -1,70 +1,70 @@ var assert = chai.assert; -describe('LessPass v2', function () { - var defaultPasswordProfile = { - length: 16, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true +describe('LessPass v2', function() { + var defaultPasswordProfile = { + length: 16, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true + }; + it('render password use remainder of long division beetween entropy and set of chars length as an index', function() { + var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; + assert.equal('W', LessPass._renderPassword(entropy, defaultPasswordProfile)[0]); + }); + it('render password use quotient as second entropy recursively', function() { + var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; + assert.equal('H', LessPass._renderPassword(entropy, defaultPasswordProfile)[1]); + }); + it('render password has default length of 16', function() { + var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; + assert.equal(16, LessPass._renderPassword(entropy, defaultPasswordProfile).length); + }); + it('render password can specify length', function() { + var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; + var passwordProfile = { + length: 20, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true }; - it('render password use remainder of long division beetween entropy and set of chars length as an index', function () { - var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; - assert.equal('W', LessPass._renderPassword(entropy, defaultPasswordProfile)[0]); - }); - it('render password use quotient as second entropy recursively', function () { - var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; - assert.equal('H', LessPass._renderPassword(entropy, defaultPasswordProfile)[1]); - }); - it('render password has default length of 16', function () { - var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; - assert.equal(16, LessPass._renderPassword(entropy, defaultPasswordProfile).length); - }); - it('render password can specify length', function () { - var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; - var passwordProfile = { - length: 20, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true - }; - assert.equal(20, LessPass._renderPassword(entropy, passwordProfile).length); - }); - it('include one char per set of characters', function () { - var password = LessPass._insertStringPseudoRandomly('123456', bigInt(7 * 6 + 2), 'uT'); - assert.equal('T12u3456', password); - }); - it('render password return at least one char in every characters set', function () { - var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; - var passwordProfile = { - length: 6, - lowercase: true, - uppercase: true, - numbers: true, - symbols: true, - }; - var generatedPassword = LessPass._renderPassword(entropy, passwordProfile); - var passwordLength = generatedPassword.length; - var lowercaseOk = false; - var uppercaseOk = false; - var numbersOk = false; - var symbolsOk = false; - while (passwordLength--) { - if ('abcdefghijklmnopqrstuvwxyz'.indexOf(generatedPassword[passwordLength]) !== -1) { - lowercaseOk = true; - } - if ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(generatedPassword[passwordLength]) !== -1) { - uppercaseOk = true; - } - if ('0123456789'.indexOf(generatedPassword[passwordLength]) !== -1) { - numbersOk = true; - } - if ('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'.indexOf(generatedPassword[passwordLength]) !== -1) { - symbolsOk = true; - } - } - assert.equal(6, generatedPassword.length); - assert(lowercaseOk && uppercaseOk && numbersOk && symbolsOk, 'there is no at least one char in every characters set'); - }); -}); \ No newline at end of file + assert.equal(20, LessPass._renderPassword(entropy, passwordProfile).length); + }); + it('include one char per set of characters', function() { + var password = LessPass._insertStringPseudoRandomly('123456', bigInt(7 * 6 + 2), 'uT'); + assert.equal('T12u3456', password); + }); + it('render password return at least one char in every characters set', function() { + var entropy = 'dc33d431bce2b01182c613382483ccdb0e2f66482cbba5e9d07dab34acc7eb1e'; + var passwordProfile = { + length: 6, + lowercase: true, + uppercase: true, + numbers: true, + symbols: true, + }; + var generatedPassword = LessPass._renderPassword(entropy, passwordProfile); + var passwordLength = generatedPassword.length; + var lowercaseOk = false; + var uppercaseOk = false; + var numbersOk = false; + var symbolsOk = false; + while (passwordLength--) { + if ('abcdefghijklmnopqrstuvwxyz'.indexOf(generatedPassword[passwordLength]) !== -1) { + lowercaseOk = true; + } + if ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(generatedPassword[passwordLength]) !== -1) { + uppercaseOk = true; + } + if ('0123456789'.indexOf(generatedPassword[passwordLength]) !== -1) { + numbersOk = true; + } + if ('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'.indexOf(generatedPassword[passwordLength]) !== -1) { + symbolsOk = true; + } + } + assert.equal(6, generatedPassword.length); + assert(lowercaseOk && uppercaseOk && numbersOk && symbolsOk, 'there is no at least one char in every characters set'); + }); +}); diff --git a/tests/v2/setOfCharacters.tests.js b/tests/v2/setOfCharacters.tests.js index ef96c5f..82134fa 100644 --- a/tests/v2/setOfCharacters.tests.js +++ b/tests/v2/setOfCharacters.tests.js @@ -1,59 +1,59 @@ var assert = chai.assert; -describe('LessPass v2', function () { - describe('set of characters', function () { - it('get default set of characters', function () { - var setOfCharacters = LessPass._getSetOfCharacters(); - assert.equal( - 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', - setOfCharacters - ); - assert.equal(26 * 2 + 10 + 32, setOfCharacters.length); - }); - it('get default set of characters concat rules in order', function () { - var setOfCharacters = LessPass._getSetOfCharacters(['lowercase', 'uppercase', 'numbers']); - assert.equal('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', setOfCharacters); - assert.equal(26 * 2 + 10, setOfCharacters.length); - }); - it('get set of characters only lowercase', function () { - var setOfCharacters = LessPass._getSetOfCharacters(['lowercase']); - assert.equal('abcdefghijklmnopqrstuvwxyz', setOfCharacters); - assert.equal(26, setOfCharacters.length); - }); - it('get set of characters only uppercase', function () { - var setOfCharacters = LessPass._getSetOfCharacters(['uppercase']); - assert.equal('ABCDEFGHIJKLMNOPQRSTUVWXYZ', setOfCharacters); - assert.equal(26, setOfCharacters.length); - }); - it('get set of characters only numbers', function () { - var setOfCharacters = LessPass._getSetOfCharacters(['numbers']); - assert.equal('0123456789', setOfCharacters); - assert.equal(10, setOfCharacters.length); - }); - it('get set of characters only symbols', function () { - var setOfCharacters = LessPass._getSetOfCharacters(['symbols']); - assert.equal('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', setOfCharacters); - assert.equal(32, setOfCharacters.length); - }); - it('generate one char per rules', function () { - var oneCharPerSetOfCharacters = LessPass._getOneCharPerRule( - bigInt(26 * 26), - ['lowercase', 'uppercase'] - ); - assert.equal('aA', oneCharPerSetOfCharacters.value); - assert.equal(2, oneCharPerSetOfCharacters.value.length); - assert.equal(1, oneCharPerSetOfCharacters.entropy); - }); - it('configured rules', function () { - assert.deepEqual(['uppercase'], LessPass._getConfiguredRules({uppercase: true})); - assert.deepEqual(['lowercase', 'uppercase'], LessPass._getConfiguredRules({uppercase: true, lowercase: true})); - assert.deepEqual(['lowercase'], LessPass._getConfiguredRules({lowercase: true, symbols: false})); - assert.deepEqual(['lowercase', 'uppercase', 'numbers', 'symbols'], LessPass._getConfiguredRules({ - lowercase: true, - uppercase: true, - symbols: true, - numbers: true - })); - }); +describe('LessPass v2', function() { + describe('set of characters', function() { + it('get default set of characters', function() { + var setOfCharacters = LessPass._getSetOfCharacters(); + assert.equal( + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', + setOfCharacters + ); + assert.equal(26 * 2 + 10 + 32, setOfCharacters.length); }); + it('get default set of characters concat rules in order', function() { + var setOfCharacters = LessPass._getSetOfCharacters(['lowercase', 'uppercase', 'numbers']); + assert.equal('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', setOfCharacters); + assert.equal(26 * 2 + 10, setOfCharacters.length); + }); + it('get set of characters only lowercase', function() { + var setOfCharacters = LessPass._getSetOfCharacters(['lowercase']); + assert.equal('abcdefghijklmnopqrstuvwxyz', setOfCharacters); + assert.equal(26, setOfCharacters.length); + }); + it('get set of characters only uppercase', function() { + var setOfCharacters = LessPass._getSetOfCharacters(['uppercase']); + assert.equal('ABCDEFGHIJKLMNOPQRSTUVWXYZ', setOfCharacters); + assert.equal(26, setOfCharacters.length); + }); + it('get set of characters only numbers', function() { + var setOfCharacters = LessPass._getSetOfCharacters(['numbers']); + assert.equal('0123456789', setOfCharacters); + assert.equal(10, setOfCharacters.length); + }); + it('get set of characters only symbols', function() { + var setOfCharacters = LessPass._getSetOfCharacters(['symbols']); + assert.equal('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', setOfCharacters); + assert.equal(32, setOfCharacters.length); + }); + it('generate one char per rules', function() { + var oneCharPerSetOfCharacters = LessPass._getOneCharPerRule( + bigInt(26 * 26), + ['lowercase', 'uppercase'] + ); + assert.equal('aA', oneCharPerSetOfCharacters.value); + assert.equal(2, oneCharPerSetOfCharacters.value.length); + assert.equal(1, oneCharPerSetOfCharacters.entropy); + }); + it('configured rules', function() { + assert.deepEqual(['uppercase'], LessPass._getConfiguredRules({uppercase: true})); + assert.deepEqual(['lowercase', 'uppercase'], LessPass._getConfiguredRules({uppercase: true, lowercase: true})); + assert.deepEqual(['lowercase'], LessPass._getConfiguredRules({lowercase: true, symbols: false})); + assert.deepEqual(['lowercase', 'uppercase', 'numbers', 'symbols'], LessPass._getConfiguredRules({ + lowercase: true, + uppercase: true, + symbols: true, + numbers: true + })); + }); + }); }); diff --git a/webpack.config.js b/webpack.config.js index 2f35fc9..ca67413 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -4,22 +4,22 @@ var webpack = require('webpack'); var production = process.env.NODE_ENV === 'production' || false; module.exports = { - entry: './src/lesspass.js', - output: { - filename: production ? 'lesspass.min.js' : 'lesspass.js', - path: path.resolve(__dirname, 'dist'), - library: 'LessPass', - libraryTarget: 'umd' - }, - module: { - rules: [ - {test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"} - ] - }, - plugins: production ? [ - new webpack.optimize.UglifyJsPlugin({ - beautify: false, - comments: false - }) - ] : [] -}; \ No newline at end of file + entry: './src/lesspass.js', + output: { + filename: production ? 'lesspass.min.js' : 'lesspass.js', + path: path.resolve(__dirname, 'dist'), + library: 'LessPass', + libraryTarget: 'umd' + }, + module: { + rules: [ + {test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"} + ] + }, + plugins: production ? [ + new webpack.optimize.UglifyJsPlugin({ + beautify: false, + comments: false + }) + ] : [] +};