Description
Issue Description
When a Parse.User is linked in a more than 100 Parse.Role, a LiveQuery on a Role based Parse.Object send events in an unpredictable way, or even not sending events any more !
Steps to reproduce
Make a LiveQuery on Role Based Object with a Parse.User linked in more than 100 Parse.Role
Expected Results
The LiveQuery from the Parse.User receive events correctly
Actual Outcome
The LiveQuery from Parse.User not receive events or receive events in an unpredictable way
Environment Setup
-
Server
- parse-server version : 3, 3.1
- Operating System: Ubuntu LTS
- Hardware: VPS
- Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): Remote
-
Database
- MongoDB version: 3
- Storage engine: AWS
- Hardware: VPS
- Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): remote
Logs/Trace
Logs For a User that have more than 100 Parse.Role
show that the
matchACL
return false value
2018-10-17T19:05:06.909Z - Original null | Current {...,"ACL":{"role:xxxxxxxxx":{"read":true,"write":true}},"__type":"Object","className":"Aptitude","objectId":"xxxxxxxx"} | Match: false, true, false, false(isCurrentMatched) | Query: ClassName:fieldOfTheQuery|["valueForTheQuery"]
The ACL function fail because
isCurrentMatched
equal tofalse
Logs For a User that have less than 100 Parse.Role
show that the
matchACL
returntrue
value
2018-10-17T19:05:06.909Z - Original null | Current {...,"ACL":{"role:xxxxxxxxx":{"read":true,"write":true}},"__type":"Object","className":"Aptitude","objectId":"xxxxxxxx"} | Match: false, true, false, true(isCurrentMatched) | Query: ClassName:fieldOfTheQuery|["valueForTheQuery"]
The ACL function success because
isCurrentMatched
equal totrue
Investigation on Parse.Server 3.1.0
- Target File : Auth.js
- Target Function : getRolesForUser()
- Bug Identified : Parse.Query return just 100 results by default
Auth.prototype.getRolesForUser = function() {
if (this.config) {
const restWhere = {
users: {
__type: 'Pointer',
className: '_User',
objectId: this.user.id,
},
};
const query = new RestQuery(
this.config,
master(this.config),
'_Role',
restWhere,
{}
);
return query.execute().then(({ results }) => results);
}
//!!!!!!The Bug is right there
return new Parse.Query(Parse.Role)
.equalTo('users', this.user)
.find({ useMasterKey: true })
.then(results => results.map(obj => obj.toJSON()));
};
- Fast Option for fix that works (tested on my env) : add a
.limit(99999)
- Disadvantages : For a Parse.User with a lot (a lot) of Parse.Role, memory leak can appear
Auth.prototype.getRolesForUser = function() {
if (this.config) {
const restWhere = {
users: {
__type: 'Pointer',
className: '_User',
objectId: this.user.id,
},
};
const query = new RestQuery(
this.config,
master(this.config),
'_Role',
restWhere,
{}
);
return query.execute().then(({ results }) => results);
}
//!!!!!!The Bug is right there
return new Parse.Query(Parse.Role)
.limit(999999999)
.equalTo('users', this.user)
.find({ useMasterKey: true })
.then(results => results.map(obj => obj.toJSON()));
};
@flovilmart what I was talking about on Twitter