mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-22 10:21:36 +03:00
a701ee7023
no-issue * Added default for getting origin of request This function is used to attach the origin of the request to the session, and later check that requests using the session are coming from the same origin. This protects us against CSRF attacks as requests in the browser MUST originate from the same origin on which the user logged in. Previously, when we could not determine the origin we would return null, as a "safety" net. This updates the function to use a secure and sensible default - which is the origin of the Ghost-Admin application, and if that's not set - the origin of the Ghost application. This will make dealing with magic links simpler as you can not always guaruntee the existence of these headers when visiting via a hyperlink * Removed init fns and getters from session service This simplifies the code here, making it easier to read and maintain * Moved express-session initialisation to own file This is complex enough that it deserves its own module * Added createSessionFromToken to session service * Wired up the createSessionFromToken middleware
93 lines
3.5 KiB
JavaScript
93 lines
3.5 KiB
JavaScript
const debug = require('ghost-ignition').debug('web:parent');
|
|
const express = require('express');
|
|
const vhost = require('@tryghost/vhost-middleware');
|
|
const config = require('../config');
|
|
const compress = require('compression');
|
|
const netjet = require('netjet');
|
|
const shared = require('./shared');
|
|
const escapeRegExp = require('lodash.escaperegexp');
|
|
const {URL} = require('url');
|
|
const urlUtils = require('../lib/url-utils');
|
|
const storage = require('../adapters/storage');
|
|
const sentry = require('../sentry');
|
|
|
|
const STATIC_IMAGE_URL_PREFIX = `/${urlUtils.STATIC_IMAGE_URL_PREFIX}`;
|
|
|
|
module.exports = function setupParentApp(options = {}) {
|
|
debug('ParentApp setup start');
|
|
const parentApp = express();
|
|
parentApp.use(sentry.requestHandler);
|
|
|
|
// ## Global settings
|
|
|
|
// Make sure 'req.secure' is valid for proxied requests
|
|
// (X-Forwarded-Proto header will be checked, if present)
|
|
parentApp.enable('trust proxy');
|
|
|
|
parentApp.use(shared.middlewares.requestId);
|
|
parentApp.use(shared.middlewares.logRequest);
|
|
|
|
// Register event emmiter on req/res to trigger cache invalidation webhook event
|
|
parentApp.use(shared.middlewares.emitEvents);
|
|
|
|
// enabled gzip compression by default
|
|
if (config.get('compress') !== false) {
|
|
parentApp.use(compress());
|
|
}
|
|
|
|
// Preload link headers
|
|
if (config.get('preloadHeaders')) {
|
|
parentApp.use(netjet({
|
|
cache: {
|
|
max: config.get('preloadHeaders')
|
|
}
|
|
}));
|
|
}
|
|
|
|
// This sets global res.locals which are needed everywhere
|
|
parentApp.use(shared.middlewares.ghostLocals);
|
|
|
|
// Mount the express apps on the parentApp
|
|
|
|
const adminHost = config.get('admin:url') ? (new URL(config.get('admin:url')).hostname) : '';
|
|
const frontendHost = new URL(config.get('url')).hostname;
|
|
const hasSeparateAdmin = adminHost && adminHost !== frontendHost;
|
|
|
|
// Wrap the admin and API apps into a single express app for use with vhost
|
|
const adminApp = express();
|
|
adminApp.use(sentry.requestHandler);
|
|
adminApp.enable('trust proxy'); // required to respect x-forwarded-proto in admin requests
|
|
adminApp.use('/ghost/api', require('./api')());
|
|
adminApp.use('/ghost/.well-known', require('./well-known')());
|
|
adminApp.use('/ghost', require('../services/auth/session').createSessionFromToken, require('./admin')());
|
|
|
|
// TODO: remove {admin url}/content/* once we're sure the API is not returning relative asset URLs anywhere
|
|
// only register this route if the admin is separate so we're not overriding the {site}/content/* route
|
|
if (hasSeparateAdmin) {
|
|
adminApp.use(
|
|
STATIC_IMAGE_URL_PREFIX,
|
|
[
|
|
shared.middlewares.image.handleImageSizes,
|
|
storage.getStorage().serve(),
|
|
shared.middlewares.errorHandler.handleThemeResponse
|
|
]
|
|
);
|
|
}
|
|
|
|
// ADMIN + API
|
|
// with a separate admin url only serve on that host, otherwise serve on all hosts
|
|
const adminVhostArg = hasSeparateAdmin && adminHost ? adminHost : /.*/;
|
|
parentApp.use(vhost(adminVhostArg, adminApp));
|
|
|
|
// BLOG
|
|
// with a separate admin url we adjust the frontend vhost to exclude requests to that host, otherwise serve on all hosts
|
|
const frontendVhostArg = (hasSeparateAdmin && adminHost) ?
|
|
new RegExp(`^(?!${escapeRegExp(adminHost)}).*`) : /.*/;
|
|
|
|
parentApp.use(vhost(frontendVhostArg, require('./site')(options)));
|
|
|
|
debug('ParentApp setup end');
|
|
|
|
return parentApp;
|
|
};
|