Enabling a node.js SSL webserver using Let’s Encrypt .pem certificates

In this article I will show a simple example of getting a node.js SSL website up and running using the .pem certificates issued from Let’s Encrypt.

Introduction

 

Once you have gone through the process of getting your Let’s Encrypt certificates you will have 4 certificates

w1

You will need to download the root certificate and an intermediate certificate from Let’s Encrypt – https://letsencrypt.org/certificates/

w2

Once you have the root.pem the actual node code to get this running is relatively simple.

 

// Startup Express App
var express = require('express');

var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();

var options = {
  key: fs.readFileSync('copperCerts/privkey1.pem'),
  cert: fs.readFileSync('copperCerts/cert1.pem'),
  ca: [
    fs.readFileSync('copperCerts/root.pem', 'utf8'),
    fs.readFileSync('copperCerts/chain.pem', 'utf8')
  ]
};

http.createServer(app).listen(8080);
https.createServer(options, app).listen(3000);

 

Advertisements

IBM is a platinum sponsor of the new node.js foundation

Take a look at the video from Angel Diaz IBM VP Cloud it is only 90 seconds – IBM’s now big behind Node.js

Angel also wrote this article on node explaining is some more detail about the foundation and IBM’s involvement

http://www.thoughtsoncloud.com/2015/06/node-js-embarks-on-open-governance-journey/

IBM are a platinum sponsor of the new node.js foundation.

Here’s a quote from the linux foundation press release

http://www.linuxfoundation.org/news-media/announcements/2015/06/nodejs-foundation-advances-community-collaboration-announces-new?utm_source=nodeweekly&utm_medium=email

IBM

“An independent Node.js Foundation built on open governance is a major industry wide event as it ensures the continued adoption and growth of one of the world’s most ubiquitous programming languages. The Node.js foundation will provide developers with a top development platform that when combined with the power of IBM Cloud and Mobile will accelerate time to application concept, deployment, and refinement.  As a platinum member of the foundation, IBM looks forward to continued partnership in developing and promoting Node.js and the inevitable expansion of this vibrant community,” said Angel Diaz, Vice President, Cloud Architecture & Technology, IBM. 

XPages and Bluemix: Sending a targeted Websockets message to specific XPages

In this article I will demonstrate how the use of socket.io “rooms” enables us to send message to users who are only accessing specific pages within our application, rather than blanket messages to all users.

Introduction

In the previous article I demonstrated how to use a message POST to the node.js server which could then be turned into a chat message and sent out to all users. While this is a nice example it only serves as such and does not have significant business value. In this article I will begin the peel back the potential for much greater application flexibility through the controlled use of targeted Websockets messages to users of an application.

Most applications have more than one “page” within it and we may wish to send a message to users of one page rather than all pages. Conversely we may want to only send messages to users who are viewing certain types of information wherever they are within the application.

In this article we are still going to use the chat example but this will be the last time we use “chat” as the use case. In future articles I will look into more practical applications of Websockets messaging within an application.

Using rooms within socket.io

Looking at the socket.io documentation for rooms and namespaces you can see that the API exposes the ability to create individual communication channels between the server and the application users.

How this translates to our application on the node.js server looks like this:

  socket.on('joinRoom', function(room, name){
    socket.join(room);
    io.sockets.in(room).emit('notice', name+" has joined");
    console.log(name+" has joined room "+room)
  })

When the “joinRoom” event is registered on the server then the socket is joined to the room name which is passed in. A message is the broadcast specifically out to all the existing room members that the new user has joined. Note that this message is room specific because of the io.sockets.in(room) rather than a blanket message to all users.

With this code in place on any page we can register our application page (chat room in this case) with the socket server. In my case I created a generic function to take the name of the “room” from the XPage URL. The following client side JavaScript sends the “joinRoom” request to the server.

  nickname=$('.username').text()
  // Send message to server that user has joined WinX.nsf/xRoom1.xsp?open&login
  var xpageName = location.href.split('.nsf/')[1] //xRoom1.xsp?open&login
  xpageName = xpageName.split('.xsp')[0] //xRoom1
  socket.emit('joinRoom', xpageName, nickname);

On the server we can then see the console.log as someone joins the room:

s1
We can then have multiple users in individual “rooms” which are in this case 3 separate xPages xRoom1.xsp, xRoom2.xsp, xRoom3.xsp From the original chat room I am able to sen all three rooms a blanket message because they are all “listening” for “msg” as in the previous articles

 socket.on('msg', function(data) {
    console.log('msg here')
    console.log(data)
    redisClient.lpush('messages', JSON.stringify(data));
    redisClient.ltrim('messages', 0, 99);
    socket.broadcast.emit('msg', data);        //broadcast to all users indiscriminately
  });

s2

Sending a message to a specific room

Modifying the original POST code which was shown in the previous article I was then able to create an XPage which will send a targetted message to a specific room. To do this, all I had to do was pass in an additional POST parameter of the room I wanted to send a message to.

I create a new Master XPage which had 3 fields on it – one for each room. Each of the individual fields had a “room” attribute which allows me to pick up a value to specify which room to send it to.

<div id="msgRoom1" class="msgCenter">
	<input placeholder="Send a message to Room1" room="xRoom1" autocomplete="off" autofocus="autofocus" />
	<button type="button">Send</button>
</div>
<br/><br/>
<div id="msgRoom2" class="msgCenter">
	<input placeholder="Send a message to Room2"  room="xRoom2" autocomplete="off"  />
	<button type="button">Send</button>
</div>
<br/><br/>
<div id="msgRoom3" class="msgCenter">
	<input placeholder="Send a message to Room3"  room="xRoom3" autocomplete="off" />
	<button type="button">Send</button>
</div>

s3

In the following code we bind to each of the buttons so that when the are clicked they:

  • set msgField to be the jQuery object representing the pertinent field
  • create the data object to send to the socket server
  • create the newMessage passing in data

The new message function then:

  • POSTs the data object at the “/roomPost” path on the server
  var socketServerURL = (location.href.indexOf('copper.xomino.com')>0) ? "http://copper.xomino.com:3000" : 'http://xominosocket.mybluemix.net'
  var socket = io.connect(socketServerURL)

$('.msgCenter Button').on('click', function(){
  	var msgField = $(this).prev('INPUT')
	var data = { text: msgField.val(), nickname: nickname, when: new Date(), room: msgField.attr("room") };
	sendMessageToRoom(data)
	newMessage(data);
	// Clear the message field
	msgField.val('');
})

var sendMessageToRoom = function(data){
	console.log(data)
	$.ajax({ url:
	        socketServerURL+"/roomPost",
		type: "POST",
		data: data
	}).done(function( msg ) {
		console.log( msg);
	});
}

We can see the message come through on the server

s4

You can also see from the log that I was able to join 3 rooms from the Message Center page – this is as simple as creating three requests to join:

  //client side JavaScript
  socket.emit('joinRoom', 'xRoom1', nickname);
  socket.emit('joinRoom', 'xRoom2', nickname);
  socket.emit('joinRoom', 'xRoom3', nickname);

Site in action
The best way to see all this is to see it in action – as you can see from the video below.

Moving the application to Bluemix

Working locally I used to following code to determine if I was on copper.xomino.com or another server (demo.xomino.com or different again)

  var socketServerURL = (location.href.indexOf('copper.xomino.com')>0) ? "http://copper.xomino.com:3000" : 'http://xominosocket.mybluemix.net'
  var socket = io.connect(socketServerURL)

I had to make a slight change to my cors code in the local node server setup. I looked at the cors npm site to see how to dynamically add cors support and found the answer and modified my code accordingly. So you need to make sure you

//Marky adding CORS from copper
//app.use(cors()); //not used for whitelists

var whitelist = ['http://copper.xomino.com', 'http://demo.xomino.com', 'http://marky.psclistens.com'];
var corsOptions = {
  origin: function(origin, callback){
    var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
    callback(null, originIsWhitelisted);
  }
};

marky.psclistens.com is the same local server as copper.xomino.com (I use a hosts file to make them both look at localhost). But this allows me to play with cors and in this case talk to the local or bluemix node server without needing another “Domino” server.

s6

Because the site running locally is already connected to the Jazz Hub Git repository, as with the previous examples all I have to do is commit the changes locally, push to the Jazz Hub repository, the application will then be re-built and re-deployed to Bluemix.

It’s really about as simple as that. Because the code is already primed to check to see if we are looking locally or at Bluemix, a new URL for the application now looks at Bluemix.

s5

 

So why do we need Bluemix again?

While the development was performed locally, the intention is to be able to create a capability which does not require the user to have a locally running node.js server. That is where Bluemix comes in. In essence what we are creating is a cloud hosted Websockets service which can be integrated into existing applications.

 

Conclusion

In this article we have seen that with a little creativity we are able to register different chat rooms within the same application. There are other ways to do this of course but the point of this example was to demonstrate the ability to send a specific message to specific users looking at an individual XPage.

In the next article we will take a look at the practical implications of this within an XPages application.

 

Integrating the Bluemix Watson Translation service into an XPages application

In this article I will demonstrate how to integrate the Bluemix Watson Translation service into a functioning XPages application.

Bluemix Watson Translation Service

Following on from one from my previous posts on the subject I have been looking for a good workable example of using a Bluemix service within an XPages application. As I said before this is as much an exercise in me learning more about node.js and Bluemix as anything else – but I also love being able to share.

Based on the previous post about how to get the Watson Q and A service up and running it took me 12 minutes to get a working example of the Watson Translation service up and running on a Bluemix site. Just for disclaimers I have no idea how good the Watson service is and I am not advocating it – this is purely an exercise in being able to use a Bluemix service, more so that what it does.

So I followed the steps in my previous blog but applied them to the example post on the Watson Translation service. This was pretty simple and once again the only thing to change was the manifest.yml file to name the service and application correctly.

w2

http://xominowatsontranslate.mybluemix.net/

When you type into the TEXTAREA box (1) and then hit “Translate”(2) the result is displayed in the Output (3)

The page does a full refresh and the answer is displayed. The node.js code running behind the application is fairly self explanatory :

  • (looking at the code snippet below) we can see the values POST’d from the application are received on the node.js server in the app.POST
  • The posted field values are turned into a separate request to the Watson translation service
  • The Watson request (watson_req) is sent as a serversiude request to the Watson service
  • The results from that are sent back to the response object “watson_res”
  • The node.js response (res) back to the user is then set back to the browser using the jade template (index)
    • return res.render(‘index’,request_data);

// Handle the form POST containing the text and sid, reply with the language
app.post('/', function(req, res){

    var request_data = {
        'txt': req.body.text,
        'sid': req.body.sid,
        'rt':'text' // return type e.g. json, text or xml
    };

    var parts = url.parse(service_url);
    // create the request options to POST our question to Watson
    var options = { host: parts.hostname,
        port: parts.port,
        path: parts.pathname,
        method: 'POST',
        headers: {
            'Content-Type'  :'application/x-www-form-urlencoded', // only content type supported
            'X-synctimeout' : '30',
            'Authorization' :  auth }
    };

    // Create a request to POST to Watson
    var watson_req = https.request(options, function(result) {
        result.setEncoding('utf-8');
        var responseString = '';

        result.on("data", function(chunk) {
            responseString += chunk;
        });

        result.on('end', function() { //this is triggered when the response from Watson is completed
            // add the response to the request so we can show the text and the response in the template
            request_data.translation = responseString;
            console.log('request',request_data);
            return res.render('index',request_data); //<------response sent back to the web page
        })

    });

    watson_req.on('error', function(e) {
        return res.render('index', {'error': e.message})
    });

    // create the request to Watson
    watson_req.write(querystring.stringify(request_data));
    watson_req.end();

});

 

You can see that in action through firebug – here is the POST parameters

w3and here is the response – the new HTML containing the answer

w4

 

Modifying the service

Here is the thought process which occurred to me:

  • Well that is cool but if I want to integrate this into an XPage then I will need to return the result as JSON and not a whole HTML page
  • But I do not want to break the example so how can I do that ?
  • I can use a new route – so if I POST at a different URL, the node.js server can be made to be smart enough to do something different
  • Ah…….and then I will have CORS issues because my application will be running at xomino.com and the bluemix app is not

Replicating the POST as code

So the first thing I did was try and replicate the code in jQuery (as I know best) so that I could mimic a POST event in ajax without using a form. In the following example you can see I added jQuery to my page (jQuerify plugin for firebug). I then simulated an AJAX POST to the translation service (emulating the form post).

w5

 

The response is the HTML of the new page, so I know this is at least the right AJAX code.

w6

 

But when I am on the copper.xomino.com site and I try and repeat the same thing, as expected CORS issues.

w7

Ryan Baxter (who frankly has been a huge support and help in learning all this) said to me

“You are in luck, CORS is dead simple with Node  – https://www.npmjs.org/package/cors” and how right he was.

Adding the CORS package to my Bluemix application

The way you add a package to your Bluemix application is by updating the package.json file. This file contains all the npm modules that will be needed and what is even cooler is that these will be npm installed within your node server automagically on deployment

w8

So then I need to add the cors enabled page to my application. But I did not want to change the core example on the site. So what I did was create a new “route” within the node.js application and told it to do something different….

Originally we had this within the example


// Handle the form POST containing the text and sid, reply with the language
//the route in this case is "/" - so basically the root of the application
app.post('/', function(req, res){
	//stuff
}

and to create a new route we just add a different app.post


// Handle the form POST containing the text and sid, reply with the language
var cors = require('cors'); //add the cors module code to the application
app.use(cors());
var corsOptions = {
    origin: 'http://copper.xomino.com' //allow copper to be a site which can work with the watson site
};

//note the new cors(corsOptions) parameter in the app.post function
app.post('/xpages', cors(corsOptions), function(req, res){ //when a user posts to  site.com/xpages do this code instead of the default '/'
	//stuff
}

What I then changed was the response code – this was the original code responding with text and rendering using the jade index.jade template

	//......
        result.on('end', function() {
            // add the response to the request so we can show the text and the response in the template
            request_data.translation = responseString;
            console.log('request',request_data);
            return res.render('index',request_data); //render the response using the index,jade template and passing the request_data
        })

Instead of res.render I used res.json to send the request_data object back to the browser directly.

	//......
        result.on('end', function() {
            // add the response to the request so we can show the text and the response in the template
            request_data.translation = responseString;
            console.log('request',request_data);
            return res.json(request_data);
        })

So in this way I left the default page alone (“/” server root) – the example still works – but I added a new route (“/xpages”) so that my XPage application could POST at it.

I committed the code and pushed back up to Jazz Hub, restarting the service as we went…….and low and behold success…..

w9

As you can see from the above image, I am at the copper.xomino.com website. Using the slightly modified code to now post at

I get a response from the Bluemix website with the JSON from the Translation service. You can see from the headers the CORS header is added for copper.xomino.com

w10

Note – if you go to http://xominowatsontranslate.mybluemix.net/xpages you will GET an error. This is because my node application does not have an app.get for the /xpages route

So then XPages….

Integrating the Watson Transation service into an XPage application

Once I have the working ajax code it is very simple to add it to an XPage and just pick up the field values on the fly….. I cheated to some extent and copied and pasted the HTML from the original example into my XPage….hey why not this is an example after all…

I added a couple of classes to the example so that I could easily pick out the field values…

a1

And then the jQuery code to add to the application. In this code I

  • Select the .translate class (the translate button)
  • In the click event I get the data from the form
    • the .sid select box for the language translation
    • The text value from the textbox (.theOriginal) field
  • I then submit to the the translation service as before
  • In the .done() of the AJAX request, the incoming msg.translation is then added to the .theTranslation field

a2


 The demo

As you can see from the video – I am able to:

  • type in any value
  • send it to the bluemix service
  • receive the answer and display it on the screen
  • save the original and translated values as notes documents within my XPages application
  • Firebug shows the fact that the POSTS are going to http://xominowatsontranslate.mybluemix.net/xpages

Conclusion

I think this is a great example of using a “service” on another website to be able to enhance the functionality in your own XPages application. If IBM are successful in their investigation to put Domino inside of Bluemix, this capability will all happen behind the scenes and could be easily written as one true application……bring it on… 🙂

 

PS

This exercise was particularly gratifying because it feels like a culmination of all the work I have done in XPages over the last 3 years.

  • Without the jQuery and Firebug work I did at the start of XPages development, prototyping this would have been much more tedious.
  • Learning XPages has forced me to have a better understanding of AJAX and jQuery
  • If it were not for Angular and the “Write once run anywhere” I did for MWLUG, I would not have learned about CORS.
  • If it was not for the Angular work I would not understand “routes” within an application
  • …..and now I am learning about node.js and Bluemix PaaS

Keep learning !

 

 

Create your own Watson Q and A example with Bluemix, Webstorm and Jazz Hub

Introduction

In this article I will demonstrate how to get up and running with one of the Bluemix/Watson service examples. I will be using the example provided by IBM in their documentation as the basis for the article but the way in which I achieved the final goal was quite different from the way that they explained it in the example.

This example will use:

I could have added BS words as an attention seeking headline, and it would fit because there is so much I want to show in this one post (it is probably should be 5 separate posts). But I figured that it’s probably better to have a more description title about what this is really about (more googlable that way). So be warned this is a longer post than normal because of all the pictures. Going through this experience helped me better understand Git, Webstorm (and how it uses Git), Jazz Hub and Bluemix.

Creating an example of using the Bluemix Watson service.

Earlier this week IBM announced that they added the Watson API as a service to Bluemix. I honestly have no idea what I would ever use this for in my line of business but the coolness factor is huge!

In this post I am going to demonstrate how I was able to create the example service without using the same process as laid out in the IBM documented example. As this is a long post (lots of pictures) I will be discussing the separate parts in other posts.

There are also other ways of creating your App from scratch (for example Create an App, select node.js as a runtime and then bind the Watson service.) The reason I did the example this way was to highlight that you do not always have to start with a new service. I needed a node.js runtime, and it happened that one of my services already provided that (the DataCache starter service). That’s kinda cool and kinda the point of Bluemix!

1) Log into Bluemix

https://ace.ng.bluemix.net

Your should be presented with your dashboard.

2) Create an App 

 

 

a1

 

Select the Node.js runtime
w1

 

Name the App (in my case the App is called xominoWatsonQandA and the Host is xominoWatsonQ)

w2

3) Add a service – Watson Question and Answer 

w3

w3

4) Assign meta-data to the new service

  • Give the service a name – you will need this later so don’t over complicate this (qa-service)
  • The Watson service is currently in Bluemix as a Beta at time of writing

w4


5) Confirm you have an application

Now we have the pieces necessary to build the application on.

  1. A Node server
  2. The Watson service.

w5

6) Make sure you have a Jazz Hub account

If you do not already have a Jazz Hub account then go and create one here https://hub.jazz.net/

NOTE: The Jazz Hub site uses your IBM login userid and your Jazz Hub password – do yourself a HUGE favor and make the password the same as your IBM account and if you ever change the password on your IBM account you have been warned 🙂

Here is a shot of my Jazz Hub account before we start – note no “xominoWatsonQandA”

w1

7) Add your new application to Jazz Hub

Select the “Add GIT” option on the top right of your App dashboard

w6

8) Confirm existing service code?

The next prompt asks me if I want to create starter code in the new Git Source Control repository. In this case I do not – un-check it.

w9

9) Go to your new source control Git repository

Click on the Jazz Hub URL displayed on the right hand side.

The Add Git link will be replaced with a link to the repository. Click on the link to go to there. We will look at Edit Code in another post.

 

w7

 

10) Get the URL of the repository

In the picture below you can see over on the right there is a link for the Git URL – click on that and copy the URL.

w11

11) Open Webstorm IDE

As I was working my way through this example I wanted to learn more about how Webstorm functions as a Git client. You can use Source Tree or the Git command line if you prefer.

You need to ensure that Git is enabled in Webstorm before you proceed. it is not configured out of the box. The instructions for enabling git are found here https://www.jetbrains.com/webstorm/webhelp/using-git-integration.html. You will need to have Git installed before hand. Follow the ssh key instructions and it will show you how.

12) Checkout the new repository

Select Checkout from Version Control > Git form the Webstorm VCS menu option

w12

 

Paste the URL from the Jazz Hub site into the Vcs Repository URL

w13

Select Clone and a new project is created within Webstorm and as you can see, the files downloaded are those from the repository on Jazz Hub

w14

12) Download the example code and add to the local repository

Following the example site, download the sample file qa-nodejs-sample.zip. Unzip it locally and drag the files into the repository directory created by Webstorm in the previous step.

w15

Clicking back into Webstorm you will see the files refresh in the project – they all appear “red” because although the files are in the repository directory they are not current added to the Git configuration, it does not know they exist.

w16

13) Add the files to the local Git repository

Right click on the project and add the directory as follows.

w17

The files will all turn green

14) Edit the manifest.yml file

Within Bluemix the manifest,yml file is the key to holding everything together. It contains the “services” and the application they are used in. In my case the service name for Watson was qa-service and the application is xominoWatsonQandA.

Save the Manifest file

w8

You can also see from the manifest file command “node app.js“. If you look into the other files currently in the example you will find app.js. This tells Bluemix how to start the application.

15) Commit the files to the local repository

Right click on the project name – select Git > Commit Directory

In this case I chose to Commit and Push back to the repository

 

w20

w21

Webstorm then does a stupidity check on your files (we all need that)

w22

And then Webstorm tells you that you are stupid!!

w23

On dear……….well actually if you look into this, Webstorm is reporting issues in the example app css files and missing semi-colons in the JavaScript. Without going into correcting all of them, the application works despite these errors. So we Commit and continue.

w24

My commit comments are “Modified manifest and all files”

Pushing…

w25

We get confirmation that the files were committed and pushed up to the Jazz Hub repository

16) Confirm Jazz Hub

You can now see by refreshing your Jazz Hub page that all the files are now in the server repository. You can also see next to my picture in the middle “Manifest change and all files” as the last commit comment.

w26

Then comes the really cool and completely not Command Line experience. In the top right of the page you can see Build and Deploy….

17) Build and Deploy

w27

18) Confirm

You will be taken to a page where you can see the results of the build and deploy. Jazz Hub is very smart and self aware. If you have un-committed changes within your repository it will not let you Deploy. That is for another day though.

w28

 

Note: what’s interesting is that the Deploy to URL which I cannot change is xominoWatsonQandA.mybluemix.net not what I would expect as xominoWatsonQ.mybluemix.net which is the route I gave the application in the first place. Turns out I not have two routes to the same App. I can see this back on my bluemix dashboard as there is now a (+1) next to my routes options!

So note to self, name your route the same as the application name!

w10

19) You now own Watson

Click on the route link back on your Bluemix dashboard and you now have a running example of the Watson Heathcare service

w9

In review

In this example we saw a LOT of cool new features, concepts and ideas for Domino developers and you know that we have barely scratched the Bluemix, Webstorm, Jazz Hub surface. I learned a significant amount of new and cool things from going through this process. The first time from scratch it took about 90 minutes to figure out what I was doing. The second time I went through it, even taking all the screenshots for the blog it took 25 minutes.

We only changed two lines in one file to make this work – anyone can do this !!

Like I said at the top of the article, I have no idea how I would use Watson in the day job but that was not the purpose for doing this example. These “services” are componentized capabilities which we can take advantage of. Imagine the growth possibilities as more and more services are added to Bluemix. This has got to be fun to watch and follow along. Remember IBM are investigating putting Domino into Bluemix.

The Watson Cloud REST API information is available here http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/apis/#!/Question_Answer

This is so cool 🙂