diff --git a/package.json b/package.json index 3a7fbf1..024d066 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "bcryptjs": "^2.3.0", "debug": "^2.2.0", "feathers-errors": "^2.4.0", + "lodash.get": "^4.4.2", "lodash.merge": "^4.6.0", "lodash.omit": "^4.5.0", "lodash.pick": "^4.4.0", diff --git a/src/verifier.js b/src/verifier.js index 209a7ca..f09d998 100644 --- a/src/verifier.js +++ b/src/verifier.js @@ -1,6 +1,7 @@ import Debug from 'debug'; import errors from 'feathers-errors'; import bcrypt from 'bcryptjs'; +import get from 'lodash.get'; const debug = Debug('feathers-authentication-local:verify'); @@ -20,14 +21,15 @@ class LocalVerifier { } _comparePassword(entity, password) { - const hash = entity[this.options.passwordField]; + // find password in entity, this allows for dot notation + const hash = get(entity, this.options.passwordField); if (!hash) { return Promise.reject(new Error(`'${this.options.entity}' record in the database is missing a '${this.options.passwordField}'`)); } debug('Verifying password'); - + return new Promise((resolve, reject) => { bcrypt.compare(password, hash, function(error, result) { // Handle 500 server error. @@ -80,4 +82,4 @@ class LocalVerifier { } } -export default LocalVerifier; \ No newline at end of file +export default LocalVerifier; diff --git a/test/index.test.js b/test/index.test.js index 3205eb3..75bca28 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -36,7 +36,7 @@ describe('feathers-authentication-local', () => { app.configure(authentication({ secret: 'supersecret' })); }); - it('throws an error if passport has not been registered', () => { + it('throws an error if passport has not been registered', () => { expect(() => { feathers().configure(local()); }).to.throw(); @@ -50,7 +50,7 @@ describe('feathers-authentication-local', () => { expect(passportLocal.Strategy).to.have.been.calledOnce; expect(app.passport.use).to.have.been.calledWith('local'); - + app.passport.use.restore(); passportLocal.Strategy.restore(); }); @@ -61,7 +61,7 @@ describe('feathers-authentication-local', () => { app.setup(); expect(app.passport.options).to.have.been.calledOnce; - + app.passport.options.restore(); }); @@ -116,7 +116,7 @@ describe('feathers-authentication-local', () => { app.setup(); expect(passportLocal.Strategy.getCall(0).args[0].usernameField).to.equal('username'); - + passportLocal.Strategy.restore(); }); @@ -131,7 +131,7 @@ describe('feathers-authentication-local', () => { expect(passportLocal.Strategy.getCall(0).args[0].usernameField).to.equal('username'); expect(passportLocal.Strategy.getCall(0).args[0].passwordField).to.equal('password'); - + passportLocal.Strategy.restore(); }); @@ -146,7 +146,7 @@ describe('feathers-authentication-local', () => { expect(passportLocal.Strategy.getCall(0).args[0].usernameField).to.equal('username'); expect(passportLocal.Strategy.getCall(0).args[0].passwordField).to.equal('password'); - + passportLocal.Strategy.restore(); }); diff --git a/test/verifier.test.js b/test/verifier.test.js index 655f554..39a9370 100644 --- a/test/verifier.test.js +++ b/test/verifier.test.js @@ -21,7 +21,7 @@ describe('Verifier', () => { return hasher('admin').then(password => { user = { email: 'admin@feathersjs.com', - password + password }; service = { @@ -45,6 +45,8 @@ describe('Verifier', () => { expect(typeof Verifier).to.equal('function'); }); + + describe('constructor', () => { it('retains an app reference', () => { expect(verifier.app).to.deep.equal(app); @@ -95,18 +97,30 @@ describe('Verifier', () => { expect(result).to.deep.equal(user); }); }); + + it('allows dot notation for password field', () => { + user.password = { + value: user.password + }; + + verifier.options.passwordField = 'password.value'; + + return verifier._comparePassword(user, 'admin').then(result => { + expect(result).to.deep.equal(user); + }); + }); }); }); describe('_normalizeResult', () => { describe('when has results', () => { - it('returns entity when paginated', () => { + it('returns entity when paginated', () => { return verifier._normalizeResult({ data: [user] }).then(result => { expect(result).to.deep.equal(user); }); }); - it('returns entity when not paginated', () => { + it('returns entity when not paginated', () => { return verifier._normalizeResult([user]).then(result => { expect(result).to.deep.equal(user); }); @@ -114,13 +128,13 @@ describe('Verifier', () => { }); describe('when no results', () => { - it('rejects with false when paginated', () => { + it('rejects with false when paginated', () => { return verifier._normalizeResult({ data: [] }).catch(error => { expect(error).to.equal(false); }); }); - it('rejects with false when not paginated', () => { + it('rejects with false when not paginated', () => { return verifier._normalizeResult([]).catch(error => { expect(error).to.equal(false); });