contra/graphql-helix

Enabling CSP protection with koa + @koa/helmet causes 404 error

leandroruel opened this issue · 0 comments

i was following one of examples from koa repository to CSP but in koa instead of express. but it causes a 404 error Not Found and don't give me any more information.

my code:

import Koa from 'koa'
import logger from 'koa-logger'
import helmet from 'koa-helmet'
import cors from '@koa/cors'
import bodyParser from 'koa-bodyparser'
import {
  getGraphQLParameters,
  processRequest,
  renderGraphiQL,
  shouldRenderGraphiQL,
  sendResult
} from 'graphql-helix'
import Mongoose from 'mongoose'
import { schema } from './graphql/schema'
import router from './routes'
import { MONGODB_USERNAME, MONGODB_PASSWORD, MONGODB_URL } from './config'
import { randomBytes } from 'crypto'
import { formatGraphQLResult } from '@/helpers/errors'

const app = new Koa()

// Middlewares
app.use(logger())

app.use(
  cors({
    origin: '*',
    allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'],
    exposeHeaders: ['X-Request-Id']
  })
)

// Routes
app.use(router.routes())
app.use(router.allowedMethods())

// Body parser
app.use(bodyParser())

// Database
const mongooseOptions = {
  user: MONGODB_USERNAME,
  pass: MONGODB_PASSWORD
}

Mongoose.connect(MONGODB_URL, mongooseOptions)

app.use(async (ctx, next) => {
  ctx.state.contentSecurityPolicyNonce = randomBytes(16).toString('hex')
  await next()
})

app.use(async (ctx, next) => {
  helmet({
    contentSecurityPolicy: {
      directives: {
        'default-src': ["'self'"],
        'script-src': [
          "'self'",
          'data:',
          `'nonce-${ctx.state.contentSecurityPolicyNonce}'`
        ]
      }
    }
  })
})

// GraphQL
app.use(async (ctx) => {
  const request: any = {
    body: ctx.request.body,
    headers: ctx.req.headers,
    method: ctx.request.method,
    query: ctx.request.query
  }

  if (shouldRenderGraphiQL(request)) {
    ctx.body = renderGraphiQL({ nonce: ctx.state.contentSecurityPolicyNonce })
  } else {
    const { operationName, query, variables } = getGraphQLParameters(request)

    const result = await processRequest({
      operationName,
      query,
      variables,
      request,
      schema
    })

    ctx.respond = false
    sendResult(result, ctx.res, formatGraphQLResult)
  }
})

export default app