From 0ad799e9a5c65821bce7b38740df3d2d62fd00e9 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Fri, 2 Feb 2018 13:42:51 -0800 Subject: [PATCH 1/2] Fix "undefined property '__op'" in postgres update This causes a TypeError which becomes a regular Error, before the update can be issued. (I think) This happens when there is an object schema, and there is also an unrelated field in originalUpdate which is null or undefined. e.g. when 'location' is a mandatory object in postgres, and 'middleName' is an optional string, PostgresStorageAdapter would throw when a query similar to the below was performed: (Object.keys(originalUpdate) would include "middleName" as a value of `k`) query.set('location', {'country': 'US'}) query.set('middleName', undefined); --- .../Storage/Postgres/PostgresStorageAdapter.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 906147512d..9b76379c55 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1200,7 +1200,11 @@ export class PostgresStorageAdapter implements StorageAdapter { // Gather keys to increment const keysToIncrement = Object.keys(originalUpdate).filter(k => { // choose top level fields that have a delete operation set - return originalUpdate[k].__op === 'Increment' && k.split('.').length === 2 && k.split(".")[0] === fieldName; + // Note that Object.keys is iterating over the **original** update object + // and that some of the keys of the original update could be null or undefined: + // (See the above check `if (fieldValue === null || typeof fieldValue == "undefined")`) + const value = originalUpdate[k]; + return value && value.__op === 'Increment' && k.split('.').length === 2 && k.split(".")[0] === fieldName; }).map(k => k.split('.')[1]); let incrementPatterns = ''; @@ -1216,8 +1220,9 @@ export class PostgresStorageAdapter implements StorageAdapter { } const keysToDelete = Object.keys(originalUpdate).filter(k => { - // choose top level fields that have a delete operation set - return originalUpdate[k].__op === 'Delete' && k.split('.').length === 2 && k.split(".")[0] === fieldName; + // choose top level fields that have a delete operation set. + const value = originalUpdate[k]; + return value && value.__op === 'Delete' && k.split('.').length === 2 && k.split(".")[0] === fieldName; }).map(k => k.split('.')[1]); const deletePatterns = keysToDelete.reduce((p, c, i) => { From 37b9944fdcf8a2cf3ae0eb88004a28f54c6431d0 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Fri, 2 Feb 2018 13:59:36 -0800 Subject: [PATCH 2/2] Fix lint error --- src/Routers/UsersRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index 0863f99136..9f671bd384 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -268,7 +268,7 @@ export class UsersRouter extends ClassesRouter { throw new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`); } const user = results[0]; - + // remove password field, messes with saving on postgres delete user.password;