From 5b17a33595923b0147bcf733d2d59f0841c02a00 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 5 Mar 2023 13:49:14 +1100 Subject: [PATCH 1/3] fix: LiveQuery can return incorrectly formatted Dates --- spec/ParseLiveQueryServer.spec.js | 56 +++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 5b4690ae85..537b754268 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -754,6 +754,58 @@ describe('ParseLiveQueryServer', function () { parseLiveQueryServer._onAfterSave(message); }); + fit('sends correct object for dates', async () => { + jasmine.restoreLibrary('../lib/LiveQuery/QueryTools', 'matchesQuery'); + + const parseLiveQueryServer = new ParseLiveQueryServer({}); + + const date = new Date(); + const message = { + currentParseObject: { + date: { __type: 'Date', iso: date.toISOString() }, + __type: 'Object', + key: 'value', + className: testClassName, + }, + }; + // Add mock client + const clientId = 1; + const client = addMockClient(parseLiveQueryServer, clientId); + + const requestId2 = 2; + + await addMockSubscription(parseLiveQueryServer, clientId, requestId2); + + parseLiveQueryServer._matchesSubscription = function (parseObject, subscription) { + if (!parseObject) { + return false; + } + subscription.query.date = { $exists: true }; + const matchesQuery = require('../lib/LiveQuery/QueryTools').matchesQuery; + matchesQuery(parseObject, subscription.query); + return true; + }; + parseLiveQueryServer._matchesACL = function () { + return Promise.resolve(true); + }; + + parseLiveQueryServer._inflateParseObject(message); + parseLiveQueryServer._onAfterSave(message); + + // Make sure we send leave and enter command to client + await timeout(); + + expect(client.pushCreate).toHaveBeenCalledWith( + requestId2, + { + className: 'TestObject', + key: 'value', + date: { __type: 'Date', iso: date.toISOString() }, + }, + null + ); + }); + it('can handle object save command which does not match any subscription', async done => { const parseLiveQueryServer = new ParseLiveQueryServer({}); // Make mock request message @@ -1138,8 +1190,7 @@ describe('ParseLiveQueryServer', function () { expect(toSend.original).toBeUndefined(); expect(spy).toHaveBeenCalledWith({ usage: 'Subscribing using fields parameter', - solution: - `Subscribe using "keys" instead.`, + solution: `Subscribe using "keys" instead.`, }); }); @@ -1945,6 +1996,7 @@ describe('ParseLiveQueryServer', function () { } else { subscription.clientRequestIds = new Map([[clientId, [requestId]]]); } + subscription.query = query.where; return subscription; } From 3020c6998f97f31b4da2820ef119884172214a9b Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 5 Mar 2023 13:55:18 +1100 Subject: [PATCH 2/3] fix --- spec/ParseLiveQueryServer.spec.js | 5 ++--- src/LiveQuery/QueryTools.js | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 537b754268..dfe1648d6f 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -754,7 +754,7 @@ describe('ParseLiveQueryServer', function () { parseLiveQueryServer._onAfterSave(message); }); - fit('sends correct object for dates', async () => { + it('sends correct object for dates', async () => { jasmine.restoreLibrary('../lib/LiveQuery/QueryTools', 'matchesQuery'); const parseLiveQueryServer = new ParseLiveQueryServer({}); @@ -782,8 +782,7 @@ describe('ParseLiveQueryServer', function () { } subscription.query.date = { $exists: true }; const matchesQuery = require('../lib/LiveQuery/QueryTools').matchesQuery; - matchesQuery(parseObject, subscription.query); - return true; + return matchesQuery(parseObject, subscription.query); }; parseLiveQueryServer._matchesACL = function () { return Promise.resolve(true); diff --git a/src/LiveQuery/QueryTools.js b/src/LiveQuery/QueryTools.js index 50d8d3394a..a015c7d65e 100644 --- a/src/LiveQuery/QueryTools.js +++ b/src/LiveQuery/QueryTools.js @@ -1,6 +1,7 @@ var equalObjects = require('./equalObjects'); var Id = require('./Id'); var Parse = require('parse/node'); +const deepcopy = require('deepcopy'); /** * Query Hashes are deterministic hashes for Parse Queries. @@ -124,6 +125,7 @@ function contains(haystack: Array, needle: any): boolean { * queries, we can avoid building a full-blown query tool. */ function matchesQuery(object: any, query: any): boolean { + object = deepcopy(object); if (query instanceof Parse.Query) { var className = object.id instanceof Id ? object.id.className : object.className; if (className !== query.className) { From 899c97e66a8331402347c6f86cdddb0045e5dfba Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 5 Mar 2023 17:32:38 +1100 Subject: [PATCH 3/3] deep copy --- spec/ParseLiveQueryServer.spec.js | 8 -------- src/LiveQuery/ParseLiveQueryServer.js | 3 ++- src/LiveQuery/QueryTools.js | 2 -- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index dfe1648d6f..16654cdd64 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -776,14 +776,6 @@ describe('ParseLiveQueryServer', function () { await addMockSubscription(parseLiveQueryServer, clientId, requestId2); - parseLiveQueryServer._matchesSubscription = function (parseObject, subscription) { - if (!parseObject) { - return false; - } - subscription.query.date = { $exists: true }; - const matchesQuery = require('../lib/LiveQuery/QueryTools').matchesQuery; - return matchesQuery(parseObject, subscription.query); - }; parseLiveQueryServer._matchesACL = function () { return Promise.resolve(true); }; diff --git a/src/LiveQuery/ParseLiveQueryServer.js b/src/LiveQuery/ParseLiveQueryServer.js index 934a556966..0b71265f33 100644 --- a/src/LiveQuery/ParseLiveQueryServer.js +++ b/src/LiveQuery/ParseLiveQueryServer.js @@ -24,6 +24,7 @@ import UserRouter from '../Routers/UsersRouter'; import DatabaseController from '../Controllers/DatabaseController'; import { isDeepStrictEqual } from 'util'; import Deprecator from '../Deprecator/Deprecator'; +import deepcopy from 'deepcopy'; class ParseLiveQueryServer { clients: Map; @@ -496,7 +497,7 @@ class ParseLiveQueryServer { if (!parseObject) { return false; } - return matchesQuery(parseObject, subscription.query); + return matchesQuery(deepcopy(parseObject), subscription.query); } async _clearCachedRoles(userId: string) { diff --git a/src/LiveQuery/QueryTools.js b/src/LiveQuery/QueryTools.js index a015c7d65e..50d8d3394a 100644 --- a/src/LiveQuery/QueryTools.js +++ b/src/LiveQuery/QueryTools.js @@ -1,7 +1,6 @@ var equalObjects = require('./equalObjects'); var Id = require('./Id'); var Parse = require('parse/node'); -const deepcopy = require('deepcopy'); /** * Query Hashes are deterministic hashes for Parse Queries. @@ -125,7 +124,6 @@ function contains(haystack: Array, needle: any): boolean { * queries, we can avoid building a full-blown query tool. */ function matchesQuery(object: any, query: any): boolean { - object = deepcopy(object); if (query instanceof Parse.Query) { var className = object.id instanceof Id ? object.id.className : object.className; if (className !== query.className) {