Skip to content

LiveQuery on Object Role Based don't send events for some users #5131

Closed
@Moumouls

Description

@Moumouls

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 to false

Logs For a User that have less than 100 Parse.Role

show that the matchACL return true 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 to true

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions