diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 1de2551a..3d7f30b3 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1239,6 +1239,17 @@ describe('Cloud Code', () => { }); }); +describe('cloud functions', () => { + it('Should have request ip', (done) => { + Parse.Cloud.define('myFunction', (req, res) => { + expect(req.ip).toBeDefined(); + res.success("success"); + }); + + Parse.Cloud.run('myFunction', {}).then(() => done()); + }); +}); + describe('beforeSave hooks', () => { it('should have request headers', (done) => { Parse.Cloud.beforeSave('MyObject', (req, res) => { @@ -1250,6 +1261,17 @@ describe('beforeSave hooks', () => { const myObject = new MyObject(); myObject.save().then(() => done()); }); + + it('should have request ip', (done) => { + Parse.Cloud.beforeSave('MyObject', (req, res) => { + expect(req.ip).toBeDefined(); + res.success(); + }); + + const MyObject = Parse.Object.extend('MyObject'); + const myObject = new MyObject(); + myObject.save().then(() => done()); + }); }); describe('afterSave hooks', () => { @@ -1263,6 +1285,17 @@ describe('afterSave hooks', () => { myObject.save() .then(() => done()); }); + + it('should have request ip', (done) => { + Parse.Cloud.afterSave('MyObject', (req, res) => { + expect(req.ip).toBeDefined(); + res.success(); + }); + + const MyObject = Parse.Object.extend('MyObject'); + const myObject = new MyObject(); + myObject.save().then(() => done()); + }); }); describe('beforeDelete hooks', () => { @@ -1278,6 +1311,19 @@ describe('beforeDelete hooks', () => { .then(myObj => myObj.destroy()) .then(() => done()); }); + + it('should have request ip', (done) => { + Parse.Cloud.beforeDelete('MyObject', (req, res) => { + expect(req.ip).toBeDefined(); + res.success(); + }); + + const MyObject = Parse.Object.extend('MyObject'); + const myObject = new MyObject(); + myObject.save() + .then(myObj => myObj.destroy()) + .then(() => done()); + }); }); describe('afterDelete hooks', () => { @@ -1292,6 +1338,18 @@ describe('afterDelete hooks', () => { .then(myObj => myObj.destroy()) .then(() => done()); }); + + it('should have request ip', (done) => { + Parse.Cloud.afterDelete('MyObject', (req) => { + expect(req.ip).toBeDefined(); + }); + + const MyObject = Parse.Object.extend('MyObject'); + const myObject = new MyObject(); + myObject.save() + .then(myObj => myObj.destroy()) + .then(() => done()); + }); }); describe('beforeFind hooks', () => { @@ -1448,6 +1506,26 @@ describe('beforeFind hooks', () => { }) .then(() => done()); }); + + it('should have request ip', (done) => { + Parse.Cloud.beforeFind('MyObject', (req) => { + expect(req.ip).toBeDefined(); + }); + + const MyObject = Parse.Object.extend('MyObject'); + const myObject = new MyObject(); + myObject.save() + .then((myObj) => { + const query = new Parse.Query('MyObject'); + query.equalTo('objectId', myObj.id); + return Promise.all([ + query.get(myObj.id), + query.first(), + query.find(), + ]); + }) + .then(() => done()); + }); }); describe('afterFind hooks', () => { @@ -1667,6 +1745,27 @@ describe('afterFind hooks', () => { .then(() => done()); }); + it('should have request ip', (done) => { + Parse.Cloud.afterFind('MyObject', (req, res) => { + expect(req.ip).toBeDefined(); + res.success(); + }); + + const MyObject = Parse.Object.extend('MyObject'); + const myObject = new MyObject(); + myObject.save() + .then((myObj) => { + const query = new Parse.Query('MyObject'); + query.equalTo('objectId', myObj.id); + return Promise.all([ + query.get(myObj.id), + query.first(), + query.find(), + ]); + }) + .then(() => done()); + }); + it('should validate triggers correctly', () => { expect(() => { Parse.Cloud.beforeSave('_Session', () => {}); diff --git a/src/Routers/FunctionsRouter.js b/src/Routers/FunctionsRouter.js index ead8c28b..f3ea4d38 100644 --- a/src/Routers/FunctionsRouter.js +++ b/src/Routers/FunctionsRouter.js @@ -54,7 +54,8 @@ export class FunctionsRouter extends PromiseRouter { const request = { params: params, log: req.config.loggerController, - headers: req.headers, + headers: req.config.headers, + ip: req.config.ip, jobName }; const status = { @@ -111,7 +112,8 @@ export class FunctionsRouter extends PromiseRouter { user: req.auth && req.auth.user, installationId: req.info.installationId, log: req.config.loggerController, - headers: req.headers, + headers: req.config.headers, + ip: req.config.ip, functionName }; diff --git a/src/middlewares.js b/src/middlewares.js index 5afac5f1..d81ff12c 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -106,12 +106,15 @@ export function handleParseHeaders(req, res, next) { req.body = new Buffer(base64, 'base64'); } + const clientIp = getClientIp(req); + info.app = AppCache.get(info.appId); req.config = new Config(info.appId, mount); req.config.headers = req.headers || {}; + req.config.ip = clientIp; req.info = info; - if (info.masterKey && req.config.masterKeyIps && req.config.masterKeyIps.length !== 0 && req.config.masterKeyIps.indexOf(getClientIp(req)) === -1) { + if (info.masterKey && req.config.masterKeyIps && req.config.masterKeyIps.length !== 0 && req.config.masterKeyIps.indexOf(clientIp) === -1) { return invalidRequest(req, res); } diff --git a/src/triggers.js b/src/triggers.js index f15b7e33..a11a71f7 100644 --- a/src/triggers.js +++ b/src/triggers.js @@ -144,6 +144,7 @@ export function getRequestObject(triggerType, auth, parseObject, originalParseOb master: false, log: config.loggerController, headers: config.headers, + ip: config.ip, }; if (originalParseObject) { @@ -176,6 +177,7 @@ export function getRequestQueryObject(triggerType, auth, query, count, config, i log: config.loggerController, isGet, headers: config.headers, + ip: config.ip, }; if (!auth) {