Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useMasterKey in cloudCode not working as expected #37

Closed
REggar opened this issue Jan 29, 2016 · 25 comments
Closed

useMasterKey in cloudCode not working as expected #37

REggar opened this issue Jan 29, 2016 · 25 comments
Labels
type:question Support or code-level question

Comments

@REggar
Copy link

REggar commented Jan 29, 2016

We had some Cloud Code like this in Parse:


Parse.Cloud.define('deleteUser', function (request, response) {`
    var User = Parse.Object.extend('_User');
    var query = new Parse.Query(User);

    query.get(request.params.user).then(function (result) {
        result.destroy();
    }).then(function (results) {
        response.success('User deleted');
    }, function (error) {
        response.error(error);
    })
});

It worked fine in Cloud Code however, it seems to be broken in parse-server, on debugging it looks like Parse.Cloud.useMasterKey(); is not being applied to the options of all ParseObject calls. This is required because the ACL prevents anyone creating additional items in the table.

@wagnercsfilho
Copy link

#13 In the top of the cloud code file, try:

Parse.serverURL = 'http://localhost:1337/parse';

@REggar
Copy link
Author

REggar commented Jan 29, 2016

No such luck, it's worth adding that I'm getting errors on .save() of ParseObjects as well.

@gfosco
Copy link
Contributor

gfosco commented Jan 29, 2016

Will take a look at this...

@silvermana
Copy link

+1. I can't .save() objects in Cloud Code via parse-sever if it requires useMasterKey(). In a beforeSave() function if I return success() early (before I create/save a protected object) it works fine, but if the code to create/save a sub-object runs I get an error:

ParseError { code: 141, message: 'User beforeSave error = 2 the service is currently unavailable' }

EDIT: I found the answer to my problem: #132

@gfosco
Copy link
Contributor

gfosco commented Feb 6, 2016

Much like how Parse.User.current() is invalid in a node script, because of the global nature, so is Parse.Cloud.useMasterKey(), because it is global and it would cause other requests to use the master key even if it was not intended.

The correct approach is to always pass a useMasterKey: true option to saves and queries which need to use the master key. We are going to document this as soon as possible, but I wanted to get this out to you and be able to close some issues.

In a save call, the options block is the second param:

obj.save(null, { useMasterKey: true });

In a query, it's the first.

q.get({ useMasterKey: true }).then(.......)
q.find({ useMasterKey: true}).then(......)

Please update your code to follow this and open a new issue if you have problems. Thank you!

@sivi29y
Copy link

sivi29y commented May 11, 2016

@gfosco you should move this info to the guide imho.

some people like myself with not a lot of node js experience will find it helpful

@OxyFlax
Copy link

OxyFlax commented May 17, 2016

I have the same problem, I tried to use @gfosco answer but I think I did it wrong. Could you help me? I read https://github.com/ParsePlatform/Parse-Server/wiki/Compatibility-with-Hosted-Parse#Cloud-Code too but it doesn't seem to work.

Parse.Cloud.define("removeFriendRequest", function(request, response) {
  Parse.Cloud.useMasterKey();

  console.log("removeFriendRequest: remove userid: " + request.params.userIdToRemove + " from user: " + request.params.userId);
  var query = new Parse.Query(Parse.User);
  query.equalTo("objectId", request.params.userId);

  // Get the first user which matches the above constraints.
  query.first({
    success: function(anotherUser) {
        anotherUser.remove("friends", request.params.userIdToRemove);
        anotherUser.save(null, {
        success: function(user) {
          response.success("removeFriendRequest updated");
        },
        error: function(user, error) {
          response.error(error);
        }
        });
    }
  });
});

Parse.Cloud.define("addGroupChatCount", function(request, response) {
  Parse.Cloud.useMasterKey();

  console.log("addGroupChatCount: added userid: " + request.params.userId + " for users: " + request.params.userIds + " for weevent: " + request.params.weeventId);
  var GroupMessage = Parse.Object.extend("GroupMessage");
  var query = new Parse.Query(GroupMessage);
  query.containedIn("fromId", request.params.userIds);
  query.equalTo("weeventId", request.params.weeventId);

  // Get the first user which matches the above constraints.
  query.find({ 
    success: function(results) {
      for (var i = 0; i < results.length; i++) {
        var result = results[i];
        result.increment("unreadAmount");
      };
      Parse.Object.saveAll(results, {
        success: function(list){
          response.success("add group chat succeeded");
        },
        error: function(error){
          response.error(error);
        }
      });
    }
  });
});

PS: This is the original code, I can give you what I tried if you want.

EDIT: Problem solved.

@TheRyanHickman
Copy link

@OxyFlax It would be great if you shared what you did to make your code above work.

@khanamir
Copy link

@gfosco What should be the syntax for setting useMasterKey: true in:

var query = new Parse.Query(Parse.Installation); query.containedIn("user", userList);

because for push notifications, we don't call find or fetch

@code-K
Copy link

code-K commented Jun 17, 2016

@gfosco I would also need to know the new syntax about useMasterKey: true if I would like to use it on
query.equalTo('user', request.object.get("createdBy"));

So for push...

Thanks much for feedback and best regards,
Chris

@kumarpranav
Copy link

@OxyFlax Can you please post your solution/ fix done?

@Haraldson
Copy link

I have the same problem as @khanamir – seemingly no way to just set an option?

I need to rewrite this to pass in { useMasterKey: true } somewhere, somehow;

Parse.Cloud.useMasterKey();
var installationQuery = new Parse.Query(Parse.Installation);
installationQuery.equalTo('user', user);

Parse.Push.send({
    where: installationQuery,
    data: { ... }
},
{
    // Would passing in `useMasterKey: true` here make the query
    // passed into the `where` above use the master key?

    // useMasterKey: true, ?

    success: function() {},
    error: function() {}
});

/cc @OxyFlax

@flovilmart
Copy link
Contributor

Alongside success and error, as you commented

@HemanParbhakar
Copy link

Same Error I am Getting Here ::: ==>

Parse.Cloud.define("assignPasswordToUser", function(request, response){
var query = new Parse.Query(Parse.User);
query.equalTo("email", request.params.email);
query.find({
success: function(results){
if (results) {
Parse.Cloud.useMasterKey();
var password = request.params.password;
console.log(results);
results[0].setPassword(password);
results[0].save();
response.success(1);
};
},
error: function(){
response.error("Error");
}
});
});

@flovilmart
Copy link
Contributor

Stop using Parse.Cloud.useMasterKey() once and for all, use .save(null, {useMasterKey: true})

@HemanParbhakar
Copy link

HemanParbhakar commented Jan 12, 2017

Parse.Cloud.define("assignPasswordToUser", function(request, response){
var query = new Parse.Query(Parse.User);
query.equalTo("email", request.params.email);
query.find({
success: function(results){
if (results) {

            var password = request.params.password;
            console.log(results);
            results[0].setPassword(password);
			results[0].save(null, {useMasterKey: true});
            response.success(1);
        };
    },
    error: function(){
        response.error("Error");
    }
});

});

Using This Gives Me An Error

@HemanParbhakar
Copy link

error: Failed running cloud function assignPasswordToUser for user undefined with:
Input: {"username":"9988736886","password":"********"}
Error: {"code":141,"message":"Object not found."} functionName=assignPasswordToUser, code=141, message=Object not found., username=9988736886, password=hello, user=undefined
error: Error generating response. ParseError { code: 141, message: 'Object not found.' } code=141, message=Object not found.
[object Object]

I Am Getting This Error When Using this Function

Parse.Cloud.define('assignPasswordToUser', function(request, response) {
new Parse.Query(Parse.User).get(request.params.username, {
useMasterKey: true,
success: function(user) {
username.setPassword(request.params.password);
username.save(null, {
useMasterKey: true,
success: response.success,
error: function(obj, error) {
response.error(error.message);
}
});
},
error: function(obj, error) {
response.error(error.message);
}
});
});

@flovilmart
Copy link
Contributor

Parse.Query().get takes an objectId as a parameter not a username

@ericraio
Copy link
Contributor

ericraio commented Feb 12, 2017

I would just like to add that we were using useMasterKey() method the entire time for a year than out of now where everything started breaking without any code changes, after hours of headbanging I discovered the useMasterKey: true option

What changed for this to break?

If useMasterKey() is not the correct way anymore, we need to have some kind of deprecation logging.

@flovilmart
Copy link
Contributor

The depreciation notice has been added on Dec 7th: https://github.com/ParsePlatform/parse-server/blob/master/src/cloud-code/Parse.Cloud.js#L64 and 025e7a3

This should have been deprecated at an earlier date, sorry for the inconvenience.

@r1cebank
Copy link

r1cebank commented Mar 3, 2017

I am having trouble finding documentations for the change, the link everyone uses that links to the github wiki no longer works. Can I get the updated url for the documentation for this change? Thanks

@flovilmart
Copy link
Contributor

@ZacharyKhan
Copy link

@flovilmart the link you posted is broken and returning a 404.

What about for destroyAll(), how do I pass in useMasterKey:true?

My example:

     query.find({
         success: function(posts) {
           Parse.Cloud.useMasterKey();
             Parse.Object.destroyAll(posts, {
                 success: function() {
                 }
             })
         }
     });

@flovilmart
Copy link
Contributor

see: http://docs.parseplatform.org/parse-server/guide/#cloud-code

@ZacharyKhan
Copy link

ZacharyKhan commented Apr 20, 2017

@flovilmart thanks for the updated link, but can you answer my question above about the proper use of useMasterKey:true within my example?

EDIT: Fixed with the following code

  query.find({
        success: function(posts) {
            Parse.Object.destroyAll(posts, {useMasterKey: true});
        }
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:question Support or code-level question
Projects
None yet
Development

No branches or pull requests