Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asynchronous dynamic cors not even worked! #137

Closed
2 tasks done
tngflx opened this issue Jun 26, 2021 · 3 comments · Fixed by #205
Closed
2 tasks done

asynchronous dynamic cors not even worked! #137

tngflx opened this issue Jun 26, 2021 · 3 comments · Fixed by #205
Labels

Comments

@tngflx
Copy link

tngflx commented Jun 26, 2021

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure it has not already been reported

Fastify version

latest

Plugin version

latest

Node.js version

14

Operating system

Windows

Operating system version (i.e. 20.04, 11.3, 10)

win10

Description

yo your origin is pointing to nothing. How to fix this? I know it suppose to be an object?

Steps to Reproduce

fastify.register(require('fastify-cors'), (instance) => (req, callback) => {
  let corsOptions;
  // do not include CORS headers for requests from localhost
  if (/localhost/.test(origin)) {
    corsOptions = { origin: false }
  } else {
    corsOptions = { origin: true }
  }
  callback(null, corsOptions) // callback expects two parameters: error and options
})

fastify.get('/', (req, reply) => {
  reply.send({ hello: 'world' })
})

.test(origin) points to undefined man

Expected Behavior

origin should not be undefined

@zekth
Copy link
Member

zekth commented Jun 26, 2021

Indeed documentation is off.
The code snippet should be something like this:

fastify.register(require('fastify-cors'), (instance) => (req, callback) => {
  let corsOptions;
  // do not include CORS headers for requests from localhost
  if (/localhost/.test(req.getHeader(origin))) {
    corsOptions = { origin: false }
  } else {
    corsOptions = { origin: true }
  }
  callback(null, corsOptions) // callback expects two parameters: error and options
})

fastify.get('/', (req, reply) => {
  reply.send({ hello: 'world' })
})

Which is still confusing. See this test for more explicit use case:

test('Should support dynamic config (Promise)', t => {
t.plan(16)
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) {
// request should have id
t.ok(req.id)
// request should not have send
t.notOk(req.send)
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.equal(res.statusCode, 200)
t.equal(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.equal(res.statusCode, 204)
t.equal(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.equal(res.statusCode, 500)
})
})

@tngflx
Copy link
Author

tngflx commented Jun 27, 2021

Ok found a solution :

fastify.register(require('fastify-cors'), (instance) => async (req, callback) => {
    let corsOptions = {
        credentials: true,
        allowedHeaders: ["Origin, X-Requested-With, Content-Type, Accept"],
        origin: false
    }
    // do not include CORS headers for requests from localhost
    let originHostname = req.headers.origin || req.ip || '';
    if (/(localhost|ngrok|127.0.0.1)/g.test(originHostname)) {
        corsOptions.origin = true
    } else {
        corsOptions.origin = false
    }
    callback(null, corsOptions) // callback expects two parameters: error and options
})

This can dynamically match all kind of origin and assign cors for each route. its working so far.

@Sikora00
Copy link
Contributor

I was sorry when I saw it 😟

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants