diff --git a/ghost/core/core/frontend/web/site.js b/ghost/core/core/frontend/web/site.js index 4b8188915a..cba271b24e 100644 --- a/ghost/core/core/frontend/web/site.js +++ b/ghost/core/core/frontend/web/site.js @@ -121,9 +121,6 @@ module.exports = function setupSiteApp(routerConfig) { // Serve site files using the storage adapter siteApp.use(STATIC_FILES_URL_PREFIX, storage.getStorage('files').serve()); - // Global handling for member session, ensures a member is logged in to the frontend - siteApp.use(membersService.middleware.loadMemberSession); - // /member/.well-known/* serves files (e.g. jwks.json) so it needs to be mounted before the prettyUrl mw to avoid trailing slashes siteApp.use( '/members/.well-known', @@ -148,18 +145,23 @@ module.exports = function setupSiteApp(routerConfig) { // Theme static assets/files siteApp.use(mw.staticTheme()); + + // Serve robots.txt if not found in theme + siteApp.use(mw.servePublicFile('static', 'robots.txt', 'text/plain', config.get('caching:robotstxt:maxAge'))); + debug('Static content done'); + // site map - this should probably be refactored to be an internal app + sitemapHandler(siteApp); + + // Global handling for member session, ensures a member is logged in to the frontend + siteApp.use(membersService.middleware.loadMemberSession); + // Theme middleware // This should happen AFTER any shared assets are served, as it only changes things to do with templates siteApp.use(themeMiddleware); debug('Themes done'); - // Serve robots.txt if not found in theme - siteApp.use(mw.servePublicFile('static', 'robots.txt', 'text/plain', config.get('caching:robotstxt:maxAge'))); - - // site map - this should probably be refactored to be an internal app - sitemapHandler(siteApp); debug('Internal apps done'); // Add in all trailing slashes & remove uppercase diff --git a/ghost/core/test/e2e-frontend/middleware.test.js b/ghost/core/test/e2e-frontend/middleware.test.js new file mode 100644 index 0000000000..e48032c8ae --- /dev/null +++ b/ghost/core/test/e2e-frontend/middleware.test.js @@ -0,0 +1,94 @@ +const sinon = require('sinon'); +const supertest = require('supertest'); +const testUtils = require('../utils'); +const configUtils = require('../utils/configUtils'); +const membersService = require('../../core/server/services/members'); + +describe('Middleware Execution', function () { + let loadMemberSessionMiddlewareSpy; + let request; + + before(async function () { + loadMemberSessionMiddlewareSpy = sinon.spy(membersService.middleware, 'loadMemberSession'); + + // Ensure we do a forced start so that spy is in place when the server starts + await testUtils.startGhost({forceStart: true}); + + request = supertest.agent(configUtils.config.get('url')); + }); + + after(async function () { + sinon.restore(); + + await testUtils.stopGhost(); + }); + + afterEach(function () { + loadMemberSessionMiddlewareSpy.resetHistory(); + }); + + describe('Loading a member session', function () { + describe('Page with member content', function () { + it('should load member session on home route', async function () { + await request.get('/'); + sinon.assert.calledOnce(loadMemberSessionMiddlewareSpy); + }); + + it('should load member session on post route', async function () { + await request.get('/welcome/'); + sinon.assert.calledOnce(loadMemberSessionMiddlewareSpy); + }); + }); + + describe('Sitemap', function () { + it('should not load member session on sitemap route', async function () { + await request.get('/sitemap.xml'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + + it('should not load member session on sitemap-pages route', async function () { + await request.get('/sitemap-pages.xml'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + + it('should not load member session on sitemap-posts route', async function () { + await request.get('/sitemap-posts.xml'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + + it('should not load member session on sitemap-tags route', async function () { + await request.get('/sitemap-tags.xml'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + + it('should not load member session on sitemap-authors route', async function () { + await request.get('/sitemap-authors.xml'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + }); + + describe('Recommendations', function () { + it('should not load member session on recommendations route', async function () { + await request.get('/.well-known/recommendations.json'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + }); + + describe('Static assets', function () { + it('should not load member session on fonts route', async function () { + await request.get('/assets/fonts/inter-roman.woff2'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + + it('should not load member session on source.js route', async function () { + await request.get('/assets/built/source.js'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + + it('should not load member session on screen.css route', async function () { + await request.get('/assets/built/screen.css'); + sinon.assert.notCalled(loadMemberSessionMiddlewareSpy); + }); + }); + }); +});