Ghost/core/server/web/admin/app.js
Kevin Ansfield 7284227f1e
🐛 Fixed 404s when using a proxy setup (#11269)
no issue

When using certain proxy setups that result in `host` and `x-forwarded-host` being different, it became impossible to access Ghost because all routes showed generic 404 pages.

- `vhost` module that we are using to separate front-end and admin urls does not use express' `req.hostname` so it does not pick up the `x-forwarded-host` url that express' `'trust proxy'` config gives us
- switched to the forked `@tryghost/vhost-middleware` package which has a one-line change to use `req.hostname || req.host`
- added `'trust proxy'` config to the admin express app and switched to using `req.hostname` in our redirect code to avoid infinite redirect loops
2019-10-28 11:22:05 +00:00

60 lines
2.2 KiB
JavaScript

const debug = require('ghost-ignition').debug('web:admin:app');
const express = require('express');
const serveStatic = require('express').static;
const config = require('../../config');
const constants = require('../../lib/constants');
const urlUtils = require('../../lib/url-utils');
const shared = require('../shared');
const adminMiddleware = require('./middleware');
module.exports = function setupAdminApp() {
debug('Admin setup start');
const adminApp = express();
// Make sure 'req.secure' and `req.hostname` is valid for proxied requests
// (X-Forwarded-Proto header will be checked, if present)
adminApp.enable('trust proxy');
// Admin assets
// @TODO ensure this gets a local 404 error handler
const configMaxAge = config.get('caching:admin:maxAge');
adminApp.use('/assets', serveStatic(
config.get('paths').clientAssets,
{maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : constants.ONE_YEAR_MS, fallthrough: false}
));
// Ember CLI's live-reload script
if (config.get('env') === 'development') {
adminApp.get('/ember-cli-live-reload.js', function emberLiveReload(req, res) {
res.redirect(`http://localhost:4200${urlUtils.getSubdir()}/ghost/ember-cli-live-reload.js`);
});
}
// Render error page in case of maintenance
adminApp.use(shared.middlewares.maintenance);
// Force SSL if required
// must happen AFTER asset loading and BEFORE routing
adminApp.use(shared.middlewares.urlRedirects.adminRedirect);
// Add in all trailing slashes & remove uppercase
// must happen AFTER asset loading and BEFORE routing
adminApp.use(shared.middlewares.prettyUrls);
// Cache headers go last before serving the request
// Admin is currently set to not be cached at all
adminApp.use(shared.middlewares.cacheControl('private'));
// Special redirects for the admin (these should have their own cache-control headers)
adminApp.use(adminMiddleware);
// Finally, routing
adminApp.get('*', require('./controller'));
adminApp.use(shared.middlewares.errorHandler.pageNotFound);
adminApp.use(shared.middlewares.errorHandler.handleHTMLResponse);
debug('Admin setup end');
return adminApp;
};