├── .travis.yml ├── .gitignore ├── package.json ├── LICENSE ├── Readme.md ├── index.js └── test └── index.js /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directory 2 | # Deployed apps should consider commenting this line out: 3 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 4 | node_modules 5 | 6 | # Other 7 | .DS_Store 8 | coverage 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bcrypt-as-promised", 3 | "version": "1.1.0", 4 | "description": "A promisified bcrypt", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "istanbul cover _mocha && npm run check-coverage", 8 | "check-coverage": "istanbul check-coverage" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git@github.com:iceddev/bcrypt-as-promised.git" 13 | }, 14 | "keywords": [ 15 | "bcrypt", 16 | "promise" 17 | ], 18 | "author": "Luis Montes", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/iceddev/bcrypt-as-promised/issues" 22 | }, 23 | "homepage": "https://github.com/iceddev/bcrypt-as-promised", 24 | "dependencies": { 25 | "bcrypt": "^0.8.0", 26 | "when": "^3.5.2" 27 | }, 28 | "devDependencies": { 29 | "chai": "^1.9.2", 30 | "chai-as-promised": "^4.1.1", 31 | "istanbul": "^0.3.2", 32 | "mocha": "^2.0.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Iced Development 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | bcrypt-as-promised 2 | ================== 3 | 4 | [![Build Status](https://travis-ci.org/iceddev/bcrypt-as-promised.svg?branch=master)](https://travis-ci.org/iceddev/bcrypt-as-promised) 5 | 6 | A promisified version of [bcrypt](https://github.com/ncb000gt/node.bcrypt.js) 7 | 8 | ## Install via NPM 9 | ``` 10 | npm install bcrypt-as-promised 11 | ``` 12 | 13 | ## Basic Usage 14 | 15 | hashing: 16 | ```js 17 | bcrypt.hash('my password', 10) 18 | .then(console.log, console.error) 19 | ``` 20 | 21 | comparing: 22 | ```js 23 | bcrypt.compare('my password', someHash) 24 | .then(console.log, console.error) 25 | ``` 26 | 27 | __Note: an invalid password/hash combo errors as a rejected promise__ 28 | 29 | The rejection can be checked against `instanceof bcrypt.MISMATCH_ERROR` 30 | 31 | ```js 32 | bcrypt.compare('invalid password', someHash) 33 | .then(handleValidPassword) 34 | .catch(bcrypt.MISMATCH_ERROR, handleInvalidPassword) 35 | .catch(handleOtherErrors); 36 | ``` 37 | 38 | generating a salt: 39 | ```js 40 | bcrypt.genSalt(10) 41 | .then(console.log, console.error) 42 | ``` 43 | 44 | calculating the rounds used in a salt: 45 | ```js 46 | bcrypt.getRounds(someHash) 47 | .then(console.log, console.error) 48 | ``` 49 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | 5 | var bcrypt = require('bcrypt'); 6 | var nodefn = require('when/node'); 7 | var when = require('when'); 8 | 9 | var getValid = nodefn.lift(bcrypt.compare); 10 | var hash = nodefn.lift(bcrypt.hash); 11 | 12 | var DEFAULT_ROUNDS = 10; 13 | 14 | function MismatchError(message){ 15 | Error.call(this); 16 | this.message = message; 17 | this.name = MismatchError.name; 18 | if(typeof Error.captureStackTrace === 'function'){ 19 | Error.captureStackTrace(this, MismatchError); 20 | } 21 | } 22 | util.inherits(MismatchError, Error); 23 | 24 | function throwOnInvalid(valid){ 25 | if(!valid){ 26 | return when.reject(new MismatchError('invalid')); 27 | } else { 28 | return valid; 29 | } 30 | } 31 | 32 | function compare(password, hash){ 33 | return getValid(password, hash) 34 | .then(throwOnInvalid); 35 | } 36 | 37 | function getRounds(hash){ 38 | return when.try(bcrypt.getRounds, hash); 39 | } 40 | 41 | function promisedHash(password, salt){ 42 | if(!salt){ 43 | salt = DEFAULT_ROUNDS; 44 | } 45 | return hash(password, salt); 46 | } 47 | 48 | module.exports = { 49 | hash: promisedHash, 50 | genSalt: nodefn.lift(bcrypt.genSalt), 51 | compare: compare, 52 | getRounds: getRounds, 53 | MISMATCH_ERROR: MismatchError 54 | }; 55 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var chai = require('chai'); 4 | var chaiAsPromised = require('chai-as-promised'); 5 | 6 | chai.use(chaiAsPromised); 7 | 8 | var expect = chai.expect; 9 | 10 | var bcrypt = require('../'); 11 | 12 | describe('bcrypt-as-promised', function(){ 13 | 14 | var goodPassword = 'aHBeRy85cNK*zubPPkKylAKFsBG@N&v&'; 15 | var goodHash = '$2a$10$NRSrC8ldvcmBs5/OHX5X/.WaSr1uiK8kSPuhNYXLkmLck8lTScivG'; 16 | 17 | it('should hash a password', function(){ 18 | return expect(bcrypt.hash(goodPassword, 10)) 19 | .to.eventually.be.an('string'); 20 | }); 21 | 22 | it('should hash a password with default number of rounds', function(){ 23 | return expect(bcrypt.hash(goodPassword)) 24 | .to.eventually.be.an('string'); 25 | }); 26 | 27 | it('should error hashing an invalid password', function(){ 28 | return expect(bcrypt.hash(null, 10)) 29 | .to.eventually.be.rejectedWith(Error); 30 | }); 31 | 32 | it('should generate a salt', function(){ 33 | return expect(bcrypt.genSalt(10)) 34 | .to.eventually.be.an('string'); 35 | }); 36 | 37 | it('should error generating a salt with invalid input', function(){ 38 | return expect(bcrypt.genSalt('not a number')) 39 | .to.eventually.be.rejectedWith(Error); 40 | }); 41 | 42 | it('should compare a password againts its hash', function(){ 43 | return expect(bcrypt.compare(goodPassword, goodHash)) 44 | .to.eventually.equal(true); 45 | }); 46 | 47 | it('should error on an invalid password', function(){ 48 | var badPassword = 'a BAD password'; 49 | return expect(bcrypt.compare(badPassword, goodHash)) 50 | .to.eventually.be.rejectedWith(Error); 51 | }); 52 | 53 | it('should error with MISMATCH_ERROR on an invalid password', function(){ 54 | var badPassword = 'a BAD password'; 55 | return expect(bcrypt.compare(badPassword, goodHash)) 56 | .to.eventually.be.rejectedWith(bcrypt.MISMATCH_ERROR); 57 | }); 58 | 59 | it('should get number of rounds from a hash', function(){ 60 | return expect(bcrypt.getRounds(goodHash)) 61 | .to.eventually.equal(10); 62 | }); 63 | 64 | it('should error on an invalid hash', function(){ 65 | return expect(bcrypt.getRounds('not a real hash')) 66 | .to.eventually.be.rejectedWith(Error); 67 | }); 68 | 69 | }); 70 | --------------------------------------------------------------------------------