New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

hapi-auth-jwt2

Package Overview
Dependencies
Maintainers
1
Versions
94
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hapi-auth-jwt2 - npm Package Compare versions

Comparing version 5.8.0 to 6.0.0

13

lib/extract.js

@@ -8,13 +8,12 @@ var Cookie = require('cookie'); // highly popular decoupled cookie parser

module.exports = function (request, options) {
// The key holding token value in url or cookie defaults to token
var urlKey = typeof options.urlKey === 'string' ? options.urlKey : 'token';
var cookieKey = typeof options.cookieKey === 'string' ? options.cookieKey : 'token';
var headerKey = typeof options.headerKey === 'string' ? options.headerKey : 'authorization';
var urlKey = options.urlKey === false || typeof options.urlKey === 'string' ? options.urlKey : 'token';
var cookieKey = options.cookieKey === false || typeof options.cookieKey === 'string' ? options.cookieKey : 'token';
var headerKey = options.headerKey === false || typeof options.headerKey === 'string' ? options.headerKey : 'authorization';
var auth;
if(request.query[urlKey]) { // tokens via url: https://github.com/dwyl/hapi-auth-jwt2/issues/19
if(urlKey && request.query[urlKey]) { // tokens via url: https://github.com/dwyl/hapi-auth-jwt2/issues/19
auth = request.query[urlKey];
} // JWT tokens in cookie: https://github.com/dwyl/hapi-auth-jwt2/issues/55
else if (request.headers[headerKey]) {
else if (headerKey && request.headers[headerKey]) {
if (typeof options.tokenType === 'string') {

@@ -27,3 +26,3 @@ var token = request.headers[headerKey].match(new RegExp(options.tokenType + '\\s+([^$]+)', 'i'));

}
else if (request.headers.cookie) {
else if (cookieKey && request.headers.cookie) {
auth = Cookie.parse(request.headers.cookie)[cookieKey];

@@ -30,0 +29,0 @@ }

@@ -61,6 +61,3 @@ var Boom = require('boom'); // error handling https://github.com/hapijs/boom

JWT.verify(token, key, verifyOptions, function (err, decoded) {
if (err && err.name === 'TokenExpiredError') {
return reply(Boom.unauthorized('Token expired', 'Token'), null, { credentials: null });
}
else if (err) {
if (err) {
return reply(Boom.unauthorized('Invalid token', 'Token'), null, { credentials: null });

@@ -67,0 +64,0 @@ }

{
"name": "hapi-auth-jwt2",
"version": "5.8.0",
"version": "6.0.0",
"description": "Hapi.js Authentication Plugin/Scheme using JSON Web Tokens (JWT)",

@@ -40,3 +40,3 @@ "main": "lib/index.js",

"cookie": "^0.2.3",
"jsonwebtoken": "^5.7.0"
"jsonwebtoken": "^6.2.0"
},

@@ -46,4 +46,4 @@ "devDependencies": {

"hapi": "^13.3.0",
"istanbul": "^0.4.2",
"jshint": "^2.9.1",
"istanbul": "^0.4.3",
"jshint": "^2.9.2",
"pre-commit": "^1.1.2",

@@ -50,0 +50,0 @@ "tap-spec": "^4.1.1",

@@ -9,3 +9,3 @@ # Hapi Auth using JSON Web Tokens (JWT)

[![Build Status](https://travis-ci.org/dwyl/hapi-auth-jwt2.svg "Build Status = Tests Passing")](https://travis-ci.org/dwyl/hapi-auth-jwt2)
[![codecov.io Code Coverage](https://codecov.io/github/dwyl/hapi-auth-jwt2/coverage.svg?branch=master)](https://codecov.io/github/dwyl/hapi-auth-jwt2?branch=master)
[![codecov.io Code Coverage](https://img.shields.io/codecov/c/github/dwyl/hapi-auth-jwt2.svg?maxAge=2592000)](https://codecov.io/github/dwyl/hapi-auth-jwt2?branch=master)
[![Code Climate](https://codeclimate.com/github/dwyl/hapi-auth-jwt2/badges/gpa.svg "No Nasty Code")](https://codeclimate.com/github/dwyl/hapi-auth-jwt2)

@@ -25,6 +25,6 @@ [![HAPI 13.3.0](http://img.shields.io/badge/hapi-13.3.0-brightgreen.svg "Latest Hapi.js")](http://hapijs.com)

If you are totally new to JWTs, we wrote an introductory post explaining
If you are totally new to JWTs, we wrote an introductory post explaining
the concepts & benefits: https://github.com/dwyl/learn-json-web-tokens
If you (or anyone on your team) are unfamiliar with **Hapi.js** we have a
If you (or anyone on your team) are unfamiliar with **Hapi.js** we have a
quick guide for that too: https://github.com/dwyl/learn-hapi

@@ -177,3 +177,3 @@

- `decoded` - (***required***) is the ***decoded*** and ***verified*** JWT received from the client in **request.headers.authorization**
- `request` - (***required***) is the original ***request*** received from the client
- `request` - (***required***) is the original ***request*** received from the client
- `callback` - (***required***) a callback function with the signature `function(err, isValid, credentials)` where:

@@ -195,6 +195,6 @@ - `err` - an internal error.

- `reply(err, response)`- is called if an error occurred
- `urlKey` - (***optional*** *defaults to* `'token'`) - if you prefer to pass your token via url, simply add a `token` url parameter to your request or use a custom parameter by setting `urlKey`
- `cookieKey` - (***optional*** *defaults to* `'token'`) if you prefer to set your own cookie key or your project has a cookie called `'token'` for another purpose, you can set a custom key for your cookie by setting `options.cookieKey='yourkeyhere'`.
- `headerKey` - (***optional*** *defaults to* `'authorization'`) - if you want to set a custom key for your header token use the `headerKey` option.
- `tokenType` - (***optional*** *defaults to noe*) allow custom token type, e.g. `Authorization: <tokenType> 12345678`.
- `urlKey` - (***optional*** *defaults to* `'token'`) - if you prefer to pass your token via url, simply add a `token` url parameter to your request or use a custom parameter by setting `urlKey`. To disable the url parameter set urlKey to `false` or ''.
- `cookieKey` - (***optional*** *defaults to* `'token'`) - if you prefer to set your own cookie key or your project has a cookie called `'token'` for another purpose, you can set a custom key for your cookie by setting `options.cookieKey='yourkeyhere'`. To disable cookies set cookieKey to `false` or ''.
- `headerKey` - (***optional*** *defaults to* `'authorization'`) - if you want to set a custom key for your header token use the `headerKey` option. To disable header token set headerKey to `false` or ''.
- `tokenType` - (***optional*** *defaults to none*) - allow custom token type, e.g. `Authorization: <tokenType> 12345678`.
- `complete` - (***optional*** *defaults to* `false`) - set to `true` to receive the complete token (`decoded.header`, `decoded.payload` and `decoded.signature`) as `decoded` argument to key lookup and `verifyFunc` callbacks (*not `validateFunc`*)

@@ -295,3 +295,3 @@

> What if I want to *disable* the ability to pass JWTs in via the URL?
(*asked by* @bitcloud in [issue #146](https://github.com/dwyl/hapi-auth-jwt2/pull/146))
(*asked by* @bitcloud in [issue #146](https://github.com/dwyl/hapi-auth-jwt2/pull/146))
> simply set your `urlKey` to something *impossible* to guess see:

@@ -304,3 +304,3 @@ [*example*](https://github.com/dwyl/hapi-auth-jwt2/pull/146#issuecomment-205481751)

There are _several_ options for generating secret keys.
There are _several_ options for generating secret keys.
The _easist_ way is to run node's crypto hash in your terminal:

@@ -310,3 +310,3 @@ ```js

```
and copy the resulting base64 key and use it as your JWT secret.
and copy the resulting base64 key and use it as your JWT secret.
If you are *curious* how strong that key is watch: https://youtu.be/koJQQWHI-ZA

@@ -326,3 +326,3 @@

and it's only useful if you want to use to make
request to other servers using the user's token.
request to other servers using the user's token.

@@ -335,3 +335,3 @@ The *decoded* version of the token, accessible via `request.auth.credentials`

requested the ability to send/receive tokens as cookies:
[dwyl/hapi-auth-jwt2/issues/**55**](https://github.com/dwyl/hapi-auth-jwt2/issues/55)
[dwyl/hapi-auth-jwt2/issues/**55**](https://github.com/dwyl/hapi-auth-jwt2/issues/55)
So we added the ability to *optionally* send/store your tokens in cookies

@@ -383,18 +383,18 @@ to simplify building your *web app*.

1. Do I need to include **jsonwebtoken** in my project? asked in [hapi-auth-jwt2/issues/32](https://github.com/dwyl/hapi-auth-jwt2/issues/32)
1. Do I need to include **jsonwebtoken** in my project? asked in [hapi-auth-jwt2/issues/32](https://github.com/dwyl/hapi-auth-jwt2/issues/32)
**Q**: Must I include the **jsonwebtoken** package in my project
[given that **hapi-auth-jwt2** plugin already includes it] ?
[given that **hapi-auth-jwt2** plugin already includes it] ?
**A**: Yes, you need to *manually* install the **jsonwebtoken**
node module from NPM with `npm install jsonwebtoken --save` if you want to ***sign*** JWTs in your app.
node module from NPM with `npm install jsonwebtoken --save` if you want to ***sign*** JWTs in your app.
Even though **hapi-auth-jwt2** includes it
as a **dependency** your app does not know where to find it in the **node_modules** tree for your project.
as a **dependency** your app does not know where to find it in the **node_modules** tree for your project.
Unless you include it via ***relative path*** e.g:
`var JWT = require('./node_modules/hapi-auth-jwt2/node_modules/jsonwebtoken');`
`var JWT = require('./node_modules/hapi-auth-jwt2/node_modules/jsonwebtoken');`
we *recommend* including it in your **package.json** ***explicitly*** as a **dependency** for your project.
2. Can we supply a ***Custom Verification*** function instead of using the **JWT.verify** method?
2. Can we supply a ***Custom Verification*** function instead of using the **JWT.verify** method?
asked by *both* [Marcus Stong](https://github.com/stongo) & [Kevin Stewart](https://github.com/kdstew)
in [issue #120](https://github.com/dwyl/hapi-auth-jwt2/issues/120) and [issue #130](https://github.com/dwyl/hapi-auth-jwt2/issues/130) respectively.
**Q**: Does this module support custom verification function or disabling verification?
**A**: Yes, it *does now*! (*see: "Advanced Usage" below*) the inclusion of a `verifyFunc`
in [issue #120](https://github.com/dwyl/hapi-auth-jwt2/issues/120) and [issue #130](https://github.com/dwyl/hapi-auth-jwt2/issues/130) respectively.
**Q**: Does this module support custom verification function or disabling verification?
**A**: Yes, it *does now*! (*see: "Advanced Usage" below*) the inclusion of a `verifyFunc`
gives you *complete control* over the verification of the incoming JWT.

@@ -406,3 +406,3 @@

While *most* people using `hapi-auth-jwt2` will opt for the *simpler* use case
(*using a* ***Validation Function*** *`validateFunc` - see: Basic Usage example above -
(*using a* ***Validation Function*** *`validateFunc` - see: Basic Usage example above -
which validates the JWT payload after it has been verified...*)

@@ -421,3 +421,3 @@ others may need more control over the `verify` step.

- `decoded` - (***required***) is the ***decoded*** and ***verified*** JWT received from the client in **request.headers.authorization**
- `request` - (***required***) is the original ***request*** received from the client
- `request` - (***required***) is the original ***request*** received from the client
- `callback` - (***required***) a callback function with the signature `function(err, isValid, credentials)` where:

@@ -429,3 +429,3 @@ - `err` - an internal error.

The advantage of this approach is that it allows people to write a
custom verification function or to bypass the `JWT.verify` *completely*.
custom verification function or to bypass the `JWT.verify` *completely*.
For more detail, see: use-case discussion in https://github.com/dwyl/hapi-auth-jwt2/issues/120

@@ -435,3 +435,3 @@

> ***Note***: *nobody has requested the ability to use* ***both*** *a*
`validateFunc` ***and*** `verifyFunc`.
`validateFunc` ***and*** `verifyFunc`.
This should not be *necessary*

@@ -453,3 +453,3 @@ because with a `verifyFunc` you can incorporate your own custom-logic.

> *If you have a question, or need help getting started* ***please post an issue/question on
> *If you have a question, or need help getting started* ***please post an issue/question on
GitHub***: https://github.com/dwyl/hapi-auth-jwt2/issues *or*

@@ -500,3 +500,3 @@ [![Join the chat at https://gitter.im/dwyl/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dwyl/chat/?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

If you have ***any questions*** on this please post an issue/question on GitHub:
https://github.com/dwyl/hapi-auth-jwt2/issues
https://github.com/dwyl/hapi-auth-jwt2/issues
(*we are here to help get you started on your journey to **hapi**ness!*)

@@ -510,3 +510,3 @@

If you spot an area for improvement, please raise an issue: https://github.com/dwyl/hapi-auth-jwt2/issues
If you spot an area for improvement, please raise an issue: https://github.com/dwyl/hapi-auth-jwt2/issues
*Someone* in the dwyl team is *always* online so we will usually answer within a few hours.

@@ -532,3 +532,3 @@

While making [***Time***](https://github.com/dwyl/time) we want to ensure
our app (and API) is as ***simple*** as *possible* to use.
our app (and API) is as ***simple*** as *possible* to use.
This lead us to using JSON Web Tokens for ***Stateless*** Authentication.

@@ -541,3 +541,3 @@

but they were invariably ***too complicated***, poorly documented and
had *useless* (non-real-world) "examples"!
had *useless* (non-real-world) "examples"!

@@ -554,3 +554,3 @@ Also, none of the *existing* modules exposed the **request** object

The name we wanted was taken.
The name we wanted was taken.
Think of our module as the "***new, simplified and actively maintained version***"

@@ -557,0 +557,0 @@

@@ -44,2 +44,30 @@ var Hapi = require('hapi');

server.auth.strategy('jwt-nourl', 'jwt', {
key: secret,
validateFunc: validate,
verifyOptions: { algorithms: [ 'HS256' ] }, // only allow HS256 algorithm
urlKey: false
});
server.auth.strategy('jwt-nocookie', 'jwt', {
key: secret,
validateFunc: validate,
verifyOptions: { algorithms: [ 'HS256' ] }, // only allow HS256 algorithm
cookieKey: false
});
server.auth.strategy('jwt-nourl2', 'jwt', {
key: secret,
validateFunc: validate,
verifyOptions: { algorithms: [ 'HS256' ] }, // only allow HS256 algorithm
urlKey: ''
});
server.auth.strategy('jwt-nocookie2', 'jwt', {
key: secret,
validateFunc: validate,
verifyOptions: { algorithms: [ 'HS256' ] }, // only allow HS256 algorithm
cookieKey: ''
});
server.route([

@@ -49,2 +77,6 @@ { method: 'GET', path: '/', handler: home, config: { auth: false } },

{ method: 'POST', path: '/privado', handler: privado, config: { auth: 'jwt' } },
{ method: 'POST', path: '/privadonourl', handler: privado, config: { auth: 'jwt-nourl' } },
{ method: 'POST', path: '/privadonocookie', handler: privado, config: { auth: 'jwt-nocookie' } },
{ method: 'POST', path: '/privadonourl2', handler: privado, config: { auth: 'jwt-nourl2' } },
{ method: 'POST', path: '/privadonocookie2', handler: privado, config: { auth: 'jwt-nocookie2' } },
{ method: 'POST', path: '/required', handler: privado, config: { auth: { mode: 'required', strategy: 'jwt' } } },

@@ -51,0 +83,0 @@ { method: 'POST', path: '/optional', handler: privado, config: { auth: { mode: 'optional', strategy: 'jwt' } } },

@@ -91,21 +91,22 @@ var test = require('tape');

test("Try using an expired token", function(t) {
// use the token as the 'authorization' header in requests
var token = JWT.sign({ id: 123, "name": "Charlie" }, secret, { expiresInSeconds: 1 });
// console.log(" - - - - - - token - - - - -")
// console.log(token);
var options = {
method: "POST",
url: "/privado",
headers: { authorization: "Bearer " + token }
};
// server.inject lets us simulate an http request
setTimeout(function () {
server.inject(options, function(response) {
t.equal(response.statusCode, 401, "Expired token should be invalid");
t.equal(response.result.message, 'Token expired', 'Message should be "Token expired"');
t.end();
});
}, 1000);
});
// see: https://github.com/dwyl/hapi-auth-jwt2/issues/166
// test.only("Try using an expired token", function(t) {
// // use the token as the 'authorization' header in requests
// var token = JWT.sign({ id: 123, "name": "Charlie" }, secret, { expiresInSeconds: 1 });
// console.log(" - - - - - - token - - - - -")
// console.log(token);
// var options = {
// method: "POST",
// url: "/privado",
// headers: { authorization: "Bearer " + token }
// };
// // server.inject lets us simulate an http request
// setTimeout(function () {
// server.inject(options, function(response) {
// t.equal(response.statusCode, 401, "Expired token should be invalid");
// t.equal(response.result.message, 'Token expired', 'Message should be "Token expired"');
// t.end();
// });
// }, 1000);
// });

@@ -336,1 +337,5 @@ test("Token is well formed but is allowed=false so should be denied", function(t) {

});
test.onFinish(function () {
server.stop(function(){});
})

@@ -8,7 +8,8 @@ var test = require('tape');

var server = new Hapi.Server();
server.connection();
test('Full token payload (header + payload + signature) is available to key lookup function using completeToken option', function (t) {
var server = new Hapi.Server();
server.connection();
server.register(require('../'), function (err) {

@@ -39,3 +40,3 @@ t.ifError(err, 'No error registering hapi-auth-jwt2 plugin');

url: '/',
headers: {Authorization: JWT.sign({ id: 1234 }, secret, { headers: { x5t: 5678 } })} // set custom JWT header field "x5t"
headers: {Authorization: JWT.sign({ id: 1234 }, secret, { header: { x5t: 5678 } })} // set custom JWT header field "x5t"
};

@@ -49,1 +50,6 @@

});
test.onFinish(function () {
server.stop(function(){});
})

@@ -150,1 +150,31 @@ var test = require('tape');

});
test("Attempt to access restricted content with cookieKey=false", function(t) {
var token = JWT.sign({ id: 123, "name": "Charlie" }, secret);
var options = {
method: "POST",
url: "/privadonocookie",
headers: { cookie: "token=" + token }
};
// server.inject lets us simulate an http request
server.inject(options, function(response) {
t.equal(response.statusCode, 401, "Disabled cookie auth shouldn't accept valid token!");
t.end();
});
});
test("Attempt to access restricted content with cookieKey=''", function(t) {
var token = JWT.sign({ id: 123, "name": "Charlie" }, secret);
var options = {
method: "POST",
url: "/privadonocookie2",
headers: { cookie: "=" + token }
};
// server.inject lets us simulate an http request
server.inject(options, function(response) {
t.equal(response.statusCode, 400, "Disabled cookie auth shouldn't accept valid token!");
t.end();
});
});

@@ -40,3 +40,3 @@ var test = require('tape');

url: '/',
headers: {auths: JWT.sign({ id: 1234 }, secret, { headers: { x5t: 5678 } })} // set custom JWT header field "x5t"
headers: {auths: JWT.sign({ id: 1234 }, secret, { header: { x5t: 5678 } })} // set custom JWT header field "x5t"
};

@@ -43,0 +43,0 @@

@@ -79,1 +79,31 @@ var test = require('tape');

});
test("Using route with urlKey=false should be denied", function(t) {
// use the token as the 'authorization' header in requests
var token = JWT.sign({ id: 123, "name": "Charlie" }, secret);
token = "?token=" + token;
var options = {
method: "POST",
url: "/privadonourl" + token
};
// server.inject lets us simulate an http request
server.inject(options, function(response) {
t.equal(response.statusCode, 401, "No urlKey configured so URL-Tokens should be denied");
t.end();
});
});
test("Using route with urlKey='' should be denied", function(t) {
// use the token as the 'authorization' header in requests
var token = JWT.sign({ id: 123, "name": "Charlie" }, secret);
token = "?=" + token;
var options = {
method: "POST",
url: "/privadonourl2" + token
};
// server.inject lets us simulate an http request
server.inject(options, function(response) {
t.equal(response.statusCode, 401, "No urlKey configured so URL-Tokens should be denied");
t.end();
});
});

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