hapijs / hapi

The Simple, Secure Framework Developers Trust

Home Page:https://hapi.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CORS Configuration Expectations and Assumptions

morgangraphics opened this issue · comments

Context

  • Node 14:
  • Hapijs 21.3.0:

What are you trying to achieve or the steps to reproduce ?

I am not sure if the documentation or my expectations are unclear or the intent is the hapijs project "it works as expected" But I think the CORS Documentation at the server level and route level could use some additional clarification in either case

Server Config with CORS enabled

const server = hapi.server({
  host: 'localhost',
  listener,
  port: 3000,
  router: {
    stripTrailingSlash: true,
  },
  routes: {
    cors: {
      origin: 'https://10.0.0.1',
      headers: ['Accept', 'Content-Type'],
      exposedHeaders: ['x-some custom-header'],
    },
    payload: {
      allow: ['application/json', 'application/*+json'],
    },
    security: true,
  },
  tls: true,
});

The above configuration would enable CORS, at the server level, for ALL routes as per the documentation.

server.options.routes
Default value: none.
A route options object used as the default configuration for every route.

I would expect that if I turned off the CORS at the route level (cors: false), that CORS should be disabled for that route e.g.

Route

const healthcheck = {
  method: 'GET',
  path: '/healthcheck',
  options: {
    cors: false
    handler: () => ({ status: 'Ok' }),
    description: 'Test if the Service is up',
    notes: [],
    tags: ['api'], // ADD THIS TAG
  },
};

route.options.app
Application-specific route configuration state. Should not be used by plugins which should use options.plugins[name] instead.

However, this is not the case. CORS is still enabled at the route regardless for the cors: false due to the original CORS specification at the server level. To "disable" CORS at the route level, you have to specify the ['*'] in the CORS origin field. The issue here is that CORS is still enabled for this route but you have to specify that anything/everything is allowed to access it which seems counter intuitive.

const healthcheck = {
  method: 'GET',
  path: '/healthcheck',
  options: {
    cors: {
      origin: ['*']
    },
    handler: () => ({ status: 'Ok' }),
    description: 'Test if the Service is up',
    notes: [],
    tags: ['api'], // ADD THIS TAG
  },
};

Maybe this is by design, in which case the documentation should call out that CORS configuration at the server level is an ALL or nothing kind of deal, whereas at the route level, CORS configuration will illicit finer control with some overhead.

If this is indeed a bug, then the expected behavior would be that adding cors: false at the route level would disable CORS

const some = 'properly formatted code example';