Parse.com, Adding users to created roles - parse-platform

I have a cloud code which creates two account roles when a user signs up. Below is the method
Parse.Cloud.afterSave("account", function(request) {
var accountName = request.object.get("name");
//create admin role
var adminRoleACL = new Parse.ACL();
adminRoleACL.setPublicWriteAccess(true);
var adminRole = new Parse.Role(accountName + "_Administrator", adminRoleACL);
adminRole.save() ;
//create user role
var userRoleACL = new Parse.ACL();
userRoleACL.setPublicWriteAccess(true);
var userRole = new Parse.Role(accountName + "_User", userRoleACL);
userRole.save();
});
Now what i wanted to achieve was to add the user which just signed up to these two roles. But unfortunately i saw that in cloud code i can't get the current user.
So what i did was to add the users in the role after the roles are created from the client side. Below is the code for the same. The code executes fine and i did not see any error, however i did not see the users being added to the roles in the data browser. Any idea why is this happening? Am i missing something. I would be really thankful for all your help.
user.signUp(null, {
success : function(user) {
var currentUser = Parse.User.current();
var accountName = account.get("name");
var query = new Parse.Query(Parse.Role);
query.contains("name", accountName);
query.find({
success : function(roles) {
if (!roles) {
alert("No roles for " + accountName + " were found");
} else {
for (var i = 0; i < roles.length; i++) {
//add the user for admin role
//TODO: this needs to be done only once for the account owner
if (roles[i].get("name").search(USER_TYPE.ADMIN) >= 0) {
roles[i].getUsers().add(currentUser);
}
//add the user for user role
if (roles[i].get("name").search(USER_TYPE.USER) >= 0) {
roles[i].getUsers().add(currentUser);
}
var saved = roles[i].save();
}
alert("User was added into roles");
}
},
error : function(error) {
alert("Could not add users to the account " + accountName + " error: " + error.message);
}
});
alert("User created successfully");
},
error : function(user, error) {
alert("Error: " + error.code + " " + error.message);
}
});

thanks for the help. I go it done by using a cloud code like this
Create the roles while creating the account.
Parse.Cloud.afterSave("account", function(request) {
var accountName = request.object.get("name");
//create admin role
var adminRoleACL = new Parse.ACL();
adminRoleACL.setPublicReadAccess(false);
adminRoleACL.setPublicWriteAccess(false);
var adminRole = new Parse.Role(accountName + "_Administrator", adminRoleACL);
adminRole.save();
//create user role
var userRoleACL = new Parse.ACL();
userRoleACL.setPublicReadAccess(false);
userRoleACL.setPublicWriteAccess(false);
var userRole = new Parse.Role(accountName + "_User", userRoleACL);
userRole.save();
});
Then add the users to the created role
Parse.Cloud.define("addUsersToRole", function(request, response) {
Parse.Cloud.useMasterKey();
var currentUser = request.user;
var accountName = request.params.accountname;
var isAdmin = request.params.admin;
var query = new Parse.Query(Parse.Role);
query.contains("name", accountName);
query.find({
success : function(roles) {
console.log("roles: " + roles.length);
for (var i = 0; i < roles.length; i++) {
if ( isAdmin = false && roles[i].get("name").search("_Administrator") >= 0)
continue;
roles[i].getUsers().add(currentUser);
roles[i].save();
}
response.success();
},
error : function(error) {
response.error("error adding to admin role " + error);
}
});
});

Actually you can access the user that is performing the request, check the Cloud Code Documentation for more details.
In particular, what you want is to look at request.user:
var currentUser = request.user;

Related

Getting Status 400 error while posting data on server in Razor page and AJAX

I am developing a website related to medical treatment, in which we ask different type of questions from patient actually, my task is, to enter their Email so I can check if he is already registered or not logged in then I redirect the user to the login page else I can register the user and assign a random password to the user and send him a mail on that Email,
so logged in user and if a user is not logged in these flows are working fine but when I'm when I register the user then and come to the next question I'm getting an error of status 400
Code for checking for user:
public async Task<IActionResult> OnGetCheckUserAsync(string Email)
{
if (User.Identity.IsAuthenticated)
{
var UserCred = _userManagmentServices.GetProfileAsync(Email).Result;
ProfileModel = new ProfileModel()
{
Id = UserCred.Id,
Email = UserCred.Email,
Name = UserCred.Name,
Applications = UserCred.Applications,
Address = UserCred.Address,
City = UserCred.City,
DisplayName = UserCred.DisplayName,
Phone = UserCred.Phone,
PostalCode = UserCred.PostalCode,
};
return new JsonResult(ProfileModel);
}
else
{
var user = await _userManager.FindByEmailAsync(Email);
if (user == null)
{
string randomString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!##$%^&*";
Random random = new Random();
char[] myPassword = new char[6];
for (int i = 0; i < 6; i++)
{
myPassword[i] = randomString[(int)(35 * random.NextDouble())];
}
var randomPassword = string.Concat(myPassword);
var UserModel = new UserModel()
{
Email = Email,
FirstName = "Mr",
LastName = "Patient",
Password = randomPassword,
PhoneNo = "03000000000",
};
var response = await _userManagmentServices.CreateAsync(UserModel);
if (response.IsSuccessful)
{
var Body = $"Dear {UserModel.FirstName + UserModel.LastName} Your password is auto generated successfull and your password is {UserModel.Password}";
await _mailServices.SendEmailNotificationAsync(UserModel.Email, "Auto Generated Password", Body);
}
if (!response.IsSuccessful)
{
foreach (var Error in response.Errors)
{
ModelState.AddModelError("", Error.ToString());
}
return new JsonResult("Error while creating your account");
}
var UserCred = _userManagmentServices.GetProfileAsync(UserModel.Email).Result;
ProfileModel = new ProfileModel()
{
Id = UserCred.Id,
Email = UserCred.Email,
Name = UserCred.Name,
Applications = UserCred.Applications,
Address = UserCred.Address,
City = UserCred.City,
DisplayName = UserCred.DisplayName,
Phone = UserCred.Phone,
PostalCode = UserCred.PostalCode,
};
return new JsonResult(ProfileModel);
}
else
{
application = new FEApplication();
application.Status = Status.Incomplete;
application.UserEmail = Email;
application.ApplicationType = "Premature Ejaculation";
application.FlowId = await _applicationManagementService.Create(application);
var _signinUrl = "../Auth/Signin";
return new JsonResult(_signinUrl);
}
}
}
public async Task<IActionResult> OnPostSubmitAsync(FEApplication? application)
{
if (application.FlowId != null)
{
application.ApplicationType = "Premature Ejaculation";
if (application.DoctorToKnow == "No" || application.ExplainDoctorToKnow != null)
{
application.Status = Status.PaymentDue;
}
else
{
application.Status = Status.Incomplete;
}
await _applicationManagementService.UpdatePEAsync(application.FlowId, application);
}
else
{
if (User.Identity.IsAuthenticated)
{
application.PatientUserName = ProfileModel.DisplayName;
application.ApplicationType = "Premature Ejaculation";
application.Status = Status.Incomplete;
application.UserEmail = User?.Identity?.Name;
ProfileModel = _userManagmentServices.GetProfileAsync(application.UserEmail).Result;
}
else
{
application.PatientUserName = ProfileModel.DisplayName ?? string.Empty;
application.UserEmail = application.UserEmail;
}
application.Status = Status.Incomplete;
application.ApplicationType = "Premature Ejaculation";
application.FlowId = await _applicationManagementService.Create(application);
//_application = _applicationManagementService.GetOneById(FlowId);
}
return new JsonResult(application.FlowId);
}
function CheckUserEmail() {
$("#modalspinner").show();
var email = document.getElementById("Email").value;
$.ajax({
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken" ]').val());
},
url: "./Start?handler=CheckUser",
type: "GET",
dataType: "json",
data: {
Email: email
},
success: function (response) {
console.log("Success block");
if (response) {
$("#modalspinner").hide();
console.log("response " + response)
if (response == "../Auth/Signin") {
window.location.href = response;
}
else {
if (response.id) {
console.log("if block =" + JSON.stringify(response));
var firstName = JSON.stringify(response.displayName) ?? "";
var lastName = JSON.stringify(response.displayName) ?? "";
var email = JSON.stringify(response.email) ?? "";
var phoneNo = JSON.stringify(response.phone);
var address = JSON.stringify(response.address) ?? "";
var city = JSON.stringify(response.city);
var postalCode = JSON.stringify(response.postalCode) ?? "";
$("#FirstName").val(firstName.replace(/\"/g, ""));
$("#LastName").val(lastName.replace(/\"/g, ""));
$("#Email").val(email.replace(/\"/g, ""));
$("#PhoneNoTextbox").val(phoneNo.replace(/\"/g, ""));
$("#CustomerShippingAddress").val(address.replace(/\"/g, ""));
$("#CustomerCity").val(city.replace(/\"/g, ""));
$("#CustomerPostalCode").val(postalCode.replace(/\"/g, ""));
console.log("response data :" + firstName, lastName, email, phoneNo, address, city, postalCode);
}
else {
$("#modalspinner").hide();
console.log("Error while creating new user" + JSON.stringify(response));
}
}
}
},
error: function (response) {
console.log("Error block =" + JSON.stringify(response));
$("#modalspinner").hide();
$('#EmailMessage').show();
setTimeout(function () { $('#EmailMessage').hide(); }, 5000);
$("#modalspinner").hide();
}
});
}
function SubmitForm() {
/*var flowId = document.getElementById("FlowId").value;*/
var data = $("#ApplicationData").serialize();
console.log("data :" + data);
$.ajax({
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken" ]').val());
},
type: "POST",
url: "./Start?handler=Submit",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
data: data,
success: function (response) {
var res = JSON.stringify(response);
console.log("Application data saved!");
$("#FlowId").val(res.replace(/\"/g, ""));
}
})
}
Please check below with your code:
In the cshtml, add
#Html.AntiForgeryToken()
The Ajax request should send the anti-forgery token in request header to the server.
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
In startup, since the script sends the token in a header called XSRF-TOKEN, configure the antiforgery service to look for the XSRF-TOKEN header:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

User object not saving in afterSave code

I have tried multiple variations of this and for some reason the field "Followers" is not being incremented:
ParseObject follow = new ParseObject("Follow");
follow.put("from", currentUser);
follow.put("to", parseUser);
follow.put("approved", approved);
Then in cloud code:
Parse.Cloud.afterSave("Follow", function(request) {
var to = request.object.get("to");
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", to.id);
query.first({
success: function(user) {
user.increment("Followers");
user.save();
console.log("User: " + user.id + " Followers: " + user.get("Followers"));
}, error: function(error) {
console.log("afterSave: " + error);
}
});
var currentUser = Parse.User.current();
currentUser.increment("Following");
currentUser.save();
});
According to the logs it is working:
I2015-11-28T18:21:54.745Z]v47 after_save triggered for Follow for user k0ZvNAy3Mk:
Input: {"object":{"approved":false,"createdAt":"2015-11-28T18:21:54.743Z","from":{"__type":"Pointer","className":"_User","objectId":"k0ZvNAy3Mk"},"objectId":"JQBO9m21uA","to":{"__type":"Pointer","className":"_User","objectId":"bcpbFaXj9C"},"updatedAt":"2015-11-28T18:21:54.743Z"}}
Result: Success
I2015-11-28T18:21:54.906Z]User: bcpbFaXj9C Followers: 1
But when I look at the data the Followers field for that user still says 0
I have also tried:
Parse.Cloud.afterSave("Follow", function(request) {
var to = request.object.get("to");
to.increment("Followers");
to.save();
var currentUser = Parse.User.current();
currentUser.increment("Following");
currentUser.save();
});
According to the docs since it is a pointer I should be able to manipulate it directly but that did not work either.
Any ideas what to do or why this is not working correctly?
save() is asynchronous function, you should not leave the function before it is completed. Use this:
user.save().then(function(success){
console.log("User: " + success.id + " Followers: " + success.get("Followers"));
}, function (error){
console.log(error.message);
});
Looks like the parse cloud code depends on the user that is currently logged in and manipulating data on another user is not allowed unless you are logged in as them.
Parse.Cloud.afterSave("Follow", function(request) {
Parse.Cloud.useMasterKey(); // Needed this
var to = request.object.get("to");
to.increment("Followers");
to.save();
var currentUser = Parse.User.current();
currentUser.increment("Following");
currentUser.save();
});

why save event is not working in cloud code?

Find my code below which working very fine. but only problem facing by me is that save event is not working for me.Also you can see my log file in the picture. In each method i tried success and error function which working fine as you can see in picture. I tried this code alot but still... it is not working for me.
It always shows error message.
Code :
Parse.Cloud.afterSave("HouserDetailed", function(request, response)
{
var obj = request.object.id;
//console.log(obj);
// code !
var houserdetailed = new Parse.Object("HouserDetailed");
var query = new Parse.Query("HouserDetailed");
query.equalTo("objectId", obj);
query.first({
success: function(results) {
//alert("updates objectId " +request.object.id + " " + "input" + " "+ request.object.bet_title );
var bet_title = results.get("bet_title");
var match_id = results.get("match_id");
var level_coin = results.get("level_coin");
if(bet_title !== "false")
{
console.log("bet_title :- "+bet_title+", match_id:- "+match_id+", level_coin:- "+level_coin);
// nested query
var better = new Parse.Object("Better");
var query1 = new Parse.Query("Better");
query1.equalTo("match_id", match_id);
query1.first({
success: function(result){
var bet_title_better = result.get("bet_title");
var user_id = result.get("user_id");
var bet_OnNoOfticket = result.get("bet_OnNoOfticket");
var bet_price = result.get("bet_price");
var money_got = bet_OnNoOfticket * bet_price;
console.log("bet_title_better :-"+bet_title_better);
if(bet_title !== bet_title_better)
{
console.log("Condition does not match!");
}
else
{
console.log("Condition match!" + "money got :- "+money_got);
// checking for existing user in parse DB
var wallet = new Parse.Object("Wallet");
var query2 = new Parse.Query("Wallet");
query2.equalTo("user_id", user_id);
query2.first({
success: function(result)
{
console.log("User found");
var wallet_coins_number = result.get("wallet_coins_number");
var objectId = result.get("objectId");
total_amount = +wallet_coins_number + +money_got;
console.log("Total amount got :- " + total_amount );
// saving amount in wallet
var Wallet = Parse.Object.extend("Wallet");
var wallet = new Wallet();
wallet.set("user_id", user_id);
wallet.set("wallet_coins_number", total_amount);
wallet.save(null, {
success: function(wallet){
console.log("amount saved in wallet!");
},
error: function(wallet)
{
console.log("amount not saved in wallet!");
}
});
},
error: function(error)
{
console.log("User not found");
}
});
}
},error: function(error)
{
}
});
}
// nested query end
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
// code !
});][1]][1]
I don't see any log, probably it would tell you what is wrong. But you are attempting to save existing ParseObject with dirty objectId, which is bad idea. You are not allowed to change objectId of existing object. Try to remove wallet.set("objectId", objectId) from your code.
You should not use result.get("objectId") either, use result.id instead.

Cloud Code, complex query with adding a key-value pair before response

I want to get a batch of User objects using Cloud Code. And before collection of objects will send to client they have to take a unique number.
Now it's looking like this
Parse.Cloud.define("getUsers", function(request, response)
{
var query = new Parse.Query(Parse.User);
var mode = parseInt(request.params.mode);
var username = request.params.username;
var skip = parseInt(request.params.skip);
var limit = parseInt(request.params.limit);
if(mode==1)
{
query.notEqualTo("fbLogged",true)
.descending("score")
.notEqualTo("username",username)
.skip(skip)
.limit(limit);
query.find({
success: function(objects)
{
var i = 0;
objects.forEach(function(item)
{
item["rank"]=skip+i; //setting a unique number (position based on score)
});
response.success(objects);
},
error: function(error)
{
response.error(error);
}
});
}
});
And how I use it on client side...
void Start () {
IDictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("username", "477698883");
dict.Add("skip", "300");
dict.Add("limit", "50");
dict.Add("mode", "1");
ParseCloud.CallFunctionAsync<IEnumerable<object>>("getUsers", dict).ContinueWith(t =>
{
if(t.IsCanceled || t.IsFaulted)
{
foreach (var e in t.Exception.InnerExceptions)
Debug.LogError(e.Message);
}
else
{
var r = t.Result;
List<ParseUser> users = new List<ParseUser>();
foreach(var o in r)
{
try {
ParseObject pu = (ParseObject)o;
foreach (var key in pu.Keys)
Debug.Log(key + " = " + pu[key]);
}
catch(Exception e)
{
Debug.LogError(e.Message);
}
break;
}
}
});
}
As you see I just display first of received objects.
And it gives me this data.
But where is the "rank" field?
I just found solution. Each ParseObject which will send to Client by response.success() have to be saved on Parse before sent.
Now my code looks like this and it works
Parse.Cloud.define("getUsers", function(request, response)
{
var query = new Parse.Query(Parse.User);
var mode = parseInt(request.params.mode);
var username = request.params.username;
var skip = parseInt(request.params.skip);
var limit = parseInt(request.params.limit);
if(mode==1)
{
query.notEqualTo("fbLogged",true)
.descending("score")
.notEqualTo("username",username)
.skip(skip)
.limit(limit);
query.find({
success: function(objects)
{
for(var i = 0; i<objects.length; i++)
{
objects[i].set("rank", skip+i);
objects[i].save();
}
response.success(objects);
},
error: function(error)
{
response.error(error);
}
});
}
});

Setting a Parse.Object.relation at/after object creation

My Email object (my own custom class) is being written though the relation is not being set on time, any ideas how to chain this properly?
// Create new Email model and friend it
addFriendOnEnter: function(e) {
var self = this;
if (e.keyCode != 13) return;
var email = this.emails.create({
email: this.emailInput.val(),
ACL: new Parse.ACL(Parse.User.current())
});
var user = Parse.User.current();
var relation = user.relation("friend");
relation.add(email);
user.save();
this.emailInput.val('');
}
Thanks!
Gon
Because talking to Parse's servers is asynchronous, Parse.Collection.create uses a Backbone-style options object with a callback for when the object is created. I think what you want to do is:
// Create new Email model and friend it
addFriendOnEnter: function(e) {
var self = this;
if (e.keyCode != 13) return;
this.emails.create({
email: this.emailInput.val(),
ACL: new Parse.ACL(Parse.User.current())
}, {
success: function(email) {
var user = Parse.User.current();
var relation = user.relation("friend");
relation.add(email);
user.save();
self.emailInput.val('');
}
});
}
Got it!
The .create method on the this.emails collection does not actually return an object, so var email was empty. Somehow Parse guess it was an empty object of class Email, so I guess the structure is the only thing that remained once .create did its job.
Instead I retrieve the email object on the server using .query, .equalTo and .first
// Create new Email model and friend it
addFriendOnEnter: function(e) {
var self = this;
if (e.keyCode != 13) return;
this.emails.create({
email: this.emailInput.val(),
ACL: new Parse.ACL(Parse.User.current())
});
var query = new Parse.Query(Email);
query.equalTo("email", this.emailInput.val());
query.first({
success: function(result) {
alert("Successfully retrieved an email.");
var user = Parse.User.current();
var relation = user.relation("friend");
relation.add(result);
user.save();
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
this.emailInput.val('');
}

Resources