From 70e0ffcbd28baaffdfd35111b21a41b6f2beaacf Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Wed, 7 Mar 2018 21:44:24 -0600 Subject: [PATCH 1/3] skip unset fields on canAddField --- spec/schemas.spec.js | 45 +++++++++++++++++++++++++-- src/Controllers/DatabaseController.js | 6 +++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/spec/schemas.spec.js b/spec/schemas.spec.js index b3c8453f56..ef8c47564d 100644 --- a/spec/schemas.spec.js +++ b/spec/schemas.spec.js @@ -1667,9 +1667,50 @@ describe('schemas', () => { fail(JSON.stringify(error)); done(); }) - }) + }); + + fit('unset field in beforeSave should not stop object creation', (done) => { + const hook = { + method: function(req, res) { + if (req.object.get('undesiredField')) { + req.object.unset('undesiredField'); + } + return res.success(); + } + }; + spyOn(hook, 'method').and.callThrough(); + Parse.Cloud.beforeSave('AnObject', hook.method); + setPermissionsOnClass('AnObject', { + get: {"*": true}, + find: {"*": true}, + create: {'*': true}, + update: {'*': true}, + delete: {'*': true}, + addField:{} + }).then(() => { + const obj = new Parse.Object('AnObject'); + obj.set('desiredField', 'createMe'); + return obj.save(null, {useMasterKey: true}); + }).then(() => { + const obj = new Parse.Object('AnObject'); + obj.set('desiredField', 'This value should be kept'); + obj.set('undesiredField', 'This value should be IGNORED'); + return obj.save(); + }).then(() => { + const query = new Parse.Query('AnObject'); + return query.find(); + }).then((results) => { + expect(results.length).toBe(2); + expect(results[0].has('desiredField')).toBe(true); + expect(results[1].has('desiredField')).toBe(true); + expect(results[0].has('undesiredField')).toBe(false); + expect(results[1].has('undesiredField')).toBe(false); + expect(hook.method).toHaveBeenCalled(); + done(); + }); + }); - it('gives correct response when deleting a schema with CLPs (regression test #1919)', done => { + fit('gives correct response when deleting a schema with CLPs (regression test #1919)', done => { new Parse.Object('MyClass').save({ data: 'foo'}) .then(obj => obj.destroy()) .then(() => setPermissionsOnClass('MyClass', { find: {}, get: {} }, true)) diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 349ac09063..e13c778b0f 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -622,8 +622,12 @@ class DatabaseController { const fields = Object.keys(object); const schemaFields = Object.keys(classSchema); const newKeys = fields.filter((field) => { + // Skip fields that are unset + if (object[field].__op && object[field].__op === 'Delete') { + return false; + } return schemaFields.indexOf(field) < 0; - }) + }); if (newKeys.length > 0) { return schema.validatePermission(className, aclGroup, 'addField'); } From 3811af2f9ea597af52b9e776f700a49f612fc5d9 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Wed, 7 Mar 2018 21:49:47 -0600 Subject: [PATCH 2/3] removed fit --- spec/schemas.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/schemas.spec.js b/spec/schemas.spec.js index ef8c47564d..a5a8256d84 100644 --- a/spec/schemas.spec.js +++ b/spec/schemas.spec.js @@ -1669,7 +1669,7 @@ describe('schemas', () => { }) }); - fit('unset field in beforeSave should not stop object creation', (done) => { + it('unset field in beforeSave should not stop object creation', (done) => { const hook = { method: function(req, res) { if (req.object.get('undesiredField')) { @@ -1710,7 +1710,7 @@ describe('schemas', () => { }); }); - fit('gives correct response when deleting a schema with CLPs (regression test #1919)', done => { + it('gives correct response when deleting a schema with CLPs (regression test #1919)', done => { new Parse.Object('MyClass').save({ data: 'foo'}) .then(obj => obj.destroy()) .then(() => setPermissionsOnClass('MyClass', { find: {}, get: {} }, true)) From c11808221d2efbfe69320e00bcee52ad58fd7458 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Wed, 7 Mar 2018 22:19:07 -0600 Subject: [PATCH 3/3] add null check --- src/Controllers/DatabaseController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index e13c778b0f..786e69ac05 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -623,7 +623,7 @@ class DatabaseController { const schemaFields = Object.keys(classSchema); const newKeys = fields.filter((field) => { // Skip fields that are unset - if (object[field].__op && object[field].__op === 'Delete') { + if (object[field] && object[field].__op && object[field].__op === 'Delete') { return false; } return schemaFields.indexOf(field) < 0;