Skip to content

Feat/preflight add logLevel option to silence CORS preflight logs#375

Merged
mcollina merged 6 commits intofastify:mainfrom
gulbaki:feat/preflight-loglevel
Aug 1, 2025
Merged

Feat/preflight add logLevel option to silence CORS preflight logs#375
mcollina merged 6 commits intofastify:mainfrom
gulbaki:feat/preflight-loglevel

Conversation

@gulbaki
Copy link
Contributor

@gulbaki gulbaki commented Jun 20, 2025

This PR introduces an optional logLevel field to FastifyCorsOptions, letting users override the Fastify logger level for the internal OPTIONS * pre-flight route.

  • Adds logLevel to default options and TypeScript typings
  • Applies level when registering the pre-flight route
  • New unit test verifies OPTIONS logs are suppressed, GET logs remain
  • README/types comments updated accordingly

fixes: #320

Checklist

Copy link
Member

@jean-michelet jean-michelet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not a user of logLevel, but based on the Fastify docs about it, it looks like logLevel, when passed in plugin options, applies to the entire plugin.

In your implementation, however, it only affects the OPTIONS route used for preflight requests.

Given that, a more appropriate name for this option might be preflightLogLevel or optionsRouteLogLevel.

@jean-michelet jean-michelet requested a review from a team June 20, 2025 07:25
@climba03003
Copy link
Member

I’m not a user of logLevel, but based on the Fastify docs about it, it looks like logLevel, when passed in plugin options, applies to the entire plugin.

logLevel only works when the plugin is encapsulated. So, in this plugin the logLevel is ignored by the core and need to apply manually.

@climba03003
Copy link
Member

The change below should be enough and there is no need on types change.
The core types already include the logLevel for you.

diff --git a/index.js b/index.js
index 94c1dd2..7ec92a2 100644
--- a/index.js
+++ b/index.js
@@ -46,6 +46,7 @@ function fastifyCors (fastify, opts, next) {
   fastify.decorateRequest('corsPreflightEnabled', false)

   let hideOptionsRoute = true
+  let logLevel
   if (typeof opts === 'function') {
     handleCorsOptionsDelegator(opts, fastify, { hook: defaultOptions.hook }, next)
   } else if (opts.delegator) {
@@ -53,6 +54,7 @@ function fastifyCors (fastify, opts, next) {
     handleCorsOptionsDelegator(delegator, fastify, options, next)
   } else {
     if (opts.hideOptionsRoute !== undefined) hideOptionsRoute = opts.hideOptionsRoute
+    if (opts.logLevel !== undefined) logLevel = opts.logLevel
     const corsOptions = normalizeCorsOptions(opts)
     validateHook(corsOptions.hook, next)
     if (hookWithPayload.indexOf(corsOptions.hook) !== -1) {
@@ -72,7 +74,7 @@ function fastifyCors (fastify, opts, next) {
   // remove most headers (such as the Authentication header).
   //
   // This route simply enables fastify to accept preflight requests.
-  fastify.options('*', { schema: { hide: hideOptionsRoute } }, (req, reply) => {
+  fastify.options('*', { schema: { hide: hideOptionsRoute }, logLevel }, (req, reply) => {
     if (!req.corsPreflightEnabled) {
       // Do not handle preflight requests if the origin option disabled CORS
       reply.callNotFound()

@Eomm Eomm linked an issue Jun 20, 2025 that may be closed by this pull request
2 tasks
@gulbaki
Copy link
Contributor Author

gulbaki commented Jun 20, 2025

@climba03003
I think, if I put the if condition there as you said this code will not work
await app.register(cors, { delegator: () => ({ origin: '*' }), logLevel: 'silent' })

@climba03003
Copy link
Member

@climba03003 I think, if I put the if condition there as you said this code will not work await app.register(cors, { delegator: () => ({ origin: '*' }), logLevel: 'silent' })

Same argument apply to hideOptionsRoute, just move those outside the else block.
I am also thinking should we allows, or even deprecate the function feature and use option only.

function delegator() {}
delegator.logLevel = 'info'
delegator.hideOptionsRoute = true

fastify.register(CORS, (instance) => delegator)

@gulbaki
Copy link
Contributor Author

gulbaki commented Jun 21, 2025

@climba03003 I think, if I put the if condition there as you said this code will not work await app.register(cors, { delegator: () => ({ origin: '*' }), logLevel: 'silent' })

Same argument apply to hideOptionsRoute, just move those outside the else block. I am also thinking should we allows, or even deprecate the function feature and use option only.

function delegator() {}
delegator.logLevel = 'info'
delegator.hideOptionsRoute = true

fastify.register(CORS, (instance) => delegator)

I have refactored the code as you suggested (logLevel, hideOptionsRoute). I also added tests that cover delegator usage for both.
However, regarding the part:
I am also thinking should we allow, or even deprecate the function feature and use option only.
If there's anything I should do about this, please let me know . I’d be happy to take care of it.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Copy link
Member

@climba03003 climba03003 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be the last change before land.

@gulbaki gulbaki requested a review from climba03003 June 23, 2025 03:51
@mcollina mcollina merged commit dad4009 into fastify:main Aug 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

logLevel option not respected

6 participants