Socket
Socket
Sign inDemoInstall

@fastify/cors

Package Overview
Dependencies
Maintainers
20
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fastify/cors - npm Package Compare versions

Comparing version 10.0.0-pre.fv5.2 to 10.0.0

13

package.json
{
"name": "@fastify/cors",
"version": "10.0.0-pre.fv5.2",
"version": "10.0.0",
"description": "Fastify CORS",

@@ -9,3 +9,2 @@ "main": "index.js",

"scripts": {
"coverage": "tap --coverage-report=html test",
"lint": "standard",

@@ -15,3 +14,3 @@ "lint:fix": "standard --fix",

"test:typescript": "tsd",
"test:unit": "tap test/*.test.js"
"test:unit": "c8 --100 node --test"
},

@@ -40,6 +39,6 @@ "keywords": [

"@typescript-eslint/parser": "^7.3.1",
"c8": "^10.1.2",
"cors": "^2.8.5",
"fastify": "^5.0.0-alpha.3",
"fastify": "^5.0.0-alpha.4",
"standard": "^17.1.0",
"tap": "18.7.1",
"tsd": "^0.31.1",

@@ -49,3 +48,3 @@ "typescript": "^5.4.2"

"dependencies": {
"fastify-plugin": "^5.0.0-pre.fv5.1",
"fastify-plugin": "^5.0.0",
"mnemonist": "0.39.8"

@@ -63,2 +62,2 @@ },

]
}
}
'use strict'
const { test } = require('tap')
const { test } = require('node:test')
const { createReadStream, statSync, readFileSync } = require('node:fs')

@@ -8,4 +8,5 @@ const Fastify = require('fastify')

const { resolve } = require('node:path')
const { setTimeout: sleep } = require('node:timers/promises')
test('Should add cors headers', t => {
test('Should add cors headers', async t => {
t.plan(4)

@@ -20,17 +21,17 @@

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': '*'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.deepStrictEqual(res.headers['access-control-allow-origin'],
'*'
)
})
test('Should add cors headers when payload is a stream', t => {
test('Should add cors headers when payload is a stream', async t => {
t.plan(4)

@@ -52,18 +53,22 @@

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, fileContent)
t.match(res.headers, {
'access-control-allow-origin': '*',
'content-length': statSync(filePath).size
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, fileContent)
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'content-length': statSync(filePath).size.toString()
})
})
test('Should add cors headers (custom values)', t => {
test('Should add cors headers (custom values)', async t => {
t.plan(10)

@@ -86,3 +91,3 @@

fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',

@@ -94,39 +99,53 @@ url: '/',

}
}, (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': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, woo',
'access-control-max-age': '123',
'cache-control': 'max-age=321',
'content-length': '0'
})
t.notMatch(res.headers, { vary: 'Origin' })
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
'access-control-allow-headers': res.headers['access-control-allow-headers'],
'access-control-max-age': res.headers['access-control-max-age'],
'cache-control': res.headers['cache-control'],
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, woo',
'access-control-max-age': '123',
'cache-control': 'max-age=321',
'content-length': '0'
})
t.assert.notDeepEqual(res.headers, { vary: 'Origin' })
fastify.inject({
res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2'
})
t.notMatch(res.headers, { vary: 'Origin' })
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders2 = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders2, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2'
})
t.assert.notDeepEqual(res.headers, { vary: 'Origin' })
})
test('Should support dynamic config (callback)', t => {
test('Should support dynamic config (callback)', async t => {
t.plan(16)

@@ -154,7 +173,8 @@

let requestId = 0
const configDelegation = function (req, cb) {
const configDelegation = async function (req, cb) {
// request should have id
t.ok(req.id)
t.assert.ok(req.id)
// request should not have send
t.notOk(req.send)
t.assert.ifError(req.send)
const config = configs[requestId]

@@ -168,3 +188,3 @@ requestId++

}
fastify.register(cors, () => configDelegation)
await fastify.register(cors, () => configDelegation)

@@ -175,20 +195,28 @@ fastify.get('/', (req, reply) => {

fastify.inject({
let res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
// Sleep to wait for callback
sleep()
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2',
vary: 'Origin'
})
fastify.inject({
res = await fastify.inject({
method: 'OPTIONS',

@@ -200,21 +228,33 @@ url: '/',

}
}, (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': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'cache-control': '456',
'content-length': '0',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders2 = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
'access-control-allow-headers': res.headers['access-control-allow-headers'],
'access-control-max-age': res.headers['access-control-max-age'],
'cache-control': res.headers['cache-control'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
// Sleep to wait for callback
sleep()
t.assert.deepStrictEqual(actualHeaders2, {
'access-control-allow-origin': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'cache-control': '456',
'content-length': '0',
vary: 'Origin'
})
fastify.inject({
res = await fastify.inject({
method: 'GET',

@@ -226,9 +266,8 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Should support dynamic config (Promise)', t => {
test('Should support dynamic config (Promise)', async t => {
t.plan(23)

@@ -264,7 +303,7 @@

let requestId = 0
const configDelegation = function (req) {
const configDelegation = async function (req) {
// request should have id
t.ok(req.id)
t.assert.ok(req.id)
// request should not have send
t.notOk(req.send)
t.assert.ifError(req.send)
const config = configs[requestId]

@@ -278,3 +317,3 @@ requestId++

}
fastify.register(cors, () => configDelegation)
await fastify.register(cors, () => configDelegation)

@@ -285,20 +324,26 @@ fastify.get('/', (req, reply) => {

fastify.inject({
let res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2',
vary: 'Origin'
})
fastify.inject({
res = await fastify.inject({
method: 'OPTIONS',

@@ -310,21 +355,30 @@ url: '/',

}
}, (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': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0',
vary: 'Origin'
})
t.equal(res.headers['cache-control'], undefined, 'cache-control omitted (invalid value)')
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const acutalHeaders2 = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
'access-control-allow-headers': res.headers['access-control-allow-headers'],
'access-control-max-age': res.headers['access-control-max-age'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(acutalHeaders2, {
'access-control-allow-origin': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0',
vary: 'Origin'
})
t.assert.strictEqual(res.headers['cache-control'], undefined, 'cache-control omitted (invalid value)')
fastify.inject({
res = await fastify.inject({
method: 'OPTIONS',

@@ -336,21 +390,31 @@ url: '/',

}
}, (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': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'cache-control': 'public, max-age=456', // cache-control included (custom string)
'content-length': '0',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders3 = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
'access-control-allow-headers': res.headers['access-control-allow-headers'],
'access-control-max-age': res.headers['access-control-max-age'],
'cache-control': res.headers['cache-control'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders3, {
'access-control-allow-origin': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'cache-control': 'public, max-age=456', // cache-control included (custom string)
'content-length': '0',
vary: 'Origin'
})
fastify.inject({
res = await fastify.inject({
method: 'GET',

@@ -362,9 +426,8 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Should support dynamic config. (Invalid function)', t => {
test('Should support dynamic config. (Invalid function)', async t => {
t.plan(2)

@@ -379,3 +442,3 @@

fastify.inject({
const res = await fastify.inject({
method: 'GET',

@@ -387,9 +450,8 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Dynamic origin resolution (valid origin)', t => {
test('Dynamic origin resolution (valid origin)', async t => {
t.plan(6)

@@ -399,4 +461,4 @@

const origin = function (header, cb) {
t.equal(header, 'example.com')
t.same(this, fastify)
t.assert.strictEqual(header, 'example.com')
t.assert.equal(this, fastify)
cb(null, true)

@@ -410,19 +472,22 @@ }

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'example.com',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'example.com',
vary: 'Origin'
})
})
test('Dynamic origin resolution (not valid origin)', t => {
test('Dynamic origin resolution (not valid origin)', async t => {
t.plan(5)

@@ -432,3 +497,3 @@

const origin = (header, cb) => {
t.equal(header, 'example.com')
t.assert.strictEqual(header, 'example.com')
cb(null, false)

@@ -442,21 +507,26 @@ }

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.same(res.headers, {
'content-length': '2',
'content-type': 'text/plain; charset=utf-8',
connection: 'keep-alive',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'content-length': res.headers['content-length'],
'content-type': res.headers['content-type'],
connection: res.headers.connection,
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'content-length': '2',
'content-type': 'text/plain; charset=utf-8',
connection: 'keep-alive',
vary: 'Origin'
})
})
test('Dynamic origin resolution (errored)', t => {
test('Dynamic origin resolution (errored)', async t => {
t.plan(3)

@@ -466,3 +536,3 @@

const origin = (header, cb) => {
t.equal(header, 'example.com')
t.assert.strictEqual(header, 'example.com')
cb(new Error('ouch'))

@@ -472,13 +542,12 @@ }

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Dynamic origin resolution (invalid result)', t => {
test('Dynamic origin resolution (invalid result)', async t => {
t.plan(3)

@@ -488,3 +557,3 @@

const origin = (header, cb) => {
t.equal(header, 'example.com')
t.assert.strictEqual(header, 'example.com')
cb(null, undefined)

@@ -494,13 +563,12 @@ }

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Dynamic origin resolution (valid origin - promises)', t => {
test('Dynamic origin resolution (valid origin - promises)', async t => {
t.plan(5)

@@ -511,3 +579,3 @@

return new Promise((resolve, reject) => {
t.equal(header, 'example.com')
t.assert.strictEqual(header, 'example.com')
resolve(true)

@@ -522,19 +590,22 @@ })

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'example.com',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'example.com',
vary: 'Origin'
})
})
test('Dynamic origin resolution (not valid origin - promises)', t => {
test('Dynamic origin resolution (not valid origin - promises)', async t => {
t.plan(5)

@@ -545,3 +616,3 @@

return new Promise((resolve, reject) => {
t.equal(header, 'example.com')
t.assert.strictEqual(header, 'example.com')
resolve(false)

@@ -556,21 +627,26 @@ })

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.same(res.headers, {
'content-length': '2',
'content-type': 'text/plain; charset=utf-8',
connection: 'keep-alive',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'content-length': res.headers['content-length'],
'content-type': res.headers['content-type'],
connection: res.headers.connection,
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'content-length': '2',
'content-type': 'text/plain; charset=utf-8',
connection: 'keep-alive',
vary: 'Origin'
})
})
test('Dynamic origin resolution (errored - promises)', t => {
test('Dynamic origin resolution (errored - promises)', async t => {
t.plan(3)

@@ -581,3 +657,3 @@

return new Promise((resolve, reject) => {
t.equal(header, 'example.com')
t.assert.strictEqual(header, 'example.com')
reject(new Error('ouch'))

@@ -588,13 +664,12 @@ })

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Should reply 404 without cors headers when origin is false', t => {
test('Should reply 404 without cors headers when origin is false', async t => {
t.plan(8)

@@ -616,34 +691,37 @@

fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 404)
t.equal(res.payload, '{"message":"Route OPTIONS:/ not found","error":"Not Found","statusCode":404}')
t.same(res.headers, {
'content-length': '76',
'content-type': 'application/json; charset=utf-8',
connection: 'keep-alive'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 404)
t.assert.strictEqual(res.payload, '{"message":"Route OPTIONS:/ not found","error":"Not Found","statusCode":404}')
const actualHeaders = {
'content-length': res.headers['content-length'],
'content-type': res.headers['content-type'],
connection: res.headers.connection
}
t.assert.deepStrictEqual(actualHeaders, {
'content-length': '76',
'content-type': 'application/json; charset=utf-8',
connection: 'keep-alive'
})
fastify.inject({
res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.same(res.headers, {
'content-length': '2',
'content-type': 'text/plain; charset=utf-8',
connection: 'keep-alive'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.deepStrictEqual(res.headers, {
'content-length': '2',
'content-type': 'text/plain; charset=utf-8',
connection: 'keep-alive'
})
})
test('Server error if origin option is falsy but not false', t => {
test('Server error if origin option is falsy but not false', async t => {
t.plan(4)

@@ -654,20 +732,24 @@

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 500)
t.same(res.json(), { statusCode: 500, error: 'Internal Server Error', message: 'Invalid CORS origin option' })
t.same(res.headers, {
'content-length': '89',
'content-type': 'application/json; charset=utf-8',
connection: 'keep-alive'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 500)
t.assert.deepStrictEqual(res.json(), { statusCode: 500, error: 'Internal Server Error', message: 'Invalid CORS origin option' })
const actualHeaders = {
'content-length': res.headers['content-length'],
'content-type': res.headers['content-type'],
connection: res.headers.connection
}
t.assert.deepStrictEqual(actualHeaders, {
'content-length': '89',
'content-type': 'application/json; charset=utf-8',
connection: 'keep-alive'
})
})
test('Allow only request from a specific origin', t => {
test('Allow only request from a specific origin', async t => {
t.plan(5)

@@ -682,19 +764,18 @@

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'example.com' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'other.io'
})
t.notMatch(res.headers, { vary: 'Origin' })
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.deepStrictEqual(res.headers['access-control-allow-origin'],
'other.io'
)
t.assert.notDeepEqual(res.headers, { vary: 'Origin' })
})
test('Allow only request from multiple specific origin', t => {
test('Allow only request from multiple specific origin', async t => {
t.plan(9)

@@ -709,34 +790,36 @@

fastify.inject({
let res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'other.io' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'other.io',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'other.io',
vary: 'Origin'
})
fastify.inject({
res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'foo.com' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
vary: 'Origin'
})
t.equal(res.headers['access-control-allow-origin'], undefined)
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.deepStrictEqual(res.headers.vary,
'Origin'
)
t.assert.strictEqual(res.headers['access-control-allow-origin'], undefined)
})
test('Allow only request from a specific origin using regex', t => {
test('Allow only request from a specific origin using regex', async t => {
t.plan(8)

@@ -755,20 +838,23 @@

for (let i = 0; i < 2; i++) {
fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/',
headers: { origin: 'https://www.example.com/' }
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'https://www.example.com/',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'https://www.example.com/',
vary: 'Origin'
})
}
})
test('Disable preflight', t => {
test('Disable preflight', async t => {
t.plan(7)

@@ -783,29 +869,27 @@

fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',
url: '/hello'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 404)
t.match(res.headers, {
'access-control-allow-origin': '*'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 404)
t.assert.strictEqual(res.headers['access-control-allow-origin'],
'*'
)
fastify.inject({
res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': '*'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.strictEqual(res.headers['access-control-allow-origin'],
'*'
)
})
test('Should always add vary header to `Origin` for reflected origin', t => {
test('Should always add vary header to `Origin` for reflected origin', async t => {
t.plan(12)

@@ -821,17 +905,16 @@

// Invalid Preflight
fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 400)
t.equal(res.payload, 'Invalid Preflight Request')
t.match(res.headers, {
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 400)
t.assert.strictEqual(res.payload, 'Invalid Preflight Request')
t.assert.strictEqual(res.headers.vary,
'Origin'
)
// Valid Preflight
fastify.inject({
res = await fastify.inject({
method: 'OPTIONS',

@@ -843,28 +926,26 @@ url: '/',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 204)
t.equal(res.payload, '')
t.match(res.headers, {
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
t.assert.strictEqual(res.headers.vary,
'Origin, Access-Control-Request-Headers'
)
// Other Route
fastify.inject({
res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.strictEqual(res.headers.vary,
'Origin'
)
})
test('Should always add vary header to `Origin` for reflected origin (vary is array)', t => {
test('Should always add vary header to `Origin` for reflected origin (vary is array)', async t => {
t.plan(4)

@@ -883,17 +964,16 @@

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
vary: 'foo, bar, Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.strictEqual(res.headers.vary,
'foo, bar, Origin'
)
})
test('Allow only request from with specific headers', t => {
test('Allow only request from with specific headers', async t => {
t.plan(8)

@@ -911,3 +991,3 @@

fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',

@@ -919,27 +999,25 @@ url: '/',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 204)
t.match(res.headers, {
'access-control-allow-headers': 'foo'
})
t.notMatch(res.headers, { vary: 'Origin' })
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.deepStrictEqual(res.headers['access-control-allow-headers'],
'foo'
)
t.assert.notDeepEqual(res.headers.vary, 'Origin')
fastify.inject({
res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-expose-headers': 'bar'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.strictEqual(res.headers['access-control-expose-headers'],
'bar'
)
})
test('Should support wildcard config /1', t => {
test('Should support wildcard config /1', async t => {
t.plan(4)

@@ -954,14 +1032,13 @@

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.equal(res.headers['access-control-allow-origin'], '*')
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.strictEqual(res.headers['access-control-allow-origin'], '*')
})
test('Should support wildcard config /2', t => {
test('Should support wildcard config /2', async t => {
t.plan(4)

@@ -976,11 +1053,10 @@

fastify.inject({
const res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.equal(res.headers['access-control-allow-origin'], '*')
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
t.assert.strictEqual(res.headers['access-control-allow-origin'], '*')
})
'use strict'
const { test } = require('tap')
const { test } = require('node:test')
const Fastify = require('fastify')
const kFastifyContext = require('fastify/lib/symbols').kRouteContext
const cors = require('..')
const { setTimeout: sleep } = require('node:timers/promises')
test('Should error on invalid hook option', async (t) => {
t.plan(1)
t.plan(3)
const fastify = Fastify()
t.rejects(async () => fastify.register(cors, { hook: 'invalid' }), new TypeError('@fastify/cors: Invalid hook option provided.'))
await t.assert.rejects(
async () => fastify.register(cors, { hook: 'invalid' }),
(err) => {
t.assert.strictEqual(err.name, 'TypeError')
t.assert.strictEqual(err.message, '@fastify/cors: Invalid hook option provided.')
return true
}
)
})

@@ -23,9 +31,9 @@

fastify.addHook('onResponse', (request, reply, done) => {
t.equal(request[kFastifyContext].onError, null)
t.equal(request[kFastifyContext].onRequest.length, 1)
t.equal(request[kFastifyContext].onSend, null)
t.equal(request[kFastifyContext].preHandler, null)
t.equal(request[kFastifyContext].preParsing, null)
t.equal(request[kFastifyContext].preSerialization, null)
t.equal(request[kFastifyContext].preValidation, null)
t.assert.strictEqual(request[kFastifyContext].onError, null)
t.assert.strictEqual(request[kFastifyContext].onRequest.length, 1)
t.assert.strictEqual(request[kFastifyContext].onSend, null)
t.assert.strictEqual(request[kFastifyContext].preHandler, null)
t.assert.strictEqual(request[kFastifyContext].preParsing, null)
t.assert.strictEqual(request[kFastifyContext].preSerialization, null)
t.assert.strictEqual(request[kFastifyContext].preValidation, null)
done()

@@ -45,5 +53,8 @@ })

delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeader = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeader, {
'access-control-allow-origin': '*'

@@ -63,9 +74,9 @@ })

fastify.addHook('onResponse', (request, reply, done) => {
t.equal(request[kFastifyContext].onError, null)
t.equal(request[kFastifyContext].onRequest.length, 1)
t.equal(request[kFastifyContext].onSend, null)
t.equal(request[kFastifyContext].preHandler, null)
t.equal(request[kFastifyContext].preParsing, null)
t.equal(request[kFastifyContext].preSerialization, null)
t.equal(request[kFastifyContext].preValidation, null)
t.assert.strictEqual(request[kFastifyContext].onError, null)
t.assert.strictEqual(request[kFastifyContext].onRequest.length, 1)
t.assert.strictEqual(request[kFastifyContext].onSend, null)
t.assert.strictEqual(request[kFastifyContext].preHandler, null)
t.assert.strictEqual(request[kFastifyContext].preParsing, null)
t.assert.strictEqual(request[kFastifyContext].preSerialization, null)
t.assert.strictEqual(request[kFastifyContext].preValidation, null)
done()

@@ -85,5 +96,8 @@ })

delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeader = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeader, {
'access-control-allow-origin': '*'

@@ -103,9 +117,9 @@ })

fastify.addHook('onResponse', (request, reply, done) => {
t.equal(request[kFastifyContext].onError, null)
t.equal(request[kFastifyContext].onRequest, null)
t.equal(request[kFastifyContext].onSend, null)
t.equal(request[kFastifyContext].preHandler, null)
t.equal(request[kFastifyContext].preParsing.length, 1)
t.equal(request[kFastifyContext].preSerialization, null)
t.equal(request[kFastifyContext].preValidation, null)
t.assert.strictEqual(request[kFastifyContext].onError, null)
t.assert.strictEqual(request[kFastifyContext].onRequest, null)
t.assert.strictEqual(request[kFastifyContext].onSend, null)
t.assert.strictEqual(request[kFastifyContext].preHandler, null)
t.assert.strictEqual(request[kFastifyContext].preParsing.length, 1)
t.assert.strictEqual(request[kFastifyContext].preSerialization, null)
t.assert.strictEqual(request[kFastifyContext].preValidation, null)
done()

@@ -125,8 +139,11 @@ })

delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeader = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeader, {
'access-control-allow-origin': '*'
})
t.notMatch(res.headers, { vary: 'Origin' })
t.assert.notStrictEqual(res.headers.vary, 'Origin')
})

@@ -144,9 +161,9 @@

fastify.addHook('onResponse', (request, reply, done) => {
t.equal(request[kFastifyContext].onError, null)
t.equal(request[kFastifyContext].onRequest, null)
t.equal(request[kFastifyContext].onSend, null)
t.equal(request[kFastifyContext].preHandler, null)
t.equal(request[kFastifyContext].preParsing, null)
t.equal(request[kFastifyContext].preSerialization, null)
t.equal(request[kFastifyContext].preValidation.length, 1)
t.assert.strictEqual(request[kFastifyContext].onError, null)
t.assert.strictEqual(request[kFastifyContext].onRequest, null)
t.assert.strictEqual(request[kFastifyContext].onSend, null)
t.assert.strictEqual(request[kFastifyContext].preHandler, null)
t.assert.strictEqual(request[kFastifyContext].preParsing, null)
t.assert.strictEqual(request[kFastifyContext].preSerialization, null)
t.assert.strictEqual(request[kFastifyContext].preValidation.length, 1)
done()

@@ -166,8 +183,11 @@ })

delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeader = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeader, {
'access-control-allow-origin': '*'
})
t.notMatch(res.headers, { vary: 'Origin' })
t.assert.notStrictEqual(res.headers.vary, 'Origin')
})

@@ -185,9 +205,9 @@

fastify.addHook('onResponse', (request, reply, done) => {
t.equal(request[kFastifyContext].onError, null)
t.equal(request[kFastifyContext].onRequest, null)
t.equal(request[kFastifyContext].onSend, null)
t.equal(request[kFastifyContext].preHandler, null)
t.equal(request[kFastifyContext].preParsing.length, 1)
t.equal(request[kFastifyContext].preSerialization, null)
t.equal(request[kFastifyContext].preValidation, null)
t.assert.strictEqual(request[kFastifyContext].onError, null)
t.assert.strictEqual(request[kFastifyContext].onRequest, null)
t.assert.strictEqual(request[kFastifyContext].onSend, null)
t.assert.strictEqual(request[kFastifyContext].preHandler, null)
t.assert.strictEqual(request[kFastifyContext].preParsing.length, 1)
t.assert.strictEqual(request[kFastifyContext].preSerialization, null)
t.assert.strictEqual(request[kFastifyContext].preValidation, null)
done()

@@ -207,8 +227,11 @@ })

delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeader = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeader, {
'access-control-allow-origin': '*'
})
t.notMatch(res.headers, { vary: 'Origin' })
t.assert.notStrictEqual(res.headers.vary, 'Origin')
})

@@ -226,9 +249,9 @@

fastify.addHook('onResponse', (request, reply, done) => {
t.equal(request[kFastifyContext].onError, null)
t.equal(request[kFastifyContext].onRequest, null)
t.equal(request[kFastifyContext].onSend, null)
t.equal(request[kFastifyContext].preHandler.length, 1)
t.equal(request[kFastifyContext].preParsing, null)
t.equal(request[kFastifyContext].preSerialization, null)
t.equal(request[kFastifyContext].preValidation, null)
t.assert.strictEqual(request[kFastifyContext].onError, null)
t.assert.strictEqual(request[kFastifyContext].onRequest, null)
t.assert.strictEqual(request[kFastifyContext].onSend, null)
t.assert.strictEqual(request[kFastifyContext].preHandler.length, 1)
t.assert.strictEqual(request[kFastifyContext].preParsing, null)
t.assert.strictEqual(request[kFastifyContext].preSerialization, null)
t.assert.strictEqual(request[kFastifyContext].preValidation, null)
done()

@@ -248,8 +271,11 @@ })

delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeader = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeader, {
'access-control-allow-origin': '*'
})
t.notMatch(res.headers, { vary: 'Origin' })
t.assert.notStrictEqual(res.headers.vary, 'Origin')
})

@@ -267,9 +293,9 @@

fastify.addHook('onResponse', (request, reply, done) => {
t.equal(request[kFastifyContext].onError, null)
t.equal(request[kFastifyContext].onRequest, null)
t.equal(request[kFastifyContext].onSend.length, 1)
t.equal(request[kFastifyContext].preHandler, null)
t.equal(request[kFastifyContext].preParsing, null)
t.equal(request[kFastifyContext].preSerialization, null)
t.equal(request[kFastifyContext].preValidation, null)
t.assert.strictEqual(request[kFastifyContext].onError, null)
t.assert.strictEqual(request[kFastifyContext].onRequest, null)
t.assert.strictEqual(request[kFastifyContext].onSend.length, 1)
t.assert.strictEqual(request[kFastifyContext].preHandler, null)
t.assert.strictEqual(request[kFastifyContext].preParsing, null)
t.assert.strictEqual(request[kFastifyContext].preSerialization, null)
t.assert.strictEqual(request[kFastifyContext].preValidation, null)
done()

@@ -289,8 +315,11 @@ })

delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeader = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeader, {
'access-control-allow-origin': '*'
})
t.notMatch(res.headers, { vary: 'Origin' })
t.assert.notStrictEqual(res.headers.vary, 'Origin')
})

@@ -308,9 +337,9 @@

fastify.addHook('onResponse', (request, reply, done) => {
t.equal(request[kFastifyContext].onError, null)
t.equal(request[kFastifyContext].onRequest, null)
t.equal(request[kFastifyContext].onSend, null)
t.equal(request[kFastifyContext].preHandler, null)
t.equal(request[kFastifyContext].preParsing, null)
t.equal(request[kFastifyContext].preSerialization.length, 1)
t.equal(request[kFastifyContext].preValidation, null)
t.assert.strictEqual(request[kFastifyContext].onError, null)
t.assert.strictEqual(request[kFastifyContext].onRequest, null)
t.assert.strictEqual(request[kFastifyContext].onSend, null)
t.assert.strictEqual(request[kFastifyContext].preHandler, null)
t.assert.strictEqual(request[kFastifyContext].preParsing, null)
t.assert.strictEqual(request[kFastifyContext].preSerialization.length, 1)
t.assert.strictEqual(request[kFastifyContext].preValidation, null)
done()

@@ -330,11 +359,14 @@ })

delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, '{"nonString":true}')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, '{"nonString":true}')
const actualHeader = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeader, {
'access-control-allow-origin': '*'
})
t.notMatch(res.headers, { vary: 'Origin' })
t.assert.notStrictEqual(res.headers.vary, 'Origin')
})
test('Should support custom hook with dynamic config', t => {
test('Should support custom hook with dynamic config', async t => {
t.plan(16)

@@ -360,16 +392,16 @@

let requestId = 0
const configDelegation = function (req, cb) {
const configDelegation = async function (req) {
// request should have id
t.ok(req.id)
t.assert.ok(req.id)
// request should not have send
t.notOk(req.send)
t.assert.ifError(req.send)
const config = configs[requestId]
requestId++
if (config) {
cb(null, config)
return Promise.resolve(config)
} else {
cb(new Error('ouch'))
return Promise.reject(new Error('ouch'))
}
}
fastify.register(cors, {
await fastify.register(cors, {
hook: 'preHandler',

@@ -383,20 +415,26 @@ delegator: configDelegation

fastify.inject({
let res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
let actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2',
vary: 'Origin'
})
fastify.inject({
res = await fastify.inject({
method: 'OPTIONS',

@@ -408,20 +446,29 @@ url: '/',

}
}, (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': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
'access-control-allow-headers': res.headers['access-control-allow-headers'],
'access-control-max-age': res.headers['access-control-max-age'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0',
vary: 'Origin'
})
fastify.inject({
res = await fastify.inject({
method: 'GET',

@@ -433,9 +480,8 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Should support custom hook with dynamic config (callback)', t => {
test('Should support custom hook with dynamic config (callback)', async t => {
t.plan(16)

@@ -463,5 +509,5 @@

// request should have id
t.ok(req.id)
t.assert.ok(req.id)
// request should not have send
t.notOk(req.send)
t.assert.ifError(req.send)
const config = configs[requestId]

@@ -488,7 +534,14 @@ requestId++

}, (err, res) => {
t.error(err)
t.assert.ifError(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'example.com',

@@ -510,7 +563,17 @@ 'access-control-allow-credentials': 'true',

}, (err, res) => {
t.error(err)
t.assert.ifError(err)
delete res.headers.date
t.equal(res.statusCode, 204)
t.equal(res.payload, '')
t.match(res.headers, {
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
'access-control-allow-headers': res.headers['access-control-allow-headers'],
'access-control-max-age': res.headers['access-control-max-age'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'sample.com',

@@ -535,8 +598,9 @@ 'access-control-allow-credentials': 'true',

}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
t.assert.ifError(err)
t.assert.strictEqual(res.statusCode, 500)
})
await sleep()
})
test('Should support custom hook with dynamic config (Promise)', t => {
test('Should support custom hook with dynamic config (Promise)', async t => {
t.plan(16)

@@ -562,7 +626,7 @@

let requestId = 0
const configDelegation = function (req) {
const configDelegation = async function (req) {
// request should have id
t.ok(req.id)
t.assert.ok(req.id)
// request should not have send
t.notOk(req.send)
t.assert.ifError(req.send)
const config = configs[requestId]

@@ -577,3 +641,3 @@ requestId++

fastify.register(cors, {
await fastify.register(cors, {
hook: 'preParsing',

@@ -587,20 +651,27 @@ delegator: configDelegation

fastify.inject({
let res = await fastify.inject({
method: 'GET',
url: '/'
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
let actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
fastify.inject({
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2',
vary: 'Origin'
})
res = await fastify.inject({
method: 'OPTIONS',

@@ -612,20 +683,29 @@ url: '/',

}
}, (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': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0',
vary: 'Origin'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-credentials': res.headers['access-control-allow-credentials'],
'access-control-expose-headers': res.headers['access-control-expose-headers'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
'access-control-allow-headers': res.headers['access-control-allow-headers'],
'access-control-max-age': res.headers['access-control-max-age'],
'content-length': res.headers['content-length'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': 'sample.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'zoo, bar',
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0',
vary: 'Origin'
})
fastify.inject({
res = await fastify.inject({
method: 'GET',

@@ -637,9 +717,8 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Should support custom hook with dynamic config (Promise), but should error /1', t => {
test('Should support custom hook with dynamic config (Promise), but should error /1', async t => {
t.plan(6)

@@ -652,3 +731,3 @@

fastify.register(cors, {
await fastify.register(cors, {
hook: 'preParsing',

@@ -662,3 +741,3 @@ delegator: configDelegation

fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',

@@ -670,13 +749,15 @@ url: '/',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 500)
t.equal(res.payload, '{"statusCode":500,"error":"Internal Server Error","message":"Invalid CORS origin option"}')
t.match(res.headers, {
'content-length': '89'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 500)
t.assert.strictEqual(res.payload, '{"statusCode":500,"error":"Internal Server Error","message":"Invalid CORS origin option"}')
const actualHeaders = {
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'content-length': '89'
})
fastify.inject({
res = await fastify.inject({
method: 'GET',

@@ -688,9 +769,8 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
test('Should support custom hook with dynamic config (Promise), but should error /2', t => {
test('Should support custom hook with dynamic config (Promise), but should error /2', async t => {
t.plan(6)

@@ -703,3 +783,3 @@

fastify.register(cors, {
await fastify.register(cors, {
delegator: configDelegation

@@ -712,3 +792,3 @@ })

fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',

@@ -720,13 +800,15 @@ url: '/',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 500)
t.equal(res.payload, '{"statusCode":500,"error":"Internal Server Error","message":"Invalid CORS origin option"}')
t.match(res.headers, {
'content-length': '89'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 500)
t.assert.strictEqual(res.payload, '{"statusCode":500,"error":"Internal Server Error","message":"Invalid CORS origin option"}')
const actualHeaders = {
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'content-length': '89'
})
fastify.inject({
res = await fastify.inject({
method: 'GET',

@@ -738,6 +820,5 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 500)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 500)
})
'use strict'
const { test } = require('tap')
const { test } = require('node:test')
const Fastify = require('fastify')
const cors = require('../')
test('Should reply to preflight requests', t => {
test('Should reply to preflight requests', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register(cors)
await fastify.register(cors)
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -20,23 +20,28 @@ url: '/',

}
}, (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',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
test('Should add access-control-allow-headers to response if preflight req has access-control-request-headers', t => {
test('Should add access-control-allow-headers to response if preflight req has access-control-request-headers', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register(cors)
await fastify.register(cors)
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -50,24 +55,30 @@ url: '/',

}, (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: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
'access-control-allow-headers': res.headers['access-control-allow-headers'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
'access-control-allow-headers': 'x-requested-with',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
test('Should reply to preflight requests with custom status code', t => {
test('Should reply to preflight requests with custom status code', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register(cors, { optionsSuccessStatus: 200 })
await fastify.register(cors, { optionsSuccessStatus: 200 })
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -79,21 +90,26 @@ url: '/',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, '')
t.match(res.headers, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
test('Should be able to override preflight response with a route', t => {
test('Should be able to override preflight response with a route', async t => {
t.plan(5)
const fastify = Fastify()
fastify.register(cors, { preflightContinue: true })
await fastify.register(cors, { preflightContinue: true })

@@ -104,3 +120,3 @@ fastify.options('/', (req, reply) => {

fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -112,22 +128,24 @@ url: '/',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
// Only the base cors headers and no preflight headers
'access-control-allow-origin': '*'
})
t.notMatch(res.headers, { vary: 'Origin' })
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin']
}
t.assert.deepStrictEqual(actualHeaders, {
// Only the base cors headers and no preflight headers
'access-control-allow-origin': '*'
})
t.assert.notStrictEqual(res.headers.vary, 'Origin')
})
test('Should reply to all options requests', t => {
test('Should reply to all options requests', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register(cors)
await fastify.register(cors)
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -139,21 +157,26 @@ url: '/hello',

}
}, (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',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
test('Should support a prefix for preflight requests', t => {
test('Should support a prefix for preflight requests', async t => {
t.plan(6)
const fastify = Fastify()
fastify.register((instance, opts, next) => {
await fastify.register((instance, opts, next) => {
instance.register(cors)

@@ -163,11 +186,10 @@ next()

fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',
url: '/hello'
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 404)
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 404)
fastify.inject({
res = await fastify.inject({
method: 'OPTIONS',

@@ -179,17 +201,22 @@ url: '/subsystem/hello',

}
}, (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',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
test('hide options route by default', t => {
test('hide options route by default', async t => {
t.plan(2)

@@ -201,13 +228,12 @@

if (route.method === 'OPTIONS' && route.url === '*') {
t.equal(route.schema.hide, true)
t.assert.strictEqual(route.schema.hide, true)
}
})
fastify.register(cors)
await fastify.register(cors)
fastify.ready(err => {
t.error(err)
})
const ready = await fastify.ready()
t.assert.ok(ready)
})
test('show options route', t => {
test('show options route', async t => {
t.plan(2)

@@ -219,19 +245,18 @@

if (route.method === 'OPTIONS' && route.url === '*') {
t.equal(route.schema.hide, false)
t.assert.strictEqual(route.schema.hide, false)
}
})
fastify.register(cors, { hideOptionsRoute: false })
await fastify.register(cors, { hideOptionsRoute: false })
fastify.ready(err => {
t.error(err)
})
const ready = await fastify.ready()
t.assert.ok(ready)
})
test('Allow only request from with specific methods', t => {
test('Allow only request from with specific methods', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register(cors, { methods: ['GET', 'POST'] })
await fastify.register(cors, { methods: ['GET', 'POST'] })
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -243,20 +268,22 @@ url: '/',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 204)
t.match(res.headers, {
'access-control-allow-methods': 'GET, POST'
})
t.notMatch(res.headers, { vary: 'Origin' })
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
const actualHeaders = {
'access-control-allow-methods': res.headers['access-control-allow-methods']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-methods': 'GET, POST'
})
t.assert.notStrictEqual(res.headers.vary, 'Origin')
})
test('Should reply with 400 error to OPTIONS requests missing origin header when default strictPreflight', t => {
test('Should reply with 400 error to OPTIONS requests missing origin header when default strictPreflight', async t => {
t.plan(3)
const fastify = Fastify()
fastify.register(cors)
await fastify.register(cors)
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -267,18 +294,17 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 400)
t.equal(res.payload, 'Invalid Preflight Request')
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 400)
t.assert.strictEqual(res.payload, 'Invalid Preflight Request')
})
test('Should reply with 400 to OPTIONS requests when missing Access-Control-Request-Method header when default strictPreflight', t => {
test('Should reply with 400 to OPTIONS requests when missing Access-Control-Request-Method header when default strictPreflight', async t => {
t.plan(3)
const fastify = Fastify()
fastify.register(cors, {
await fastify.register(cors, {
strictPreflight: true
})
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -289,40 +315,44 @@ url: '/',

}
}, (err, res) => {
t.error(err)
t.equal(res.statusCode, 400)
t.equal(res.payload, 'Invalid Preflight Request')
})
t.assert.ok(res)
t.assert.strictEqual(res.statusCode, 400)
t.assert.strictEqual(res.payload, 'Invalid Preflight Request')
})
test('Should reply to all preflight requests when strictPreflight is disabled', t => {
test('Should reply to all preflight requests when strictPreflight is disabled', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register(cors, { strictPreflight: false })
await fastify.register(cors, { strictPreflight: false })
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',
url: '/'
// No access-control-request-method or origin headers
}, (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',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
test('Default empty 200 response with preflightContinue on OPTIONS routes', t => {
test('Default empty 200 response with preflightContinue on OPTIONS routes', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register(cors, { preflightContinue: true })
await fastify.register(cors, { preflightContinue: true })
fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -334,20 +364,24 @@ url: '/doesnotexist',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, '')
t.match(res.headers, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, '')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers'
})
})
test('Can override preflight response with preflightContinue', t => {
test('Can override preflight response with preflightContinue', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register(cors, { preflightContinue: true })
await fastify.register(cors, { preflightContinue: true })

@@ -358,3 +392,3 @@ fastify.options('/', (req, reply) => {

fastify.inject({
const res = await fastify.inject({
method: 'OPTIONS',

@@ -366,16 +400,20 @@ url: '/',

}
}, (err, res) => {
t.error(err)
delete res.headers.date
t.equal(res.statusCode, 200)
t.equal(res.payload, 'ok')
t.match(res.headers, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 200)
t.assert.strictEqual(res.payload, 'ok')
const actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers'
})
})
test('Should support ongoing prefix ', t => {
test('Should support ongoing prefix ', async t => {
t.plan(12)

@@ -385,3 +423,3 @@

fastify.register(async (instance) => {
await fastify.register(async (instance) => {
instance.register(cors)

@@ -391,3 +429,3 @@ }, { prefix: '/prefix' })

// support prefixed route
fastify.inject({
let res = await fastify.inject({
method: 'OPTIONS',

@@ -399,17 +437,22 @@ url: '/prefix',

}
}, (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',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
let actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
// support prefixed route without / continue
fastify.inject({
res = await fastify.inject({
method: 'OPTIONS',

@@ -421,17 +464,22 @@ url: '/prefixfoo',

}
}, (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',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
// support prefixed route with / continue
fastify.inject({
res = await fastify.inject({
method: 'OPTIONS',

@@ -443,14 +491,19 @@ url: '/prefix/foo',

}
}, (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',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
t.assert.ok(res)
delete res.headers.date
t.assert.strictEqual(res.statusCode, 204)
t.assert.strictEqual(res.payload, '')
actualHeaders = {
'access-control-allow-origin': res.headers['access-control-allow-origin'],
'access-control-allow-methods': res.headers['access-control-allow-methods'],
vary: res.headers.vary,
'content-length': res.headers['content-length']
}
t.assert.deepStrictEqual(actualHeaders, {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
vary: 'Access-Control-Request-Headers',
'content-length': '0'
})
})
'use strict'
const test = require('tap').test
const { test } = require('node:test')
const createAddFieldnameToVary = require('../vary').createAddFieldnameToVary
const parse = require('../vary').parse
test('Should set * even if we set a specific field', t => {
test('Should set * even if we set a specific field', async t => {
t.plan(1)

@@ -21,3 +21,3 @@

addOriginToVary(replyMock)
t.pass()
t.assert.ok(true) // equalivant to tap t.pass()
})

@@ -34,4 +34,4 @@

header (name, value) {
t.same(name, 'Vary')
t.same(value, '*')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, '*')
}

@@ -52,4 +52,4 @@ }

header (name, value) {
t.same(name, 'Vary')
t.same(value, '*')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, '*')
}

@@ -59,3 +59,3 @@ }

addOriginToVary(replyMock)
t.pass()
t.assert.ok(true) // equalivant to tap t.pass()
})

@@ -72,4 +72,4 @@

header (name, value) {
t.same(name, 'Vary')
t.same(value, 'Access-Control-Request-Headers, Origin')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, 'Access-Control-Request-Headers, Origin')
}

@@ -79,3 +79,3 @@ }

addOriginToVary(replyMock)
t.pass()
t.assert.ok(true) // equalivant to tap t.pass()
})

@@ -92,4 +92,4 @@

header (name, value) {
t.same(name, 'Vary')
t.same(value, ' Access-Control-Request-Headers,Access-Control-Request-Method, Origin')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, ' Access-Control-Request-Headers,Access-Control-Request-Method, Origin')
}

@@ -99,3 +99,3 @@ }

addOriginToVary(replyMock)
t.pass()
t.assert.ok(true) // equalivant to tap t.pass()
})

@@ -112,4 +112,4 @@

header (name, value) {
t.same(name, 'Vary')
t.same(value, ' Access-Control-Request-Headers ,Access-Control-Request-Method, Origin')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, ' Access-Control-Request-Headers ,Access-Control-Request-Method, Origin')
}

@@ -119,3 +119,3 @@ }

addOriginToVary(replyMock)
t.pass()
t.assert.ok(true) // equalivant to tap t.pass()
})

@@ -132,4 +132,4 @@

header (name, value) {
t.same(name, 'Vary')
t.same(value, 'Origin')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, 'Origin')
}

@@ -150,4 +150,4 @@ }

header (name, value) {
t.same(name, 'Vary')
t.same(value, '*')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, '*')
}

@@ -168,4 +168,4 @@ }

header (name, value) {
t.same(name, 'Vary')
t.same(value, 'Accept-Encoding')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, 'Accept-Encoding')
}

@@ -187,4 +187,4 @@ }

header (name, value) {
t.same(name, 'Vary')
t.same(value, 'Accept-Encoding, X-Foo')
t.assert.deepStrictEqual(name, 'Vary')
t.assert.deepStrictEqual(value, 'Accept-Encoding, X-Foo')
this.value = value

@@ -212,3 +212,4 @@ }

addOriginToVary(replyMock)
t.pass()
t.assert.ok(true) // equalivant to tap t.pass()
})

@@ -218,28 +219,35 @@

t.plan(18)
t.same(parse(''), [])
t.same(parse('a'), ['a'])
t.same(parse('a,b'), ['a', 'b'])
t.same(parse(' a,b'), ['a', 'b'])
t.same(parse('a,b '), ['a', 'b'])
t.same(parse('a,b,c'), ['a', 'b', 'c'])
t.same(parse('A,b,c'), ['a', 'b', 'c'])
t.same(parse('a,b,c,'), ['a', 'b', 'c'])
t.same(parse('a,b,c, '), ['a', 'b', 'c'])
t.same(parse(',a,b,c'), ['a', 'b', 'c'])
t.same(parse(' ,a,b,c'), ['a', 'b', 'c'])
t.same(parse('a,,b,c'), ['a', 'b', 'c'])
t.same(parse('a,,,b,,c'), ['a', 'b', 'c'])
t.same(parse('a, b,c'), ['a', 'b', 'c'])
t.same(parse('a, b,c'), ['a', 'b', 'c'])
t.same(parse('a, , b,c'), ['a', 'b', 'c'])
t.same(parse('a, , b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse(''), [])
t.assert.deepStrictEqual(parse('a'), ['a'])
t.assert.deepStrictEqual(parse('a,b'), ['a', 'b'])
t.assert.deepStrictEqual(parse(' a,b'), ['a', 'b'])
t.assert.deepStrictEqual(parse('a,b '), ['a', 'b'])
t.assert.deepStrictEqual(parse('a,b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('A,b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('a,b,c,'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('a,b,c, '), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse(',a,b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse(' ,a,b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('a,,b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('a,,,b,,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('a, b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('a, b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('a, , b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('a, , b,c'), ['a', 'b', 'c'])
// one for the cache
t.same(parse('A,b,c'), ['a', 'b', 'c'])
t.assert.deepStrictEqual(parse('A,b,c'), ['a', 'b', 'c'])
})
test('createAddFieldnameToVary', t => {
t.plan(2)
t.same(typeof createAddFieldnameToVary('valid-header'), 'function')
t.throws(() => createAddFieldnameToVary('invalid:header'), TypeError, 'Field contains invalid characters.')
test('createAddFieldnameToVary', async t => {
t.plan(4)
t.assert.strictEqual(typeof createAddFieldnameToVary('valid-header'), 'function')
await t.assert.rejects(
async () => createAddFieldnameToVary('invalid:header'),
(err) => {
t.assert.strictEqual(err.name, 'TypeError')
t.assert.strictEqual(err.message, 'Fieldname contains invalid characters.')
return true
}
)
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc