@@ -1,23 +1,24 @@ | |||||
var pbkdf2 = require('pbkdf2'); | var pbkdf2 = require('pbkdf2'); | ||||
var createHmac = require('create-hmac'); | var createHmac = require('create-hmac'); | ||||
var Promise = require("bluebird"); | |||||
module.exports = { | module.exports = { | ||||
encryptLogin: _encryptLogin, | encryptLogin: _encryptLogin, | ||||
renderPassword: _renderPassword, | renderPassword: _renderPassword, | ||||
createFingerprint: createFingerprint, | createFingerprint: createFingerprint, | ||||
_deriveEncryptedLogin, | |||||
_getPasswordTemplate, | |||||
_prettyPrint, | |||||
_string2charCodes, | |||||
_getCharType, | |||||
_getPasswordChar, | |||||
_createHmac | |||||
_deriveEncryptedLogin: _deriveEncryptedLogin, | |||||
_getPasswordTemplate: _getPasswordTemplate, | |||||
_prettyPrint: _prettyPrint, | |||||
_string2charCodes: _string2charCodes, | |||||
_getCharType: _getCharType, | |||||
_getPasswordChar: _getPasswordChar, | |||||
_createHmac: _createHmac | |||||
}; | }; | ||||
function _encryptLogin(login, masterPassword, options) { | function _encryptLogin(login, masterPassword, options) { | ||||
const _options = options !== undefined ? options : {}; | |||||
const iterations = _options.iterations || 8192; | |||||
const keylen = _options.keylen || 32; | |||||
var _options = options !== undefined ? options : {}; | |||||
var iterations = _options.iterations || 8192; | |||||
var keylen = _options.keylen || 32; | |||||
return new Promise(function (resolve, reject) { | return new Promise(function (resolve, reject) { | ||||
if (!login || !masterPassword) { | if (!login || !masterPassword) { | ||||
@@ -35,7 +36,7 @@ function _encryptLogin(login, masterPassword, options) { | |||||
function _renderPassword(encryptedLogin, site, passwordOptions) { | function _renderPassword(encryptedLogin, site, passwordOptions) { | ||||
return _deriveEncryptedLogin(encryptedLogin, site, passwordOptions).then(function (derivedEncryptedLogin) { | return _deriveEncryptedLogin(encryptedLogin, site, passwordOptions).then(function (derivedEncryptedLogin) { | ||||
const template = passwordOptions.template || _getPasswordTemplate(passwordOptions); | |||||
var template = passwordOptions.template || _getPasswordTemplate(passwordOptions); | |||||
return _prettyPrint(derivedEncryptedLogin, template); | return _prettyPrint(derivedEncryptedLogin, template); | ||||
}); | }); | ||||
} | } | ||||
@@ -51,41 +52,41 @@ function _deriveEncryptedLogin(encryptedLogin, site, options) { | |||||
var length = _options.length || 12; | var length = _options.length || 12; | ||||
var counter = _options.counter || 1; | var counter = _options.counter || 1; | ||||
const salt = site + counter.toString(); | |||||
var salt = site + counter.toString(); | |||||
return _createHmac(encryptedLogin, salt).then(function (derivedHash) { | return _createHmac(encryptedLogin, salt).then(function (derivedHash) { | ||||
return derivedHash.substring(0, length); | return derivedHash.substring(0, length); | ||||
}); | }); | ||||
} | } | ||||
function _getPasswordTemplate(passwordTypes) { | function _getPasswordTemplate(passwordTypes) { | ||||
const templates = { | |||||
var templates = { | |||||
lowercase: 'vc', | lowercase: 'vc', | ||||
uppercase: 'VC', | uppercase: 'VC', | ||||
numbers: 'n', | numbers: 'n', | ||||
symbols: 's', | symbols: 's', | ||||
}; | }; | ||||
let template = ''; | |||||
for (let templateKey in templates) { | |||||
if (passwordTypes.hasOwnProperty(templateKey) && passwordTypes[templateKey]) { | |||||
template += templates[templateKey] | |||||
var returnedTemplate = ''; | |||||
Object.keys(templates).forEach(function (template) { | |||||
if (passwordTypes.hasOwnProperty(template) && passwordTypes[template]) { | |||||
returnedTemplate += templates[template] | |||||
} | } | ||||
} | |||||
return template; | |||||
}); | |||||
return returnedTemplate; | |||||
} | } | ||||
function _prettyPrint(hash, template) { | function _prettyPrint(hash, template) { | ||||
let password = ''; | |||||
var password = ''; | |||||
_string2charCodes(hash).forEach(function (charCode, index) { | _string2charCodes(hash).forEach(function (charCode, index) { | ||||
const charType = _getCharType(template, index); | |||||
var charType = _getCharType(template, index); | |||||
password += _getPasswordChar(charType, charCode); | password += _getPasswordChar(charType, charCode); | ||||
}); | }); | ||||
return password; | return password; | ||||
} | } | ||||
function _string2charCodes(text) { | function _string2charCodes(text) { | ||||
const charCodes = []; | |||||
for (let i = 0; i < text.length; i++) { | |||||
var charCodes = []; | |||||
for (var i = 0; i < text.length; i++) { | |||||
charCodes.push(text.charCodeAt(i)); | charCodes.push(text.charCodeAt(i)); | ||||
} | } | ||||
return charCodes; | return charCodes; | ||||
@@ -96,7 +97,7 @@ function _getCharType(template, index) { | |||||
} | } | ||||
function _getPasswordChar(charType, index) { | function _getPasswordChar(charType, index) { | ||||
const passwordsChars = { | |||||
var passwordsChars = { | |||||
V: 'AEIOUY', | V: 'AEIOUY', | ||||
C: 'BCDFGHJKLMNPQRSTVWXZ', | C: 'BCDFGHJKLMNPQRSTVWXZ', | ||||
v: 'aeiouy', | v: 'aeiouy', | ||||
@@ -107,7 +108,7 @@ function _getPasswordChar(charType, index) { | |||||
s: '@&%?,=[]_:-+*$#!\'^~;()/.', | s: '@&%?,=[]_:-+*$#!\'^~;()/.', | ||||
x: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz0123456789@&%?,=[]_:-+*$#!\'^~;()/.' | x: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz0123456789@&%?,=[]_:-+*$#!\'^~;()/.' | ||||
}; | }; | ||||
const passwordChar = passwordsChars[charType]; | |||||
var passwordChar = passwordsChars[charType]; | |||||
return passwordChar[index % passwordChar.length]; | return passwordChar[index % passwordChar.length]; | ||||
} | } | ||||
@@ -23,6 +23,7 @@ | |||||
"test:browser": "npm run build && karma start tests/karma.config.js" | "test:browser": "npm run build && karma start tests/karma.config.js" | ||||
}, | }, | ||||
"dependencies": { | "dependencies": { | ||||
"bluebird": "^3.4.6", | |||||
"create-hmac": "^1.1.4", | "create-hmac": "^1.1.4", | ||||
"pbkdf2": "^3.0.9", | "pbkdf2": "^3.0.9", | ||||
"unibabel": "^2.1.3" | "unibabel": "^2.1.3" | ||||
@@ -38,7 +39,9 @@ | |||||
"karma-chrome-launcher": "^2.0.0", | "karma-chrome-launcher": "^2.0.0", | ||||
"karma-firefox-launcher": "^1.0.0", | "karma-firefox-launcher": "^1.0.0", | ||||
"karma-mocha": "^1.3.0", | "karma-mocha": "^1.3.0", | ||||
"karma-phantomjs-launcher": "^1.0.2", | |||||
"mocha": "^3.1.2", | "mocha": "^3.1.2", | ||||
"phantomjs": "^2.1.7", | |||||
"rimraf": "^2.5.4" | "rimraf": "^2.5.4" | ||||
} | } | ||||
} | } |
@@ -100,12 +100,12 @@ describe('LessPass', function () { | |||||
} | } | ||||
]; | ]; | ||||
for (var entry of passwords) { | |||||
passwords.forEach(function (entry) { | |||||
promises.push(LessPass.encryptLogin(entry.login, entry.masterPassword)); | promises.push(LessPass.encryptLogin(entry.login, entry.masterPassword)); | ||||
} | |||||
}); | |||||
return Promise.all(promises).then(values => { | |||||
for (let i = 0; i < values.length; i++) { | |||||
return Promise.all(promises).then(function (values) { | |||||
for (var i = 0; i < values.length; i++) { | |||||
assert.equal(passwords[i].encryptedLogin, values[i]); | assert.equal(passwords[i].encryptedLogin, values[i]); | ||||
} | } | ||||
}); | }); | ||||
@@ -312,7 +312,7 @@ describe('LessPass', function () { | |||||
} | } | ||||
]; | ]; | ||||
for (var entry of passwords) { | |||||
passwords.forEach(function (entry) { | |||||
var passwordOption = { | var passwordOption = { | ||||
counter: entry.counter, | counter: entry.counter, | ||||
length: entry.length, | length: entry.length, | ||||
@@ -322,10 +322,10 @@ describe('LessPass', function () { | |||||
symbols: entry.symbols, | symbols: entry.symbols, | ||||
}; | }; | ||||
promises.push(LessPass.renderPassword(entry.encryptedLogin, entry.site, passwordOption)); | promises.push(LessPass.renderPassword(entry.encryptedLogin, entry.site, passwordOption)); | ||||
} | |||||
}); | |||||
return Promise.all(promises).then(values => { | |||||
for (let i = 0; i < values.length; i++) { | |||||
return Promise.all(promises).then(function(values) { | |||||
for (var i = 0; i < values.length; i++) { | |||||
assert.equal(passwords[i].generatedPassword, values[i]); | assert.equal(passwords[i].generatedPassword, values[i]); | ||||
} | } | ||||
}); | }); | ||||
@@ -23,7 +23,7 @@ describe('LessPass', function () { | |||||
}; | }; | ||||
var p1 = LessPass._deriveEncryptedLogin(encryptedLogin, site); | var p1 = LessPass._deriveEncryptedLogin(encryptedLogin, site); | ||||
var p2 = LessPass._deriveEncryptedLogin(encryptedLogin, site, option); | var p2 = LessPass._deriveEncryptedLogin(encryptedLogin, site, option); | ||||
Promise.all([p1, p2]).then(generatedPasswords => { | |||||
Promise.all([p1, p2]).then(function(generatedPasswords) { | |||||
assert.equal(generatedPasswords[0], generatedPasswords[1]) | assert.equal(generatedPasswords[0], generatedPasswords[1]) | ||||
}); | }); | ||||
}); | }); | ||||
@@ -45,7 +45,7 @@ describe('LessPass', function () { | |||||
const site2 = 'facebook.com'; | const site2 = 'facebook.com'; | ||||
var p1 = LessPass._deriveEncryptedLogin(encryptedLogin, site); | var p1 = LessPass._deriveEncryptedLogin(encryptedLogin, site); | ||||
var p2 = LessPass._deriveEncryptedLogin(encryptedLogin, site2); | var p2 = LessPass._deriveEncryptedLogin(encryptedLogin, site2); | ||||
Promise.all([p1, p2]).then(derivedEncryptedLogins => { | |||||
Promise.all([p1, p2]).then(function(derivedEncryptedLogins) { | |||||
assert.notEqual(derivedEncryptedLogins[0], derivedEncryptedLogins[1]) | assert.notEqual(derivedEncryptedLogins[0], derivedEncryptedLogins[1]) | ||||
}); | }); | ||||
}); | }); | ||||
@@ -56,7 +56,7 @@ describe('LessPass', function () { | |||||
const option2 = {counter: 2}; | const option2 = {counter: 2}; | ||||
var p1 = LessPass._deriveEncryptedLogin(encryptedLogin, site, option); | var p1 = LessPass._deriveEncryptedLogin(encryptedLogin, site, option); | ||||
var p2 = LessPass._deriveEncryptedLogin(encryptedLogin, site, option2); | var p2 = LessPass._deriveEncryptedLogin(encryptedLogin, site, option2); | ||||
Promise.all([p1, p2]).then(derivedEncryptedLogins => { | |||||
Promise.all([p1, p2]).then(function(derivedEncryptedLogins) { | |||||
assert.notEqual(derivedEncryptedLogins[0], derivedEncryptedLogins[1]) | assert.notEqual(derivedEncryptedLogins[0], derivedEncryptedLogins[1]) | ||||
}); | }); | ||||
}); | }); | ||||
@@ -1,8 +1,9 @@ | |||||
module.exports = function (config) { | module.exports = function (config) { | ||||
config.set({ | |||||
var configuration = { | |||||
basePath: '..', | basePath: '..', | ||||
frameworks: ['mocha', 'chai'], | frameworks: ['mocha', 'chai'], | ||||
files: [ | files: [ | ||||
'node_modules/bluebird/js/browser/bluebird.core.min.js', | |||||
'lib/lesspass.js', | 'lib/lesspass.js', | ||||
'tests/**/*.js' | 'tests/**/*.js' | ||||
], | ], | ||||
@@ -20,5 +21,9 @@ module.exports = function (config) { | |||||
browsers: ['Chrome', 'Firefox'], | browsers: ['Chrome', 'Firefox'], | ||||
singleRun: true, | singleRun: true, | ||||
concurrency: Infinity | concurrency: Infinity | ||||
}) | |||||
}; | |||||
if (process.env.TRAVIS) { | |||||
configuration.browsers = ['PhantomJS']; | |||||
} | |||||
config.set(configuration) | |||||
}; | }; |
@@ -1,5 +1,5 @@ | |||||
module.exports = function (config) { | module.exports = function (config) { | ||||
config.set({ | |||||
var configuration = { | |||||
basePath: '..', | basePath: '..', | ||||
frameworks: ['mocha', 'chai'], | frameworks: ['mocha', 'chai'], | ||||
files: [ | files: [ | ||||
@@ -22,5 +22,9 @@ module.exports = function (config) { | |||||
browsers: ['Chrome', 'Firefox'], | browsers: ['Chrome', 'Firefox'], | ||||
singleRun: true, | singleRun: true, | ||||
concurrency: Infinity | concurrency: Infinity | ||||
}) | |||||
}; | |||||
if (process.env.TRAVIS) { | |||||
configuration.browsers = ['PhantomJS']; | |||||
} | |||||
config.set(configuration) | |||||
}; | }; |
@@ -15,12 +15,12 @@ var options = { | |||||
}; | }; | ||||
LessPass.encryptLogin(login, masterPassword) | LessPass.encryptLogin(login, masterPassword) | ||||
.then(encryptedLogin => { | |||||
LessPass.renderPassword(encryptedLogin, site, options).then(generatedPassword => { | |||||
.then(function(encryptedLogin) { | |||||
LessPass.renderPassword(encryptedLogin, site, options).then(function(generatedPassword) { | |||||
assert.equal(generatedPassword, 'azYS7,olOL2]'); | assert.equal(generatedPassword, 'azYS7,olOL2]'); | ||||
console.log('generated password ok'); | console.log('generated password ok'); | ||||
}); | }); | ||||
}) | }) | ||||
.catch(e => { | |||||
.catch(function(e) { | |||||
console.log(e); | console.log(e); | ||||
}); | }); |