UNPKG

ghost

Version:

The professional publishing platform

76 lines (65 loc) 2.26 kB
const {URL} = require('url'); const cors = require('cors'); const errors = require('@tryghost/errors'); const config = require('../../../shared/config'); /** * Dynamically configures the expressjs/cors middleware * * @param {import('express').Request} req * @param {Function} callback */ function corsOptionsDelegate(req, callback) { const origin = req.header('Origin'); const corsOptions = { origin: false, // disallow cross-origin requests by default credentials: true, // required to allow admin-client to login to private sites maxAge: config.get('caching:cors:maxAge') }; if (!origin || origin === 'null') { return callback(null, corsOptions); } let originUrl; try { originUrl = new URL(origin); } catch (err) { return callback(new errors.BadRequestError({err})); } // originUrl will definitely exist here because according to WHATWG URL spec // The class constructor will either throw a TypeError or return a URL object // https://url.spec.whatwg.org/#url-class // allow all localhost and 127.0.0.1 requests no matter the port if (originUrl.hostname === 'localhost' || originUrl.hostname === '127.0.0.1') { corsOptions.origin = true; } // allow the configured host through on any protocol const siteUrl = new URL(config.get('url')); if (originUrl.host === siteUrl.host) { corsOptions.origin = true; } // allow the configured admin:url host through on any protocol if (config.get('admin:url')) { const adminUrl = new URL(config.get('admin:url')); if (originUrl.host === adminUrl.host) { corsOptions.origin = true; } } callback(null, corsOptions); } /** * * @param {Express.Request} req * @param {Express.Response} res * @param {Function} next */ const handleCaching = function handleCachingCors(req, res, next) { const method = req.method && req.method.toUpperCase && req.method.toUpperCase(); if (method === 'OPTIONS') { // @NOTE: try to add native support for dynamic 'vary' header value in 'cors' module res.vary('Origin'); } next(); }; module.exports = [ handleCaching, cors(corsOptionsDelegate) ];