Ghost/core/test/unit/web/parent-app_spec.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

111 lines
3.4 KiB
JavaScript

const should = require('should');
const sinon = require('sinon');
const proxyquire = require('proxyquire');
const configUtils = require('../../utils/configUtils');
describe('parent app', function () {
let expressStub;
let vhostSpy;
let use;
let apiSpy;
let parentApp;
let adminSpy;
let siteSpy;
let gatewaySpy;
let authPagesSpy;
beforeEach(function () {
use = sinon.spy();
expressStub = () => ({
use,
enable: () => {}
});
vhostSpy = sinon.spy();
apiSpy = sinon.spy();
adminSpy = sinon.spy();
siteSpy = sinon.spy();
gatewaySpy = sinon.spy();
authPagesSpy = sinon.spy();
parentApp = proxyquire('../../../server/web/parent-app', {
express: expressStub,
'@tryghost/vhost-middleware': vhostSpy,
'./api': apiSpy,
'./admin': adminSpy,
'./site': siteSpy,
'../services/members': {
gateway: gatewaySpy,
authPages: authPagesSpy
}
});
configUtils.set('url', 'http://ghost.blog');
});
afterEach(function () {
sinon.restore();
configUtils.restore();
});
// url = 'https://ghost.blog'
describe('without separate admin url', function () {
it('should mount and assign correct routes', function () {
parentApp();
use.calledWith('/ghost/api').should.be.true();
use.calledWith('/ghost').should.be.true();
use.calledWith('/content/images').should.be.false();
apiSpy.called.should.be.true();
adminSpy.called.should.be.true();
siteSpy.called.should.be.true();
vhostSpy.calledTwice.should.be.true();
vhostSpy.firstCall.calledWith(/.*/).should.be.true();
vhostSpy.secondCall.calledWith(/.*/).should.be.true();
});
});
// url = 'https://ghost.blog'
// admin.url = 'https://admin.ghost.blog'
describe('with separate admin url', function () {
beforeEach(function () {
configUtils.set('admin:url', 'https://admin.ghost.blog');
});
it('should mount and assign correct routes', function () {
parentApp();
use.calledWith('/content/images').should.be.true();
vhostSpy.calledTwice.should.be.true();
vhostSpy.firstCall.calledWith('admin.ghost.blog').should.be.true();
vhostSpy.secondCall.calledWith(/^(?!admin\.ghost\.blog).*/).should.be.true();
});
it('should have regex that excludes admin traffic on front-end', function () {
parentApp();
const frontendRegex = vhostSpy.secondCall.args[0];
frontendRegex.test('localhost').should.be.true();
frontendRegex.test('ghost.blog').should.be.true();
frontendRegex.test('admin.ghost.blog').should.be.false();
});
});
// url = 'http://ghost.blog'
// admin.url = 'https://ghost.blog'
describe('with separate admin protocol', function () {
it('should mount and assign correct routes', function () {
configUtils.set('admin:url', 'https://ghost.blog');
parentApp();
vhostSpy.calledTwice.should.be.true();
vhostSpy.firstCall.calledWith(/.*/).should.be.true();
vhostSpy.secondCall.calledWith(/.*/).should.be.true();
});
});
});