I'm looking to create a scheduled job using a Azure mobile service.
Since the service will end up calling another cloud service (website), I was wondering if the mobile script could access a database the cloud service already does.
I understand you can specify a database to use for the mobile script (I selected free for logging) but can't seem to tell if you can access other databases through the API.
var todoItemsTable = tables.getTable('TodoItems');
Hypothetically...
var todoItemsTable = databases.getDatabase('NonMobileSqlDb').tables.getTable('TodoItems');
I've already checked this question (Can you mix Azure Mobile Services with Azure Cloud Services?) but it doesn't seem to cover scripts talking to databases.
Some background...
The mobile service will (on a schedule) invoke a web service (with authorisation) that performs routine actions. I'd like to lock down this service (without ssl) and one way is to generate a key the service could use that the cloud service could verify. This key would be stored in the database both can access and only be available for a short period of time.
Yes you can.
You need to connect using the following example (uses Node.js) taken from the how-to guide:
To use the node-sqlserver, you must require it in your application and
specify a connection string. The connection string should be the ODBC
value returned in the How to: Get SQL Database connection information
section of this article. The code should appear similar to the
following:
var sql = require('node-sqlserver');
var conn_str = "Driver={SQL Server Native Client 10.0};Server=tcp:{dbservername}.database.windows.net,1433;Database={database};Uid={username};Pwd={password};Encrypt=yes;Connection Timeout=30;";
Queries can be performed by specifying a Transact-SQL statement with
the query method. The following code creates an HTTP server and
returns data from the ID, Column1, and Column2 rows in the Test table
when you view the web page:
var http = require('http')
var port = process.env.port||3000;
http.createServer(function (req, res) {
sql.query(conn_str, "SELECT * FROM TestTable", function (err, results) {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.write("Got error :-( " + err);
res.end("");
return;
}
res.writeHead(200, { 'Content-Type': 'text/plain' });
for (var i = 0; i < results.length; i++) {
res.write("ID: " + results[i].ID + " Column1: " + results[i].Column1 + " Column2: " + results[i].Column2);
}
res.end("; Done.");
});
}).listen(port);
Many thanks to #GauravMantri & #hhaggan for their help in getting this far.
Related
I am creating customer service chat application that get data from client website to node.js server then send this data to agent and the agent reply to the client..
Server code:
var ws = require("nodejs-websocket");
var clients = [];
var server = ws.createServer(function(conn){
console.log("New Connection");
//on text function
conn.on("text", function(str){
var object = JSON.parse(str);
conn.sendText("Message send : " + object);
console.log("User ID: " + object.id);
clients.push(object.id);
var unique=clients.filter(function(itm,i,a){
return i==a.indexOf(itm);
});
/*
conn.on('message', function("test") {
console.log('message sent to userOne:', message);
unique[0].send("Message: " + message);
});
*/
console.log("Number of connected users : " + unique.length);
//closing the connection
conn.on("close", function(){
console.log("connection closed");
});
});
}).listen(process.env.PORT, process.env.IP);
Everything works perfectly and I have each client ID but the
I want to reply with a message to that client ID..
What I have tried:
I have tried to reply to the client using conn.send("message", callBackFunction) but it send to all not with a specified user ID.
Disclaimer: co-founder of Ably - simply better realtime
You have two problems there I suspect. Firstly, if you ever need to scale to more than one server you've got problems as you will need to figure out how to pass messages between servers. Secondly, you have no way of maintaining state between disconnections which will happen as part of normal behaviour for clients.
The industry typically approaches this type of problem using the concept of channels as it scales, it decouples the publisher from the subscriber, and it's quite a simple concept to work with. For example, if you had a channel called "client:1" and you published to that channel, and your subscriber was listening on that channel, then they would receive the message. You can find out more about how we have designed our realtime service around channels, I would suggest you do consider that pattern in your system.
Matt, co-founder, Ably
I hope to send notifications to individual users using Azure Mobile Services. When I add the notification service in Visual Studio 2013, it automatically generate a custom API in my Azure service. Since I have built my mobile service with JavaScript backend. The generate code is follow:
exports.post = function (request, response) {
response.send(statusCodes.OK);
sendNotifications(request);
};
function sendNotifications(request) {
var payload = '<?xml version="1.0" encoding="utf-8"?><toast><visual><binding template="ToastText01">' +
'<text id="1">' + request.body.toast + '</text></binding></visual></toast>';
var push = request.service.push;
push.wns.send(null,
payload,
'wns/toast', {
success: function (pushResponse) {
console.log("Sent push:", pushResponse);
}
});
}
And In my client service, I have used userId as my tags and invoke the function
`await App.MobileService.GetPush().RegisterNativeAsync(channel.Uri,userIdTags);`
where userIdTags is a List of strings that contains certain userId values I hope to receive the message.
But when I debug I found that all of users will receive the notification. So I would like to know whether do I need to handle or modify the auto-generate code in the custom API or any other reason that cause the problem .
I am developing a web application where the user can type in a "device id" on the web page (we have 100's of devices out on the field in production use each with a unique ID), that result entered by the user will be sent to the Node.js server that in return will store it into a variable and use it in a SQL Query to retrieve results about that particular device from the database server and then display the results back to the client web page.
Currently the form input feature has not been implemented yet even though I've already coded the form code in html.
The program works fine as it is if I were to manually change the DEVICE_ID to the device I wish to retrieve data from in the code but of course I want to be able to enter this on the client page instead of me having to change it in the server-side source code manually.
"use strict";
var pg = require('pg').native;
var http = require('http');
var $ = require('cheerio');
var fs = require('fs');
var url = require('url');
var htmlString = fs.readFileSync('index.html').toString();
var parsedHTML = $.load(htmlString);
var dbUrl = "tcp://URL HERE/";
// The Sign-ID
var DEVICE_ID = '2001202';
// Create the http server
http.createServer(function (request, response) {
var request = url.parse(request.url, true);
var action = request.pathname;
// Connect and query the database
pg.connect(dbUrl, function(err, client) {
// The complete sql query for everything that's needed for the app!
client.query("SQL QUERY IS HERE" + DEVICE_ID + "etc..",
function (err, result) {
// Remaining program code is here that performs DOM based
// manipulation to display results returned from the server
// to the client side page.
// Time to Render the document and output to the console
console.log(parsedHTML.html());
// Render the document and project onto browser
response.end(parsedHTML.html());
}
); // End client.query
}); // End pg.connect
}).listen(8080); // End http.CreateServer
pg.end();
I've considered the following:
1) Use An OnClick() function from within the HTML code, like this:
onclick="lookupSignID()
Then include an external JS file from within the HTML that includes the lookupSignID() function however I soon found out this is only performing client-side function and is not what I want.
2) AJAX is only good for if the server is generating new information by itself, therefore I can't use AJAX since the user is entering the device ID to get information from it.
3) Possibly using POST/ GET
Can anyone please advise on what course of action I should take? If solution (3) is the best way how would I go about doing this? Can it be integrated into my existed code (shown above) without many changes?
Thanks!
If you used jQuery on the client side with an AJAX POST function, and then on the server side, you have express.js, you could do this:
app.post('/deviceid', function(req, res) {
var deviceid = req.param('deviceid')
console.log(deviceid)
...
})
So I'm currently running node.js, which has ldapjs installed. My aim is to have a system that uses ldapjs to allow users to login with a username and password.
I have been reading over the http://ldapjs.org documentation for awhile now but am struggling to understand the whole idea of ldap and ldapjs's implementation of it.
I currently have this from the documentation
var ldap = require('ldapjs');
var server = ldap.createServer();
server.bind('cn=root', function(req, res, next) {
if (req.dn.toString() !== 'cn=root' || req.credentials !== 'secret')
return next(new ldap.InvalidCredentialsError());
res.end();
return next();
});
server.listen(1389, function() {
console.log('LDAP server up at: %s', server.url);
});
Which allows me to run the below and successfully bind to the server.
ldapsearch -H ldap://localhost:1389 -x -D cn=root -w secret -LLL -b "o=myhost" objectclass=*
But I'm really unsure of where to go from here or even if this is the correct approach...
The ideal setup would be to have a range of users and passwords, and on a successful ldap connection confirm the details are correct and respond with a true, or false if the username/pass was incorrect.
Does anyone know of any good resources for finding out more about this, or better yet can suggest some basic client/server side code to give me an idea of where to go next!
Any replies would be really appreciated.
Many Thanks
I never used ldapjs, but based on what I just quickly read in its seemingly incomplete document, it can be used to implement an LDAP server or an LDAP client, which seems to be what you're trying to do (i.e., I'm assuming you want to authenticate users in your application against an existing LDAP server). Most of the examples in its document focus on creating an LDAP server that listens on a certain port and interacts with a back-end database. If you're not trying to put an LDAP-based interface between your back-end database or store of users and passwords, then you probably don't need the server API. If you already have an LDAP server running, then you will need to use its client API to do something like this:
1.Bind anonymously to the LDAP server that provides the directory services including the authentication services. It looks like you can just do this with:
var ldap = require('ldapjs');
var client = ldap.createClient({
url: 'ldap://my.ldap.server'
});
2.Search by the username (e.g., e-mail address) for the corresponding entry's DN
var opts = {
filter: '(mail=USERNAME)',
scope: 'sub'
};
client.search('ou=users,o=acme.com', opts, function(err, res) {
assert.ifError(err);
res.on('searchEntry', function(entry) {
console.log('entry: ' + JSON.stringify(entry.object));
});
res.on('searchReference', function(referral) {
console.log('referral: ' + referral.uris.join());
});
res.on('error', function(err) {
console.error('error: ' + err.message);
});
res.on('end', function(result) {
console.log('status: ' + result.status);
});
});
3.Grab the DN of the returned entry ( entry.object ). The documentation of this library doesn't talk much about how these objects can be used (e.g., what their methods, properties, etc. are). So, you will have to figure out how to actually get the DN or string representation of the DN of the entry you just retrieved from the directory server. [See the comment(s) below this answer]
4.Rebind to the server using that DN:
client.bind(DN_RETRIEVED, PASSWORD_USER_ENTERED, function(err) {
assert.ifError(err);
});
5.The result of the bind above is what you will need to use to determine whether or not the authentication was successful.
If you are trying to implement an LDAP server in front of your user/password data store for LDAP-based authentication, then you will need to follow their server examples. I personally think this is an overkill and could be problematic in terms of security.
I am trying to connect to my CouchDB database on Cloudant using Node.js.
This worked on the shell:
curl https://weng:password#weng.cloudant.com/my_app/_all_docs
But this node.js code didn't work:
var couchdb = http.createClient(443, 'weng:password#weng.cloudant.com', true);
var request = couchdb.request('GET', '/my_app/_all_docs', {
'Host': 'weng.cloudant.com'
});
request.end();
request.on('response', function (response) {
response.on('data', function (data) {
util.print(data);
});
});
It gave me this data back:
{"error":"unauthorized","reason":"_reader access is required for this request"}
How do I do to list all my databases with Node.js?
The built-in Node.js http client is pretty low level, it doesn't support HTTP Basic auth out of the box. The second argument to http.createClient is just a hostname. It doesn't expect credentials in there.
You have two options:
1. Construct the HTTP Basic Authorization header yourself
var Base64 = require('Base64');
var couchdb = http.createClient(443, 'weng.cloudant.com', true);
var request = couchdb.request('GET', '/my_app/_all_docs', {
'Host': 'weng.cloudant.com',
'Authorization': 'Basic ' + Base64.encode('weng:password')
});
request.end();
request.on('response', function (response) {
response.on('data', function (data) {
util.print(data);
});
});
You will need a Base64 lib such as one for node written in C, or a pure-JS one (e.g. the one that CouchDB Futon uses).
2. Use a more high-level Node.js HTTP client
A more featureful HTTP client, like Restler, will make it much easier to do the request above, including credentials:
var restler = require('restler');
restler.get('https://weng.cloudant.com:443/my_app/_all_docs', {
username: 'weng',
password: 'password'
}).on('complete', function (data) {
util.print(data);
});
There are lots of CouchDB modules for Node.js.
node-couch - a CouchDB connector
node-couchdb - A full API implementation
node-couchdb-min - Light-weight client with low level of abstraction and connection pooling.
cradle - a high-level, caching, CouchDB client
Just wanted to add
nano - minimalistic couchdb driver for node.js
to the list. It is written by Nuno Job, CCO of nodejitsu, and actively maintained.
This answer is looking a bit dated. Here is an updated answer that I verified using the following Cloudant Supported NPM Node Client library that works.
https://www.npmjs.com/package/cloudant#getting-started
And to answer his question on how to list his databases use the following code.
//Specify your Cloudant Database Connection URL. For Bluemix format is: https://username:password#xxxxxxxxx-bluemix.cloudant.com
dbCredentials_url = "https://username:password#xxxxxxxxx-bluemix.cloudant.com"; // Set this to your own account
// Initialize the library with my account.
// Load the Cloudant library.
cloudant = require('cloudant')(dbCredentials_url);
// List the Cloudant databases
cloudant.db.list(function(err, allDbs) {
console.log('All my databases: %s', allDbs.join(', ')) });