2015-07-15 19:01:23 +03:00
|
|
|
var bodyParser = require('body-parser'),
|
2016-05-14 21:02:45 +03:00
|
|
|
compress = require('compression'),
|
2016-07-21 14:26:16 +03:00
|
|
|
config = require('../config'),
|
|
|
|
errors = require('../errors'),
|
2016-05-14 21:02:45 +03:00
|
|
|
express = require('express'),
|
|
|
|
hbs = require('express-hbs'),
|
2015-07-15 19:01:23 +03:00
|
|
|
logger = require('morgan'),
|
|
|
|
path = require('path'),
|
2016-07-21 14:26:16 +03:00
|
|
|
routes = require('../routes'),
|
2015-09-27 22:14:09 +03:00
|
|
|
serveStatic = require('express').static,
|
2015-07-15 19:01:23 +03:00
|
|
|
slashes = require('connect-slashes'),
|
2016-07-21 14:09:11 +03:00
|
|
|
storage = require('../storage'),
|
2016-07-21 14:26:16 +03:00
|
|
|
passport = require('passport'),
|
2015-07-15 19:01:23 +03:00
|
|
|
utils = require('../utils'),
|
|
|
|
sitemapHandler = require('../data/xml/sitemap/handler'),
|
2016-07-21 14:26:16 +03:00
|
|
|
multer = require('multer'),
|
|
|
|
tmpdir = require('os').tmpdir,
|
2015-07-15 19:01:23 +03:00
|
|
|
authStrategies = require('./auth-strategies'),
|
2015-10-22 16:28:47 +03:00
|
|
|
auth = require('./auth'),
|
2015-07-15 19:01:23 +03:00
|
|
|
cacheControl = require('./cache-control'),
|
|
|
|
checkSSL = require('./check-ssl'),
|
|
|
|
decideIsAdmin = require('./decide-is-admin'),
|
2015-10-11 23:21:54 +03:00
|
|
|
oauth = require('./oauth'),
|
2015-07-15 19:01:23 +03:00
|
|
|
redirectToSetup = require('./redirect-to-setup'),
|
|
|
|
serveSharedFile = require('./serve-shared-file'),
|
|
|
|
spamPrevention = require('./spam-prevention'),
|
|
|
|
staticTheme = require('./static-theme'),
|
|
|
|
themeHandler = require('./theme-handler'),
|
2015-10-11 23:21:54 +03:00
|
|
|
uncapitalise = require('./uncapitalise'),
|
2016-07-15 19:22:41 +03:00
|
|
|
maintenance = require('./maintenance'),
|
2016-06-09 18:14:36 +03:00
|
|
|
versionMatch = require('./api/version-match'),
|
2016-03-27 01:28:00 +03:00
|
|
|
cors = require('./cors'),
|
2016-07-21 14:26:16 +03:00
|
|
|
netjet = require('netjet'),
|
2016-04-14 23:44:05 +03:00
|
|
|
labs = require('./labs'),
|
2016-05-14 21:02:45 +03:00
|
|
|
helpers = require('../helpers'),
|
2013-11-12 10:03:25 +04:00
|
|
|
|
2015-08-22 00:46:42 +03:00
|
|
|
ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy,
|
|
|
|
BearerStrategy = require('passport-http-bearer').Strategy,
|
|
|
|
|
2015-07-15 19:01:23 +03:00
|
|
|
middleware,
|
2014-07-28 17:19:49 +04:00
|
|
|
setupMiddleware;
|
2013-11-12 10:03:25 +04:00
|
|
|
|
2015-07-15 19:01:23 +03:00
|
|
|
middleware = {
|
2016-03-30 06:31:31 +03:00
|
|
|
upload: multer({dest: tmpdir()}),
|
2015-07-15 19:01:23 +03:00
|
|
|
cacheControl: cacheControl,
|
|
|
|
spamPrevention: spamPrevention,
|
2015-11-09 16:41:28 +03:00
|
|
|
oauth: oauth,
|
2015-07-15 19:01:23 +03:00
|
|
|
api: {
|
2015-10-22 16:28:47 +03:00
|
|
|
authenticateClient: auth.authenticateClient,
|
|
|
|
authenticateUser: auth.authenticateUser,
|
|
|
|
requiresAuthorizedUser: auth.requiresAuthorizedUser,
|
2015-10-23 12:03:38 +03:00
|
|
|
requiresAuthorizedUserPublicAPI: auth.requiresAuthorizedUserPublicAPI,
|
2016-03-27 01:28:00 +03:00
|
|
|
errorHandler: errors.handleAPIError,
|
2016-04-14 23:44:05 +03:00
|
|
|
cors: cors,
|
2016-06-09 18:14:36 +03:00
|
|
|
labs: labs,
|
2016-07-15 19:22:41 +03:00
|
|
|
versionMatch: versionMatch,
|
|
|
|
maintenance: maintenance
|
2015-04-25 22:54:07 +03:00
|
|
|
}
|
2015-07-15 19:01:23 +03:00
|
|
|
};
|
2014-03-09 13:28:58 +04:00
|
|
|
|
2016-05-14 21:02:45 +03:00
|
|
|
setupMiddleware = function setupMiddleware(blogApp) {
|
2014-07-17 18:33:21 +04:00
|
|
|
var logging = config.logging,
|
2016-05-14 21:02:45 +03:00
|
|
|
corePath = config.paths.corePath,
|
|
|
|
adminApp = express(),
|
|
|
|
adminHbs = hbs.create();
|
2014-06-30 16:58:10 +04:00
|
|
|
|
2016-05-14 21:02:45 +03:00
|
|
|
// ##Configuration
|
|
|
|
|
|
|
|
// enabled gzip compression by default
|
|
|
|
if (config.server.compress !== false) {
|
|
|
|
blogApp.use(compress());
|
|
|
|
}
|
|
|
|
|
|
|
|
// ## View engine
|
|
|
|
// set the view engine
|
|
|
|
blogApp.set('view engine', 'hbs');
|
|
|
|
|
|
|
|
// Create a hbs instance for admin and init view engine
|
|
|
|
adminApp.set('view engine', 'hbs');
|
|
|
|
adminApp.engine('hbs', adminHbs.express3({}));
|
|
|
|
|
|
|
|
// Load helpers
|
|
|
|
helpers.loadCoreHelpers(adminHbs);
|
|
|
|
|
|
|
|
// Initialize Auth Handlers & OAuth middleware
|
2015-08-22 00:46:42 +03:00
|
|
|
passport.use(new ClientPasswordStrategy(authStrategies.clientPasswordStrategy));
|
|
|
|
passport.use(new BearerStrategy(authStrategies.bearerStrategy));
|
2015-11-09 16:41:28 +03:00
|
|
|
oauth.init();
|
2013-12-06 18:13:15 +04:00
|
|
|
|
2014-01-27 02:00:50 +04:00
|
|
|
// Make sure 'req.secure' is valid for proxied requests
|
|
|
|
// (X-Forwarded-Proto header will be checked, if present)
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.enable('trust proxy');
|
2014-01-27 02:00:50 +04:00
|
|
|
|
2013-11-12 10:03:25 +04:00
|
|
|
// Logging configuration
|
2014-02-11 01:07:11 +04:00
|
|
|
if (logging !== false) {
|
2014-09-19 20:17:58 +04:00
|
|
|
if (blogApp.get('env') !== 'development') {
|
|
|
|
blogApp.use(logger('combined', logging));
|
2014-02-11 01:07:11 +04:00
|
|
|
} else {
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(logger('dev', logging));
|
2014-02-11 01:07:11 +04:00
|
|
|
}
|
2013-11-12 10:03:25 +04:00
|
|
|
}
|
|
|
|
|
2016-04-22 21:26:28 +03:00
|
|
|
// Preload link headers
|
|
|
|
if (config.preloadHeaders) {
|
|
|
|
blogApp.use(netjet({
|
|
|
|
cache: {
|
|
|
|
max: config.preloadHeaders
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
}
|
2016-07-15 19:22:41 +03:00
|
|
|
|
2013-11-12 10:03:25 +04:00
|
|
|
// Favicon
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(serveSharedFile('favicon.ico', 'image/x-icon', utils.ONE_DAY_S));
|
2013-11-12 10:03:25 +04:00
|
|
|
|
2015-12-15 13:41:53 +03:00
|
|
|
// Ghost-Url
|
|
|
|
blogApp.use(serveSharedFile('shared/ghost-url.js', 'application/javascript', utils.ONE_HOUR_S));
|
|
|
|
blogApp.use(serveSharedFile('shared/ghost-url.min.js', 'application/javascript', utils.ONE_HOUR_S));
|
|
|
|
|
2013-12-31 03:13:25 +04:00
|
|
|
// Static assets
|
2015-09-27 22:14:09 +03:00
|
|
|
blogApp.use('/shared', serveStatic(
|
|
|
|
path.join(corePath, '/shared'),
|
|
|
|
{maxAge: utils.ONE_HOUR_MS, fallthrough: false}
|
|
|
|
));
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use('/content/images', storage.getStorage().serve());
|
2015-09-27 22:14:09 +03:00
|
|
|
blogApp.use('/public', serveStatic(
|
|
|
|
path.join(corePath, '/built/public'),
|
|
|
|
{maxAge: utils.ONE_YEAR_MS, fallthrough: false}
|
|
|
|
));
|
2013-11-12 10:03:25 +04:00
|
|
|
|
|
|
|
// First determine whether we're serving admin or theme content
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(decideIsAdmin);
|
2016-07-21 14:26:16 +03:00
|
|
|
blogApp.use(themeHandler.updateActiveTheme);
|
2015-10-11 23:21:54 +03:00
|
|
|
blogApp.use(themeHandler.configHbsForContext);
|
2013-11-12 10:03:25 +04:00
|
|
|
|
|
|
|
// Admin only config
|
2015-09-27 22:14:09 +03:00
|
|
|
blogApp.use('/ghost', serveStatic(
|
|
|
|
config.paths.clientAssets,
|
|
|
|
{maxAge: utils.ONE_YEAR_MS}
|
|
|
|
));
|
2013-11-12 10:03:25 +04:00
|
|
|
|
2014-01-27 02:21:24 +04:00
|
|
|
// Force SSL
|
|
|
|
// NOTE: Importantly this is _after_ the check above for admin-theme static resources,
|
|
|
|
// which do not need HTTPS. In fact, if HTTPS is forced on them, then 404 page might
|
|
|
|
// not display properly when HTTPS is not available!
|
2015-07-15 19:01:23 +03:00
|
|
|
blogApp.use(checkSSL);
|
2014-09-19 20:17:58 +04:00
|
|
|
adminApp.set('views', config.paths.adminViews);
|
2014-01-27 02:21:24 +04:00
|
|
|
|
2013-11-12 10:03:25 +04:00
|
|
|
// Theme only config
|
2015-07-15 19:01:23 +03:00
|
|
|
blogApp.use(staticTheme());
|
2013-11-12 10:03:25 +04:00
|
|
|
|
2016-04-14 20:32:43 +03:00
|
|
|
// setup middleware for internal apps
|
|
|
|
// @TODO: refactor this to be a proper app middleware hook for internal & external apps
|
|
|
|
config.internalApps.forEach(function (appName) {
|
|
|
|
var app = require(path.join(config.paths.internalAppPath, appName));
|
|
|
|
if (app.hasOwnProperty('setupMiddleware')) {
|
|
|
|
app.setupMiddleware(blogApp);
|
|
|
|
}
|
|
|
|
});
|
2015-03-26 10:01:39 +03:00
|
|
|
|
|
|
|
// Serve sitemap.xsl file
|
|
|
|
blogApp.use(serveSharedFile('sitemap.xsl', 'text/xsl', utils.ONE_DAY_S));
|
|
|
|
|
2014-03-09 13:28:58 +04:00
|
|
|
// Serve robots.txt if not found in theme
|
2014-09-25 14:00:51 +04:00
|
|
|
blogApp.use(serveSharedFile('robots.txt', 'text/plain', utils.ONE_HOUR_S));
|
2014-03-09 13:28:58 +04:00
|
|
|
|
2014-10-28 03:41:18 +03:00
|
|
|
// site map
|
|
|
|
sitemapHandler(blogApp);
|
|
|
|
|
2014-12-25 03:22:45 +03:00
|
|
|
// Add in all trailing slashes
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(slashes(true, {
|
2014-08-24 00:42:44 +04:00
|
|
|
headers: {
|
|
|
|
'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S
|
2014-12-25 03:22:45 +03:00
|
|
|
}
|
2014-08-24 00:42:44 +04:00
|
|
|
}));
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(uncapitalise);
|
2013-11-12 10:03:25 +04:00
|
|
|
|
2013-12-31 03:13:25 +04:00
|
|
|
// Body parsing
|
2015-10-30 15:40:07 +03:00
|
|
|
blogApp.use(bodyParser.json({limit: '1mb'}));
|
|
|
|
blogApp.use(bodyParser.urlencoded({extended: true, limit: '1mb'}));
|
2013-11-17 22:40:26 +04:00
|
|
|
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(passport.initialize());
|
2013-11-12 10:03:25 +04:00
|
|
|
|
2014-02-14 14:00:11 +04:00
|
|
|
// ### Caching
|
2015-05-18 22:56:41 +03:00
|
|
|
// Blog frontend is cacheable
|
2015-07-15 19:01:23 +03:00
|
|
|
blogApp.use(cacheControl('public'));
|
2015-05-18 22:56:41 +03:00
|
|
|
// Admin shouldn't be cached
|
2015-07-15 19:01:23 +03:00
|
|
|
adminApp.use(cacheControl('private'));
|
2015-05-18 22:56:41 +03:00
|
|
|
// API shouldn't be cached
|
2015-07-15 19:01:23 +03:00
|
|
|
blogApp.use(routes.apiBaseUri, cacheControl('private'));
|
2014-02-14 14:00:11 +04:00
|
|
|
|
2013-11-12 10:03:25 +04:00
|
|
|
// local data
|
2015-10-11 23:21:54 +03:00
|
|
|
blogApp.use(themeHandler.ghostLocals);
|
2014-04-29 00:58:18 +04:00
|
|
|
|
2013-12-31 03:13:25 +04:00
|
|
|
// ### Routing
|
2014-04-12 07:46:15 +04:00
|
|
|
// Set up API routes
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(routes.apiBaseUri, routes.api(middleware));
|
2014-04-12 07:46:15 +04:00
|
|
|
|
2014-09-17 01:02:31 +04:00
|
|
|
// Mount admin express app to /ghost and set up routes
|
2015-07-15 19:01:23 +03:00
|
|
|
adminApp.use(redirectToSetup);
|
2016-07-25 22:28:35 +03:00
|
|
|
adminApp.use(maintenance);
|
2014-09-19 20:17:58 +04:00
|
|
|
adminApp.use(routes.admin());
|
2016-07-25 22:28:35 +03:00
|
|
|
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use('/ghost', adminApp);
|
2014-04-12 07:46:15 +04:00
|
|
|
|
2016-07-15 19:22:41 +03:00
|
|
|
// send 503 error page in case of maintenance
|
|
|
|
blogApp.use(maintenance);
|
|
|
|
|
2016-04-11 16:58:41 +03:00
|
|
|
// Set up Frontend routes (including private blogging routes)
|
|
|
|
blogApp.use(routes.frontend());
|
2013-11-12 10:03:25 +04:00
|
|
|
|
|
|
|
// ### Error handling
|
|
|
|
// 404 Handler
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(errors.error404);
|
2013-11-12 10:03:25 +04:00
|
|
|
|
|
|
|
// 500 Handler
|
2014-09-19 20:17:58 +04:00
|
|
|
blogApp.use(errors.error500);
|
2013-11-12 10:03:25 +04:00
|
|
|
};
|
|
|
|
|
2014-07-14 16:29:45 +04:00
|
|
|
module.exports = setupMiddleware;
|
2013-11-12 10:03:25 +04:00
|
|
|
// Export middleware functions directly
|
2013-11-17 22:40:26 +04:00
|
|
|
module.exports.middleware = middleware;
|