Azure Mobile Services - Alter User model on Insert script - javascript

I have a reservation model and a user model. In the insert script for my reservation model, I have the following:
function insert(item, user, request) {
response.send(200, 'test');
item.organizationid = user.organizationid;
if (user.hourstoreserve <= (item.endtime - item.starttime)) {
request.respond(400, 'You do not have the necessary hours available to make this reservation');
} else if (user.complaints >= user.complaintsallowed) {
request.respond(400, 'You are over your maximum number of allowed complaints this month.');
} else {
user.hourstoreserve = (user.hourstoreserve - (item.endtime - item.starttime));
request.execute();
};
};
I need to make sure that item, which should be my new reservation that I am inserting, gets an organizationid from my user. I also then want to make sure the user has it's hourstoreserve validated, and if the reservation is made the user's hourstoreserve should be lowered.
It seems like this script isn't being executed at all. The first response.send(200, 'test'); does not send a response.
I am calling this insert script from my custom api similar to the following:
var reservations = request.service.tables.getTable("reservations");
reservations.insert(newReservation);
The custom API call works and inserts the reservation as it should, it just doesn't seem to execute my insert script.
Any help is appreciated.

When you invoke the CRUD operations of the tables from the service itself (i.e., in the code of a custom API, scheduler or another table), the table scripts are not executed. There's an open feature request to have this feature added to the backend, please upvote it if you think it will help you.
Another problem which I see in your code - the user object which is passed to the insert script isn't an item from your user model; instead, it's the information about the logged in user to the service (i.e., in the client side, after calling one of the login operations, that will be the user information it will have). That object doesn't have any properties about organization id, hourstoreserve, etc. If you need to get that information, you'll need to query your users table and working with it directly.

Related

Can I generate a transaction on the server and send it to the client for payment

I have built a smart contract method to which I pass some sensitive data that needs to be stored on the blockchain and alter the state of the contract. I, the creator of the contract don't want to be the one paying for the fees of that transaction. I want the user on the browser to approve and pay for it.
However, I do not want to generate the transaction object on the browser as I want some of the data that will be passed to the contract to be hidden from the client. If I understand the web3 syntax correctly, in the code below, I'm doing just that
web3.eth.sendTransaction({
from: walletAddressOfTheUserThatWillPayForTheTransaction,
data: myContract.methods.changeState(..sensitive data...).encodeABI()
})
However I do not want the above to happen on the browser. In my head, the sequence of events should look like this (pseudocode):
// server
let transactionObject = {
from: walletAddressOfTheUserThatWillPayForTheTransaction,
data: myContract.methods.changeState(..sensitive data...).encodeABI()
}
sendToClient(encrypt(transactionObject))
// client
let encryptedTransactionObject = await fetchEncryptedTransactionObjectFromServer()
// this should open up Metamask for the user so that they may approve and finalise the transaction on the browser
web3.eth.sendTransaction(encryptedTransactionObject)
Is this possible ? Is there some other way of achieving this? Could you provide me with some hints about the actual syntax to be used?
However, I do not want to generate the transaction object on the browser as I want some of the data that will be passed to the contract to be hidden from the client.
Then you should not be using public blockchains in the first place, as all data on public blockchains, by definition, is public. Anyone can read it.

Parse.com Add User Pointer to a class in before save

I have a table called Roster where it stores a User Pointer in one of the column. I am trying set that column in before save method when it is new.So far i have this but i am not sure how to get the user id
Parse.Cloud.beforeSave("Roster",function(request,response){
//Update roster with sender Id
if (request.object.isNew()){
var userPointer = /*NOT SURE HOW TO GET WHO SENT IT*/
request.object.set("User",userPointer);
}
response.success();
});
Any idea?
var userPointer = request.user;
Is the proper method. Todd's answer works on the client side, but not on cloud code, where beforeSave triggers occur.
If you need to access any of the user's information beyond their id, you'll have to first fetch the user, as the entire object is not sent in the request.
Edit - Just wanted to add that before/afterSave triggers have a 3 second timeout. This is enough time to perform a quick query or two, but if you have a lot of objects in your database, or perform many save/fetch/query calls, you may end up exceeding your 3 second limit. If you have a lot of that logic that needs to occur, rather than saving the object from the client, call a cloud code function that handles all of those changes, then saves the object and returns the newly saved object, so that you can set your client side object to the returned, up to date object.
As Jake T pointed out, you will need to use
var user = request.user
Parse.User.current() is not supported in a cloud code environment.

Meteor - Allow multiple users to edit a post

I'm not able to use the node server debugger so I'm posting here to see if I can get a nudge in the right direction.
I am trying to allow multiple users to edit documents created by any of the users within their specific company. My code is below. Any help would be appreciated.
(Server)
ComponentsCollection.allow({
// Passing in the user object (has profile object {company: "1234"}
// Passing in document (has companyId field that is equal to "1234"
update: function(userObject, components) {
return ownsDocument(userObject, components);
}
});
(Server)
// check to ensure user editing document created/owned by the company
ownsDocument = function(userObject, doc) {
return userObject.profile.company === doc.companyId;
}
The error I'm getting is: Exception while invoking method '/components/update' TypeError: Cannot read property 'company' of undefined
I'm trying to be as secure as possible, though am doing some checks before presenting any data to the user, so I'm not sure if this additional check is necessary. Any advice on security for allowing multiple users to edit documents created by the company would be awesome. Thanks in advance. -Chris
Update (solution):
// check that the userId specified owns the documents
ownsDocument = function(userId, doc) {
// Gets the user form the userId being passed in
var userObject = Meteor.users.findOne(userId);
// Checking if the user is associated with the company that created the document being modified
// Returns true/false respectively
return doc.companyId === userObject.profile.companyId;
}
Looking at the docs, it looks like the first argument to the allow/deny functions is a user ID, not a user document. So you'll have to do Meteor.users.findOne(userId) to get to the document first.
Do keep in mind that users can write to their own profile subdocument, so if you don't disable that, users will be able to change their own company, allowing them to edit any post. You should move company outside of profile.
(If you can't use a proper debugger, old-fashioned console.log still works. Adding console.log(userObject) to ownsDocument probably would have revealed the solution.)

Meteor.user() alternatives

I am writing an application which needs to display some user information.
Because Meteor.user() is not immediately available I wrapped every user information with an handlerbar helper
Handlebars.registerHelper('isLoggingIn', function() {
return Meteor.loggingIn();
})
This worked for me until I needed to create an admin page and custom content for every user/user role.
Waiting for Meteor.user() to be available or showing general information first while waiting for the roles to load are options I would like to avoid.
I then tried an alternative way and published the currentUser with a new Collection.
Meteor.publish('currentUser', function() {
var sub = this;
var handle = Meteor.users.find({_id: this.userId}).observe({
added: function (user) {
sub.added('currentUser', user._id, user);
}
});
sub.ready();
sub.onStop(function() { handle.stop(); });
});
and
CurrentUser = new Meteor.Collection('currentUser');
In this way I can access the logged in user with CurrentUser.findOne(), and it's available at the same time as the other collections.
What I fear is that this alternative is not as secure and problem free as the common Meteor.user(), and I was wondering if my method is correct and if there are better ways to obtain the same result (user detail information immediately available) without reinventing the wheel.
Just a note you can use {{loggingIn}}, {{#if loggingIn}}.. without writing your own helper.
The option to publish the user who is logged in with a custom publish function adds an unnecessary complexity.
When it comes to security you have to assume if its from the client side, in any scenario it is untrustworthy. This means you publish relevant data for the role, etc only when they are logged in to that user.
On the server the data is immediately available as soon as the user logs in, all you have to do is publish only the data for that users role. On the client it may take some time to adjust to this, which is why you can use placeholder until the subscriptions are complete.
What might be a better option would be to use either a helper that checks for when subscriptions are completed and displays a 'loading message'. Or use a router such as iron-router (github.com/EventedMind/iron-router) that can let you wait for a subcription to complete for a particular page.
This way you can use Meteor.user(), {{#currentUser}} and roles in way you intend.
One thing to keep in mind, is if you want to check if the user is logged in, not to use:
if(Meteor.user())
but instead
if(Meteor.user() && Meteor.user().profile && Meteor.user().profile.name)
(You will have to insert a name property in your profile, though). While logging in the user gets more and more data. I've noticed if you wait for the profile field, then the user is 'ready'. It seems initially the profile field is empty (still loggin in), but it would return true if you used if(Meteor.user())

Using XMLHTTPRequest to extract data from Database

I want to extract some data from the database without refreshing a page. What is the best possible way to do this?
I am using the following XMLHTTPRequest function to get some data (shopping cart items) from cart.php file. This file performs various functions based on the option value.
For example: option=1 means get all the shopping cart items. option=2 means delete all shopping cart items and return string "Your shopping cart is empty.". option=3, 4...and so on.
My XHR function:
function getAllCartItems()
{
if(window.XMLHttpRequest)
{
allCartItems = new XMLHttpRequest();
}
else
{
allCartItems=new ActiveXObject("Microsoft.XMLHTTP");
}
allCartItems.onreadystatechange=function()
{
if (allCartItems.readyState==4 && allCartItems.status==200)
{
document.getElementById("cartmain").innerHTML=allCartItems.responseText;
}
else if(allCartItems.readyState < 4)
{
//do nothing
}
}
var linktoexecute = "cart.php?option=1";
allCartItems.open("GET",linktoexecute,true);
allCartItems.send();
}
cart.php file looks like:
$link = mysql_connect('localhost', 'user', '123456');
if (!$link)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db('projectdatabase');
if($option == 1) //get all cart items
{
$sql = "select itemid from cart where cartid=".$_COOKIE['cart'].";";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
while($row = mysql_fetch_array($result))
{
echo $row['itemid'];
}
}
else if($option == 2)
{
//do something
}
else if($option == 3)
{
//do something
}
else if($option == 4)
{
//do something
}
My Questions:
Is there any other way I can get the data from database without
refreshing the page?
Are there any potential threats (hacking, server utilization,
performance etc) in my way of doing this thing? I believe a hacker
can flood my server be sending unnecessary requests using option=1,
2, 3 etc.
I don't think a Denial of Service attack would be your main concern, here. That concern would be just as valid is cart.php were to return HTML. No, exposing a public API for use via AJAX is pretty common practice.
One thing to keep in mind, though, is the ambiguity of both listing and deleting items via the same URL. It would be a good idea to (at the very least) separate those actions (or "methods") into distinct URLs (for example: /cart/list and /cart/clear).
If you're willing to go a step further, you should consider implementing a "RESTful" API. This would mean, among other things, that methods can only be called using the correct HTTP verb. You've possibly only heard of GET and POST, but there's also PUT and DELETE, amongst others. The reason behind this is to make the methods idempotent, meaning that they do the same thing again and again, no matter how many times you call them. For example, a GET call to /cart will always list the contents and a DELETE call to /cart will always delete all items in the cart.
Although it is probably not practical to write a full REST API for your shopping cart, I'm sure some of the principles may help you build a more robust system.
Some reading material: A Brief Introduction to REST.
Ajax is the best option for the purpose.
Now sending and receiving data with Ajax is done best using XML. So use of Web services is the recommended option from me. You can use a SOAP / REST web service to bring data from a database on request.
You can use this Link to understand more on Webservices.
For the tutorials enough articles are available in the Internet.
you're using a XMLHttpRequest object, so you don't refresh your page (it's AJAX), or there's something you haven't tell
if a hacker want to DDOS your website, or your database, he can use any of its page... As long as you don't transfer string between client and server that will be used in your SQL requests, that should be OK
I'd warn you about the use of raw text response display. I encourage you to format your response as XML or JSON to correctly locate objects that needs to be inserted into the DOM, and to return an tag to correctly handle errors (the die("i'm your father luke") won't help any of your user) and to display them in a special area of your web page
First, you should consider separating different parts of your application. Having a general file that performs every other tasks related to carts, violates all sorts of software design principles.
Second, the first vulnerability is SQL injection. You should NEVER just concatenate the input to your SQL.
Suppose I posted 1; TRUNCATE TABLE cart;. Then your SQL would look like:
select itemid from cart where cartid=1; TRUNCATE TABLE cart; which first selects the item in question, then ruins your database.
You should write something like this:
$item = $_COOKIE['cart'];
$item = preg_replace_all("['\"]", "\\$1", $item);
To avoid refreshing, you can put a link on your page. Something like, Refresh
In terms of security, it will always pay to introduce a database layer concerned with just your data, regardless of your business logic, then adding a service layer dependent on the database layer, which would provide facilities to perform business layer actions.
You should also take #PPvG recommendation into note, and -- using Apache's mod_rewrite or other similar facilities -- make your URLs more meaningful.
Another note: try to encapsulate your data in JSON or XML format. I'd recommend the use of json_encode(); on the server side, and JSON.parse(); on the client side. This would ensure a secure delivery.

Categories

Resources