Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hapi-auth-bearer-simple

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hapi-auth-bearer-simple - npm Package Compare versions

Comparing version 2.0.0 to 3.0.0

55

lib/index.js

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc