What is context.dispatch in feathers.js - feathersjs

I read the feathersjs API documentation. (this)
But I can't understand what is the context.dispatch. and what does this do.
context.dispatch is a writeable, optional property and contains a "safe" version of the data that should be sent to any client.
If context.dispatch has not been set context.result will be sent to the client instead.
What is the "safe" version means?
When will I want to use it?

The "safe" version is what a client can see and is specifically important for hiding fields - like the password - in real-time events. For example, if - on the server - you do:
app.service('users').patch(user.id, { enabled: false })
The return value will include the hashed password even though it is using the protect hook because it is an internal call.
However, context.dispatch will not include the password and the patched real-time event will only send back the safe data to the client.

Related

Restrict feathers service method to user for external but allow any queries for internal calls

I want to restrict calls to a Feathers service method for externals calls with associateCurrentUser.
I also want to allow the server to call this service method without restricting it.
The use case is that through this service then clients use a lock table, all clients can see all locks, and occasionally the server should clear out abandoned rows in this table. Row abandonment can happen on network failures etc. When the server removes data then the normal Feathers remove events should be emitted to the clients.
I would imagine that this should be a mix of associateCurrentUser and disallow hooks but I can't even begin to experiment with this as I don't see how it would be put together.
How would one implement this, please?
Update:
I found this answer User's permissions in feathers.js API from Daff which implies that if the hook's context.params.provider is null then the call is internal, otherwise external. Can anyone confirm if this is really so in all cases, please?
It seems to be so from my own tests but I don't know if there are any special cases out there that might come and bite me down the line.
If the call is external params.provider will be set to the transport that has been used (currently either rest, socketio or primus, documented here, here and here).
If called internally on the server there is not really any magic. It will be whatever you pass as params. If you pass nothing it will be undefined if you pass (or merge with) hook.params in a hook it will be the same as what the original method was called with.
// `params` is an empty object so `params.provider` will be `undefined`
app.service('messages').find({})
// `params.provider` will be `server`
app.service('messages').find({ provider: 'server' })
// `params.provider` will be whatever the original hook was called with
function(hook) {
hook.app.service('otherservice').find(hook.params);
}

Storing data in FIWARE Object Storage

I'm building an application that stores files into the FIWARE Object Storage. I don't quite understand what is the correct way of storing files into the storage.
The code python code snippet below taken from the Object Storage - User and Programmers Guide shows 2 ways of doing it:
def store_text(token, auth, container_name, object_name, object_text):
headers = {"X-Auth-Token": token}
# 1. version
#body = '{"mimetype":"text/plain", "metadata":{}, "value" : "' + object_text + '"}'
# 2. version
body = object_text
url = auth + "/" + container_name + "/" + object_name
return swift_request('PUT', url, headers, body)
The 1. version confuses me, because when I first looked at the only Node.js module (repo: fiware-object-storage) that works with Object Storage, it seemed to use 1. version. As the module was making calls to the old (v.1.1) API version instead of the presumably newest (v.2.0), referencing to the python example, not sure if that is an outdated version of doing it or not.
As I played more with the module, realised it didn't work and the code for it was a total mess. So I forked the project and quickly understood that I will need rewrite it form the ground up, taking the above mention python example from the usage guide as an reference. Link to my repo.
As of writing this the only methods that aren't implement is the object storage (PUT) and object fetching (GET).
Had some addition questions about the Object Storage which I sent to fiware-lab-help#lists.fiware.org, but haven't heard anything back so asking them here.
Haven't got much experience with writing API libraries. Should I need to worry about auth token expiring? I presume it is not needed to make a new authentication, every time we interact with storage. The authentication should happen once when server is starting-up (we create a instance) and it internally keeps it. Should I implement some kind of mechanism that refreshes the token?
Does the tenant id change? From the quote below is presume that getting a tenant I just a one time deal, then later you can use it in the config to make less authentication calls.
A valid token is required to access an object store. This section
describes how to get a valid token assuming an identity management
system compatible with OpenStack Keystone is being used. If the
username, password and tenant details are known, only step 3 is
required. source
During the authentication when fetching tenants how should I select the "right" one? For now i'm just taking the first one similar as the example code does.
Is it true that a object storage container belongs to only a single region?
Use only what you call version 2. Ignore your version 1. It is commented out in the example. It should be removed from the documentation.
(1) The token will be valid for some period of time. This could be an hour or a day, depending on the setup. This period of time should be specified in the token that is returned by the authentication service. The token needs to be periodically refreshed.
(2) The tenant id does not change.
(3) Typically only one tenant id is returned. It is possible, however, that you were assigned more than one id, in which case you have to pick which one you are currently using. Containers typically belong to a single tenant and are not shared between tenants.
(4) Containers are typically limited to a single region. This may change in the future when multi-region support for a container is added to Swift.
Solved my troubles and created the NPM module that works with the FIWARE Object Storage: https://github.com/renarsvilnis/fiware-object-storage-ge

Is it possible CookieStore config not working correctly?

Even if I configure CookieStore with:
MyApp::Application.config.session_store :cookie_store, {
key: '_myapp_session',
cookie_only: false,
httponly: false
}
and I make a POST request with
_myapp_session = #SOME_SESSION_ID
and authenticity_token = #AUTH_TOKEN
and http-header[X-CSRF-Token] set to #AUTH_TOKEN
finally the user is not authenticated, and new session is created with new AUTH_TOKEN and session id.
Can anybody give me some suggestions ?
Unfortunately there is NO SUPPORT for this option in current 4.0 branch. Although this option is forced to TRUE and I didn't find any code in rails sources using this option.
The way to make isolated POST's requests working is to create dedicated middleware, which will add appropriate session cookie. It must be inserted in the apropriate place, because middleware's order is significant.
Because it is very dangerous in CSRF security aspect, we must add to our middleware same verification, which will limit potential risk to minimum.

How to do authentication in node.js that I can use from my website?

I want a Node.js service to authenticate the user of my website. How can I do this?
I want to implement Everyauth authentication using the simple password method, not OpenID.
I tried https://github.com/jimpick/everyauth-example-password and it works.
I want to use the database to store. This script does not use a database. I have used MySQL in past so I prefer that but I am ok with anything else as well such as MongoDB.
I just want to add database to my script. Please help.
You only need to modify .authenticate method. Since connecting to database is (or should be) an asynchronous operation, then you need to add promise object (see everyauth documentation).
Assuming you have some ORM with user data corresponding to user object with username and password attributes (in my example I'll use mongoose engine), this is how it may look:
.authenticate( function (login, password) {
var promise = this.Promise(); /* setup promise object */
/* asynchrnously connect to DB and retrieve the data for authentication */
db.find({ username:login }, function(err, user) {
if (err)
return promise.fulfill([err]);
if ((!user) || (user.password != password))
return promise.fulfill(['Incorrect username or password!']);
promise.fulfill(user);
});
return promise; /* return promise object */
})
I didn't test it, but according to the documentation it should work. Remember that errors are supposed to be held in array.
By the way: if you are using only the password method, then there is no need to, you know, use a cannon against a fly. :) Writing your own (not necessarly perfect, but working) authentication mechanism is really simple and if you don't know how to do this you should learn it. It will benefit in the future, because authentication and security in general are very important in every web app.

How can I let users register my product online?

I've a MySql database hosted in my web site, with a table named UsrLic
Where any one wants to buy my software must register and enter his/her Generated Machine Key (+ username, email ...etc).
So my question is:
I want to automate this process from my software, how this Process will be?
Should I connect and update my database directly from my software ( and this means I must save all my database connection parameters in it * my database username , password , server * and then use ADO or MyDac to connect to this database ? and if yes how secure is this process ?
or any other suggestions .
I recommend creating an API on your web site in PHP and calling the API from Delphi.
That way, the database is only available to your web server and not to the client application, ever. In fact, you should run your database on localhost or with a private IP so that only machines on the same physical network can reach it.
I have implemented this and am implementing it again as we speak.
PHP
Create a new file named register_config.php. In this file, setup your MySQL connection information.
Create a file named register.php. In this file, put your registration functions. From this file, include 'register_config.php'. You will pass parameters to the functions you create here, and they will do the reading and writing to your database.
Create a file named register_api.php. From this file, include 'register.php'. Here, you will process POST or GET variables that are sent from your client application, call functions in register.php, and return results back to the client, all via HTTP.
You will have to research connecting to and querying a MySQL database. The W3Schools tutorials will have you doing this very quickly.
For example:
Your Delphi program calls https://mysite/register_api.php with Post() and sends the following values:
name=Marcus
email=marcus#gmail.com
Here's how the beginning of register_api.php might look:
// Our actual database and registration functions are in this library
include 'register.php';
// These are the name value pairs sent via POST from the client
$name = $_POST['name'];
$email = $_POST['email'];
// Sanitize and validate the input here...
// Register them in the DB by calling my function in register.php
if registerBuyer($name, $email) {
// Let them know we succeeded
echo "OK";
} else {
// Let them know we failed
echo "ERROR";
}
Delphi
Use Indy's TIdHTTP component and its Post() or Get() method to post data to register_api.php on the website.
You will get the response back in text from your API.
Keep it simple.
Security
All validation should be done on the server (API). The server must be the gatekeeper.
Sanitize all input to the API from the user (the client) before you call any functions, especially queries.
If you are using shared web hosting, make sure that register.php and register_config.php are not world readable.
If you are passing sensitive information, and it sounds like you are, you should call the registration API function from Delphi over HTTPS. HTTPS provides end to end protection so that nobody can sniff the data being sent off the wire.
Simply hookup a TIdSSLIOHandlerSocketOpenSSL component to your TIdHTTP component, and you're good to go, minus any certificate verification.
Use the SSL component's OnVerifyPeer event to write your own certificate verification method. This is important. If you don't verify the server side certificate, other sites can impersonate you with DNS poisoning and collect the data from your users instead of you. Though this is important, don't let this hold you up since it requires a bit more understanding. Add this in a future version.
Why don't you use e.g. share*it? They also handle the buying process (i don't see how you would do this for yourself..) and let you create a reg key through a delphi app.