LoopBack REST Middleware Modify Object Before Response - javascript

Just looking for a bit of theory here as going through the Strongloop documentation doesn't seem to help with my problem.
What I'd like to do is set up some middleware that can combine the requested object with other details; effectively what I have is objects that contain a user's ID and I'd like to have the server query the username and a couple of other details and collate the information into one object and respond with the new object.
So far I've literally just got some middleware running upon every API endpoint call and able to tell which route it is, but I don't know where to go from there. The REST response object is seemingly disconnected and I'm not sure how to access it. I'm not even sure it's been created at this point; is that where the routes:after phase might be used?
Many thanks in advance for any help, completely lost right now.

Related

Anylogic error "the constructor is undefined" in a resource pool

I was trying to do a simulation of distribution center model using the tips from anylogic to our own, cause they work in similar ways but diferent products and warehouses, so the thing is when a truck came to our center we have to unload in a determinated area thats why we use the "Muelle" agent to determine all the parameters involved in this operation, and when we call this new recourse unit in the resource pool for the unload process the error appears
Code use in a resource pool:
I got the same problem y two resource pool's
Problems
Im relatively new in this program and dont know how to fix this cause for the java description, i tought the variable was already defined cause i name it and was giving every value for each parameter so i dont understand.
I attach the file so if someone requires and can inquire more to solve this ill appreciate it so much
https://drive.google.com/file/d/1uBQyLr_LyjN9J07y_J_44ha4CSskVP8y/view?usp=sharing
If Muelle is an agent, you cannot create/instantiate them like Java objects (i.e. new Muelle(...).
You must use the agent constructor that AnyLogic provides: For every agent population, you get add_myPopulation(...) and remove_MyPopulation(...) methods. You must use those.
So create an empty (?) agent population and use that. Then, call add_MyPopulationOfMuelle(...)
Check the help for more info on agent creation and populations

Wait for response from emitted message?

I'm having a trouble wrapping my head around following concept.
I'm sending OSC messages to query status of instruments in Ableton, so I have emmiter/receiver combo going on. Now, thing is that I'd like to avoid having to keep up some sort of global state and wrap everything around this.
and I do communicate with Ableto in following fashion:
sender.emit("/live/device", queryData);
receiver.on("/live/device", function(responseData){
// process response here...
})
So you can tell that I'm not really sure when I got data back and cannot really sequence new queries based on responses.
What I'd like to do is to simply
query number of instruments on ONE certain channel
get number back
query parameters of each instrument of that channel based on first query
receive parameters back
But problem is that I have no idea how to wrap eventListeners to respond to these queries, or rather how to sequence them in way that is non-blocking and yet still avoiding having some sort of global state going on.
Querying data and storing Promises to be resolved by eventListener seems like a solution, but then I'm stuck on how to pass them back to sequence.
After some research, it seems that this kind of behaving breaks the whole concept of event listeners, but then I suppose the whole point is to have some global state to keep track of what is going on, right?
Event listeners are telling you some asynchronous action coming from a user action or any other interrupt. Depending on the API you are facing, they might have re-used event listeners for replies instead of providing a promise or callback return for the send API. If the server has multiple clients interacting with it, it might want to tell all clients at the same time when their state changes as well.
If you are sure there is no way to directly provide a callback in the send method for a reply to your request or a request does not yield a promise that resolves with the reply at some point, there are usually workarounds.
Option 1: Send context, receive it back
There are APIs that allow sending a "context" object or string to the API. The API then sends this context to the event listeners whenever it answers this specific question along with their payload. This way, the context part of their payload can be checked if it's the answer to the request. You could write your own little wrapper functions for a more direct send/reply pattern then.
Option 2: Figure out the result data, if it fits your request
If the resulting data has something specific to match on, like keys on a JSON object, it may be possible to find out what the request was.
Option 3: Use state on your side to keep track of everything
In most cases where I have seen such APIs, the server didn't care much about requests and only sent out their current state if it was changed by some kind of request. The client needs to replicate the state of the server by listening to all events, if it wants to show the current server state.
In most situations where I faced this issue, I thought about Option 1 or 2 but ended up with Option 3 anyways: Other clients or hardware switches might interfere with my client UI and change the server state without me listening on that change. That way I would loose information that invalidates my UI, so I would need to listen and replicate the state of the server/machine/hardware anyways.

How to prevent invoking 'Meteor.call' from JavaScript Console?

I just noticed that Meteor.call, the concept that prevent user from invoke collection's insert, update, remove method, still able to be invoked from JavaScript console.
For client's example:
// client
...
Meteor.call('insertProduct', productInfo);
...
Here's the server part:
// server
Meteor.methods({
insertProduct: function( productInfo ){
Product.insert(...);
}
})
OK, I know people can't invoke Product.insert() directly from their JavaScript console.
But if they try a little bit more, they'd find out there's Meteor.call() in client's JavaScript from Developer tool's resource tab.
So now they can try to invoke Meteor.call from their console, then try to guessing what should be productInfo's properties.
So I wonder how can we prevent this final activity?
Does Meteor.call done the job well enough?
or I'm missing something important?
Meteor.call is a global function, just like window.alert(). Unfortunately, there is nothing you can do from preventing a user calling Meteor.call. However, you can validate the schema of data and the actual data of what a user is sending. I'd recommend https://github.com/aldeed/meteor-simple-schema (aldeed:simple-schema as the meteor package name) to ensure you don't get garbage data in your project.
As others pointed out, "Meteor.call" can surely be used from the console. The subtle issue here is that there could be a legal user of a meteor app who can in turn do bad things on the server. So even if one checks on the server if the user is legal, that by itself does not guarantee that the data is protected.
This is not an issue only with Meteor. I think all such apps would need to potentially protect against corruption of their data, even through legal users
One way to protect such corruption is by using IIFE (Immediately Invoked Function Expression)
Wrap your module in a IIFE. Inside the closure keep a private variable which stores a unique one time use key (k1). That key needs to be placed there using another route -- maybe by ensuring that a collection observer gets fired in the client at startup. One can use other strategies here too. The idea is to squirrel in the value of k1 from the server and deposit it in a private variable
Then each time you invoke a Meteor.call from inside you code, pass k1 along as one of the parameter. The server in turn checks if k1 was indeed legal for that browser connection
As k1 was stored inside a private variable in the closure that was invoked by the IIFE, it would be quite difficult for someone at the browser console to determine the value of k1. Hence, even though "Meteor.call" can indeed be called from the browser console, it would not cause any harm. This approach should be quite a good deterrent for data corruption
As mentionned by #Faysal, you have several ways to ensure your calls are legit. An easy step to do so is to implement alanning:roles and do role checks from within your method like the following:
Meteor.methods({
methodName: function() {
if (!Roles.userIsInRole(this.userId, 'admin')) {
throw new Meteor.Error(403, 'not authorized);
} else { yourcode });
This way, only admin users can call the method.
Note that you can also check this.connection from within the method and determine if the call comes from the server (this.connection === false) or from the client.
Generally speaking, doing checks and data manipulations from your methods is a nice way to go. Allow/deny are nice to begin with but become really hard to maintain when your collections get heavier and your edge-cases expand.
You cannot block Meteor.call from the console, just like you can't block CollectionName.find().count() from the console. These are global functions in meteor.
But there are simple steps you can take to secure your methods.
Use aldeed:simple-schema to set the types of data your collection can accept. This will allow you to set the specific keys that your collection takes as well as their type (string, boolean, array, object, integer) https://github.com/aldeed/meteor-simple-schema
Ensure that only logged in users can update from your method. Or set global Allow/Deny rules. https://www.meteor.com/tutorials/blaze/security-with-methods && https://www.discovermeteor.com/blog/allow-deny-a-security-primer/
Remove packages insecure and autopublish
The simple combo of schema and allow/deny should do you just fine.
As you know by now that you can't really block calling Meteor.call from Javascript console, what i'd like to add as a suggestion with #Stephen and #thatgibbyguy that, be sure to check your user's role when adding documents into the collection. Simple-Schema will help you prevent inserting/updating garbage data into the collection. and alanning:roles package certainly makes your app secure by controlling who has the permission to write/read/update your collection documents.
Alanning:roles Package

modifying res object in express.js

I had this idea for a backend design for my SPA-website. I would implement it so that routes starting with "/api/" would return only the relevant data in JSON. all other routes would lead to a full-page load.
Now my idea is to do this in middleware, as such:
app.use(function(req, res, next() ){
if(req.path.split("/")[0]=="api"){
res.send = res.json;
//or other custom response-function, I see many possibilities here!
}else{
...
}
});
app.use(routes);
now, my question is, does this modify the res object globally, or just for the current request (this instance of res)? My understanding is just the current one gets modified, and as far as I can tell thats true, but node is blazingly fast, so it's kinda hard to test on my own ( one can only refresh so many tabs in a millisecond! ) anyone know for sure?
Edit: A lot of the people answering my question have asked why I would want to do this. The point is to abstract what the server does for requests coming from clients with the front-end loaded, and clients who need the full page. I'm also considering the possibility of adding a route for loading partial templates, using this same method. by modifying res.send my controllers can worry about getting the data and send it of, res.send will already know if there needs to be some rendering involved. On second thought though res.send is really useful on its own, I might modify res to have res.answer or similar instead.(makes for less confusion too!)
I decided to make this an answer because sometimes future readers don't read the comments.
1) You can modify res and its members to your heart's content. You are operating on an instance of response, not its prototype. There is no "global" resource, but it does have a prototype.
2) Reading the documentation will pay off here. res.send operates identically to res.json if it is passed an object or array. Which is to say that the rest of your code will, in the typical case, run no differently than if you didn't monkey with res.send() but will confuse the heck out of someone (maybe you) several months or years later.
I tested this and each time a request came the response object had the original send function instead of the changed value. So no, it doesn't change it globally.
Here is the test I did:
app.use(function(req, res){
console.log(res.send);
res.send = 'a';
console.log(res.send);
});
Though I'm still not quite sure why you want to do this? It seems like it would be very confusing when someone looks at your API routes and sees res.send() but the effect instead is that of res.json. Why can't you use res.json in your API route functions?

In Meteor, how can i identify connection / a user of a site on the server, regardless of whether or not they're logged in?

How can i identify a specific connection on the server in Meteor. Similar to what you could accomplish with Session on the client - somewhere to put data related to the current connection.
Sort of like this issue, but on the server, not the client.
I can see that the Meteor Accounts package uses the following code in the Meteor.userId method:
var currentInvocation = Meteor._CurrentInvocation.get();
if (!currentInvocation)
throw new Error("Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.");
But when I try to use Meteor._CurrentInvocation in my code, it is undefined, rather than a Meteor.EnvironmentVariable object, as implied in the livedata package. And, as evidenced by the prefixing underscore, it's a private API, and should probably be avoided in general application code ;)
Any help would be greatly appreciated!
OK - i was overcomplicating the issue, and coming at it from completely the wrong direction.
The context of any Meteor.method calls has a connection property as described here. This connection property is described here, and can be used to persist data across method calls for the duration of the connection.
It is accessible in publish functions and Meteor.methods methods.

Categories