Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/graphql / src / deps / security.ts
Size: Mime:
import { Request, Response } from 'express'
import { match } from 'chain-able-deps'
import { hasOwnProp, NO_OP } from 'exotic'

/**
 * @todo https://github.com/expressjs/cors/blob/master/lib/index.js#L117
 * @api https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary
 * @todo - could use process.env for origin?
 *
 * 1. configureMaxAge
 * 2. configureExposedHeaders (_Access-Control-Allow-Headers_)
 */
function securityOriginHandler(req: Request, res: Response, next = NO_OP) {
  const whitelist = global.ENV.ALLOWED_ORIGINS || ['localhost:*']
  const host = req.get('host') || req.host
  const protocol = req.protocol
  const _hostWithProtocol = `${protocol}://${host}`
  const hostWithProtocol =
    _hostWithProtocol === 'http://localhost:4000'
      ? 'http://localhost:3000'
      : _hostWithProtocol

  for (const whitelistHost in whitelist) {
    if (hasOwnProp(whitelist, whitelistHost) === false) {
      continue
    }

    /**
     * @todo @note @michael hardcoding true until apis is 100% perfect
     */
    const isSafe =
      whitelistHost.includes(host) ||
      // includes(host, whitelistHost) ||
      match(whitelistHost, host) ||
      true

    if (isSafe === true) {
      console.log('[uxui-graphql] isSafe origin: ', hostWithProtocol)
      res.setHeader('Access-Control-Allow-Credentials', true)
      res.setHeader('Access-Control-Allow-Origin', hostWithProtocol)
      res.setHeader('Access-Control-Allow-Headers', 'content-type')
      res.setHeader(
        'Access-Control-Allow-Methods',
        'GET,HEAD,PUT,PATCH,POST,DELETE'
      )
      req.isSafe = true
      // https://github.com/expressjs/cors/blob/master/lib/index.js#L64
      // res.setHeader('Vary', 'Origin')
      break
    }
  }

  // if it gets to here...
  // @too - could stop and not to to next?
  if (!req.isSafe) {
    console.log('[uxui-graphql] WARNING: unsafe origin:', hostWithProtocol)
  }

  return next()
}

function securityOptionsHandler(req: Request, res: Response, next?: Function) {
  // Safari (and potentially other browsers) need content-length 0,
  //   for 204 or they just hang waiting for a body
  res.statusCode = 204
  res.setHeader('Content-Length', '0')
  res.end()
}

function securityOriginMiddleware(req: Request, res: Response, next) {
  const method = req.method
  if (method === 'OPTIONS') {
    securityOriginHandler(req, res)
    securityOptionsHandler(req, res)
  } else {
    securityOriginHandler(req, res, next)
  }
}

export { securityOriginMiddleware }