@fastify/jwt
Advanced tools
Comparing version 7.1.0 to 7.2.0
@@ -130,3 +130,3 @@ import { | ||
formatUser?: (payload: SignPayloadType) => UserType | ||
jwtDecode?: boolean | string | ||
jwtDecode?: string | ||
namespace?: string | ||
@@ -133,0 +133,0 @@ jwtVerify?: string |
70
jwt.js
@@ -21,2 +21,6 @@ 'use strict' | ||
function isString (x) { | ||
return Object.prototype.toString.call(x) === '[object String]' | ||
} | ||
function wrapStaticSecretInCallback (secret) { | ||
@@ -58,9 +62,35 @@ return function (request, payload, cb) { | ||
function fastifyJwt (fastify, options, next) { | ||
if (!options.secret) { | ||
return next(new Error('missing secret')) | ||
function validateOptions (options) { | ||
assert(options.secret, 'missing secret') | ||
assert(!options.options, 'options prefix is deprecated') | ||
assert(!options.jwtVerify || isString(options.jwtVerify), 'Invalid options.jwtVerify') | ||
assert(!options.jwtDecode || isString(options.jwtDecode), 'Invalid options.jwtDecode') | ||
assert(!options.jwtSign || isString(options.jwtSign), 'Invalid options.jwtSign') | ||
if ( | ||
options.sign && | ||
options.sign.algorithm && | ||
options.sign.algorithm.includes('RS') && | ||
(typeof options.secret === 'string' || | ||
options.secret instanceof Buffer) | ||
) { | ||
throw new Error('RSA Signatures set as Algorithm in the options require a private and public key to be set as the secret') | ||
} | ||
if ( | ||
options.sign && | ||
options.sign.algorithm && | ||
options.sign.algorithm.includes('ES') && | ||
(typeof options.secret === 'string' || | ||
options.secret instanceof Buffer) | ||
) { | ||
throw new Error('ECDSA Signatures set as Algorithm in the options require a private and public key to be set as the secret') | ||
} | ||
} | ||
if (options.options) { | ||
return next(new Error('options prefix is deprecated')) | ||
function fastifyJwt (fastify, options, next) { | ||
try { | ||
validateOptions(options) | ||
} catch (e) { | ||
return next(e) | ||
} | ||
@@ -124,21 +154,2 @@ | ||
if ( | ||
signOptions && | ||
signOptions.algorithm && | ||
signOptions.algorithm.includes('RS') && | ||
(typeof secret === 'string' || | ||
secret instanceof Buffer) | ||
) { | ||
return next(new Error('RSA Signatures set as Algorithm in the options require a private and public key to be set as the secret')) | ||
} | ||
if ( | ||
signOptions && | ||
signOptions.algorithm && | ||
signOptions.algorithm.includes('ES') && | ||
(typeof secret === 'string' || | ||
secret instanceof Buffer) | ||
) { | ||
return next(new Error('ECDSA Signatures set as Algorithm in the options require a private and public key to be set as the secret')) | ||
} | ||
const jwtDecorator = { | ||
@@ -162,2 +173,3 @@ decode, | ||
let jwtSignName = 'jwtSign' | ||
if (namespace) { | ||
@@ -174,3 +186,3 @@ if (!fastify.jwt) { | ||
jwtDecodeName = jwtDecode ? (typeof jwtDecode === 'string' ? jwtDecode : 'jwtDecode') : `${namespace}JwtDecode` | ||
jwtDecodeName = jwtDecode || `${namespace}JwtDecode` | ||
jwtVerifyName = jwtVerify || `${namespace}JwtVerify` | ||
@@ -183,9 +195,3 @@ jwtSignName = jwtSign || `${namespace}JwtSign` | ||
// Temporary conditional to prevent breaking changes by exposing `jwtDecode`, | ||
// which already exists in fastify-auth0-verify. | ||
// If jwtDecode has been requested, or plugin is configured to use a namespace. | ||
// TODO Remove conditional when fastify-jwt >=4.x.x | ||
if (jwtDecode || namespace) { | ||
fastify.decorateRequest(jwtDecodeName, requestDecode) | ||
} | ||
fastify.decorateRequest(jwtDecodeName, requestDecode) | ||
fastify.decorateRequest(jwtVerifyName, requestVerify) | ||
@@ -192,0 +198,0 @@ fastify.decorateReply(jwtSignName, replySign) |
{ | ||
"name": "@fastify/jwt", | ||
"version": "7.1.0", | ||
"version": "7.2.0", | ||
"description": "JWT utils for Fastify", | ||
@@ -5,0 +5,0 @@ "main": "jwt.js", |
@@ -435,6 +435,9 @@ # @fastify/jwt | ||
To define multiple JWT validators on the same routes, you may use the `namespace` option. | ||
You can combine this with custom names for `jwtVerify` and `jwtSign`. | ||
To define multiple JWT validators on the same routes, you may use the | ||
`namespace` option. You can combine this with custom names for `jwtVerify`, | ||
`jwtDecode`, and `jwtSign`. | ||
When you omit the `jwtVerify` and `jwtSign` options, the default function name will be `<namespace>JwtVerify` and `<namespace>JwtSign`. | ||
When you omit the `jwtVerify`, `jwtDecode`, or `jwtSign` options, the default | ||
function name will be `<namespace>JwtVerify`, `<namespace>JwtDecode` and | ||
`<namespace>JwtSign` correspondingly. | ||
@@ -449,2 +452,4 @@ #### Example with namespace | ||
namespace: 'security', | ||
// will decorate request with `securityVerify`, `securitySign`, | ||
// and default `securityJwtDecode` since no custom alias provided | ||
jwtVerify: 'securityVerify', | ||
@@ -456,2 +461,4 @@ jwtSign: 'securitySign' | ||
secret: 'fastify', | ||
// will decorate request with default `airDropJwtVerify`, `airDropJwtSign`, | ||
// and `airDropJwtDecode` since no custom aliases provided | ||
namespace: 'airDrop' | ||
@@ -648,6 +655,4 @@ }) | ||
Decode a JWT without verifying | ||
Decode a JWT without verifying. | ||
As of 3.2.0, decorated when `options.jwtDecode` is truthy. Will become non-conditionally decorated in 4.0.0. This avoid breaking change that would effect fastify-auth0-verify. | ||
`options` must be an `Object` and can contain `verify` and `decode` options. | ||
@@ -654,0 +659,0 @@ |
@@ -19,5 +19,4 @@ 'use strict' | ||
const fastify = Fastify() | ||
fastify.register(jwt, { namespace: 'aaa', secret: 'test', verify: { extractToken: (request) => request.headers.customauthheader }, jwtDecode: true }) | ||
fastify.register(jwt, { namespace: 'aaa', secret: 'test', verify: { extractToken: (request) => request.headers.customauthheader } }) | ||
fastify.register(jwt, { namespace: 'bbb', secret: 'sea', verify: { extractToken: (request) => request.headers.customauthheader }, jwtVerify: 'verifyCustom', jwtSign: 'signCustom', jwtDecode: 'decodeCustom' }) | ||
fastify.register(jwt, { namespace: 'ccc', secret: 'tset', verify: { extractToken: (request) => request.headers.customauthheader } }) | ||
@@ -28,6 +27,6 @@ fastify.post('/sign/:namespace', async function (request, reply) { | ||
return reply.aaaJwtSign(request.body) | ||
case 'ccc': | ||
return reply.cccJwtSign(request.body) | ||
case 'bbb': | ||
return reply.signCustom(request.body) | ||
default: | ||
return reply.signCustom(request.body) | ||
reply.code(501).send({ message: `Namespace ${request.params.namespace} is not implemented correctly` }) | ||
} | ||
@@ -40,4 +39,6 @@ }) | ||
return request.aaaJwtVerify() | ||
case 'bbb': | ||
return request.verifyCustom() | ||
default: | ||
return request.verifyCustom() | ||
reply.code(501).send({ message: `Namespace ${request.params.namespace} is not implemented correctly` }) | ||
} | ||
@@ -49,7 +50,5 @@ }) | ||
case 'aaa': | ||
return request.jwtDecode() | ||
return request.aaaJwtDecode() | ||
case 'bbb': | ||
return request.decodeCustom() | ||
case 'ccc': | ||
return request.cccJwtDecode() | ||
default: | ||
@@ -100,10 +99,2 @@ reply.code(501).send({ message: `Namespace ${request.params.namespace} is not implemented correctly` }) | ||
signResponse = await fastify.inject({ | ||
method: 'post', | ||
url: '/sign/ccc', | ||
payload: { foo: 'tset' } | ||
}) | ||
const tokenC = signResponse.payload | ||
t.ok(tokenC) | ||
verifyResponse = await fastify.inject({ | ||
@@ -147,12 +138,2 @@ method: 'get', | ||
t.match(verifyResponseBBB.json(), { foo: 'sky' }) | ||
const verifyResponseCCC = await fastify.inject({ | ||
method: 'get', | ||
url: '/decode/ccc', | ||
headers: { | ||
customauthheader: tokenC | ||
} | ||
}) | ||
t.equal(verifyResponseCCC.statusCode, 200) | ||
t.match(verifyResponseCCC.json(), { foo: 'tset' }) | ||
}) |
@@ -64,3 +64,2 @@ import fastify from 'fastify'; | ||
}, | ||
jwtDecode: true, | ||
namespace: 'security', | ||
@@ -67,0 +66,0 @@ jwtVerify: 'securityVerify', |
Sorry, the diff of this file is too big to display
159553
17
3709
829