-
-
Notifications
You must be signed in to change notification settings - Fork 600
Description
New Issue Checklist
- I am not disclosing a vulnerability.
- I am not just asking a question.
- I have searched through existing issues.
- I can reproduce the issue with the latest versions of Parse Server and the Parse JS SDK.
Issue Description
Loading an object in client, then calling saveEventually on it after killing the parseserver, then starting it up again doesn't work for me. It seems to be a few different issues. Maybe I'm just doing something really wrong, and if so I'm sorry in advance :)
Test code is really simple. I find object "Foo" (with server up) in the console, kill server, client executes this code:
result[0].set("counter", result[0].get("counter")+1); await result[0].saveEventually();
I can see the Parse.EventuallyQueue.getQueue() have the following
'[{"queueId":"save_Foo_T6r7uWTcU9_","action":"save","object":{"counter":13,"createdAt":"2023-09-22T16:00:06.541Z","updatedAt":"2023-09-22T18:48:30.396Z","ACL":{"G2lwffEEaD":{"read":true,"write":true}},"objectId":"T6r7uWTcU9"},"serverOptions":{},"id":"T6r7uWTcU9","className":"Foo","createdAt":"2023-09-22T18:48:44.083Z"}]
When I restart the server, I don't see any attempts to save to server but queue is empty. It seems to fail this test in EventuallyQueue.sendQueueCallback under save:
// Queued update was overwritten by other request. Do not save
if (
typeof object.updatedAt !== 'undefined' &&
object.updatedAt > new Date(queueObject.object.createdAt)
)
The code is checking is the object's updatedAt is greater than the object's createdAt, which will always be the case. My guess was that this should be object.updatedAt > queueObject.createdAt (when the queue object was created not the original object). hacking on the JS code did get me past this problem but it still wouldn't save.
Next issue is that the EventuallyQueue stores a .toJSON of my object, which includes among other things the ACL object.
With some extra logging, the ParseObject.save gets sent that ACL object. It fails on ParseObject.validate(attrs) (silently) with this:
Error: ACL must be a Parse ACL.
at ParseObjectSubclass.value (ParseObject.js:1259:16)
at ParseObjectSubclass.value (ParseObject.js:1578:31)
at EventuallyQueue.js:386:27
I'm not sure here if the best fix is to delete the ACL out of the json stored in EventuallyQueue or if ParseObject.validate should allow for JSON versions of the ACL, but it does fail my very simple saveEventually regardless.
I don't normally modify ACLs on client, only server using save hooks, but taking them out would be one thing.
Another fix (although still would fail with ACLs changed on client) is to not do (in EventuallyQueue.enqueue):
queueData[index] = {
queueId,
action,
object: object.toJSON(), // <-- This stores ACL in json format..
serverOptions,
id: object.id,
className: object.className,
hash: object.get('hash'),
createdAt: new Date(),
};
Instead of object being the entire toJSON() storing only the values of the changed keys (_getSaveJSON() ?). Or maybe change the ACL object if present back into a valid version.
Steps to reproduce
Actual Outcome
Data is lost
Expected Outcome
Expected data to be saved when server starts up again.
Environment
Server
- Parse Server version:
5.2.3 - Operating system:
OSX - Local or remote host (AWS, Azure, Google Cloud, Heroku, Digital Ocean, etc):
Local
Database
- System (MongoDB or Postgres):
MongoDB - Database version:
5.5 - Local or remote host (MongoDB Atlas, mLab, AWS, Azure, Google Cloud, etc):
local
Client
- Parse JS SDK version:
4.1.0