fastify-jwt
Advanced tools
Comparing version 0.5.0 to 0.6.0
@@ -1,2 +0,39 @@ | ||
# RSA Signatures - Certificates | ||
Demo certificates generates with http://travistidwell.com/jsencrypt/demo/ | ||
# Certificates generation | ||
## RSA Signatures - Certificates (without passphrase) | ||
Demo certificates `private.key` and `public.key` where generated with http://travistidwell.com/jsencrypt/demo/ | ||
## RSA Signatures - Certificates (with passphrase) | ||
Demo certificates `private.pem` and `public.pem` where generated with the following command lines | ||
```sh | ||
# we generate a 2048-bit RSA key pair, and encrypts them with a passphrase | ||
# the passphrase I choose for the demo files is: super secret passphrase | ||
openssl genrsa -des3 -out private.pem 2048 | ||
# we export the RSA public key to a file | ||
openssl rsa -in private.pem -outform PEM -pubout -out public.pem | ||
``` | ||
## ECDSA Signatures - Certificates (without passphrase) | ||
Demo certificates `privateECDSA.key` and `publicECDSA.key` where generated with the following command lines | ||
```sh | ||
# we generate a P-256 curve ECDSA key pair | ||
openssl ecparam -genkey -name secp256k1 -out privateECDSA.key | ||
# we export the ECDSA public key to a file | ||
openssl ec -in privateECDSA.key -pubout -out publicECDSA.key | ||
``` | ||
## ECDSA Signatures - Certificates (with passphrase) | ||
Demo certificates `privateECDSA.pem` and `publicECDSA.pem` where generated with the following command lines | ||
```sh | ||
# we generate a P-256 curve ECDSA key pair, and encrypts them with a passphrase | ||
# the passphrase I choose for the demo files is: super secret passphrase | ||
openssl ecparam -genkey -name secp256k1 | openssl ec -aes256 -out privateECDSA.pem | ||
# we export the ECDSA public key to a file | ||
openssl ec -in privateECDSA.pem -pubout -out publicECDSA.pem | ||
``` |
111
jwt.js
@@ -19,25 +19,42 @@ 'use strict' | ||
function fastifyJwt (fastify, options, next) { | ||
var secretKey, secretPass | ||
if (!options.secret) { | ||
return next(new Error('missing secret')) | ||
} | ||
var secret = options.secret | ||
let secret = options.secret | ||
let secretOrPrivateKey | ||
let secretOrPublicKey | ||
if (typeof secret === 'object') { | ||
if (!secret.key || !secret.passphrase) { | ||
return next(new Error('missing secret key and/or passphrase')) | ||
if (!secret.private || !secret.public) { | ||
return next(new Error('missing private key and/or public key')) | ||
} | ||
secretKey = secret.key | ||
secretPass = secret.passphrase | ||
secretOrPrivateKey = secret.private | ||
secretOrPublicKey = secret.public | ||
} else { | ||
secretKey = secretPass = secret | ||
secretOrPrivateKey = secretOrPublicKey = secret | ||
} | ||
var secretCallback = secret | ||
if (typeof secretCallback !== 'function') { secretCallback = wrapStaticSecretInCallback(secretCallback) } | ||
var defaultOptions = options.options || {} | ||
let secretCallbackSign = secretOrPrivateKey | ||
let secretCallbackVerify = secretOrPublicKey | ||
if (typeof secretCallbackSign !== 'function') { secretCallbackSign = wrapStaticSecretInCallback(secretCallbackSign) } | ||
if (typeof secretCallbackVerify !== 'function') { secretCallbackVerify = wrapStaticSecretInCallback(secretCallbackVerify) } | ||
if (defaultOptions && defaultOptions.algorithm && defaultOptions.algorithm.includes('RS') && typeof secret === 'string') { | ||
return next(new Error(`RSA Signatures set as Algorithm in the options require a key and passphrase to be set as the secret`)) | ||
let defaultOptions = options.options || {} | ||
if ( | ||
defaultOptions && | ||
defaultOptions.algorithm && | ||
defaultOptions.algorithm.includes('RS') && | ||
typeof secret === 'string' | ||
) { | ||
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 ( | ||
defaultOptions && | ||
defaultOptions.algorithm && | ||
defaultOptions.algorithm.includes('ES') && | ||
typeof secret === 'string' | ||
) { | ||
return next(new Error(`ECDSA Signatures set as Algorithm in the options require a private and public key to be set as the secret`)) | ||
} | ||
@@ -48,3 +65,3 @@ fastify.decorate('jwt', { | ||
verify: verify, | ||
secret: options.secret | ||
secret: secret | ||
}) | ||
@@ -60,2 +77,3 @@ | ||
assert(payload, 'missing payload') | ||
signOptions = signOptions || {} | ||
@@ -66,9 +84,9 @@ if (typeof signOptions === 'function') { | ||
} | ||
signOptions = Object.assign(defaultOptions, signOptions) | ||
signOptions = Object.assign({}, defaultOptions) | ||
delete signOptions['algorithms'] | ||
if (typeof callback === 'function') { | ||
jwt.sign(payload, secretKey, signOptions, callback) | ||
jwt.sign(payload, secretOrPrivateKey, signOptions, callback) | ||
} else { | ||
return jwt.sign(payload, secretKey, signOptions) | ||
return jwt.sign(payload, secretOrPrivateKey, signOptions) | ||
} | ||
@@ -80,12 +98,14 @@ } | ||
assert(secret, 'missing secret') | ||
verifyOptions = verifyOptions || {} | ||
if (typeof verifyOptions === 'function') { | ||
if ((typeof verifyOptions === 'function') && !callback) { | ||
callback = verifyOptions | ||
verifyOptions = {} | ||
} | ||
verifyOptions = Object.assign(defaultOptions, verifyOptions) | ||
verifyOptions = Object.assign({}, defaultOptions) | ||
if (typeof callback === 'function') { | ||
jwt.verify(token, secretPass, verifyOptions, callback) | ||
jwt.verify(token, secretOrPublicKey, verifyOptions, callback) | ||
} else { | ||
return jwt.verify(token, secretPass, verifyOptions) | ||
return jwt.verify(token, secretOrPublicKey, verifyOptions) | ||
} | ||
@@ -100,11 +120,15 @@ } | ||
function replySign (payload, options, next) { | ||
if (typeof options === 'function') { | ||
next = options | ||
options = {} | ||
function replySign (payload, signOptions, next) { | ||
if (typeof signOptions === 'function') { | ||
next = signOptions | ||
signOptions = {} | ||
} // support no options | ||
var reply = this | ||
signOptions = Object.assign({}, defaultOptions) | ||
delete signOptions['algorithms'] | ||
let reply = this | ||
if (next === undefined) { | ||
return new Promise(function (resolve, reject) { | ||
reply.jwtSign(payload, options, function (err, val) { | ||
reply.jwtSign(payload, signOptions, function (err, val) { | ||
err ? reject(err) : resolve(val) | ||
@@ -118,8 +142,9 @@ }) | ||
} | ||
steed.waterfall([ | ||
function getSecret (callback) { | ||
secretCallback(reply.request, payload, callback) | ||
secretCallbackSign(reply.request, payload, callback) | ||
}, | ||
function sign (secret, callback) { | ||
jwt.sign(payload, secret, options, callback) | ||
function sign (secretOrPrivateKey, callback) { | ||
jwt.sign(payload, secretOrPrivateKey, signOptions, callback) | ||
} | ||
@@ -129,13 +154,14 @@ ], next) | ||
function requestVerify (options, next) { | ||
if (typeof options === 'function') { | ||
next = options | ||
options = {} | ||
function requestVerify (verifyOptions, next) { | ||
if (typeof verifyOptions === 'function') { | ||
next = verifyOptions | ||
verifyOptions = {} | ||
} // support no options | ||
verifyOptions = Object.assign({}, defaultOptions) | ||
var request = this | ||
let request = this | ||
if (next === undefined) { | ||
return new Promise(function (resolve, reject) { | ||
request.jwtVerify(options, function (err, val) { | ||
request.jwtVerify(verifyOptions, function (err, val) { | ||
err ? reject(err) : resolve(val) | ||
@@ -146,7 +172,7 @@ }) | ||
var token | ||
let token | ||
if (request.headers && request.headers.authorization) { | ||
var parts = request.headers.authorization.split(' ') | ||
let parts = request.headers.authorization.split(' ') | ||
if (parts.length === 2) { | ||
var scheme = parts[0] | ||
let scheme = parts[0] | ||
token = parts[1] | ||
@@ -162,9 +188,10 @@ | ||
var decodedToken = jwt.decode(token, options) | ||
let decodedToken = jwt.decode(token, options) | ||
steed.waterfall([ | ||
function getSecret (callback) { | ||
secretCallback(request, decodedToken, callback) | ||
secretCallbackVerify(request, decodedToken, callback) | ||
}, | ||
function verify (secret, callback) { | ||
jwt.verify(token, secret, options, callback) | ||
function verify (secretOrPublicKey, callback) { | ||
jwt.verify(token, secretOrPublicKey, verifyOptions, callback) | ||
} | ||
@@ -171,0 +198,0 @@ ], function (err, result) { |
{ | ||
"name": "fastify-jwt", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "JWT utils for Fastify", | ||
@@ -5,0 +5,0 @@ "main": "jwt.js", |
@@ -17,4 +17,4 @@ # fastify-jwt | ||
const fastify = require('fastify') | ||
fastify.register(require('fastify-jwt'), { | ||
secret: 'supersecret' | ||
fastify.register(require('fastify-jwt'), { | ||
secret: 'supersecret' | ||
}) | ||
@@ -37,4 +37,4 @@ | ||
const fastify = require('fastify') | ||
fastify.register(require('fastify-jwt'), { | ||
secret: 'supersecret' | ||
fastify.register(require('fastify-jwt'), { | ||
secret: 'supersecret' | ||
}) | ||
@@ -102,5 +102,13 @@ | ||
### fastify-jwt | ||
`fastify-jwt` is a fastify plugin. You must pass a `secret` to the `options` parameter. The `secret` can be a primitive type String or a function that returns a String. Function based `secret` is supported by the `request.jwtVerify()` and `reply.jwtSign()` methods and is called with `request`, `reply`, and `callback` parameters. | ||
`fastify-jwt` is a fastify plugin. You must pass a `secret` to the `options` parameter. The `secret` can be a primitive type String, a function that returns a String or an object `{ private, public }`. | ||
In this object `{ private, public }` the `private` key is a string, buffer or object containing either the secret for HMAC algorithms or the PEM encoded private key for RSA and ECSA. In case of a private key with passphrase an object `{ private: { key, passphrase }, public }` can be used (based on [crypto documentation](https://nodejs.org/api/crypto.html#crypto_sign_sign_private_key_output_format)), in this case be sure you pass the `algorithm` option). | ||
In this object `{ private, public }` the `public` key is a string or buffer containing either the secret for HMAC algorithms, or the PEM encoded public key for RSA and ECDSA. | ||
Function based `secret` is supported by the `request.jwtVerify()` and `reply.jwtSign()` methods and is called with `request`, `reply`, and `callback` parameters. | ||
#### Example | ||
```js | ||
const { readFileSync } = require('fs') | ||
const path = require('path') | ||
const fastify = require('fastify')() | ||
@@ -111,15 +119,36 @@ const jwt = require('fastify-jwt') | ||
// secret as a function | ||
fastify.register(jwt, { | ||
fastify.register(jwt, { | ||
secret: function (request, reply, callback) { | ||
// do something | ||
// do something | ||
callback(null, 'supersecret') | ||
} | ||
}) | ||
// secret as an object of RSA keys (without passphrase) | ||
// assuming the key files are inside a certs directory and loaded as strings | ||
fastify.register(jwt, { | ||
secret: { | ||
private: readFileSync(`${path.join(__dirname, 'certs')}/private.key`, 'utf8') | ||
public: readFileSync(`${path.join(__dirname, 'certs')}/public.key`, 'utf8') | ||
}, | ||
options: { algorithm: 'RS256' } | ||
}) | ||
// secret as an object of P-256 ECDSA keys (with a passphrase) | ||
// assuming the pem files are inside a certs directory and loaded as buffers | ||
fastify.register(jwt, { | ||
secret: { | ||
private: { | ||
key: readFileSync(`${path.join(__dirname, 'certs')}/private.pem`), | ||
passphrase: 'super secret passphrase' | ||
}, | ||
public: readFileSync(`${path.join(__dirname, 'certs')}/public.pem`) | ||
}, | ||
options: { algorithm: 'ES256' } | ||
}) | ||
``` | ||
### fastify.jwt.sign(payload [,options] [,callback]) | ||
The `sign` method is an implementation of [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken#jwtsignpayload-secretorprivatekey-options-callback) `.sign()`. Can be used asynchronously by passing a callback function; synchronously without a callback. | ||
The `sign` method is an implementation of [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken#jwtsignpayload-secretorprivatekey-options-callback) `.sign()`. Can be used asynchronously by passing a callback function; synchronously without a callback. | ||
### fastify.jwt.verify(token, [,options] [,callback]) | ||
The `verify` method is an implementation of [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback) `.verify()`. Can be used asynchronously by passing a callback function; synchronously without a callback. | ||
The `verify` method is an implementation of [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback) `.verify()`. Can be used asynchronously by passing a callback function; synchronously without a callback. | ||
#### Example | ||
@@ -156,5 +185,5 @@ ```js | ||
fastify.register(jwt, { | ||
fastify.register(jwt, { | ||
secret: function (request, reply, callback) { | ||
// do something | ||
// do something | ||
callback(null, 'supersecret') | ||
@@ -161,0 +190,0 @@ } |
549
test.js
@@ -10,7 +10,18 @@ 'use strict' | ||
const privateKey = fs.readFileSync(`${path.join(__dirname, 'certs')}/private.key`, 'utf8') | ||
const publicKey = fs.readFileSync(`${path.join(__dirname, 'certs')}/public.key`, 'utf8') | ||
const privateKey = fs.readFileSync(`${path.join(__dirname, 'certs')}/private.key`, 'utf8') | ||
// passphrase used to protect the private key: super secret passphrase | ||
const privateKeyProtected = fs.readFileSync(`${path.join(__dirname, 'certs')}/private.pem`) | ||
const publicKeyProtected = fs.readFileSync(`${path.join(__dirname, 'certs')}/public.pem`) | ||
const privateKeyECDSA = fs.readFileSync(`${path.join(__dirname, 'certs')}/privateECDSA.key`, 'utf8') | ||
const publicKeyECDSA = fs.readFileSync(`${path.join(__dirname, 'certs')}/publicECDSA.key`, 'utf8') | ||
// passphrase used to protect the private key: super secret passphrase | ||
const privateKeyProtectedECDSA = fs.readFileSync(`${path.join(__dirname, 'certs')}/privateECDSA.pem`) | ||
const publicKeyProtectedECDSA = fs.readFileSync(`${path.join(__dirname, 'certs')}/publicECDSA.pem`) | ||
test('register', function (t) { | ||
t.plan(7) | ||
t.plan(9) | ||
@@ -44,3 +55,8 @@ t.test('expose jwt methods', function (t) { | ||
const fastify = Fastify() | ||
fastify.register(jwt, { secret: { key: privateKey, passphrase: publicKey } }).ready(function (error) { | ||
fastify.register(jwt, { | ||
secret: { | ||
private: privateKeyProtected, | ||
public: 'super secret passphrase' | ||
} | ||
}).ready(function (error) { | ||
t.is(error, null) | ||
@@ -53,3 +69,10 @@ }) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { secret: 'test', options: { issuer: 'Some issuer', subject: 'Some subject', audience: 'Some audience' } }).ready(function (error) { | ||
fastify.register(jwt, { | ||
secret: 'test', | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience' | ||
} | ||
}).ready(function (error) { | ||
t.is(error, null) | ||
@@ -62,3 +85,14 @@ }) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { secret: { key: privateKey, passphrase: publicKey }, options: { issuer: 'Some issuer', subject: 'Some subject', audience: 'Some audience', algorithm: 'RS256' } }).ready(function (error) { | ||
fastify.register(jwt, { | ||
secret: { | ||
private: privateKey, | ||
public: publicKey | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'RS256' | ||
} | ||
}).ready(function (error) { | ||
t.is(error, null) | ||
@@ -68,10 +102,53 @@ }) | ||
t.test('options and secret as an object with ES algorithm', function (t) { | ||
t.plan(1) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { | ||
secret: { | ||
private: privateKeyECDSA, | ||
public: publicKeyECDSA | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'ES256' | ||
} | ||
}).ready(function (error) { | ||
t.is(error, null) | ||
}) | ||
}) | ||
t.test('secret as string, options as an object with RS algorithm', function (t) { | ||
t.plan(1) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { secret: 'test', options: { issuer: 'Some issuer', subject: 'Some subject', audience: 'Some audience', algorithm: 'RS256' } }).ready(function (error) { | ||
t.is(error.message, 'RSA Signatures set as Algorithm in the options require a key and passphrase to be set as the secret') | ||
fastify.register(jwt, { | ||
secret: 'test', | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'RS256' | ||
} | ||
}).ready(function (error) { | ||
t.is(error.message, 'RSA Signatures set as Algorithm in the options require a private and public key to be set as the secret') | ||
}) | ||
}) | ||
t.test('secret as string, options as an object with ES algorithm', function (t) { | ||
t.plan(1) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { | ||
secret: 'test', | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'ES256' | ||
} | ||
}).ready(function (error) { | ||
t.is(error.message, 'ECDSA Signatures set as Algorithm in the options require a private and public key to be set as the secret') | ||
}) | ||
}) | ||
t.test('secret as a function', function (t) { | ||
@@ -266,3 +343,14 @@ t.plan(2) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { secret: { key: privateKey, passphrase: publicKey }, options: { issuer: 'Some issuer', subject: 'Some subject', audience: 'Some audience', algorithm: 'RS256' } }) | ||
fastify.register(jwt, { | ||
secret: { | ||
private: privateKey, | ||
public: publicKey | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'RS256' | ||
} | ||
}) | ||
@@ -300,3 +388,14 @@ fastify | ||
const fastify = Fastify() | ||
fastify.register(jwt, { secret: 'test' }) | ||
fastify.register(jwt, { | ||
secret: { | ||
private: privateKey, | ||
public: publicKey | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'RS256' | ||
} | ||
}) | ||
@@ -383,2 +482,434 @@ fastify.post('/signSync', function (request, reply) { | ||
test('sign and verify with ECDSA and options', function (t) { | ||
t.plan(2) | ||
t.test('server methods', function (t) { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { | ||
secret: { | ||
private: privateKeyECDSA, | ||
public: publicKeyECDSA | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'ES256' | ||
} | ||
}) | ||
fastify | ||
.ready() | ||
.then(function () { | ||
t.test('synchronous', function (t) { | ||
t.plan(1) | ||
const token = fastify.jwt.sign({ foo: 'bar' }) | ||
const decoded = fastify.jwt.verify(token) | ||
t.is(decoded.foo, 'bar') | ||
}) | ||
t.test('with callbacks', function (t) { | ||
t.plan(3) | ||
fastify.jwt.sign({ foo: 'bar' }, function (error, token) { | ||
t.error(error) | ||
fastify.jwt.verify(token, function (error, decoded) { | ||
t.error(error) | ||
t.is(decoded.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
t.test('route methods', function (t) { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { | ||
secret: { | ||
private: privateKeyECDSA, | ||
public: publicKeyECDSA | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'ES256' | ||
} | ||
}) | ||
fastify.post('/signSync', function (request, reply) { | ||
reply.jwtSign(request.body) | ||
.then(function (token) { | ||
return reply.send({ token }) | ||
}) | ||
}) | ||
fastify.get('/verifySync', function (request, reply) { | ||
request.jwtVerify() | ||
.then(function (decodedToken) { | ||
return reply.send(decodedToken) | ||
}) | ||
}) | ||
fastify.post('/signAsync', function (request, reply) { | ||
reply.jwtSign(request.body, function (error, token) { | ||
return reply.send(error || { token }) | ||
}) | ||
}) | ||
fastify.get('/verifyAsync', function (request, reply) { | ||
request.jwtVerify(function (error, decodedToken) { | ||
return reply.send(error || decodedToken) | ||
}) | ||
}) | ||
fastify | ||
.ready() | ||
.then(function () { | ||
t.test('synchronous', function (t) { | ||
t.plan(2) | ||
fastify.inject({ | ||
method: 'post', | ||
url: '/signSync', | ||
payload: { foo: 'bar' } | ||
}).then(function (signResponse) { | ||
const token = JSON.parse(signResponse.payload).token | ||
t.ok(token) | ||
fastify.inject({ | ||
method: 'get', | ||
url: '/verifySync', | ||
headers: { | ||
authorization: `Bearer ${token}` | ||
} | ||
}).then(function (verifyResponse) { | ||
const decodedToken = JSON.parse(verifyResponse.payload) | ||
t.is(decodedToken.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
t.test('with callbacks', function (t) { | ||
t.plan(2) | ||
fastify.inject({ | ||
method: 'post', | ||
url: '/signAsync', | ||
payload: { foo: 'bar' } | ||
}).then(function (signResponse) { | ||
const token = JSON.parse(signResponse.payload).token | ||
t.ok(token) | ||
fastify.inject({ | ||
method: 'get', | ||
url: '/verifyAsync', | ||
headers: { | ||
authorization: `Bearer ${token}` | ||
} | ||
}).then(function (verifyResponse) { | ||
const decodedToken = JSON.parse(verifyResponse.payload) | ||
t.is(decodedToken.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
test('sign and verify with RSA passphrase protected private key (PEM file) and options', function (t) { | ||
t.plan(2) | ||
t.test('server methods', function (t) { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { | ||
secret: { | ||
private: { key: privateKeyProtected, passphrase: 'super secret passphrase' }, | ||
public: publicKeyProtected | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'RS256' | ||
} | ||
}) | ||
fastify | ||
.ready() | ||
.then(function () { | ||
t.test('synchronous', function (t) { | ||
t.plan(1) | ||
const token = fastify.jwt.sign({ foo: 'bar' }) | ||
const decoded = fastify.jwt.verify(token) | ||
t.is(decoded.foo, 'bar') | ||
}) | ||
t.test('with callbacks', function (t) { | ||
t.plan(3) | ||
fastify.jwt.sign({ foo: 'bar' }, function (error, token) { | ||
t.error(error) | ||
fastify.jwt.verify(token, function (error, decoded) { | ||
t.error(error) | ||
t.is(decoded.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
t.test('route methods', function (t) { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { | ||
secret: { | ||
private: { key: privateKeyProtected, passphrase: 'super secret passphrase' }, | ||
public: publicKeyProtected | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'RS256' | ||
} | ||
}) | ||
fastify.post('/signSync', function (request, reply) { | ||
reply.jwtSign(request.body) | ||
.then(function (token) { | ||
return reply.send({ token }) | ||
}) | ||
}) | ||
fastify.get('/verifySync', function (request, reply) { | ||
request.jwtVerify() | ||
.then(function (decodedToken) { | ||
return reply.send(decodedToken) | ||
}) | ||
}) | ||
fastify.post('/signAsync', function (request, reply) { | ||
reply.jwtSign(request.body, function (error, token) { | ||
return reply.send(error || { token }) | ||
}) | ||
}) | ||
fastify.get('/verifyAsync', function (request, reply) { | ||
request.jwtVerify(function (error, decodedToken) { | ||
return reply.send(error || decodedToken) | ||
}) | ||
}) | ||
fastify | ||
.ready() | ||
.then(function () { | ||
t.test('synchronous', function (t) { | ||
t.plan(2) | ||
fastify.inject({ | ||
method: 'post', | ||
url: '/signSync', | ||
payload: { foo: 'bar' } | ||
}).then(function (signResponse) { | ||
const token = JSON.parse(signResponse.payload).token | ||
t.ok(token) | ||
fastify.inject({ | ||
method: 'get', | ||
url: '/verifySync', | ||
headers: { | ||
authorization: `Bearer ${token}` | ||
} | ||
}).then(function (verifyResponse) { | ||
const decodedToken = JSON.parse(verifyResponse.payload) | ||
t.is(decodedToken.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
t.test('with callbacks', function (t) { | ||
t.plan(2) | ||
fastify.inject({ | ||
method: 'post', | ||
url: '/signAsync', | ||
payload: { foo: 'bar' } | ||
}).then(function (signResponse) { | ||
const token = JSON.parse(signResponse.payload).token | ||
t.ok(token) | ||
fastify.inject({ | ||
method: 'get', | ||
url: '/verifyAsync', | ||
headers: { | ||
authorization: `Bearer ${token}` | ||
} | ||
}).then(function (verifyResponse) { | ||
const decodedToken = JSON.parse(verifyResponse.payload) | ||
t.is(decodedToken.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
test('sign and verify with ECDSA passphrase protected private key (PEM file) and options', function (t) { | ||
t.plan(2) | ||
t.test('server methods', function (t) { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { | ||
secret: { | ||
private: { key: privateKeyProtectedECDSA, passphrase: 'super secret passphrase' }, | ||
public: publicKeyProtectedECDSA | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'ES256' | ||
} | ||
}) | ||
fastify | ||
.ready() | ||
.then(function () { | ||
t.test('synchronous', function (t) { | ||
t.plan(1) | ||
const token = fastify.jwt.sign({ foo: 'bar' }) | ||
const decoded = fastify.jwt.verify(token) | ||
t.is(decoded.foo, 'bar') | ||
}) | ||
t.test('with callbacks', function (t) { | ||
t.plan(3) | ||
fastify.jwt.sign({ foo: 'bar' }, function (error, token) { | ||
t.error(error) | ||
fastify.jwt.verify(token, function (error, decoded) { | ||
t.error(error) | ||
t.is(decoded.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
t.test('route methods', function (t) { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
fastify.register(jwt, { | ||
secret: { | ||
private: { key: privateKeyProtectedECDSA, passphrase: 'super secret passphrase' }, | ||
public: publicKeyProtectedECDSA | ||
}, | ||
options: { | ||
issuer: 'Some issuer', | ||
subject: 'Some subject', | ||
audience: 'Some audience', | ||
algorithm: 'ES256' | ||
} | ||
}) | ||
fastify.post('/signSync', function (request, reply) { | ||
reply.jwtSign(request.body) | ||
.then(function (token) { | ||
return reply.send({ token }) | ||
}) | ||
}) | ||
fastify.get('/verifySync', function (request, reply) { | ||
request.jwtVerify() | ||
.then(function (decodedToken) { | ||
return reply.send(decodedToken) | ||
}) | ||
}) | ||
fastify.post('/signAsync', function (request, reply) { | ||
reply.jwtSign(request.body, function (error, token) { | ||
return reply.send(error || { token }) | ||
}) | ||
}) | ||
fastify.get('/verifyAsync', function (request, reply) { | ||
request.jwtVerify(function (error, decodedToken) { | ||
return reply.send(error || decodedToken) | ||
}) | ||
}) | ||
fastify | ||
.ready() | ||
.then(function () { | ||
t.test('synchronous', function (t) { | ||
t.plan(2) | ||
fastify.inject({ | ||
method: 'post', | ||
url: '/signSync', | ||
payload: { foo: 'bar' } | ||
}).then(function (signResponse) { | ||
const token = JSON.parse(signResponse.payload).token | ||
t.ok(token) | ||
fastify.inject({ | ||
method: 'get', | ||
url: '/verifySync', | ||
headers: { | ||
authorization: `Bearer ${token}` | ||
} | ||
}).then(function (verifyResponse) { | ||
const decodedToken = JSON.parse(verifyResponse.payload) | ||
t.is(decodedToken.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
t.test('with callbacks', function (t) { | ||
t.plan(2) | ||
fastify.inject({ | ||
method: 'post', | ||
url: '/signAsync', | ||
payload: { foo: 'bar' } | ||
}).then(function (signResponse) { | ||
const token = JSON.parse(signResponse.payload).token | ||
t.ok(token) | ||
fastify.inject({ | ||
method: 'get', | ||
url: '/verifyAsync', | ||
headers: { | ||
authorization: `Bearer ${token}` | ||
} | ||
}).then(function (verifyResponse) { | ||
const decodedToken = JSON.parse(verifyResponse.payload) | ||
t.is(decodedToken.foo, 'bar') | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
test('decode', function (t) { | ||
@@ -385,0 +916,0 @@ t.plan(1) |
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
47345
15
1016
247