You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							815 lines
						
					
					
						
							18 KiB
						
					
					
				
			
		
		
	
	
							815 lines
						
					
					
						
							18 KiB
						
					
					
				| 'use strict'
 | |
| 
 | |
| const { test } = require('tap')
 | |
| const Fastify = require('fastify')
 | |
| const cors = require('../')
 | |
| 
 | |
| test('Should add cors headers', t => {
 | |
|   t.plan(4)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors)
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': '*'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Should add cors headers (custom values)', t => {
 | |
|   t.plan(8)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, {
 | |
|     origin: 'example.com',
 | |
|     methods: 'GET',
 | |
|     credentials: true,
 | |
|     exposedHeaders: ['foo', 'bar'],
 | |
|     allowedHeaders: ['baz', 'woo'],
 | |
|     maxAge: 123
 | |
|   })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'OPTIONS',
 | |
|     url: '/',
 | |
|     headers: {
 | |
|       'access-control-request-method': 'GET',
 | |
|       origin: 'example.com'
 | |
|     }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 204)
 | |
|     t.strictEqual(res.payload, '')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'example.com',
 | |
|       vary: 'Origin',
 | |
|       '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',
 | |
|       'content-length': '0'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'example.com',
 | |
|       vary: 'Origin',
 | |
|       'access-control-allow-credentials': 'true',
 | |
|       'access-control-expose-headers': 'foo, bar',
 | |
|       'content-length': '2'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Should support dynamic config (callback)', t => {
 | |
|   t.plan(10)
 | |
| 
 | |
|   const configs = [{
 | |
|     origin: 'example.com',
 | |
|     methods: 'GET',
 | |
|     credentials: true,
 | |
|     exposedHeaders: ['foo', 'bar'],
 | |
|     allowedHeaders: ['baz', 'woo'],
 | |
|     maxAge: 123
 | |
|   }, {
 | |
|     origin: 'sample.com',
 | |
|     methods: 'GET',
 | |
|     credentials: true,
 | |
|     exposedHeaders: ['zoo', 'bar'],
 | |
|     allowedHeaders: ['baz', 'foo'],
 | |
|     maxAge: 321
 | |
|   }]
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   let requestId = 0
 | |
|   const configDelegation = function (req, cb) {
 | |
|     const config = configs[requestId]
 | |
|     requestId++
 | |
|     if (config) {
 | |
|       cb(null, config)
 | |
|     } else {
 | |
|       cb(new Error('ouch'))
 | |
|     }
 | |
|   }
 | |
|   fastify.register(cors, () => configDelegation)
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'example.com',
 | |
|       vary: 'Origin',
 | |
|       'access-control-allow-credentials': 'true',
 | |
|       'access-control-expose-headers': 'foo, bar',
 | |
|       'content-length': '2'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'OPTIONS',
 | |
|     url: '/',
 | |
|     headers: {
 | |
|       'access-control-request-method': 'GET',
 | |
|       origin: 'example.com'
 | |
|     }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 204)
 | |
|     t.strictEqual(res.payload, '')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'sample.com',
 | |
|       vary: 'Origin',
 | |
|       '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'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: {
 | |
|       'access-control-request-method': 'GET',
 | |
|       origin: 'example.com'
 | |
|     }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     t.strictEqual(res.statusCode, 500)
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Should support dynamic config (Promise)', t => {
 | |
|   t.plan(10)
 | |
| 
 | |
|   const configs = [{
 | |
|     origin: 'example.com',
 | |
|     methods: 'GET',
 | |
|     credentials: true,
 | |
|     exposedHeaders: ['foo', 'bar'],
 | |
|     allowedHeaders: ['baz', 'woo'],
 | |
|     maxAge: 123
 | |
|   }, {
 | |
|     origin: 'sample.com',
 | |
|     methods: 'GET',
 | |
|     credentials: true,
 | |
|     exposedHeaders: ['zoo', 'bar'],
 | |
|     allowedHeaders: ['baz', 'foo'],
 | |
|     maxAge: 321
 | |
|   }]
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   let requestId = 0
 | |
|   const configDelegation = function (req) {
 | |
|     const config = configs[requestId]
 | |
|     requestId++
 | |
|     if (config) {
 | |
|       return Promise.resolve(config)
 | |
|     } else {
 | |
|       return Promise.reject(new Error('ouch'))
 | |
|     }
 | |
|   }
 | |
|   fastify.register(cors, () => configDelegation)
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'example.com',
 | |
|       vary: 'Origin',
 | |
|       'access-control-allow-credentials': 'true',
 | |
|       'access-control-expose-headers': 'foo, bar',
 | |
|       'content-length': '2'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'OPTIONS',
 | |
|     url: '/',
 | |
|     headers: {
 | |
|       'access-control-request-method': 'GET',
 | |
|       origin: 'example.com'
 | |
|     }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 204)
 | |
|     t.strictEqual(res.payload, '')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'sample.com',
 | |
|       vary: 'Origin',
 | |
|       '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'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: {
 | |
|       'access-control-request-method': 'GET',
 | |
|       origin: 'example.com'
 | |
|     }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     t.strictEqual(res.statusCode, 500)
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Should support dynamic config. (Invalid function)', t => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, () => (a, b, c) => {})
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: {
 | |
|       'access-control-request-method': 'GET',
 | |
|       origin: 'example.com'
 | |
|     }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     t.strictEqual(res.statusCode, 500)
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Dynamic origin resolution (valid origin)', t => {
 | |
|   t.plan(6)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   const origin = function (header, cb) {
 | |
|     t.strictEqual(header, 'example.com')
 | |
|     t.deepEqual(this, fastify)
 | |
|     cb(null, true)
 | |
|   }
 | |
|   fastify.register(cors, { origin })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'example.com',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Dynamic origin resolution (not valid origin)', t => {
 | |
|   t.plan(5)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   const origin = (header, cb) => {
 | |
|     t.strictEqual(header, 'example.com')
 | |
|     cb(null, false)
 | |
|   }
 | |
|   fastify.register(cors, { origin })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.deepEqual(res.headers, {
 | |
|       'content-length': '2',
 | |
|       'content-type': 'text/plain; charset=utf-8',
 | |
|       connection: 'keep-alive',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Dynamic origin resolution (errored)', t => {
 | |
|   t.plan(3)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   const origin = (header, cb) => {
 | |
|     t.strictEqual(header, 'example.com')
 | |
|     cb(new Error('ouch'))
 | |
|   }
 | |
|   fastify.register(cors, { origin })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     t.strictEqual(res.statusCode, 500)
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Dynamic origin resolution (invalid result)', t => {
 | |
|   t.plan(3)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   const origin = (header, cb) => {
 | |
|     t.strictEqual(header, 'example.com')
 | |
|     cb(null, undefined)
 | |
|   }
 | |
|   fastify.register(cors, { origin })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     t.strictEqual(res.statusCode, 500)
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Dynamic origin resolution (valid origin - promises)', t => {
 | |
|   t.plan(5)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   const origin = (header, cb) => {
 | |
|     return new Promise((resolve, reject) => {
 | |
|       t.strictEqual(header, 'example.com')
 | |
|       resolve(true)
 | |
|     })
 | |
|   }
 | |
|   fastify.register(cors, { origin })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'example.com',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Dynamic origin resolution (not valid origin - promises)', t => {
 | |
|   t.plan(5)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   const origin = (header, cb) => {
 | |
|     return new Promise((resolve, reject) => {
 | |
|       t.strictEqual(header, 'example.com')
 | |
|       resolve(false)
 | |
|     })
 | |
|   }
 | |
|   fastify.register(cors, { origin })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.deepEqual(res.headers, {
 | |
|       'content-length': '2',
 | |
|       'content-type': 'text/plain; charset=utf-8',
 | |
|       connection: 'keep-alive',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Dynamic origin resolution (errored - promises)', t => {
 | |
|   t.plan(3)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   const origin = (header, cb) => {
 | |
|     return new Promise((resolve, reject) => {
 | |
|       t.strictEqual(header, 'example.com')
 | |
|       reject(new Error('ouch'))
 | |
|     })
 | |
|   }
 | |
|   fastify.register(cors, { origin })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     t.strictEqual(res.statusCode, 500)
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Should reply 404 without cors headers other than `vary` when origin is false', t => {
 | |
|   t.plan(8)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, {
 | |
|     origin: false,
 | |
|     methods: 'GET',
 | |
|     credentials: true,
 | |
|     exposedHeaders: ['foo', 'bar'],
 | |
|     allowedHeaders: ['baz', 'woo'],
 | |
|     maxAge: 123
 | |
|   })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'OPTIONS',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 404)
 | |
|     t.strictEqual(res.payload, '{"message":"Route OPTIONS:/ not found","error":"Not Found","statusCode":404}')
 | |
|     t.deepEqual(res.headers, {
 | |
|       'content-length': '76',
 | |
|       'content-type': 'application/json; charset=utf-8',
 | |
|       connection: 'keep-alive',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.deepEqual(res.headers, {
 | |
|       'content-length': '2',
 | |
|       'content-type': 'text/plain; charset=utf-8',
 | |
|       connection: 'keep-alive',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Server error if origin option is falsy but not false', t => {
 | |
|   t.plan(4)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, { origin: '' })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 500)
 | |
|     t.deepEqual(res.json(), { statusCode: 500, error: 'Internal Server Error', message: 'Invalid CORS origin option' })
 | |
|     t.deepEqual(res.headers, {
 | |
|       'content-length': '89',
 | |
|       'content-type': 'application/json; charset=utf-8',
 | |
|       connection: 'keep-alive',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Allow only request from a specific origin', t => {
 | |
|   t.plan(4)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, { origin: 'other.io' })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'other.io',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Allow only request from multiple specific origin', t => {
 | |
|   t.plan(8)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, { origin: ['other.io', 'example.com'] })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'other.io' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'other.io',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'foo.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': false,
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Allow only request from a specific origin using regex', t => {
 | |
|   t.plan(4)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, { origin: /^(example|other)\.com/ })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/',
 | |
|     headers: { origin: 'example.com' }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': 'example.com',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Disable preflight', t => {
 | |
|   t.plan(7)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, { preflight: false })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'OPTIONS',
 | |
|     url: '/hello'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 404)
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': '*'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-origin': '*'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Should always add vary header to `Origin` by default', t => {
 | |
|   t.plan(12)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors)
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   // Invalid Preflight
 | |
|   fastify.inject({
 | |
|     method: 'OPTIONS',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 400)
 | |
|     t.strictEqual(res.payload, 'Invalid Preflight Request')
 | |
|     t.match(res.headers, {
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   // Valid Preflight
 | |
|   fastify.inject({
 | |
|     method: 'OPTIONS',
 | |
|     url: '/',
 | |
|     headers: {
 | |
|       'access-control-request-method': 'GET',
 | |
|       origin: 'example.com'
 | |
|     }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 204)
 | |
|     t.strictEqual(res.payload, '')
 | |
|     t.match(res.headers, {
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   // Other Route
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Should always add vary header to `Origin` by default (vary is array)', t => {
 | |
|   t.plan(4)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
| 
 | |
|   // Mock getHeader function
 | |
|   fastify.decorateReply('getHeader', (name) => ['foo', 'bar'])
 | |
| 
 | |
|   fastify.register(cors)
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       vary: 'foo, bar, Origin'
 | |
|     })
 | |
|   })
 | |
| })
 | |
| 
 | |
| test('Allow only request from with specific headers', t => {
 | |
|   t.plan(7)
 | |
| 
 | |
|   const fastify = Fastify()
 | |
|   fastify.register(cors, {
 | |
|     allowedHeaders: 'foo',
 | |
|     exposedHeaders: 'bar'
 | |
|   })
 | |
| 
 | |
|   fastify.get('/', (req, reply) => {
 | |
|     reply.send('ok')
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'OPTIONS',
 | |
|     url: '/',
 | |
|     headers: {
 | |
|       'access-control-request-method': 'GET',
 | |
|       origin: 'example.com'
 | |
|     }
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 204)
 | |
|     t.match(res.headers, {
 | |
|       'access-control-allow-headers': 'foo',
 | |
|       vary: 'Origin'
 | |
|     })
 | |
|   })
 | |
| 
 | |
|   fastify.inject({
 | |
|     method: 'GET',
 | |
|     url: '/'
 | |
|   }, (err, res) => {
 | |
|     t.error(err)
 | |
|     delete res.headers.date
 | |
|     t.strictEqual(res.statusCode, 200)
 | |
|     t.strictEqual(res.payload, 'ok')
 | |
|     t.match(res.headers, {
 | |
|       'access-control-expose-headers': 'bar'
 | |
|     })
 | |
|   })
 | |
| })
 |