Skip to content

Instantly share code, notes, and snippets.

@jaketrent
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaketrent/d30106405d111ae27038 to your computer and use it in GitHub Desktop.
Save jaketrent/d30106405d111ae27038 to your computer and use it in GitHub Desktop.
Bcrypt Hash
'use strict'
const bcrypt = require('bcryptjs')
exports.create = function (secret, done) {
if (!secret || !done) throw new Error('Secret and callback required to encrypt')
bcrypt.genSalt(function (saltErr, salt) {
if (saltErr) return done(saltErr)
bcrypt.hash(secret, salt, function (hashErr, hash) {
if (hashErr) return done(hashErr)
done(null, hash)
})
})
}
exports.matches = function (secret, hash, done) {
if (!(secret && hash && done)) throw new Error('Secret, hash, and callback required to match')
bcrypt.compare(secret, hash, function (err, matches) {
if (err) return done(err)
done(null, matches)
})
}
'use strict'
should = require 'should'
spyquire = require 'spyquire'
spies = spyquire('../../../../app/common/util/hash')
.with('bcryptjs', 'genSalt').nick('genSalt')
.with('bcryptjs', 'hash').nick('hash')
.with('bcryptjs', 'compare').nick('compare')
hashUtil = spies.exec()
describe 'util/hash', ->
beforeEach ->
spies.reset()
describe '#create', ->
it 'takes a secret and a callback', ->
hashUtil.create.length.should.eql 2
it 'must be called with a secret', ->
(-> hashUtil.create()).should.throw()
it 'must be called with a callback', ->
(-> hashUtil.create('fakeSecret')).should.throw()
it 'generates a salt', (done) ->
hashUtil.create 'fakeSecret', (err, hash) ->
spies.at('genSalt').called.should.be.true
done()
it 'returns salt errors', (done) ->
saltErr = { some: 'error' }
spies.at('genSalt').errors = saltErr
hashUtil.create 'fakeSecret', (err, hash) ->
err.should.eql saltErr
done()
it 'uses the salt in the hashing', (done) ->
plainTxt = 'fakeSecret'
salt = 'fakeSalt'
spies.at('genSalt').returns = salt
hashUtil.create 'fakeSecret', (err, hash) ->
spies.at('hash').called.should.be.true
spies.at('hash').args[0].should.eql plainTxt
spies.at('hash').args[1].should.eql salt
done()
it 'returns hash errors', (done) ->
hashErr = { some: 'hash err' }
spies.at('hash').errors = hashErr
hashUtil.create 'fakeSecret', (err, hash) ->
err.should.eql hashErr
done()
it 'returns the hash', (done) ->
hashTxt = 'pureNonIntelligbleEncryptionGoodness'
salt = 'fakeSalt'
spies.at('genSalt').returns = salt
spies.at('hash').returns = hashTxt
hashUtil.create 'fakeSecret', (err, hash) ->
hash.should.eql hashTxt
done()
describe '#matches', ->
it 'takes a secret, hash, and callback', ->
hashUtil.matches.length.should.eql 3
it 'must be called with a secret, hash, and callback', ->
(-> hashUtil.matches()).should.throw()
(-> hashUtil.matches('secret')).should.throw()
(-> hashUtil.matches('secret', 'hash')).should.throw()
it 'calls compare with secret and hash', (done) ->
plainTxt = 'fakeSecret'
hashTxt = 'fakeHash'
hashUtil.matches plainTxt, hashTxt, (err, matches) ->
spies.at('compare').called.should.be.true
spies.at('compare').args[0].should.eql plainTxt
spies.at('compare').args[1].should.eql hashTxt
done()
it 'returns compare errors', (done) ->
compareErr = { some: 'error' }
spies.at('compare').errors = compareErr
hashUtil.matches 'fakeSecret', 'fakeHash', (err, matches) ->
err.should.eql compareErr
done()
it 'returns false if secret and hash dont match', (done) ->
spies.at('compare').returns = false
hashUtil.matches 'fakeSecret', 'fakeHash', (err, matches) ->
matches.should.be.false
done()
it 'returns true if secret and hash match', (done) ->
spies.at('compare').returns = true
hashUtil.matches 'fakeSecret', 'fakeHash', (err, matches) ->
matches.should.be.true
done()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment