From 68ccc3e7c2c08c830652dda64665cd7a2dcd649d Mon Sep 17 00:00:00 2001 From: steven-supersolid Date: Wed, 26 Oct 2016 18:14:04 +0100 Subject: [PATCH 1/3] Add tests. Fail request if any of the 4 optional keys does not match --- spec/Middlewares.spec.js | 55 ++++++++++++++++++++++++++++++++++++++++ src/middlewares.js | 16 +++--------- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/spec/Middlewares.spec.js b/spec/Middlewares.spec.js index 45efc2fd2d..fd62d0e9f1 100644 --- a/spec/Middlewares.spec.js +++ b/spec/Middlewares.spec.js @@ -17,6 +17,7 @@ describe('middlewares', () => { return fakeReq.headers[key.toLowerCase()] } }; + fakeRes = jasmine.createSpyObj('fakeRes', ['end', 'status']); AppCache.put(fakeReq.body._ApplicationId, {}); }); @@ -35,6 +36,60 @@ describe('middlewares', () => { }); }); + it('should give invalid response when any configured key is missing', () => { + AppCache.put(fakeReq.body._ApplicationId, { + masterKey: 'masterKey', + restAPIKey: 'restAPIKey' + }); + middlewares.handleParseHeaders(fakeReq, fakeRes); + expect(fakeRes.status).toHaveBeenCalledWith(403); + }); + + it('should give invalid response when any configured key is supplied but incorrect', () => { + AppCache.put(fakeReq.body._ApplicationId, { + masterKey: 'masterKey', + restAPIKey: 'restAPIKey' + }); + fakeReq.headers['x-parse-rest-api-key'] = 'wrongKey'; + middlewares.handleParseHeaders(fakeReq, fakeRes); + expect(fakeRes.status).toHaveBeenCalledWith(403); + }); + + it('should succeed when all configured keys supplied', (done) => { + AppCache.put(fakeReq.body._ApplicationId, { + masterKey: 'masterKey', + restAPIKey: 'restAPIKey' + }); + fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey'; + middlewares.handleParseHeaders(fakeReq, fakeRes, () => { + expect(fakeRes.status).not.toHaveBeenCalled(); + done(); + }); + }); + + it('should succeed when no keys are configured and none supplied', (done) => { + AppCache.put(fakeReq.body._ApplicationId, { + masterKey: 'masterKey' + }); + middlewares.handleParseHeaders(fakeReq, fakeRes, () => { + expect(fakeRes.status).not.toHaveBeenCalled(); + done(); + }); + }); + + it('should succeed when keys are configured and extra keys supplied', (done) => { + AppCache.put(fakeReq.body._ApplicationId, { + masterKey: 'masterKey', + restAPIKey: 'restAPIKey' + }); + fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey'; + fakeReq.headers['x-parse-client-key'] = 'clientKey'; + middlewares.handleParseHeaders(fakeReq, fakeRes, () => { + expect(fakeRes.status).not.toHaveBeenCalled(); + done(); + }); + }); + const BodyParams = { clientVersion: '_ClientVersion', installationId: '_InstallationId', diff --git a/src/middlewares.js b/src/middlewares.js index ca054c0a32..0f870b1faa 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -121,19 +121,11 @@ export function handleParseHeaders(req, res, next) { // Client keys are not required in parse-server, but if any have been configured in the server, validate them // to preserve original behavior. let keys = ["clientKey", "javascriptKey", "dotNetKey", "restAPIKey"]; + var keyMismatch = keys.some(function(key){ + return req.config[key] && info[key] !== req.config[key]; + }); - // We do it with mismatching keys to support no-keys config - var keyMismatch = keys.reduce(function(mismatch, key){ - - // check if set in the config and compare - if (req.config[key] && info[key] !== req.config[key]) { - mismatch++; - } - return mismatch; - }, 0); - - // All keys mismatch - if (keyMismatch == keys.length) { + if (keyMismatch) { return invalidRequest(req, res); } From 2bfeeb968aa9c6f1a52a10b10f242cf15ea65941 Mon Sep 17 00:00:00 2001 From: steven-supersolid Date: Wed, 26 Oct 2016 18:56:03 +0100 Subject: [PATCH 2/3] Only require one key to be supplied in the request, except when no keys are configured --- spec/Middlewares.spec.js | 29 ++++++++++++++--------------- src/middlewares.js | 9 ++++++--- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/spec/Middlewares.spec.js b/spec/Middlewares.spec.js index fd62d0e9f1..a17b40e782 100644 --- a/spec/Middlewares.spec.js +++ b/spec/Middlewares.spec.js @@ -36,7 +36,7 @@ describe('middlewares', () => { }); }); - it('should give invalid response when any configured key is missing', () => { + it('should give invalid response when keys are configured but no key supplied', () => { AppCache.put(fakeReq.body._ApplicationId, { masterKey: 'masterKey', restAPIKey: 'restAPIKey' @@ -45,7 +45,7 @@ describe('middlewares', () => { expect(fakeRes.status).toHaveBeenCalledWith(403); }); - it('should give invalid response when any configured key is supplied but incorrect', () => { + it('should give invalid response when keys are configured but supplied key is incorrect', () => { AppCache.put(fakeReq.body._ApplicationId, { masterKey: 'masterKey', restAPIKey: 'restAPIKey' @@ -55,35 +55,34 @@ describe('middlewares', () => { expect(fakeRes.status).toHaveBeenCalledWith(403); }); - it('should succeed when all configured keys supplied', (done) => { + it('should give invalid response when keys are configured but different key is supplied', () => { AppCache.put(fakeReq.body._ApplicationId, { masterKey: 'masterKey', restAPIKey: 'restAPIKey' }); - fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { - expect(fakeRes.status).not.toHaveBeenCalled(); - done(); - }); + fakeReq.headers['x-parse-client-key'] = 'clientKey'; + middlewares.handleParseHeaders(fakeReq, fakeRes); + expect(fakeRes.status).toHaveBeenCalledWith(403); }); - it('should succeed when no keys are configured and none supplied', (done) => { + + it('should succeed when any one of the configured keys supplied', (done) => { AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey' + clientKey: 'clientKey', + masterKey: 'masterKey', + restAPIKey: 'restAPIKey' }); + fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey'; middlewares.handleParseHeaders(fakeReq, fakeRes, () => { expect(fakeRes.status).not.toHaveBeenCalled(); done(); }); }); - it('should succeed when keys are configured and extra keys supplied', (done) => { + it('should succeed when no keys are configured and none supplied', (done) => { AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - restAPIKey: 'restAPIKey' + masterKey: 'masterKey' }); - fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey'; - fakeReq.headers['x-parse-client-key'] = 'clientKey'; middlewares.handleParseHeaders(fakeReq, fakeRes, () => { expect(fakeRes.status).not.toHaveBeenCalled(); done(); diff --git a/src/middlewares.js b/src/middlewares.js index 0f870b1faa..f690c01fd0 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -121,11 +121,14 @@ export function handleParseHeaders(req, res, next) { // Client keys are not required in parse-server, but if any have been configured in the server, validate them // to preserve original behavior. let keys = ["clientKey", "javascriptKey", "dotNetKey", "restAPIKey"]; - var keyMismatch = keys.some(function(key){ - return req.config[key] && info[key] !== req.config[key]; + var oneKeyConfigured = keys.some(function(key) { + return req.config[key]; + }); + var oneKeyMatches = keys.some(function(key){ + return req.config[key] && info[key] == req.config[key]; }); - if (keyMismatch) { + if (oneKeyConfigured && !oneKeyMatches) { return invalidRequest(req, res); } From 6fea8b3a2b507fe05abe4f41e3a5a0875ea04ee8 Mon Sep 17 00:00:00 2001 From: steven-supersolid Date: Wed, 26 Oct 2016 20:49:23 +0100 Subject: [PATCH 3/3] Use const over let, var --- src/middlewares.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/middlewares.js b/src/middlewares.js index f690c01fd0..650b20d9a2 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -120,11 +120,11 @@ export function handleParseHeaders(req, res, next) { // Client keys are not required in parse-server, but if any have been configured in the server, validate them // to preserve original behavior. - let keys = ["clientKey", "javascriptKey", "dotNetKey", "restAPIKey"]; - var oneKeyConfigured = keys.some(function(key) { + const keys = ["clientKey", "javascriptKey", "dotNetKey", "restAPIKey"]; + const oneKeyConfigured = keys.some(function(key) { return req.config[key]; }); - var oneKeyMatches = keys.some(function(key){ + const oneKeyMatches = keys.some(function(key){ return req.config[key] && info[key] == req.config[key]; });