hapi-auth-jwt2
Advanced tools
Comparing version 10.4.0 to 10.5.0
import { Request, ResponseObject, Plugin, ResponseToolkit } from '@hapi/hapi'; | ||
import { VerifyOptions } from 'jsonwebtoken'; | ||
import { Jwt, VerifyOptions } from 'jsonwebtoken'; | ||
@@ -33,2 +33,10 @@ declare module '@hapi/hapi' { | ||
}; | ||
/** | ||
* the exception thrown (e.g., by `jsonwebtoken.verify`) | ||
*/ | ||
error?: Error; | ||
/** | ||
* the decoded (possibly invalid) JWT received from the client | ||
*/ | ||
decoded?: Jwt; | ||
} | ||
@@ -157,2 +165,2 @@ | ||
export = hapiAuthJwt2; | ||
export = hapiAuthJwt2; |
@@ -97,4 +97,3 @@ 'use strict'; | ||
'token is null', | ||
tokenType, | ||
null, //attributes | ||
{ scheme: tokenType }, | ||
true //flag missing token to HAPI auth framework to allow subsequent auth strategies | ||
@@ -117,4 +116,3 @@ ), | ||
'Invalid token format', | ||
tokenType, | ||
null, //attributes | ||
{ scheme: tokenType }, | ||
true //flag missing token to HAPI auth framework to allow subsequent auth strategies | ||
@@ -130,2 +128,3 @@ ), | ||
// otherwise use the same key (String) to validate all JWTs | ||
let decodeErr; | ||
try { | ||
@@ -139,2 +138,3 @@ decoded = JWT.decode(token, { complete: options.complete || false }); | ||
// both failure types at once | ||
decodeErr = e; | ||
} | ||
@@ -150,3 +150,3 @@ | ||
'Invalid token format', | ||
tokenType | ||
{ scheme: tokenType, error: decodeErr } | ||
), | ||
@@ -182,3 +182,3 @@ payload: { | ||
err_message, | ||
tokenType | ||
{ scheme: tokenType, decoded, error: verify_err } | ||
), | ||
@@ -204,3 +204,3 @@ payload: { credentials: token }, | ||
errorMessage || 'Invalid credentials', | ||
tokenType | ||
{ scheme: tokenType, decoded } | ||
), | ||
@@ -230,3 +230,4 @@ payload: { credentials: decoded }, | ||
'boomify', | ||
validate_err | ||
validate_err, | ||
{ decoded } | ||
), | ||
@@ -255,3 +256,3 @@ payload: { | ||
'Invalid credentials', | ||
tokenType | ||
{ scheme: tokenType, decoded } | ||
), | ||
@@ -273,3 +274,10 @@ payload: { credentials: decoded }, | ||
return { | ||
error: internals.raiseError(options, request, h, 'boomify', verify_error), | ||
error: internals.raiseError( | ||
options, | ||
request, | ||
h, | ||
'boomify', | ||
verify_error, | ||
{ decoded } | ||
), | ||
payload: { | ||
@@ -288,5 +296,4 @@ credentials: decoded, | ||
errorType, | ||
message, | ||
scheme, | ||
attributes, | ||
errorOrMessage, | ||
extraContext, | ||
isMissingToken | ||
@@ -296,6 +303,6 @@ ) { | ||
errorType: errorType, | ||
message: message, | ||
scheme: scheme, | ||
attributes: attributes, | ||
message: errorOrMessage.toString(), | ||
error: typeof errorOrMessage === 'object' ? errorOrMessage : undefined, | ||
}; | ||
Object.assign(errorContext, extraContext); | ||
@@ -325,7 +332,7 @@ if (internals.isFunction(options.errorFunc)) { | ||
* implementation is the "main" interface to the plugin and contains all the | ||
* "implementation details" (methods) such as authenicate, response & raiseError | ||
* "implementation details" (methods) such as authenticate, response & raiseError | ||
* @param {Object} server - the Hapi.js server object we are attaching the | ||
* the hapi-auth-jwt2 plugin to. | ||
* @param {Object} options - any configuration options passed in. | ||
* @returns {Function} authenicate - we return the authenticate method after | ||
* @returns {Function} authenticate - we return the authenticate method after | ||
* registering the plugin as that's the method that gets called for each route. | ||
@@ -332,0 +339,0 @@ */ |
{ | ||
"name": "hapi-auth-jwt2", | ||
"version": "10.4.0", | ||
"version": "10.5.0", | ||
"description": "Hapi.js Authentication Plugin/Scheme using JSON Web Tokens (JWT)", | ||
@@ -59,10 +59,10 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"@hapi/boom": "^9.0.0", | ||
"cookie": "^0.4.0", | ||
"@hapi/boom": "^10.0.0", | ||
"cookie": "^0.6.0", | ||
"jsonwebtoken": "^9.0.0" | ||
}, | ||
"devDependencies": { | ||
"@hapi/basic": "^6.0.0", | ||
"@hapi/basic": "^7.0.0", | ||
"@hapi/hapi": "^21.1.0", | ||
"@types/hapi__hapi": "^19.0.1", | ||
"@types/hapi__hapi": "^21.0.0", | ||
"aguid": "^2.0.0", | ||
@@ -69,0 +69,0 @@ "eslint": "^8.31.0", |
@@ -202,3 +202,5 @@ # Hapi Auth using JSON Web Tokens (JWT) | ||
- `errorContext.attributes` - the `attributes` passed into the `Boom` method call | ||
- The function is expected to return the modified `errorContext` with all above fields defined. | ||
- `errorContext.error` - the exception thrown (optional, if available) | ||
- `errorContext.token` - the JWT provided, in string form (optional, if available) | ||
- The function is expected to return the modified `errorContext` with all above non-optional fields defined. | ||
- `request` - the request object. | ||
@@ -205,0 +207,0 @@ - `h`- the response toolkit. |
@@ -18,6 +18,12 @@ const Hapi = require('@hapi/hapi'); | ||
let lastErrorContext = undefined; | ||
function getLastErrorContext() { | ||
return lastErrorContext; | ||
} | ||
// defining our own validate function lets us do something | ||
// useful/custom with the decodedToken before reply(ing) | ||
const customVerify = function (decoded, request) { | ||
if(decoded.error) { | ||
lastErrorContext = undefined; | ||
if (decoded.error) { | ||
throw new Error('customVerify fails!'); | ||
@@ -38,2 +44,3 @@ } | ||
const result = errorContext; | ||
lastErrorContext = errorContext; | ||
@@ -68,2 +75,2 @@ h.response().state('customError', 'setInCustomErrorFn'); | ||
module.exports = server; | ||
module.exports = { server, getLastErrorContext }; |
@@ -5,4 +5,10 @@ const test = require('tape'); | ||
const server = require('./error_func_server'); // test server which in turn loads our module | ||
const { server, getLastErrorContext } = require('./error_func_server'); // test server which in turn loads our module | ||
function getPayloadFromDecoded(decoded) { | ||
const payload = Object.assign({}, decoded); | ||
delete payload.iat; | ||
return payload; | ||
} | ||
test("Access a route that has no auth strategy", async function(t) { | ||
@@ -29,4 +35,7 @@ const options = { | ||
const response = await server.inject(options); | ||
const errorContext = getLastErrorContext(); | ||
t.equal(response.statusCode, 500, "customVerify force error"); | ||
t.equal(response.result.message, "An internal server error occurred", "GET /required with forced error that has not been customised"); | ||
t.deepEqual(getPayloadFromDecoded(errorContext.decoded), payload); | ||
t.equal(errorContext.error.message, 'customVerify fails!'); | ||
t.end(); | ||
@@ -45,4 +54,7 @@ }); | ||
const response = await server.inject(options); | ||
const errorContext = getLastErrorContext(); | ||
t.equal(response.statusCode, 500, "customVerify force error"); | ||
t.equal(response.result.message, "An internal server error occurred", "GET /required with forced error that has not been customised"); | ||
t.deepEqual(getPayloadFromDecoded(errorContext.decoded), payload); | ||
t.equal(errorContext.error.message, 'ignore'); | ||
t.end(); | ||
@@ -61,5 +73,8 @@ }); | ||
const response = await server.inject(options); | ||
const errorContext = getLastErrorContext(); | ||
t.equal(response.statusCode, 401, "GET /required with customVerify rejected"); | ||
t.equal(response.result.message, "Invalid credentials mate", "GET /required with customVerify rejected and customised error message"); | ||
t.deepEqual(response.headers['set-cookie'], [ 'customError=setInCustomErrorFn; Secure; HttpOnly; SameSite=Strict' ], 'Valid request should have access to the response toolkit object'); | ||
t.deepEqual(getPayloadFromDecoded(errorContext.decoded), payload); | ||
t.equal(errorContext.error, undefined); | ||
t.end(); | ||
@@ -66,0 +81,0 @@ }); |
Sorry, the diff of this file is not supported yet
210282
3485
775
+ Added@hapi/boom@10.0.1(transitive)
+ Added@hapi/hoek@11.0.7(transitive)
+ Addedcookie@0.6.0(transitive)
- Removed@hapi/boom@9.1.4(transitive)
- Removed@hapi/hoek@9.3.0(transitive)
- Removedcookie@0.4.2(transitive)
Updated@hapi/boom@^10.0.0
Updatedcookie@^0.6.0