Connect to socket Qlik Sense Entreprise with EnigmaJS - websocket

I build a working mashup on QlikSense Desktop connecting with the usual:
appId = 'engine';
this.session = enigma.create({
schema,
url: 'ws://localhost:4848/app/' + appId
})
But now I uploaded the mashup on the server, and for once, it behaves as expected. It doesn't.
I tried to change it to the following as the server doesn't have SSL certificates.
'ws://domainname:4747/'+appId
But nothing works, any idea ?
(Basically my question is: How can I find my QIX Engine ws url ?)

Whats the error?
But in general, when using QS server you have to be authenticated in order to get some data.
You can check all the received data by listening to all traffic for more details on the error:
session.on('traffic:received', data => console.log('received:', data));
Or you can just "listen" to data related only to authentication by setting a dedicated notification:
session.on('notification:OnAuthenticationInformation', (authInfo) => {
console.log(authInfo)
});
Have a look at Connecting to the Qlik Engine JSON API (scroll down to Qlik Sense Enterprise section) to get the idea what types of authentication are supported

Related

Connecting to AWS IoT Websocket without MQTT client

I have a client application which runs in the browser which I can't change the implementation of to implement an MQTT client such as mqtt on npm.
The code in the library is as follows and allows me to pass in a socketUrl
const ws = new WebSocket(socketUrl)
I have tried generating a presigned URL for IoT, which seems to work in terms of authenticating (i.e. no Unauthorized response) but I get a 426 Upgrade Required response.
I believe I'm correct in saying that if it were working it'd reply with a 101 Switching protocols but without knowing much about MQTT i'm unsure if this is not happening because I'm doing something wrong or because I'm not using MQTT.
I'm generating a signed URL using the below code (I'll switch to Cognito Identities if I get this working rather than using the fixed key/secret)
const v4 = require('aws-signature-v4')
const crypto = require('crypto')
const socketUrl = v4.createPresignedURL(
'GET',
'myioturl.iot.us-east-1.amazonaws.com',
'/mqtt', // tried just /mytopic, too
'iotdevicegateway',
crypto.createHash('sha256').update('', 'utf8').digest('hex'), {
'key': 'removed',
'secret': 'removed',
'protocol': 'wss',
'region': 'us-east-1'
}
)
The protocols page in the iot documentation seems to suggest that if I point at /mqtt I'm indicating I'll be using MQTT.
mqtt Specifies you will be sending MQTT messages over the WebSocket protocol.
What does this mean if I just specify /foobar? Should I be able to connect to the socket but not using MQTT?
There are quite a few unknowns for me so I'm struggling to work out if it should work at all, and if so, which bit am I doing wrong.

Google APIs OAuth refresh token url return 401 on http redirect uri?

I had implemented the code to received authorization code as described in this step:
https://developers.google.com/android-publisher/authorization#generating_a_refresh_token
We deployed this code to one server that has "https://..." domain and this works well. We can get the access_token, refresh_token...
But now we need to deploy the same code to a dev server that has no "https".
I created a new OAuth client id with redirect uri using the dev server (no https, the rest /api/v1/... is the same as the previous working server)
Now anytime I tried to go to this url and Allow access
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=http://dev_server/api/v1/...&client_id=dev_server_client_id
I got 401 Unauthorized.
I'm not sure why, but the only difference I can see is "https" vs "http".
Any idea why?
Thank you very much.
Actually I forgot to update the corresponding values in my code
const oauth2Client = new OAuth2(
config.googleApi.clientId,
config.googleApi.clientSecret,
config.googleApi.redirectUri // <= Especially this value
);
These values need to be updated to (beside values on google console).

Is AJAX request from localhost to an HTTPS destination is securely encrypted?

Maybe it is incorrect, but this is not a tutorial or something, its a question. So if it is incorrect, please correct it.
Situation:
Sending data from client side to server side using GET / POST / PUT / DELETE.
**
Here there is just another AJAX request as described above using the POST method with jQuery and AngularJS:
$.ajax({
type: "POST",
headers: {
"Content-Type": "application/json"
},
url: "https://www.myawesomedomainname.com",
data: JSON.stringify($scope.fetchData),
success: function(response) {
// some code
},
error: function(err) {
// some code
}
});
The security problem:
One can use the same Internet Wifi and since the data is not ecrypted, one can see the data transferred to the server. This security issue called: "Man in the middle".
The solution:
Working with HTTPS to encrypt the transferred data from client side to server side, will let the man in the middle see just bla bla bla.
The problem:
If we want the described above to work, both client side and server side have to know the encryption keys, otherwise, the targeted server will get the data encrypted too (like the man in the middle).
Not everytime we have that privilege - sometimes the client side does not own any kind of domain - maybe it is a mobile application?
The question:
When I am sending, lets say, from cordova mobile app, data to server side, which the server side has HTTPS url, does it securely encrypted and prevents man in the middle attacks?
When using HTTPS the entire request including other than the host address in the URL is encrypted. That includes the query string and server path.
Essentially MiTM attacks are prevented with only a very small attack surface by a very sophisticated and dedicated network attacker or an attacker that has physical access to the client device such as the device owner. That can be closed by pinning the certificate. This is generally not required.
Pinning the certificate means the client verifying that the certificate is the correct server certificate by comparing all or a portion of the certificate against compiled-in information. Many networking APIs contain pinning support.

Invoke worklight SQL adapter procedure using AJAX

Can someone give an example of how to invoke and receive a response from an SQL adapter in worklight using AJAX call? I'm using worklight 6.0
I have security at the app level. I need to invoke a procedure that doesn't need authentication (example: Registering an account) and hence need to invoke the adapter using AJAX
This is my adapter:
var invocationData = {
adapter : 'UserInfo',
procedure : 'addUserInfo',
parameters : [ customerData.firstName,
customerData.lastName, customerData.email,
customerData.province, customerData.zipPostal,
customerData.phoneNumber, customerData.streetName,
customerData.streetNumber, customerData.country,
customerData.city ]
};
WL.Client.invokeProcedure(invocationData, {
onSuccess : insertUserSuccess,
onFailure : insertUserFailure
});
My understanding is that you just want to invoke an Adapter procedure using Ajax from some client.
Is it the same as this other question ?
Calling Worklight adapter from external app
You can check the details of the HTTP API here
http://www-01.ibm.com/support/knowledgecenter/SSZH4A_6.0.0/com.ibm.worklight.help.doc/admin/r_http_interface_of_the_prod_server.html?lang=en
Update:
Also note that if you have any security tests configured, different than "wl_unprotected" (your adapter is 100% public with that, be careful!!) you may need extra steps to handle authentication.
If you have a default adapter, without any security test set, you may receive a 401 unauthorized in your first request, and in the body of the 401 you may find a WL-Instance-ID property, that you must send together with a new request to get authorized to use it.
Update 2:
Worklight/MobileFirst Platform doesn't enable CORS (so you can't "naturally" call adapters using ajax from an external web page). It may be possible to workaround that by using a gateway (IHS maybe) that adds the header "Access-Control-Allow-Origin" to all adapter responses. Note that you are handling a security thing, so make sure you know what you are doing.
Worklight (6.3 and below) adapters can work only with the Worklight Server.
If you plan on using Worklight adapters, you are required to use the API as provided by the Worklight framework - the code mentioned in the question.
You can still use regular AJAX requests - but those won't/cannot be requests sent to/by the Worklight adapter.
WLJQ.ajax( "some-URL" )
.done(function (data) {
console.log(data);
});
If the destination does require going through the Worklight Server, and it is not protected by any realm, what is the problem then? Send the request.
Perhaps you should not protect the app at the environment level but rather at the procedure level (set the security test on the adapter procedure in the adapter XML and not on the environment in application-descriptor.xml).
Perhaps you need to better explain your specific scenario...

How do I receive an http request with a Node.js server and then pass that request along to another server?

There's a lot going on here so I'll simplify this into a pseudo example. Forget about security and whatnot for a minute here. The point is to understand the functionality.
Let's say I'm running a local web server with node.js to dev a website. In the website, the user should be able to create a new account. The account information will be submitted via ajax to the node server. I then need the node server to take the incoming request and pass it along to another server that gives me access to a database. CouchDB, for example.
So here's a pseudo example of what I'd like to happen.
In the client's browser:
$.ajax({
url: './database_stuff/whatever', // points to the node web server
method: 'POST',
data: {name: 'Billy', age: 24}
});
In the Node web server:
var http = require('http'),
dbServer = 'http://127.0.0.1:5984/database_url';
http.createServer(function (req, res) {
/* figure out that we need to access the database then... */
// magically pass the request on to the db server
http.magicPassAlongMethod(req, dbServer, function (dbResponse) {
// pass the db server's response back to the client
dbResponse.on('data', function (chunk) {
res.end(chunk);
});
})
}).listen(8888);
Make sense? Basically what's the best way to pass the original request along to another server and then pass the response back to the client?
If the server at dbServer url supports streaming you could do something like
var request = require('request');
req.pipe(request.post(dbServer)).pipe(res)
where request is a module, for more info look here https://github.com/mikeal/request
This is quite readable and easy to implement, if for whatever reason you cannot do this then you could take what you need from the request and manually POST it, then take the response and res.send it to the client.
Sorry if there's an error in my code, I haven't tested it but my point should be clear, if it's not then ask away.

Resources