From f0674df424fce014b9f586a6a18550e75b0f7b19 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Thu, 8 Mar 2018 10:31:53 -0600 Subject: [PATCH] Fixes Issue unsetting in beforeSave doesn't allow object creation (#4610) * skip unset fields on canAddField * removed fit * add null check --- spec/schemas.spec.js | 43 ++++++++++++++++++++++++++- src/Controllers/DatabaseController.js | 6 +++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/spec/schemas.spec.js b/spec/schemas.spec.js index b3c8453f..a5a8256d 100644 --- a/spec/schemas.spec.js +++ b/spec/schemas.spec.js @@ -1667,7 +1667,48 @@ describe('schemas', () => { fail(JSON.stringify(error)); done(); }) - }) + }); + + it('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 => { new Parse.Object('MyClass').save({ data: 'foo'}) diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 349ac090..786e69ac 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] && object[field].__op && object[field].__op === 'Delete') { + return false; + } return schemaFields.indexOf(field) < 0; - }) + }); if (newKeys.length > 0) { return schema.validatePermission(className, aclGroup, 'addField'); }