From 5f9f8d8499daf106b3acdcb5f82bcfbd542463b9 Mon Sep 17 00:00:00 2001 From: James Crosby Date: Thu, 18 Apr 2024 11:51:46 +0100 Subject: [PATCH] enhance checkOptions to reject invalid signer objects, and test. This catches accidentally passing a Buffer instead of a string. (#241) --- lib/fastifySession.js | 18 ++++++----- test/fastifySession.checkOptions.test.js | 38 +++++++++++++++++++++++- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/lib/fastifySession.js b/lib/fastifySession.js index e624882..9e43429 100644 --- a/lib/fastifySession.js +++ b/lib/fastifySession.js @@ -203,14 +203,16 @@ function fastifySession (fastify, options, next) { } function checkOptions (options) { - if (!options.secret) { - return new Error('the secret option is required!') - } - if (typeof options.secret === 'string' && options.secret.length < 32) { - return new Error('the secret must have length 32 or greater') - } - if (Array.isArray(options.secret) && options.secret.length === 0) { - return new Error('at least one secret is required') + if (typeof options.secret === 'string') { + if (options.secret.length < 32) { + return new Error('the secret must have length 32 or greater') + } + } else if (Array.isArray(options.secret)) { + if (options.secret.length === 0) { + return new Error('at least one secret is required') + } + } else if (!(options.secret && typeof options.secret.sign === 'function' && typeof options.secret.unsign === 'function')) { + return new Error('the secret option is required, and must be a String, Array of Strings, or a signer object with .sign and .unsign methods') } } diff --git a/test/fastifySession.checkOptions.test.js b/test/fastifySession.checkOptions.test.js index d11868c..a897140 100644 --- a/test/fastifySession.checkOptions.test.js +++ b/test/fastifySession.checkOptions.test.js @@ -14,7 +14,7 @@ test('fastifySession.checkOptions: register should fail if no secret is specifie fastify.register(fastifyCookie) fastify.register(fastifySession, options) - await t.rejects(fastify.ready(), new Error('the secret option is required!')) + await t.rejects(fastify.ready(), new Error('the secret option is required, and must be a String, Array of Strings, or a signer object with .sign and .unsign methods')) }) test('fastifySession.checkOptions: register should succeed if secret with 32 characters is specified', async t => { @@ -73,3 +73,39 @@ test('fastifySession.checkOptions: register should fail if no secret is present fastify.register(fastifySession, { secret: [] }) await t.rejects(fastify.ready(), new Error('at least one secret is required')) }) + +test('fastifySession.checkOptions: register should fail if a Buffer is passed', async t => { + t.plan(1) + const fastify = Fastify() + + fastify.register(fastifyCookie) + fastify.register(fastifySession, { secret: crypto.randomBytes(32) }) + await t.rejects(fastify.ready(), new Error('the secret option is required, and must be a String, Array of Strings, or a signer object with .sign and .unsign methods')) +}) + +test('fastifySession.checkOptions: register should fail if a signer missing unsign is passed', async t => { + t.plan(1) + const fastify = Fastify() + + const invalidSigner = { + sign: (x) => x, + unsign: true + } + + fastify.register(fastifyCookie) + fastify.register(fastifySession, { secret: invalidSigner }) + await t.rejects(fastify.ready(), new Error('the secret option is required, and must be a String, Array of Strings, or a signer object with .sign and .unsign methods')) +}) + +test('fastifySession.checkOptions: register should fail if a signer missing sign is passed', async t => { + t.plan(1) + const fastify = Fastify() + + const invalidSigner = { + unsign: (x) => true + } + + fastify.register(fastifyCookie) + fastify.register(fastifySession, { secret: invalidSigner }) + await t.rejects(fastify.ready(), new Error('the secret option is required, and must be a String, Array of Strings, or a signer object with .sign and .unsign methods')) +})