diff --git a/index.js b/index.js index f113e81..b4c20be 100644 --- a/index.js +++ b/index.js @@ -70,9 +70,8 @@ function fastifyCors (fastify, opts, next) { // preflight requests BEFORE possible authentication plugins. If the preflight reply // occurred in this handler, other plugins may deny the request since the browser will // remove most headers (such as the Authentication header). - // - // This route simply enables fastify to accept preflight requests. - fastify.options('/*', { schema: { hide: hideOptionsRoute } }, (req, reply) => { + const handlerOptions = { schema: { hide: hideOptionsRoute } } + const handler = (req, reply) => { if (!req.corsPreflightEnabled) { // Do not handle preflight requests if the origin option disabled CORS reply.callNotFound() @@ -80,7 +79,12 @@ function fastifyCors (fastify, opts, next) { } reply.send() - }) + } + + // This route enables fastify to accept preflight requests on all nested routes, as well as the index route in prefixed setups + // https://github.com/fastify/fastify-cors/issues/281 + fastify.options('/', handlerOptions, handler) + fastify.options('/*', handlerOptions, handler) next() } diff --git a/test/preflight.test.js b/test/preflight.test.js index 42ed499..0c85822 100644 --- a/test/preflight.test.js +++ b/test/preflight.test.js @@ -360,3 +360,36 @@ test('Can override preflight response with preflightContinue', t => { }) }) }) + +test('Can get a preflight response on prefixed index routes', t => { + t.plan(4) + + const fastify = Fastify() + const noop = () => {} + const prefixRoutes = (app, done) => { + app.register(cors) + app.get("/", noop) + } + fastify.register(prefixRoutes, {prefix: "test"}) + + fastify.inject({ + method: 'OPTIONS', + url: '/test', + headers: { + 'access-control-request-method': 'GET', + origin: 'example.com' + } + }, (err, res) => { + t.error(err) + delete res.headers.date + t.equal(res.statusCode, 204) + t.equal(res.payload, '') + t.match(res.headers, { + 'access-control-allow-origin': '*', + 'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE', + 'access-control-allow-headers': 'x-requested-with', + vary: 'Origin, Access-Control-Request-Headers', + 'content-length': '0' + }) + }) +})