Diving in

If you have been following so far, the remaining parts should be a piece of cake. We will dive right into creating the app from scratch.

Code Structure

We’ll use npm for managing our code dependencies.

appbase-socket-interface/

|

|_ _js/

| |_ _acl.js

| |_ _client.js

| |_ _sockbase.js

|

|_ _view/

| |_ _index.html

|

|_ _config.js

|_ _index.js

|_ _package.json

|_ _bower.json

|

|_ _node_modules/

|

|_ _bower_components/

|

|

|_ _data_init.js /* this is not part of original code,

we’ll use it to initialize some

empty table in the database */

Start with initializing the files

mkdir js

mkdir view

touch js/acl.js

touch js/client.js

touch js/sockbase.js

touch view/index.html

touch config.js

touch index.js

touch data_init.js

Run the following commands to download necessary dependencies

npm install --save express@4.10.2

npm install --save socket.io

npm install --save appbase-js

npm install --save socketio-wildcard

npm install --save nsp

bower install --save bootstrap

Now add the following code in your config.js file. This will contain our appbase.io app credentials.

UI and Client Javascript

Let’s start with our client side UI first. Paste the following code segment in index.html file, which structures the entirety of the UI — from the role selection option to user post, moderation and publishing dashboards.

Line 9–36 contains the page style.

Line 42–135 contains some div’s for our UI dashboards and form input.

Line 48–64 contains a drop down to allow user select a role from [guest, user, admin]. In a real system we won’t need it. We’ll do that from the back-end in a real system.

Line 68–89 contains another div for input form where user will write new post.

Line 90–111 we’ve a div for moderation dashboard.

Line 112–131, we’ve a div for published post dashboard.

Now let’s see the corresponding client side JavaScript functions. The following code segment contains all client side JavaScript functions and we’ll put them on client.js file.

Most of the JavaScript functions in client side are listeners for socket events. They are pretty self explanatory and the added comment will also help to understand how they are working.

Serverside ACL middleware

If you have followed till here, we are done with 50% of the app and have laid the groundwork for the server side security middleware.

We will start with the acl.js file

addPermission: This method add user roles to a permissions array. This array will contain information about which user can access which resource.

array. This array will contain information about which user can access which resource. isAllowed: This method checks if a given user has access to a given resource by iterating over the permissions array.

This ACL security model allows us to add new roles, models and permissions on the fly. An example code snippet for adding new access permissions would look like below:

aclRef.addPermission('user', 'pendingpost', 'read')

aclRef.addPermission('a_new_role', 'pendingpost', 'write')

Next, we’ll write server side socket listeners which will interact with the database models (i.e. pendingpost and approvedpost tables defined above) when Acl.isAllowed() method returns true. Paste the following code in sockbase.js file.

Constructor: In the constructor, we supply a reference to our ACL class and appbaseRef.

Next we’ve multiple event listeners. Here we’ll talk about one of them. Lets discuss about the ‘onBlogPost’ event listener. This event means someone trying to make a new blog post. Whenever a new blog post is created, we store it in a ‘pendingpost’ table. So we first check whether this user has a “write” permission to the ‘pendingpost’ table(line 145). If the user has a write permission, we send the blog post to our database using the appbaseRef.index method. Otherwise we emit a ‘failure’ event using socket.emit method. On successful operation of the index method, we get the generated id for our new post and emit it back to client side so the client can update its UI accordingly.

onApprovePost: As usual we check ACL and if successful we move the pending post to the approved post table.

onDisapprovePost: This is just opposite of onApprovePost. We check the ACL and move the post to pending post table.

onSubscribeApproved: A user can subscribe to the approved post. So any time a new post is created, he gets notification. We use appbase.searchStream method for streaming live update in the approved post.

onSubscribePending: An admin can subscribe to get notification of new posts created by other user. So he’ll use the appbase.searchStream function to get live update in the ‘pendingpost’ table.

onDeletePost: This is opposite of onBlogPost function. We check for ACL to validate that the requester has delete permission and on success remove the post with the given id. We use appbaseRef.delete to do that.

So far we’re done with our acl, socket listener and database communication. Now we’ll add the pieces together. Lets paste this code in our index.js table.

Line 1–9 we are initializing our application

Line 11, we are initializing socketio-wildcard to intercept all incoming event.

Line 21–30 we declared the permissions. In a real system, this will be in a database.

Line 35–44 we create a mapping between socket events and its callback function for easy access.

Line 57–60 we initialize the wildcard middleware and pass it to io for intercepting all incoming events.

Line 72–74, on an incoming event we call the appropriate callback.

So we are done and ready to test our app. Before running the actual application, copy the following code in data_init.js file.

Now run it using the command “node data_init.js”. You’ve to do it only once. Please follow the last section of this writing for an explanation of why I’m doing it. This will create two table in the database and prompt you to start the original app. Run the original app with the command “node index.js” and browse to http://localhost:3000. Following video might help to get started.

appbase.io + socket.io demo

P.S: The reason we are creating two empty table is because the subscription method use the appbase.searchStream to get live update to the table. So if there is no table at the beginning and the application tries to subscribe to get live update, it’ll fail throwing an error message. So before the first run, we are making sure that we have some tables ready in the database even though none of them contain any data.