diff --git a/config.json.example b/config.json.example index 94c5c7b043..2caba18448 100644 --- a/config.json.example +++ b/config.json.example @@ -77,5 +77,6 @@ "STRIPE_PUB_KEY": "22223333444455556666777788889999", "TEST_DB_URI": "mongodb://localhost/habitrpg_test", "TRANSIFEX_SLACK_CHANNEL": "transifex", - "WEB_CONCURRENCY": 1 + "WEB_CONCURRENCY": 1, + "SKIP_SSL_CHECK_KEY": "key" } diff --git a/test/api/unit/middlewares/redirects.js b/test/api/unit/middlewares/redirects.js index d93ed5345c..17f58d15da 100644 --- a/test/api/unit/middlewares/redirects.js +++ b/test/api/unit/middlewares/redirects.js @@ -73,6 +73,39 @@ describe('redirects middleware', () => { expect(res.redirect).to.have.not.been.called; }); + + it('does not redirect if passed skip ssl request param is passed with corrrect key', () => { + let nconfStub = sandbox.stub(nconf, 'get'); + nconfStub.withArgs('BASE_URL').returns('https://habitica.com'); + nconfStub.withArgs('IS_PROD').returns(true); + nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns('test-key'); + + req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('http'); + req.originalUrl = '/static/front'; + req.query.skipSSLCheck = 'test-key'; + + const attachRedirects = requireAgain(pathToRedirectsMiddleware); + attachRedirects.forceSSL(req, res, next); + + expect(res.redirect).to.have.not.been.called; + }); + + it('does redirect if skip ssl request param is passed with incorrrect key', () => { + let nconfStub = sandbox.stub(nconf, 'get'); + nconfStub.withArgs('BASE_URL').returns('https://habitica.com'); + nconfStub.withArgs('IS_PROD').returns(true); + nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns('test-key'); + + req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('http'); + req.originalUrl = '/static/front?skipSSLCheck=INVALID'; + req.query.skipSSLCheck = 'INVALID'; + + const attachRedirects = requireAgain(pathToRedirectsMiddleware); + attachRedirects.forceSSL(req, res, next); + + expect(res.redirect).to.be.calledOnce; + expect(res.redirect).to.be.calledWith('https://habitica.com/static/front?skipSSLCheck=INVALID'); + }); }); context('forceHabitica', () => { diff --git a/website/server/middlewares/redirects.js b/website/server/middlewares/redirects.js index a7c2a2a56c..b7de10f80c 100644 --- a/website/server/middlewares/redirects.js +++ b/website/server/middlewares/redirects.js @@ -4,6 +4,9 @@ import url from 'url'; const IS_PROD = nconf.get('IS_PROD'); const IGNORE_REDIRECT = nconf.get('IGNORE_REDIRECT') === 'true'; const BASE_URL = nconf.get('BASE_URL'); +// A secret key that if passed as req.query.skipSSLCheck allows to skip +// the redirects to SSL, used for health checks from the load balancer +const SKIP_SSL_CHECK_KEY = nconf.get('SKIP_SSL_CHECK_KEY'); const BASE_URL_HOST = url.parse(BASE_URL).hostname; @@ -17,7 +20,8 @@ function isHTTP (req) { } export function forceSSL (req, res, next) { - if (isHTTP(req)) { + const skipSSLCheck = req.query.skipSSLCheck; + if (isHTTP(req) && (!skipSSLCheck || skipSSLCheck !== SKIP_SSL_CHECK_KEY)) { return res.redirect(BASE_URL + req.originalUrl); }