hapi-auth-bearer-simple
Advanced tools
Comparing version 2.0.0 to 3.0.0
@@ -5,28 +5,26 @@ 'use strict'; | ||
var Boom = require('boom'); | ||
var Hoek = require('hoek'); | ||
const Boom = require('boom'); | ||
const Hoek = require('hoek'); | ||
var internals = {}; | ||
const internals = {}; | ||
internals.validateCallback = function (err, isValid, credentials, token, reply) { | ||
credentials = credentials || null; | ||
if (err) { | ||
return reply(Boom.unauthorized(err.message, 'bearerAuth'), { | ||
isValid: isValid, | ||
credentials: credentials | ||
}, null, {}); | ||
return reply(err, null, { credentials: credentials }); | ||
} | ||
if (!isValid) { | ||
return reply(Boom.unauthorized(null, 'bearerAuth', { | ||
return reply(Boom.unauthorized('Bad token', 'bearerAuth', { | ||
isValid: isValid, | ||
credentials: credentials | ||
}), null, {}); | ||
}), null, { credentials: credentials }); | ||
} | ||
if (!credentials) { | ||
return reply(Boom.unauthorized(null, 'bearerAuth', { | ||
isValid: isValid, | ||
credentials: credentials | ||
}), null, {}); | ||
if (!credentials || | ||
typeof credentials !== 'object') { | ||
return reply(Boom.badImplementation('Bad credentials object received for bearerAuth auth validation')); | ||
} | ||
@@ -46,32 +44,33 @@ | ||
var settings = Hoek.clone(options); | ||
const settings = Hoek.clone(options); | ||
var scheme = { | ||
authenticate: function (request, reply) { | ||
const scheme = { | ||
authenticate: (request, reply) => { | ||
if (!request.headers.authorization || | ||
request.headers.authorization === undefined) { | ||
return reply(Boom.unauthorized('NO_AUTHORIZATION_HEADER', 'bearerAuth'), null, {}); | ||
return reply(Boom.unauthorized(null, 'bearerAuth'), null, {}); | ||
} | ||
var headerParts = request.headers.authorization.split(' '); | ||
const headerParts = request.headers.authorization.split(' '); | ||
if (headerParts[0].toLowerCase() !== 'bearer') { | ||
return reply(Boom.notAcceptable('Token should be given in the Authorization header in "Bearer [token]" form. Example: "Authorization: Bearer azertyuiop0123"')); | ||
return reply(Boom.badRequest('Token should be given in the Authorization header in "Bearer [token]" form. Example: "Authorization: Bearer azertyuiop0123"')); | ||
} | ||
var token = headerParts[1]; | ||
const token = headerParts[1]; | ||
// use provided validate function to return | ||
if (settings.exposeRequest) { | ||
settings.validateFunction(token, request, function (err, isValid, credentials) { | ||
return settings.validateFunction(token, request, (err, isValid, credentials) => { | ||
internals.validateCallback(err, isValid, credentials, token, reply); | ||
return internals.validateCallback(err, isValid, credentials, token, reply); | ||
}); | ||
} else { | ||
settings.validateFunction(token, function (err, isValid, credentials) { | ||
} | ||
internals.validateCallback(err, isValid, credentials, token, reply); | ||
}); | ||
} | ||
return settings.validateFunction(token, (err, isValid, credentials) => { | ||
return internals.validateCallback(err, isValid, credentials, token, reply); | ||
}); | ||
} | ||
@@ -78,0 +77,0 @@ }; |
{ | ||
"name": "hapi-auth-bearer-simple", | ||
"description": "Custom authentication plugin for Hapi using Bearer tokens", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"author": "Adri Van Houdt <adri@salesflare.com>", | ||
@@ -23,9 +23,9 @@ "private": false, | ||
"dependencies": { | ||
"boom": "2.9.0", | ||
"hoek": "2.16.3" | ||
"boom": "3.0.x", | ||
"hoek": "3.0.x" | ||
}, | ||
"devDependencies": { | ||
"lab": "6.2.0", | ||
"code": "1.5.0", | ||
"hapi": "11.0.0" | ||
"lab": "7.x.x", | ||
"code": "2.x.x", | ||
"hapi": "11.0.x" | ||
}, | ||
@@ -32,0 +32,0 @@ "peerDependencies": { |
@@ -1,2 +0,2 @@ | ||
![Build Status](https://travis-ci.org/Salesflare/hapi-auth-bearer-simple.svg?branch=master) ![](https://david-dm.org/salesflare/hapi-auth-bearer-simple.svg) ![](https://david-dm.org/salesflare/hapi-auth-bearer-simple/dev-status.svg) ![](https://david-dm.org/salesflare/hapi-auth-bearer-simple/peer-status.svg) | ||
[![Build Status](https://travis-ci.org/Salesflare/hapi-auth-bearer-simple.svg?branch=master)](https://travis-ci.org/Salesflare/hapi-auth-bearer-simple) ![](https://david-dm.org/salesflare/hapi-auth-bearer-simple.svg) ![](https://david-dm.org/salesflare/hapi-auth-bearer-simple/dev-status.svg) ![](https://david-dm.org/salesflare/hapi-auth-bearer-simple/peer-status.svg) | ||
[![Code Climate](https://codeclimate.com/github/Salesflare/hapi-auth-bearer-simple/badges/gpa.svg)](https://codeclimate.com/github/Salesflare/hapi-auth-bearer-simple) | ||
@@ -19,3 +19,4 @@ | ||
callback(null, true, userCredentials); | ||
} else { | ||
} | ||
else { | ||
callback(null, false, userCredentials); | ||
@@ -27,3 +28,5 @@ } | ||
if (err) throw err; | ||
if (err) { | ||
throw err; | ||
} | ||
@@ -50,4 +53,8 @@ server.auth.strategy('bearer', 'bearerAuth', { | ||
server.start(function () { | ||
server.start(function (err) { | ||
if (err) { | ||
throw err; | ||
} | ||
server.log([],'Server started at: ' + server.info.uri); | ||
@@ -64,4 +71,4 @@ }); | ||
- `isValid` - `true` if both the username was found and the password matched, otherwise `false`. | ||
- `credentials` - an object passed back to the plugin and which will become available in the `request`object as `request.auth.credentials`. Normally credentials are only included when `isValid`is `true`. This object can be only the token as in the example but is preferably all the info you need from the authenticated user | ||
- `exposeRequest` - (optional / advanced) If set to `true` the `validateFunction`'s signature will be `function (token, request, callback)`. This can be usefull if you have plugins that expose certain functions/object to the `request` object and you want to use them in your `validateFunction`. Be aware that modifying the object is not recommended because this is the same object that you will use in the whole lifecycle. Also exposing functions/object to the `resuest` object during the validation is not recommended. Follow the `Hapi` standards whenever you can! | ||
- `credentials` - an object passed back to the plugin and which will become available in the `request`object as `request.auth.credentials`. Normally credentials are only included when `isValid`is `true`. | ||
- `exposeRequest` - (optional / advanced) If set to `true` the `validateFunction`'s signature will be `function (token, request, callback)`. This can be usefull if you have plugins that expose certain functions/object to the `request` object and you want to use them in your `validateFunction`. Be aware that modifying the object is not recommended because this is the same object that you will use in the whole lifecycle. Also exposing functions/object to the `request` object during the validation is not recommended. Follow the `hapi` standards whenever you can! | ||
@@ -68,0 +75,0 @@ ## Notes |
'use strict'; | ||
var Code = require('code'); | ||
var Hapi = require('hapi'); | ||
var Lab = require('lab'); | ||
const Code = require('code'); | ||
const Hapi = require('hapi'); | ||
const Lab = require('lab'); | ||
var lab = exports.lab = Lab.script(); | ||
var it = lab.it; | ||
var expect = Code.expect; | ||
const lab = exports.lab = Lab.script(); | ||
const it = lab.it; | ||
const expect = Code.expect; | ||
var internals = { | ||
const internals = { | ||
validCredentials: { | ||
@@ -25,7 +25,7 @@ email: 'test@test.com', | ||
lab.experiment('Integration', function () { | ||
lab.experiment('hapi-auth-bearer-simple', () => { | ||
it('authenticates a request', function (done) { | ||
it('authenticates a request', (done) => { | ||
var validFunc = function (token, callback) { | ||
const validFunc = (token, callback) => { | ||
@@ -37,6 +37,6 @@ expect(token).to.exist(); | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), function (err) { | ||
server.register(require('../lib/'), (err) => { | ||
@@ -48,7 +48,7 @@ expect(err).to.not.exist(); | ||
server.route({ | ||
method: 'GET', | ||
method: 'POST', | ||
path: '/login/{user}', | ||
config: { | ||
auth: 'default', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -60,5 +60,5 @@ return reply(request.auth.credentials); | ||
var request = { method: 'GET', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
server.inject(request, function (res) { | ||
server.inject(request, (res) => { | ||
@@ -73,5 +73,5 @@ expect(res.statusCode).to.equal(200); | ||
it('exposes the request object', function (done) { | ||
it('exposes the request object', (done) => { | ||
var validFunc = function (token, request, callback) { | ||
const validFunc = function (token, request, callback) { | ||
@@ -86,6 +86,6 @@ expect(token).to.exist(); | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), function (err) { | ||
server.register(require('../lib/'), (err) => { | ||
@@ -100,7 +100,7 @@ expect(err).to.not.exist(); | ||
server.route({ | ||
method: 'GET', | ||
method: 'POST', | ||
path: '/login/{user}', | ||
config: { | ||
auth: 'default', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -112,5 +112,5 @@ return reply(request.auth.credentials); | ||
var request = { method: 'GET', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
server.inject(request, function (res) { | ||
server.inject(request, (res) => { | ||
@@ -125,15 +125,15 @@ expect(res.statusCode).to.equal(200); | ||
it('Returns unAuthorized error if validFunction throws error', function (done) { | ||
it('Returns unAuthorized error if validFunction throws error', (done) => { | ||
var validFunc = function (token, callback) { | ||
const validFunc = (token, callback) => { | ||
expect(token).to.exist(); | ||
return callback('401', false, null); | ||
return callback(new Error('fail'), false, null); | ||
}; | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), function (err) { | ||
server.register(require('../lib/'), (err) => { | ||
@@ -145,7 +145,7 @@ expect(err).to.not.exist(); | ||
server.route({ | ||
method: 'GET', | ||
method: 'POST', | ||
path: '/login/{user}', | ||
config: { | ||
auth: 'default', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -157,8 +157,8 @@ return reply('ok'); | ||
var request = { method: 'GET', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
server.inject(request, function (res) { | ||
server.inject(request, (res) => { | ||
expect(res.result).to.exist(); | ||
expect(res.statusCode).to.equal(401); | ||
expect(res.statusCode).to.equal(500); | ||
@@ -170,15 +170,15 @@ done(); | ||
it('Returns unAuthorized error if validFunction determines token is not valid', function (done) { | ||
it('Returns unAuthorized error if validFunction does not return credentials', (done) => { | ||
var validFunc = function (token, callback) { | ||
const validFunc = (token, callback) => { | ||
expect(token).to.exist(); | ||
return callback(null, token !== internals.token, null); | ||
return callback(null, true, null); | ||
}; | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), function (err) { | ||
server.register(require('../lib/'), (err) => { | ||
@@ -190,7 +190,7 @@ expect(err).to.not.exist(); | ||
server.route({ | ||
method: 'GET', | ||
method: 'POST', | ||
path: '/login/{user}', | ||
config: { | ||
auth: 'default', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -202,8 +202,8 @@ return reply('ok'); | ||
var request = { method: 'GET', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
server.inject(request, function (res) { | ||
server.inject(request, (res) => { | ||
expect(res.result).to.exist(); | ||
expect(res.statusCode).to.equal(401); | ||
expect(res.statusCode).to.equal(500); | ||
@@ -215,15 +215,15 @@ done(); | ||
it('Returns unAuthorized error if validFunction does not return credentials', function (done) { | ||
it('Returns unAuthorized error if validFunction determines token is not valid', (done) => { | ||
var validFunc = function (token, callback) { | ||
const validFunc = (token, callback) => { | ||
expect(token).to.exist(); | ||
return callback(null, token === internals.token, null); | ||
return callback(null, token !== internals.token, null); | ||
}; | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), function (err) { | ||
server.register(require('../lib/'), (err) => { | ||
@@ -235,7 +235,7 @@ expect(err).to.not.exist(); | ||
server.route({ | ||
method: 'GET', | ||
method: 'POST', | ||
path: '/login/{user}', | ||
config: { | ||
auth: 'default', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -247,5 +247,5 @@ return reply('ok'); | ||
var request = { method: 'GET', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
server.inject(request, function (res) { | ||
server.inject(request, (res) => { | ||
@@ -260,5 +260,5 @@ expect(res.result).to.exist(); | ||
it('Returns unAuthorized error if no authorization header', function (done) { | ||
it('Returns unAuthorized error if no authorization header', (done) => { | ||
var validFunc = function (token, callback) { | ||
const validFunc = (token, callback) => { | ||
@@ -270,6 +270,6 @@ expect(token).to.exist(); | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), function (err) { | ||
server.register(require('../lib/'), (err) => { | ||
@@ -281,7 +281,7 @@ expect(err).to.not.exist(); | ||
server.route({ | ||
method: 'GET', | ||
method: 'POST', | ||
path: '/login/{user}', | ||
config: { | ||
auth: 'default', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -293,5 +293,5 @@ return reply('ok'); | ||
var request = { method: 'GET', url: '/login/testuser' }; | ||
const request = { method: 'POST', url: '/login/testuser' }; | ||
server.inject(request, function (res) { | ||
server.inject(request, (res) => { | ||
@@ -306,5 +306,5 @@ expect(res.result).to.exist(); | ||
it('Returns unAuthorized error if authorization header is undefined', function (done) { | ||
it('Returns unAuthorized error if authorization header is undefined', (done) => { | ||
var validFunc = function (token, callback) { | ||
const validFunc = (token, callback) => { | ||
@@ -316,6 +316,6 @@ expect(token).to.exist(); | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), function (err) { | ||
server.register(require('../lib/'), (err) => { | ||
@@ -327,7 +327,7 @@ expect(err).to.not.exist(); | ||
server.route({ | ||
method: 'GET', | ||
method: 'POST', | ||
path: '/login/{user}', | ||
config: { | ||
auth: 'default', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -339,5 +339,5 @@ return reply('ok'); | ||
var request = { method: 'GET', url: '/login/testuser', headers: { Authorization: undefined } }; | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: undefined } }; | ||
server.inject(request, function (res) { | ||
server.inject(request, (res) => { | ||
@@ -352,5 +352,5 @@ expect(res.result).to.exist(); | ||
it('Returns notAcceptable error if authorization header is not bearer', function (done) { | ||
it('Returns badRequest error if authorization header is not bearer', (done) => { | ||
var validFunc = function (token, callback) { | ||
const validFunc = (token, callback) => { | ||
@@ -362,6 +362,6 @@ expect(token).to.exist(); | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), function (err) { | ||
server.register(require('../lib/'), (err) => { | ||
@@ -373,7 +373,7 @@ expect(err).to.not.exist(); | ||
server.route({ | ||
method: 'GET', | ||
method: 'POST', | ||
path: '/login/{user}', | ||
config: { | ||
auth: 'default', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -385,8 +385,8 @@ return reply('ok'); | ||
var request = { method: 'GET', url: '/login/testuser', headers: { Authorization: internals.invalidAuhtorizationHeader } }; | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: internals.invalidAuhtorizationHeader } }; | ||
server.inject(request, function (res) { | ||
server.inject(request, (res) => { | ||
expect(res.result).to.exist(); | ||
expect(res.statusCode).to.equal(406); | ||
expect(res.statusCode).to.equal(400); | ||
@@ -397,2 +397,245 @@ done(); | ||
}); | ||
it('returns a reply on failed optional auth', (done) => { | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), (err) => { | ||
expect(err).to.not.exist(); | ||
server.auth.strategy('default', 'bearerAuth', 'required', { validateFunction: () => {} }); | ||
server.route({ | ||
method: 'POST', | ||
path: '/login/{user}', | ||
handler: (request, reply) => { | ||
return reply('ok'); | ||
}, | ||
config: { | ||
auth: { | ||
mode: 'optional' | ||
} | ||
} | ||
}); | ||
const request = { method: 'POST', url: '/login/testuser' }; | ||
server.inject(request, (res) => { | ||
expect(res.result).to.equal('ok'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on success optional auth but no valid credentials', (done) => { | ||
const validFunc = (token, callback) => { | ||
expect(token).to.exist(); | ||
return callback(null, true, null); | ||
}; | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), (err) => { | ||
expect(err).to.not.exist(); | ||
server.auth.strategy('default', 'bearerAuth', 'required', { validateFunction: validFunc }); | ||
server.route({ | ||
method: 'POST', | ||
path: '/login/{user}', | ||
handler: (request, reply) => { | ||
return reply('ok'); | ||
}, | ||
config: { | ||
auth: { | ||
mode: 'optional' | ||
} | ||
} | ||
}); | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
server.inject(request, (res) => { | ||
expect(res.result.statusCode).to.equal(500); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('returns a reply on failed try auth', (done) => { | ||
const validFunc = (token, callback) => { | ||
expect(token).to.exist(); | ||
return callback(null, false, null); | ||
}; | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), (err) => { | ||
expect(err).to.not.exist(); | ||
server.auth.strategy('default', 'bearerAuth', 'required', { validateFunction: validFunc }); | ||
server.route({ | ||
method: 'POST', | ||
path: '/login/{user}', | ||
handler: (request, reply) => { | ||
return reply('ok'); | ||
}, | ||
config: { | ||
auth: { | ||
mode: 'try' | ||
} | ||
} | ||
}); | ||
const request = { method: 'POST', url: '/login/testuser', headers: { Authorization: internals.authorizationHeader } }; | ||
server.inject(request, (res) => { | ||
expect(res.result).to.equal('ok'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('cannot add a route that has payload validation required', (done) => { | ||
const validFunc = (token, callback) => { | ||
expect(token).to.exist(); | ||
return callback(null, token === internals.token, internals.validUser); | ||
}; | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), (err) => { | ||
expect(err).to.not.exist(); | ||
server.auth.strategy('default', 'bearerAuth', 'required', { validateFunction: validFunc }); | ||
const fn = () => { | ||
server.route({ | ||
method: 'POST', | ||
path: '/', | ||
handler: (request, reply) => { | ||
return reply('ok'); | ||
}, | ||
config: { | ||
auth: { | ||
mode: 'required', | ||
payload: 'required' | ||
} | ||
} | ||
}); | ||
}; | ||
expect(fn).to.throw('Payload validation can only be required when all strategies support it in path: /'); | ||
done(); | ||
}); | ||
}); | ||
it('cannot add a route that has payload validation optional', (done) => { | ||
const validFunc = (token, callback) => { | ||
expect(token).to.exist(); | ||
return callback(null, token === internals.token, internals.validUser); | ||
}; | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), (err) => { | ||
expect(err).to.not.exist(); | ||
server.auth.strategy('default', 'bearerAuth', 'required', { validateFunction: validFunc }); | ||
const fn = () => { | ||
server.route({ | ||
method: 'POST', | ||
path: '/', | ||
handler: (request, reply) => { | ||
return reply('ok'); | ||
}, | ||
config: { | ||
auth: { | ||
mode: 'required', | ||
payload: 'optional' | ||
} | ||
} | ||
}); | ||
}; | ||
expect(fn).to.throw('Payload authentication requires at least one strategy with payload support in path: /'); | ||
done(); | ||
}); | ||
}); | ||
it('can add a route that has payload validation as none', (done) => { | ||
const validFunc = (token, callback) => { | ||
expect(token).to.exist(); | ||
return callback(null, token === internals.token, internals.validUser); | ||
}; | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register(require('../lib/'), (err) => { | ||
expect(err).to.not.exist(); | ||
server.auth.strategy('default', 'bearerAuth', 'required', { validateFunction: validFunc }); | ||
const fn = () => { | ||
server.route({ | ||
method: 'POST', | ||
path: '/', | ||
handler: (request, reply) => { | ||
return reply('ok'); | ||
}, | ||
config: { | ||
auth: { | ||
mode: 'required', | ||
payload: false | ||
} | ||
} | ||
}); | ||
}; | ||
expect(fn).to.not.throw(); | ||
done(); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25417
484
76
+ Addedboom@3.0.0(transitive)
+ Addedhoek@3.0.4(transitive)
- Removedboom@2.9.0(transitive)
- Removedhoek@2.16.3(transitive)
Updatedboom@3.0.x
Updatedhoek@3.0.x