0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Have /ghost use its own express instance

closes #1961
- Refactor admin to use its own express instance
- Refactor middlewares to work with /ghost mounted admin express instance
This commit is contained in:
Fabian Becker 2014-09-16 21:02:31 +00:00
parent 9fb038f8d3
commit 9394fad6aa
5 changed files with 65 additions and 77 deletions

View file

@ -132,6 +132,7 @@ function initNotifications() {
function init(options) { function init(options) {
// Get reference to an express app instance. // Get reference to an express app instance.
var server = options.app ? options.app : express(), var server = options.app ? options.app : express(),
adminExpress = express(),
// create a hash for cache busting assets // create a hash for cache busting assets
assetHash = (crypto.createHash('md5').update(packageInfo.version + Date.now()).digest('hex')).substring(0, 10); assetHash = (crypto.createHash('md5').update(packageInfo.version + Date.now()).digest('hex')).substring(0, 10);
@ -191,13 +192,14 @@ function init(options) {
server.set('view engine', 'hbs'); server.set('view engine', 'hbs');
// Create a hbs instance for admin and init view engine // Create a hbs instance for admin and init view engine
server.set('admin view engine', adminHbs.express3({})); adminExpress.set('view engine', 'hbs');
adminExpress.engine('hbs', adminHbs.express3({}));
// Load helpers // Load helpers
helpers.loadCoreHelpers(adminHbs, assetHash); helpers.loadCoreHelpers(adminHbs, assetHash);
// ## Middleware and Routing // ## Middleware and Routing
middleware(server, dbHash); middleware(server, adminExpress);
// Log all theme errors and warnings // Log all theme errors and warnings
_.each(config.paths.availableThemes._messages.errors, function (error) { _.each(config.paths.availableThemes._messages.errors, function (error) {

View file

@ -43,16 +43,6 @@ function ghostLocals(req, res, next) {
next(); next();
} }
function initThemeData(secure) {
var themeConfig = config.theme;
if (secure && config.urlSSL) {
// For secure requests override .url property with the SSL version
themeConfig = _.clone(themeConfig);
themeConfig.url = config.urlSSL.replace(/\/$/, '');
}
return themeConfig;
}
// ### Activate Theme // ### Activate Theme
// Helper for manageAdminAndTheme // Helper for manageAdminAndTheme
function activateTheme(activeTheme) { function activateTheme(activeTheme) {
@ -72,7 +62,7 @@ function activateTheme(activeTheme) {
} }
}); });
expressServer.set('theme view engine', hbs.express3(hbsOptions)); expressServer.engine('hbs', hbs.express3(hbsOptions));
// Update user error template // Update user error template
errors.updateActiveTheme(activeTheme); errors.updateActiveTheme(activeTheme);
@ -91,18 +81,16 @@ function decideIsAdmin(req, res, next) {
// ### configHbsForContext Middleware // ### configHbsForContext Middleware
// Setup handlebars for the current context (admin or theme) // Setup handlebars for the current context (admin or theme)
function configHbsForContext(req, res, next) { function configHbsForContext(req, res, next) {
if (res.isAdmin) { var themeData = config.theme;
expressServer.enable('admin'); if (req.secure && config.urlSSL) {
expressServer.engine('hbs', expressServer.get('admin view engine')); // For secure requests override .url property with the SSL version
expressServer.set('views', config.paths.adminViews); themeData = _.clone(themeData);
} else { themeData.url = config.urlSSL.replace(/\/$/, '');
expressServer.disable('admin');
var themeData = initThemeData(req.secure);
hbs.updateTemplateOptions({data: {blog: themeData}});
expressServer.engine('hbs', expressServer.get('theme view engine'));
expressServer.set('views', path.join(config.paths.themePath, expressServer.get('activeTheme')));
} }
hbs.updateTemplateOptions({data: {blog: themeData}});
expressServer.set('views', path.join(config.paths.themePath, expressServer.get('activeTheme')));
// Pass 'secure' flag to the view engine // Pass 'secure' flag to the view engine
// so that templates can choose 'url' vs 'urlSSL' // so that templates can choose 'url' vs 'urlSSL'
res.locals.secure = req.secure; res.locals.secure = req.secure;
@ -143,7 +131,7 @@ function redirectToSetup(req, res, next) {
/*jslint unparam:true*/ /*jslint unparam:true*/
api.authentication.isSetup().then(function (exists) { api.authentication.isSetup().then(function (exists) {
if (!exists.setup[0].status && !req.path.match(/\/ghost\/setup\//)) { if (!exists.setup[0].status && !req.path.match(/\/setup\//)) {
return res.redirect(config.paths.subdir + '/ghost/setup/'); return res.redirect(config.paths.subdir + '/ghost/setup/');
} }
next(); next();
@ -247,7 +235,7 @@ function serveSharedFile(file, type, maxAge) {
}; };
} }
setupMiddleware = function (server) { setupMiddleware = function (server, adminExpress) {
var logging = config.logging, var logging = config.logging,
corePath = config.paths.corePath, corePath = config.paths.corePath,
oauthServer = oauth2orize.createServer(); oauthServer = oauth2orize.createServer();
@ -289,13 +277,14 @@ setupMiddleware = function (server) {
expressServer.use(configHbsForContext); expressServer.use(configHbsForContext);
// Admin only config // Admin only config
expressServer.use('/ghost', middleware.whenEnabled('admin', express['static'](path.join(corePath, '/client/assets'), {maxAge: utils.ONE_YEAR_MS}))); expressServer.use('/ghost', express['static'](path.join(corePath, '/client/assets'), {maxAge: utils.ONE_YEAR_MS}));
// Force SSL // Force SSL
// NOTE: Importantly this is _after_ the check above for admin-theme static resources, // 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 // 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! // not display properly when HTTPS is not available!
expressServer.use(checkSSL); expressServer.use(checkSSL);
adminExpress.set('views', config.paths.adminViews);
// Theme only config // Theme only config
expressServer.use(middleware.staticTheme()); expressServer.use(middleware.staticTheme());
@ -321,7 +310,7 @@ setupMiddleware = function (server) {
// ### Caching // ### Caching
expressServer.use(middleware.cacheControl('public')); expressServer.use(middleware.cacheControl('public'));
expressServer.use('/ghost/', middleware.cacheControl('private')); adminExpress.use(middleware.cacheControl('private'));
// enable authentication // enable authentication
expressServer.use(middleware.authenticate); expressServer.use(middleware.authenticate);
@ -333,8 +322,10 @@ setupMiddleware = function (server) {
// Set up API routes // Set up API routes
expressServer.use(routes.apiBaseUri, routes.api(middleware)); expressServer.use(routes.apiBaseUri, routes.api(middleware));
// Set up Admin routes // Mount admin express app to /ghost and set up routes
expressServer.use(routes.admin(middleware)); adminExpress.use(middleware.redirectToSetup);
adminExpress.use(routes.admin());
expressServer.use('/ghost', adminExpress);
// Set up Frontend routes // Set up Frontend routes
expressServer.use(routes.frontend()); expressServer.use(routes.frontend());

View file

@ -50,31 +50,29 @@ middleware = {
return a; return a;
}); });
if (res.isAdmin) { if (subPath.indexOf('/ghost/api/') === 0
if (subPath.indexOf('/ghost/api/') === 0 && path.indexOf('/ghost/api/v0.1/authentication/') !== 0) {
&& path.indexOf('/ghost/api/v0.1/authentication/') !== 0) { return passport.authenticate('bearer', {session: false, failWithError: true},
return passport.authenticate('bearer', {session: false, failWithError: true}, function (err, user, info) {
function (err, user, info) { if (err) {
if (err) { return next(err); // will generate a 500 error
return next(err); // will generate a 500 error
}
// Generate a JSON response reflecting authentication status
if (!user) {
var msg = {
type: 'error',
message: 'Please Sign In',
status: 'passive'
};
res.status(401);
return res.send(msg);
}
// TODO: figure out, why user & authInfo is lost
req.authInfo = info;
req.user = user;
return next(null, user, info);
} }
)(req, res, next); // Generate a JSON response reflecting authentication status
} if (!user) {
var msg = {
type: 'error',
message: 'Please Sign In',
status: 'passive'
};
res.status(401);
return res.send(msg);
}
// TODO: figure out, why user & authInfo is lost
req.authInfo = info;
req.user = user;
return next(null, user, info);
}
)(req, res, next);
} }
next(); next();
}, },

View file

@ -1,33 +1,12 @@
var admin = require('../controllers/admin'), var admin = require('../controllers/admin'),
config = require('../config'),
express = require('express'), express = require('express'),
utils = require('../utils'),
adminRoutes; adminRoutes;
adminRoutes = function (middleware) { adminRoutes = function () {
var router = express.Router(), var router = express.Router();
subdir = config.paths.subdir;
// ### Admin routes router.get('*', admin.index);
router.get(/^\/(logout|signout)\/$/, function redirect(req, res) {
/*jslint unparam:true*/
res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
res.redirect(301, subdir + '/ghost/signout/');
});
router.get(/^\/signup\/$/, function redirect(req, res) {
/*jslint unparam:true*/
res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
res.redirect(301, subdir + '/ghost/signup/');
});
// redirect to /ghost and let that do the authentication to prevent redirects to /ghost//admin etc.
router.get(/^\/((ghost-admin|admin|wp-admin|dashboard|signin|login)\/?)$/, function (req, res) {
/*jslint unparam:true*/
res.redirect(subdir + '/ghost/');
});
router.get(/^\/ghost\//, middleware.redirectToSetup, admin.index);
return router; return router;
}; };

View file

@ -9,6 +9,24 @@ frontendRoutes = function () {
var router = express.Router(), var router = express.Router(),
subdir = config.paths.subdir; subdir = config.paths.subdir;
// ### Admin routes
router.get(/^\/(logout|signout)\/$/, function redirect(req, res) {
/*jslint unparam:true*/
res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
res.redirect(301, subdir + '/ghost/signout/');
});
router.get(/^\/signup\/$/, function redirect(req, res) {
/*jslint unparam:true*/
res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
res.redirect(301, subdir + '/ghost/signup/');
});
// redirect to /ghost and let that do the authentication to prevent redirects to /ghost//admin etc.
router.get(/^\/((ghost-admin|admin|wp-admin|dashboard|signin|login)\/?)$/, function (req, res) {
/*jslint unparam:true*/
res.redirect(subdir + '/ghost/');
});
// ### Frontend routes // ### Frontend routes
router.get('/rss/', frontend.rss); router.get('/rss/', frontend.rss);
router.get('/rss/:page/', frontend.rss); router.get('/rss/:page/', frontend.rss);