592d02fd23
closes: https://github.com/TryGhost/Ghost/issues/13739 - Ghost cannot write to the core folder in correctly configured production installations - Built assets therefore need to be written to the content directory - Ghost does not overwrite anything in the content folder as part of an upgrade, therefore static files that are provided by Ghost must still live inside /core - So as a result, we now have core/frontend/public and content/public
108 lines
3.5 KiB
JavaScript
108 lines
3.5 KiB
JavaScript
const path = require('path');
|
|
const escapeRegExp = require('lodash/escapeRegExp');
|
|
const {URL} = require('url');
|
|
|
|
const DEFAULT_HOST_ARG = /.*/;
|
|
|
|
const getHostInfo = (config) => {
|
|
const frontendHost = new URL(config.getSiteUrl()).hostname;
|
|
|
|
const backendHost = config.getAdminUrl() ? (new URL(config.getAdminUrl()).hostname) : '';
|
|
const hasSeparateBackendHost = backendHost && backendHost !== frontendHost;
|
|
|
|
return {
|
|
backendHost,
|
|
hasSeparateBackendHost
|
|
};
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @returns {string|RegExp}
|
|
*/
|
|
const getBackendMountPath = function getFrontendMountPath() {
|
|
const {backendHost, hasSeparateBackendHost} = getHostInfo(this);
|
|
|
|
// with a separate admin url only serve on that host, otherwise serve on all hosts
|
|
return (hasSeparateBackendHost) && backendHost ? backendHost : DEFAULT_HOST_ARG;
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @returns {string|RegExp}
|
|
*/
|
|
const getFrontendMountPath = function getFrontendMountPath() {
|
|
const {backendHost, hasSeparateBackendHost} = getHostInfo(this);
|
|
|
|
// with a separate admin url we adjust the frontend vhost to exclude requests to that host, otherwise serve on all hosts
|
|
return (hasSeparateBackendHost && backendHost) ? new RegExp(`^(?!${escapeRegExp(backendHost)}).*`) : DEFAULT_HOST_ARG;
|
|
};
|
|
|
|
/**
|
|
* @callback isPrivacyDisabledFn
|
|
* @param {string} privacyFlag - the flag to be looked up
|
|
* @returns {boolean}
|
|
*/
|
|
const isPrivacyDisabled = function isPrivacyDisabled(privacyFlag) {
|
|
if (!this.get('privacy')) {
|
|
return false;
|
|
}
|
|
|
|
// CASE: disable all privacy features
|
|
if (this.get('privacy').useTinfoil === true) {
|
|
// CASE: you can still enable single features
|
|
if (this.get('privacy')[privacyFlag] === true) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return this.get('privacy')[privacyFlag] === false;
|
|
};
|
|
|
|
/**
|
|
* @callback getContentPathFn
|
|
* @param {string} type - the type of context you want the path for
|
|
* @returns {string}
|
|
*/
|
|
const getContentPath = function getContentPath(type) {
|
|
switch (type) {
|
|
case 'images':
|
|
return path.join(this.get('paths:contentPath'), 'images/');
|
|
case 'media':
|
|
return path.join(this.get('paths:contentPath'), 'media/');
|
|
case 'files':
|
|
return path.join(this.get('paths:contentPath'), 'files/');
|
|
case 'themes':
|
|
return path.join(this.get('paths:contentPath'), 'themes/');
|
|
case 'adapters':
|
|
return path.join(this.get('paths:contentPath'), 'adapters/');
|
|
case 'logs':
|
|
return path.join(this.get('paths:contentPath'), 'logs/');
|
|
case 'data':
|
|
return path.join(this.get('paths:contentPath'), 'data/');
|
|
case 'settings':
|
|
return path.join(this.get('paths:contentPath'), 'settings/');
|
|
case 'public':
|
|
return path.join(this.get('paths:contentPath'), 'public/');
|
|
default:
|
|
// new Error is allowed here, as we do not want config to depend on @tryghost/error
|
|
// @TODO: revisit this decision when @tryghost/error is no longer dependent on all of ghost-ignition
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
throw new Error('getContentPath was called with: ' + type);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @typedef ConfigHelpers
|
|
* @property {isPrivacyDisabledFn} isPrivacyDisabled
|
|
* @property {getContentPathFn} getContentPath
|
|
*/
|
|
module.exports.bindAll = (nconf) => {
|
|
nconf.isPrivacyDisabled = isPrivacyDisabled.bind(nconf);
|
|
nconf.getContentPath = getContentPath.bind(nconf);
|
|
nconf.getBackendMountPath = getBackendMountPath.bind(nconf);
|
|
nconf.getFrontendMountPath = getFrontendMountPath.bind(nconf);
|
|
};
|