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.
		
		
		
		
		
			
		
			
				
					
					
						
							346 lines
						
					
					
						
							8.3 KiB
						
					
					
				
			
		
		
	
	
							346 lines
						
					
					
						
							8.3 KiB
						
					
					
				'use strict'
 | 
						|
 | 
						|
const { test } = require('tap')
 | 
						|
const Fastify = require('fastify')
 | 
						|
const cors = require('../')
 | 
						|
 | 
						|
test('Should reply to preflight requests', t => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors)
 | 
						|
 | 
						|
  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': '*',
 | 
						|
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
 | 
						|
      vary: 'Origin, 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 => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors)
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'OPTIONS',
 | 
						|
    url: '/',
 | 
						|
    headers: {
 | 
						|
      'access-control-request-headers': 'x-requested-with',
 | 
						|
      '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': '*',
 | 
						|
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
 | 
						|
      'access-control-allow-headers': 'x-requested-with',
 | 
						|
      vary: 'Origin, Access-Control-Request-Headers',
 | 
						|
      'content-length': '0'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Should reply to preflight requests with custom status code', t => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors, { optionsSuccessStatus: 200 })
 | 
						|
 | 
						|
  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, 200)
 | 
						|
    t.strictEqual(res.payload, '')
 | 
						|
    t.match(res.headers, {
 | 
						|
      'access-control-allow-origin': '*',
 | 
						|
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
 | 
						|
      vary: 'Origin, Access-Control-Request-Headers',
 | 
						|
      'content-length': '0'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Should be able to override preflight response with a route', t => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors, { preflightContinue: true })
 | 
						|
 | 
						|
  fastify.options('/', (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, 200)
 | 
						|
    t.strictEqual(res.payload, 'ok')
 | 
						|
    t.match(res.headers, {
 | 
						|
      // Only the base cors headers and no preflight headers
 | 
						|
      'access-control-allow-origin': '*',
 | 
						|
      vary: 'Origin'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Should reply to all options requests', t => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors)
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'OPTIONS',
 | 
						|
    url: '/hello',
 | 
						|
    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': '*',
 | 
						|
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
 | 
						|
      vary: 'Origin, Access-Control-Request-Headers',
 | 
						|
      'content-length': '0'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Should support a prefix for preflight requests', t => {
 | 
						|
  t.plan(6)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register((instance, opts, next) => {
 | 
						|
    instance.register(cors)
 | 
						|
    next()
 | 
						|
  }, { prefix: '/subsystem' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'OPTIONS',
 | 
						|
    url: '/hello'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.strictEqual(res.statusCode, 404)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'OPTIONS',
 | 
						|
    url: '/subsystem/hello',
 | 
						|
    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': '*',
 | 
						|
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
 | 
						|
      vary: 'Origin, Access-Control-Request-Headers',
 | 
						|
      'content-length': '0'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('show options route', t => {
 | 
						|
  t.plan(2)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.addHook('onRoute', (route) => {
 | 
						|
    if (route.method === 'OPTIONS' && route.url === '*') {
 | 
						|
      t.strictEqual(route.schema.hide, false)
 | 
						|
    }
 | 
						|
  })
 | 
						|
  fastify.register(cors, { hideOptionsRoute: false })
 | 
						|
 | 
						|
  fastify.ready(err => {
 | 
						|
    t.error(err)
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Allow only request from with specific methods', t => {
 | 
						|
  t.plan(3)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors, { methods: ['GET', 'POST'] })
 | 
						|
 | 
						|
  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-methods': 'GET, POST',
 | 
						|
      vary: 'Origin'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Should reply with 400 error to OPTIONS requests missing origin header when default strictPreflight', t => {
 | 
						|
  t.plan(3)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors)
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'OPTIONS',
 | 
						|
    url: '/',
 | 
						|
    headers: {
 | 
						|
      'access-control-request-method': 'GET'
 | 
						|
    }
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.strictEqual(res.statusCode, 400)
 | 
						|
    t.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 => {
 | 
						|
  t.plan(3)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors, {
 | 
						|
    strictPreflight: true
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'OPTIONS',
 | 
						|
    url: '/',
 | 
						|
    headers: {
 | 
						|
      origin: 'example.com'
 | 
						|
    }
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.strictEqual(res.statusCode, 400)
 | 
						|
    t.strictEqual(res.payload, 'Invalid Preflight Request')
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Should reply to all preflight requests when strictPreflight is disabled', t => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors, { strictPreflight: false })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'OPTIONS',
 | 
						|
    url: '/'
 | 
						|
    // No access-control-request-method or origin headers
 | 
						|
  }, (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': '*',
 | 
						|
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
 | 
						|
      vary: 'Origin, Access-Control-Request-Headers',
 | 
						|
      'content-length': '0'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Default empty 200 response with preflightContinue on OPTIONS routes', t => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors, { preflightContinue: true })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'OPTIONS',
 | 
						|
    url: '/doesnotexist',
 | 
						|
    headers: {
 | 
						|
      'access-control-request-method': 'GET',
 | 
						|
      origin: 'example.com'
 | 
						|
    }
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    delete res.headers.date
 | 
						|
    t.strictEqual(res.statusCode, 200)
 | 
						|
    t.strictEqual(res.payload, '')
 | 
						|
    t.match(res.headers, {
 | 
						|
      'access-control-allow-origin': '*',
 | 
						|
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
 | 
						|
      vary: 'Origin, Access-Control-Request-Headers'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Can override preflight response with preflightContinue', t => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(cors, { preflightContinue: true })
 | 
						|
 | 
						|
  fastify.options('/', (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, 200)
 | 
						|
    t.strictEqual(res.payload, 'ok')
 | 
						|
    t.match(res.headers, {
 | 
						|
      'access-control-allow-origin': '*',
 | 
						|
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
 | 
						|
      vary: 'Origin, Access-Control-Request-Headers'
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 |