### Actual Request Example (HTTP) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/TECHNICAL_REFERENCE_INDEX.md This is an example of the actual HTTP request sent by the browser after a successful preflight check. ```http POST /api/resource HTTP/1.1 Origin: https://example.com Content-Type: application/json ``` -------------------------------- ### Actual Response Example (HTTP) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/TECHNICAL_REFERENCE_INDEX.md This is an example of the server's response to the actual HTTP request, including CORS headers. ```http HTTP/1.1 200 OK Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: X-Total-Count { "data": "..." } ``` -------------------------------- ### Preflight Request Example (HTTP) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/TECHNICAL_REFERENCE_INDEX.md This is an example of a preflight OPTIONS request sent by the browser to the server to check if the actual request is permitted. ```http OPTIONS /api/resource HTTP/1.1 Origin: https://example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type ``` -------------------------------- ### Basic Fastify CORS Setup Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/fastify-cors-plugin.md Demonstrates the basic registration of the fastify-cors plugin with common options for origin and allowed methods. ```javascript import Fastify from 'fastify' import cors from '@fastify/cors' const fastify = Fastify() await fastify.register(cors, { origin: '*', methods: ['GET', 'HEAD', 'POST'] }) fastify.get('/', (req, reply) => { reply.send({ hello: 'world' }) }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Example Usage Summary Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Illustrates various ways to register the Fastify CORS plugin with different configuration approaches. ```APIDOC ## Example Usage Summary ### Direct options ```typescript // Direct options await fastify.register(cors, { origin: 'https://example.com', credentials: true }) ``` ### Delegator callback ```typescript // Delegator callback await fastify.register(cors, (fastify) => { return (req, callback) => { callback(null, { origin: true }) } }) ``` ### Delegator promise ```typescript // Delegator promise await fastify.register(cors, { delegator: async (req) => { return { origin: true } } }) ``` ### Custom origin function ```typescript // Custom origin function await fastify.register(cors, { origin: async (origin) => { const allowed = await isAllowed(origin) return allowed ? origin : false } }) ``` ``` -------------------------------- ### Fastify CORS Plugin Registration Example Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Demonstrates how to register the Fastify CORS plugin with various configuration options. This example shows how to set allowed origins, methods, headers, credentials, and other CORS-related settings. ```javascript await fastify.register(cors, { origin: ['https://example.com', /\.example\.com$/], methods: ['GET', 'POST', 'PUT', 'DELETE'], allowedHeaders: ['Content-Type', 'Authorization'], credentials: true, maxAge: 86400, exposedHeaders: ['X-Total-Count'], preflightContinue: false, optionsSuccessStatus: 200, preflight: true, strictPreflight: true, hideOptionsRoute: true, logLevel: 'warn' }) ``` -------------------------------- ### Simple Preflight Request and Response Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/endpoints.md A basic example of an OPTIONS preflight request and its default response. ```http OPTIONS /api/users HTTP/1.1 Host: api.example.com Origin: https://example.com Access-Control-Request-Method: POST ``` ```http HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET, HEAD, POST Content-Length: 0 ``` -------------------------------- ### Install @fastify/cors Source: https://github.com/fastify/fastify-cors/blob/main/README.md Install the @fastify/cors package using npm. This is the first step to enable CORS in your Fastify application. ```bash npm i @fastify/cors ``` -------------------------------- ### Manual Preflight Handling Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/endpoints.md Example of manually handling preflight requests when automatic handling is disabled. ```javascript await fastify.register(cors, { preflight: false }) fastify.options('*', (req, reply) => { // Manual preflight handling reply.send() }) ``` -------------------------------- ### AsyncOriginFunction Example Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md An example of implementing an asynchronous origin validation function. This snippet demonstrates checking an origin against a database and returning the origin if allowed, or false to deny. ```javascript origin: async (origin) => { const allowed = await database.checkOrigin(origin) return allowed ? origin : false } ``` -------------------------------- ### Configure Allowed Methods (String) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Specify allowed HTTP methods as a comma-separated string. Defaults to 'GET,HEAD,POST'. ```javascript methods: 'GET,POST,PUT,DELETE,PATCH' ``` -------------------------------- ### Minimal Fastify CORS Setup Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Register the fastify-cors plugin with default settings to allow all origins. Ensure Fastify and the cors plugin are imported. ```javascript import Fastify from 'fastify' import cors from '@fastify/cors' const fastify = Fastify() // Register with all defaults (origin: '*') await fastify.register(cors) fastify.get('/', (req, reply) => { reply.send({ hello: 'world' }) }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Configure Allowed Methods (Array) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Specify allowed HTTP methods as an array of strings. Defaults to 'GET,HEAD,POST'. ```javascript methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] ``` -------------------------------- ### Browser Fetch Example Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/errors.md This JavaScript snippet shows a typical browser fetch request. Modern browsers automatically include the necessary headers for preflight requests, simplifying client-side implementation. ```javascript // Browser automatically sends proper headers fetch('https://api.example.com/resource', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ data: 'value' }) }) ``` -------------------------------- ### Synchronous Origin Validation Example Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Provides an example of a synchronous origin validation function. It checks if the request origin's hostname is 'localhost' and either allows it or denies it with an error. ```javascript origin: (origin, callback) => { const hostname = new URL(origin).hostname if (hostname === 'localhost') { callback(null, true) } else { callback(new Error('Not allowed'), false) } } ``` -------------------------------- ### Example: Wildcard Origin Header - Fastify CORS Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Illustrates how to set the Access-Control-Allow-Origin header to a wildcard ('*') when the origin option is set to '*'. This allows all origins to access the resource. ```javascript // Wildcard getAccessControlAllowOriginHeader('https://example.com', '*') // Returns: '*' ``` -------------------------------- ### Flexible Origin Array Example Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Demonstrates a practical usage of ValueOrArray for defining a complex origin configuration with a mix of string literals, regular expressions, and nested arrays. ```javascript origin: [ 'https://example1.com', /example2\.com$/, ['https://example3.com', /example4\.com$/] ] ``` -------------------------------- ### Client-side Request with Credentials Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md This client-side JavaScript example shows how to send cookies with a fetch request to an API endpoint configured for CORS with credentials. Ensure `credentials: 'include'` is set. ```javascript // Client-side JavaScript const response = await fetch('https://api.example.com/user', { method: 'GET', credentials: 'include', // Send cookies with request headers: { 'Content-Type': 'application/json' } }) const user = await response.json() ``` -------------------------------- ### Allow Origins Matching a Regular Expression Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Use a regular expression to match origins based on a pattern. This example allows origins ending with 'example.com'. ```javascript origin: /example\.com$/ ``` -------------------------------- ### Example Usage of resolveOriginWrapper - Fastify CORS Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Demonstrates how to use the `resolveOriginWrapper` to handle asynchronous origin validation. The wrapper ensures that both promise-based and callback-based functions work correctly when validating requests. ```javascript // Handles both callback and promise functions const wrapper = resolveOriginWrapper(fastify, async (origin) => { return await validateOrigin(origin) }) wrapper(req, (err, result) => { // Both callback and promise forms work }) ``` -------------------------------- ### Setup CORS Options Delegator Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Configures a delegator-based CORS system by detecting the options resolver's arity (callback or promise-based) and attaching the appropriate hook. ```typescript function handleCorsOptionsDelegator( optionsResolver: Function, fastify: FastifyInstance, opts: Partial, next: Function ): void ``` -------------------------------- ### Asynchronous CORS Configuration with Dynamic Origin Source: https://github.com/fastify/fastify-cors/blob/main/README.md This example demonstrates how to configure CORS asynchronously. It dynamically sets the 'origin' option based on the request's origin header, disabling CORS for localhost requests. This approach is not recommended for production due to potential reflection exploits. ```javascript const fastify = require('fastify')() fastify.register(require('@fastify/cors'), (instance) => { return (req, callback) => { const corsOptions = { // This is NOT recommended for production as it enables reflection exploits origin: true }; // do not include CORS headers for requests from localhost if (/^localhost$/m.test(req.headers.origin)) { corsOptions.origin = false } // callback expects two parameters: error and options callback(null, corsOptions) } }) fastify.register(async function (fastify) { fastify.get('/', (req, reply) => { reply.send({ hello: 'world' }) }) }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### OriginValue Example Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Illustrates how ValueOrArray can be used with OriginType to define flexible origin configurations, allowing single values, arrays, or nested arrays. ```typescript type OriginValue = ValueOrArray // Equivalent to: OriginType | OriginType[] | (OriginType | OriginType[])[] | ... ``` -------------------------------- ### Custom Origin Function for Allowlisting Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Implement a custom function for the `origin` option to dynamically determine allowed origins. This example checks against an `allowlist` and handles same-origin requests. ```javascript await fastify.register(cors, { origin: async (origin) => { if (!origin) return true // Same-origin requests try { const url = new URL(origin) const allowed = await allowlist.has(url.hostname) return allowed ? origin : false } catch { return false } } }) ``` -------------------------------- ### Curl Examples for Invalid Preflight Requests Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/errors.md These curl commands demonstrate scenarios where a preflight request fails due to missing required headers like 'Origin' or 'Access-Control-Request-Method'. This is relevant when `strictPreflight` is enabled in Fastify CORS. ```bash # Missing Access-Control-Request-Method header curl -X OPTIONS \ -H "Origin: https://example.com" \ http://api.example.com/resource # Response: 400 Invalid Preflight Request # Missing Origin header curl -X OPTIONS \ -H "Access-Control-Request-Method: POST" \ http://api.example.com/resource # Response: 400 Invalid Preflight Request ``` -------------------------------- ### Example Usage of isRequestOriginAllowed Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Demonstrates how to use `isRequestOriginAllowed` with different origin validation rules, including arrays, regular expressions, and string comparisons. ```javascript // Array of allowed origins isRequestOriginAllowed('https://example.com', [ 'https://example.com', /example2\.com$/ ]) // Returns: true (matches first item) // RegExp isRequestOriginAllowed('https://api.example.com', /example\.com$/) // Returns: true (matches pattern) // Not allowed isRequestOriginAllowed('https://attacker.com', 'https://example.com') // Returns: false (exact mismatch) ``` -------------------------------- ### Example: Specific Origin Header - Fastify CORS Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Shows how to set the Access-Control-Allow-Origin header to a specific origin when the origin option matches the request's origin. This restricts access to only the specified domain. ```javascript // Specific origin getAccessControlAllowOriginHeader('https://example.com', 'https://example.com') // Returns: 'https://example.com' ``` -------------------------------- ### Invalid Preflight Request in Strict Mode Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/endpoints.md An example of an invalid preflight request (missing Access-Control-Request-Method) and the 400 Bad Request response when strictPreflight is enabled. ```http OPTIONS /api/users HTTP/1.1 Host: api.example.com Origin: https://example.com ``` ```http HTTP/1.1 400 Bad Request Content-Type: text/plain Content-Length: 23 Invalid Preflight Request ``` -------------------------------- ### Example: Disallowed Origin Header - Fastify CORS Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Demonstrates a scenario where the request origin is not allowed according to the configured origin option. The function correctly returns `false`, indicating that the origin should not be permitted. ```javascript // Request origin not allowed getAccessControlAllowOriginHeader('https://attacker.com', 'https://example.com') // Returns: false ``` -------------------------------- ### Enable Debug Logging for Fastify CORS Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/errors.md Configure Fastify with logger enabled and set the `logLevel` option for the CORS plugin to 'debug' to get detailed information about preflight requests. ```javascript const fastify = Fastify({ logger: true }) await fastify.register(cors, { logLevel: 'debug' // Debug preflight requests }) ``` -------------------------------- ### Debug Preflight Issues with Fastify CORS Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Set the CORS plugin's logLevel to 'debug' to help diagnose preflight request problems. This example also includes an 'onSend' hook to log CORS headers for inspection. ```javascript await fastify.register(cors, { origin: '*', logLevel: 'debug' }) fastify.addHook('onSend', (req, reply, payload, done) => { console.log('CORS Headers:') console.log(' Allow-Origin:', reply.getHeader('Access-Control-Allow-Origin')) console.log(' Allow-Methods:', reply.getHeader('Access-Control-Allow-Methods')) done() }) ``` -------------------------------- ### Preflight Request with Custom Headers Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/endpoints.md Demonstrates a preflight request including custom headers and the corresponding response when these headers are allowed. ```http OPTIONS /api/users HTTP/1.1 Host: api.example.com Origin: https://example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type, Authorization ``` ```http HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET, HEAD, POST Access-Control-Allow-Headers: Content-Type, Authorization Content-Length: 0 ``` -------------------------------- ### Preflight Request with Credentials Enabled Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/endpoints.md Illustrates a preflight request where credentials are required, and the response includes Access-Control-Allow-Credentials: true. ```http OPTIONS /api/users HTTP/1.1 Host: api.example.com Origin: https://example.com Access-Control-Request-Method: POST ``` ```http HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET, HEAD, POST Access-Control-Allow-Credentials: true Content-Length: 0 ``` -------------------------------- ### Support Credentials and Reflect Origin Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/START_HERE.md Enable support for credentials (like cookies and HTTP authentication) and configure the plugin to reflect the requesting origin. This is often used in conjunction with `origin: true`. ```javascript await fastify.register(cors, { origin: true, // Reflect origin credentials: true }) ``` -------------------------------- ### OPTIONS * Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/endpoints.md Handles CORS preflight requests for all paths. This is a catch-all route automatically registered by the fastify-cors plugin to comply with the CORS specification. ```APIDOC ## OPTIONS * ### Description Handles CORS preflight requests for all paths. This is a catch-all route automatically registered by the fastify-cors plugin to comply with the CORS specification. ### Method OPTIONS ### Endpoint * ### Parameters #### Request Headers - **Origin** (string) - Required if `strictPreflight: true` - The origin of the request. - **Access-Control-Request-Method** (string) - Required if `strictPreflight: true` - The HTTP method of the actual request. - **Access-Control-Request-Headers** (string) - Optional - A list of headers the client wants to send in the actual request. ### Request Example None (request body is ignored) ### Response #### Success Response (204 No Content or 200 OK) - **Access-Control-Allow-Origin** (string) - The allowed origin. - **Access-Control-Allow-Methods** (string) - Comma-separated list of allowed HTTP methods. - **Access-Control-Allow-Headers** (string) - Comma-separated list of allowed headers. - **Access-Control-Max-Age** (integer) - Maximum cache age in seconds. - **Access-Control-Allow-Credentials** (string) - `true` if credentials are allowed. - **Cache-Control** (string) - Cache control directives. - **Vary** (string) - Header names for caching. - **Content-Length** (string) - `0` #### Error Response (400 Bad Request) - **Body**: `Invalid Preflight Request` (text/plain) #### Error Response (404 Not Found) - This response occurs if the `preflight` option is set to `false`. ``` -------------------------------- ### Allow Any Origin (Wildcard) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Use '*' to allow any origin. Not recommended for production environments. ```javascript origin: '*' ``` -------------------------------- ### Disable Strict Preflight in Fastify CORS Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/errors.md This example shows how to disable the `strictPreflight` option in Fastify CORS. This is generally not recommended as it bypasses essential security checks for preflight requests. ```javascript await fastify.register(cors, { strictPreflight: false }) ``` -------------------------------- ### Configure Exposed Headers (Array) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Specify response headers to be exposed to the client as an array of strings. ```javascript exposedHeaders: ['X-Total-Count', 'X-Page-Number'] ``` -------------------------------- ### Wrapper for Plugin Registration with Delegator Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md This snippet demonstrates how to use `FastifyPluginOptionsDelegate` to wrap a delegator function, allowing access to the Fastify instance during its creation. ```javascript fastify.register(cors, (instance) => { // Can access instance here return (req, callback) => { // Return CORS options } }) ``` -------------------------------- ### Configure Cache Control (String) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Apply cache control directives as a raw string for full control. ```javascript cacheControl: 'max-age=86400, must-revalidate' ``` -------------------------------- ### Configure Exposed Headers (String) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Specify response headers to be exposed to the client as a comma-separated string. ```javascript exposedHeaders: 'X-Total-Count,X-Page-Number' ``` -------------------------------- ### Custom CORS Hook Placement Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/fastify-cors-plugin.md Shows how to specify a custom lifecycle hook for CORS handling, such as 'preHandler'. ```javascript import Fastify from 'fastify' import cors from '@fastify/cors' const fastify = Fastify() await fastify.register(cors, { hook: 'preHandler', origin: 'https://example.com' }) fastify.get('/', (req, reply) => { reply.send({ hello: 'world' }) }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Preflight Caching Configuration for CORS Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Configures CORS with methods and a maxAge for preflight requests. This allows browsers to cache the preflight response for a specified duration (24 hours in this example), reducing redundant requests. ```javascript await fastify.register(cors, { origin: '*', methods: ['GET', 'POST', 'PUT', 'DELETE'], maxAge: 86400 // Cache preflight for 24 hours }) // Preflight response includes: // Access-Control-Max-Age: 86400 // // Browsers cache this and won't send preflight again for 24 hours ``` -------------------------------- ### Catching Invalid CORS Preflight Errors Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/errors.md This Fastify hook example demonstrates how to intercept and log errors specifically related to invalid CORS preflight requests by checking the status code and content type of the response. ```javascript fastify.addHook('onError', (req, reply, err) => { if (reply.statusCode === 400 && reply.getHeader('content-type') === 'text/plain') { console.error('Invalid CORS preflight:', err.message) } }) ``` -------------------------------- ### Origin Function with Fastify Context Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Demonstrates how to access the Fastify instance within an origin validation function using `this`. This allows access to Fastify configuration like its version. ```javascript origin: function(origin, callback) { console.log(this.version) // Access Fastify instance callback(null, true) } ``` -------------------------------- ### Usage Example for Add Fieldname to Vary Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/vary-header-utilities.md Demonstrates how to use the `createAddFieldnameToVary` function within a Fastify application. It sets up a hook to add the 'Origin' field to the Vary header whenever a request includes an 'Origin' header, ensuring proper caching for CORS requests. ```javascript const { createAddFieldnameToVary } = require('./vary') const addOriginToVary = createAddFieldnameToVary('Origin') fastify.addHook('onSend', (req, reply, payload, done) => { if (req.headers.origin) { addOriginToVary(reply) } done() }) ``` -------------------------------- ### Configure Allowed Headers (Null/Omitted) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md When 'allowedHeaders' is null or omitted, the plugin echoes back headers from 'Access-Control-Request-Headers'. ```javascript allowedHeaders: null // or omitted ``` -------------------------------- ### Control OPTIONS Route Logging Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Configure the logging level for the internal OPTIONS `*` route using `logLevel`. Options include 'silent' to suppress logs, 'debug' for full logging, or 'info' to inherit from Fastify. ```javascript logLevel: 'silent' // Suppress preflight request logs ``` ```javascript logLevel: 'debug' // Full debug logging for preflight ``` ```javascript logLevel: 'info' // Default: inherit from Fastify ``` -------------------------------- ### Asynchronous CORS Configuration with Delegator Source: https://github.com/fastify/fastify-cors/blob/main/README.md Illustrates how to configure CORS asynchronously by providing a `delegator` function. This function allows for dynamic CORS option determination based on request properties, such as disabling CORS for localhost origins. ```javascript const fastify = require('fastify')() fastify.register(require('@fastify/cors'), { hook: 'preHandler', delegator: (req, callback) => { const corsOptions = { // This is NOT recommended for production as it enables reflection exploits origin: true }; // do not include CORS headers for requests from localhost if (/^localhost$/m.test(req.headers.origin)) { corsOptions.origin = false } // callback expects two parameters: error and options callback(null, corsOptions) }, }) fastify.register(async function (fastify) { fastify.get('/', (req, reply) => { reply.send({ hello: 'world' }) }) }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Correct Wildcard Origin with Credentials Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md When using credentials, avoid setting `origin` to '*'. Instead, set `origin: true` to reflect the request origin, preventing security errors. ```javascript await fastify.register(cors, { origin: true, // Reflects request origin credentials: true }) ``` -------------------------------- ### Legacy Browser Support CORS Configuration Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/TECHNICAL_REFERENCE_INDEX.md This configuration includes `optionsSuccessStatus` to ensure compatibility with legacy browsers like IE11 and some SmartTVs, while disabling `preflightContinue`. ```javascript await fastify.register(cors, { origin: '*', optionsSuccessStatus: 200, // IE11, SmartTVs use 200 preflightContinue: false }) ``` -------------------------------- ### FastifyCorsOptionsDelegateCallback Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Callback-based asynchronous delegation for resolving CORS options. This function takes the request object and a callback to return the CORS options or an error. ```APIDOC ## FastifyCorsOptionsDelegateCallback ### Description Callback-based async delegation for resolving CORS options. ### Type Definition ```typescript interface FastifyCorsOptionsDelegateCallback { (req: FastifyRequest, cb: (error: Error | null, corsOptions?: FastifyCorsOptions) => void): void } ``` ### Parameters #### Callback Parameters - **req** (FastifyRequest) - The incoming request object with headers and route information - **cb** ((error: Error | null, corsOptions?: FastifyCorsOptions) => void) - Callback to invoke with resolved options or error ### Example ```javascript fastify.register(cors, (instance) => { return (req, callback) => { const options = { origin: true } if (req.headers.origin === 'http://localhost:3000') { options.origin = false } callback(null, options) } }) ``` ``` -------------------------------- ### Preflight on Disabled Origin Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/endpoints.md Demonstrates a preflight request from an origin not in the allowlist, resulting in a 404 Not Found response. ```http OPTIONS /api/users HTTP/1.1 Host: api.example.com Origin: https://attacker.com Access-Control-Request-Method: POST ``` ```http HTTP/1.1 404 Not Found ``` -------------------------------- ### Configure Cache Control (Integer) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Set cache control duration in seconds, automatically formatted as 'max-age'. ```javascript cacheControl: 3600 ``` -------------------------------- ### Configure Max Age for Preflight Caching Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Set the `maxAge` option to control how long browsers cache preflight responses. Recommended values are 600 seconds for development and 86400 seconds for production. ```javascript maxAge: 86400 // Cache for 24 hours (in seconds) ``` -------------------------------- ### Register Fastify CORS with Defaults Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/START_HERE.md Use this to register the CORS plugin with its default configuration. No specific imports are shown, assuming `fastify` and `cors` are available. ```bash await fastify.register(cors) ``` -------------------------------- ### Configure Allowed Headers (String) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Specify allowed request headers as a comma-separated string. If omitted or null, it reflects the request's 'Access-Control-Request-Headers'. ```javascript allowedHeaders: 'Content-Type,Authorization' ``` -------------------------------- ### FastifyPluginOptionsDelegate Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md A wrapper type for use in the plugin registration syntax, allowing a delegator function to be returned after receiving the Fastify instance. ```APIDOC ## FastifyPluginOptionsDelegate ### Description For use in the plugin registration syntax where a delegator is wrapped. ### Type Definition ```typescript type FastifyPluginOptionsDelegate = (instance: FastifyInstance) => T ``` ### Usage Allows passing a function that receives the Fastify instance and returns a delegator: ```javascript fastify.register(cors, (instance) => { // Can access instance here return (req, callback) => { // Return CORS options } }) ``` ``` -------------------------------- ### resolveOriginWrapper Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Wraps user-provided origin functions to seamlessly handle both asynchronous (Promise-based) and synchronous (callback-based) implementations, ensuring consistent behavior. ```APIDOC ## resolveOriginWrapper ### Description Wraps user-provided origin functions to handle both callbacks and promises. ### Function Signature ```typescript function resolveOriginWrapper( fastify: FastifyInstance, origin: OriginFunction | AsyncOriginFunction ): (req: FastifyRequest, cb: OriginCallback) => void ``` ### Parameters - **fastify** (FastifyInstance) - Fastify instance bound to the origin function's `this` context - **origin** (OriginFunction | AsyncOriginFunction) - User-provided origin validation function ### Return Value A function with signature `(req: FastifyRequest, cb: OriginCallback) => void` ### Behavior 1. Calls the user's origin function with `fastify` bound as `this` 2. Passes request origin as first argument 3. Provides a callback for callback-based functions 4. **Promise Detection:** If function returns a Promise (`.then` property exists): - Waits for promise resolution - On resolve: calls callback with resolved value - On reject: calls callback with error 5. **Callback Functions:** If function doesn't return a Promise, assumes callback-based (2-param functions) ### Example ```javascript // Handles both callback and promise functions const wrapper = resolveOriginWrapper(fastify, async (origin) => { return await validateOrigin(origin) }) wrapper(req, (err, result) => { // Both callback and promise forms work }) ``` ``` -------------------------------- ### Configure Allowed Headers (Array) Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Specify allowed request headers as an array of strings. If omitted or null, it reflects the request's 'Access-Control-Request-Headers'. ```javascript allowedHeaders: ['Content-Type', 'Authorization'] ``` -------------------------------- ### Register Fastify CORS with Credentials Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/START_HERE.md Enable support for credentials (like cookies or HTTP authentication headers) in cross-origin requests. Requires `origin` to be `true` or a specific origin. ```bash await fastify.register(cors, { origin: true, credentials: true }) ``` -------------------------------- ### handleCorsOptionsDelegator Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Sets up a delegator-based CORS configuration system by validating hooks, detecting the delegator type (callback or promise-based), and attaching the appropriate hook with payload handling. ```APIDOC ## handleCorsOptionsDelegator ### Description Sets up a delegator-based CORS configuration system. ### Function Signature ```typescript function handleCorsOptionsDelegator( optionsResolver: Function, fastify: FastifyInstance, opts: Partial, next: Function ): void ``` ### Behavior 1. **Hook Validation:** Validates the hook option 2. **Delegator Type Detection:** Checks function arity (number of parameters): - 2 parameters: Callback-based delegator → uses `handleCorsOptionsCallbackDelegator` - 1 parameter: Promise-based delegator → expects Promise return 3. **Hook Attachment:** Attaches hook with payload handling based on hook type ### Supported Delegator Arities - **2 parameters:** Callback signature `(req, callback) => void` - **1 parameter:** Promise signature `(req) => Promise` ``` -------------------------------- ### Register Fastify CORS Plugin Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/START_HERE.md Basic registration of the Fastify CORS plugin. Ensure Fastify and the CORS plugin are imported. ```javascript import Fastify from 'fastify' import cors from '@fastify/cors' const fastify = Fastify() await fastify.register(cors) ``` -------------------------------- ### Register Fastify CORS with Direct Options Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Use this snippet to register the Fastify CORS plugin with direct configuration options for origin and credentials. ```typescript // Direct options await fastify.register(cors, { origin: 'https://example.com', credentials: true }) ``` -------------------------------- ### Dynamic CORS Configuration with Caching Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Implements dynamic CORS configuration using a promise-based delegator with caching. It utilizes NodeCache to store validated origin configurations for a specified TTL (1 hour), improving performance by avoiding repeated expensive validation calls. ```javascript import NodeCache from 'node-cache' const cache = new NodeCache({ stdTTL: 3600 }) // 1 hour fastify.register(cors, { delegator: async (req) => { const origin = req.headers.origin // Check cache first const cached = cache.get(origin) if (cached !== undefined) { return cached } // Expensive operation const result = await validateOriginAgainstAuthService(origin) // Store in cache cache.set(origin, result) return result } }) ``` -------------------------------- ### Register CORS Plugin with Static Configuration Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/TECHNICAL_REFERENCE_INDEX.md Register the CORS plugin with static configuration for allowing all origins. ```javascript await fastify.register(cors, { origin: '*' }) ``` -------------------------------- ### Async Configuration: Callback-Based Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Dynamically resolve CORS options per request using a callback function. This function receives the request object and should call back with either an error or the CORS options. ```javascript fastify.register(cors, (instance) => { return (req, callback) => { // Query database, fetch config, etc. const options = { origin: isOriginAllowed(req.headers.origin) ? req.headers.origin : false } callback(null, options) } }) ``` -------------------------------- ### Fastify CORS Project Directory Structure Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/INDEX.md This snippet displays the directory structure of the Fastify CORS project, indicating the purpose of each file and directory. ```text /workspace/home/output/ ├── INDEX.md ← You are here ├── START_HERE.md ✓ Quick start ├── README.md Project overview ├── TECHNICAL_REFERENCE_INDEX.md ✓ Navigation hub ├── MANIFEST.md ✓ Complete index ├── PRACTICAL_EXAMPLES.md ✓ 80+ examples ├── configuration.md ✓ 15 options ├── types.md ✓ 8 types ├── endpoints.md ✓ HTTP details ├── errors.md ✓ Error ref ├── COMPLETION_REPORT.md QA report └── api-reference/ ├── fastify-cors-plugin.md ✓ Plugin API ├── vary-header-utilities.md ✓ Utilities └── internal-functions.md ✓ Architecture ``` -------------------------------- ### Register Fastify CORS with Async Configuration Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/START_HERE.md Use an asynchronous function to dynamically determine CORS options, such as the allowed origin, based on the incoming request. This provides flexibility for complex scenarios. ```bash await fastify.register(cors, { delegator: async (req) => {...} }) ``` -------------------------------- ### Dynamic Database-Driven CORS Configuration Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/configuration.md Configure CORS dynamically by fetching client-specific settings from a database. This allows for granular control over origins, credentials, methods, and caching based on the client's domain. ```javascript await fastify.register(cors, { delegator: async (req) => { const client = req.headers.origin.split('://')[1] const config = await database.query('SELECT * FROM cors_clients WHERE domain = ?', [client]) return { origin: config ? req.headers.origin : false, credentials: config?.allow_credentials || false, methods: config?.allowed_methods?.split(',') || ['GET', 'POST'], maxAge: config?.cache_age || 3600 } } }) ``` -------------------------------- ### Preflight Pass-Through to Handler for Customization Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Enables preflight requests to reach the application handlers by setting 'preflightContinue' to true. This allows for custom preflight response handling, such as adding custom headers. ```javascript await fastify.register(cors, { origin: '*', preflightContinue: true // Let OPTIONS requests reach handlers }) fastify.options('*', (req, reply) => { // Custom preflight handling reply.header('X-Custom-Preflight', 'true') reply.send() }) // Now your handler can customize preflight responses ``` -------------------------------- ### CORS Configuration for Legacy Browser Support Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Configures CORS to support legacy browsers like IE11 and some SmartTVs by returning a 200 status code for preflight requests instead of the default 204 No Content. ```javascript await fastify.register(cors, { origin: '*', optionsSuccessStatus: 200 // IE11, some SmartTVs expect 200 }) // IE11 preflight response will be: // HTTP/1.1 200 OK (instead of 204 No Content) ``` -------------------------------- ### Register Fastify CORS with Delegator Promise Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/types.md Configure Fastify CORS using a delegator function that returns a promise to asynchronously determine CORS options. ```typescript // Delegator promise await fastify.register(cors, { delegator: async (req) => { return { origin: true } } }) ``` -------------------------------- ### Handling Strict Mode Preflight Requests Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md If strict preflight requests are causing issues, ensure the client sends proper preflight headers or update the client library. Avoid disabling `strictPreflight` globally due to security risks. ```javascript // Send proper preflight headers from client // OR update browser/client library to send required headers ``` -------------------------------- ### Default CORS Options Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Provides the default configuration values used by the fastify-cors plugin when specific options are not provided by the user. ```javascript { origin: '*', methods: 'GET,HEAD,POST', hook: 'onRequest', preflightContinue: false, optionsSuccessStatus: 204, credentials: false, exposedHeaders: null, allowedHeaders: null, maxAge: null, preflight: true, strictPreflight: true } ``` -------------------------------- ### Configure CORS with Specific Origin and Credentials Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Use this when you need to allow requests from a specific origin and require credentials (like cookies) to be sent. The origin must be explicitly defined, not a wildcard. ```javascript await fastify.register(cors, { origin: 'https://app.example.com', // MUST be specific, not '*' credentials: true }) fastify.get('/user', (req, reply) => { // Browser will now send cookies with this request const userId = req.cookies.userId reply.send({ userId }) }) ``` -------------------------------- ### Promise-Based Delegator for Dynamic CORS Configuration with Database Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Dynamically configures CORS using a promise-based delegator that fetches origin configurations from a SQLite database. It handles origin validation, method enforcement, credential settings, and max age based on database records. ```javascript import Database from 'better-sqlite3' const db = new Database('cors.db') db.exec(` CREATE TABLE IF NOT EXISTS cors_clients ( id INTEGER PRIMARY KEY, domain TEXT UNIQUE, methods TEXT, credentials INTEGER, max_age INTEGER ) `) fastify.register(cors, { delegator: async (req) => { const origin = req.headers.origin if (!origin) { return { origin: false } } try { const url = new URL(origin) const domain = url.hostname const row = db.prepare( 'SELECT * FROM cors_clients WHERE domain = ?' ).get(domain) if (!row) { return { origin: false } } return { origin: origin, methods: row.methods.split(','), credentials: Boolean(row.credentials), maxAge: row.max_age } } catch (err) { fastify.log.error(err) return { origin: false } } } }) ``` -------------------------------- ### Database-Driven CORS Allowlist with Redis Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/PRACTICAL_EXAMPLES.md Implement a dynamic CORS allowlist by checking a Redis cache. The 'delegator' function checks if an origin is allowed based on a Redis key, returning specific CORS options or denying access. ```javascript import redis from 'redis' const redisClient = redis.createClient() await fastify.register(cors, { delegator: async (req) => { const origin = req.headers.origin if (!origin) { return { origin: false } } try { // Check Redis for allowlist const allowed = await redisClient.getEx( `cors:allowed:${origin}`, { EX: 3600 } ) return { origin: allowed === 'true' ? origin : false, credentials: true, maxAge: 86400 } } catch (err) { fastify.log.error(err) return { origin: false } // Deny on error } } }) ``` -------------------------------- ### Callback-Based Async CORS Configuration Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/fastify-cors-plugin.md Configures CORS options dynamically using a callback function that inspects the request origin. ```javascript const fastify = require('fastify')() fastify.register(require('@fastify/cors'), (instance) => { return (req, callback) => { const corsOptions = { origin: true } if (/^localhost$/m.test(req.headers.origin)) { corsOptions.origin = false } callback(null, corsOptions) } }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Route-Level CORS Overrides Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/fastify-cors-plugin.md Demonstrates how to override global CORS settings for specific routes, including enabling all origins or disabling CORS. ```javascript const fastify = require('fastify')() fastify.register(require('@fastify/cors'), { origin: 'https://example.com' }) fastify.get('/cors-enabled', (_req, reply) => { reply.send('CORS enabled') }) fastify.get('/cors-allow-all', { config: { cors: { origin: '*' } } }, (_req, reply) => { reply.send('All origins allowed') }) fastify.get('/cors-disabled', { config: { cors: false } }, (_req, reply) => { reply.send('CORS disabled') }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Preflight Request with Caching Enabled Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/endpoints.md Shows a preflight request configured for caching, including max-age and Cache-Control headers in the response. ```http OPTIONS /api/users HTTP/1.1 Host: api.example.com Origin: https://example.com Access-Control-Request-Method: POST ``` ```http HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET, HEAD, POST Access-Control-Max-Age: 86400 Cache-Control: max-age=86400, public Content-Length: 0 ``` -------------------------------- ### Exact String Match for Allowed Origin Source: https://github.com/fastify/fastify-cors/blob/main/_autodocs/api-reference/internal-functions.md Compares the request origin directly against a single string rule for exact matching. ```javascript return reqOrigin === allowedOrigin ```