Use JSON Web Token with Koa

JSON Web Token (JWT) is used to issue a secure authentication token once the user successfully logs in. In Koa we use the koa-jwt middleware to manage these tokens.

npm install koa-jwt --save

Import the package from your code.

var jwt = require('koa-jwt');

We can use the middleware to guard access to protected URLs. The following will try to decrypt the token sent with the request using the secret key 'pa$$word'. If that does not succeed the processing pipeline will be terminated and the subsequent middlewares will not run. We use the unless escape hatch so that this token validation is skipped for paths starting with "/public".

app.use(jwt({ secret: 'pa$$word' })
    .unless({ path: [/^\/public/] }));

Add the jwt middleware before any routes for it to have any meaningful effect.

A new token is issued using jwt.sign(). You can store identifying information like user ID, name etc. as a payload in the token.

api.get('/public/login', function *(){
    var user = {
      userId: "bibhas",
      name: "Bibhas B"
    }

    this.body = {
      token: jwt.sign(user, "pa$$word")
    }
});

A client is responsible for saving the token and sending it back with every request using the Authorization header. In the example below ABCXYZ is a token issued by the server:

curl -H "Authorization: Bearer ABCXYZ" localhost:8080/protected-stuff

The middleware saves the payload decrypted from the token as the state.user property of the context. So we can easily access that as follows:

api.get('/protected-stuff', function *(){
    var userId = this.state.user.userId //"bibhas"
    var fullName = this.state.user.name //"Bibhas B"
});

Use Angular 2 from an ExpressJS Application

Most Angular 2 starter projects use a development time web server. This will not work well if you are developing the application using Node and Express. An Angular 2 project works best when it is the document root of a web server. This requires a bit of careful planning.

In today’s post I will explore how to create a Express application that uses Angular 2. We will explore two separate approaches:

  • A single project hosting both Node and Angular 2 code.
  • Separate projects for Node and Angular 2 code.

We will use generators and official starter projects whenever possible. This will help you follow along this article and experiment quickly.

Continue reading

Module Loading in Angular 2

Typescript uses the ES6 import and export syntax to load modules. The syntax is quite easy to work with. But what happens at runtime is far from simple. Browsers do not fully support ES6 yet. Which means that these import and export statements need to be somehow transpiled into ES5. This is where things get complicated. In today’s post I will discuss how module loading works using three approaches:

  • Using SystemJS
  • Using Webpack
  • Using Webpack through Angular CLI

Continue reading

Working with NEHotspotHelper

I had to evaluate NEHotspotHelper for a project I am working on. The documentation from Apple is sordid to say the least. Here are a few bits and pieces of information that will help you understand the API better.

Apply for the Network Extension Entitlement

You may already know this but to use the NEHotspotHelper API you will need to apply for the Network Extension Entitlement from Apple. It may take several days for Apple to approve or reject your application.

Modify your Provisioning Profiles

Once you are granted the entitlement, go to iOS developer console and add the entitlement to your developer and deployment provisioning profiles. Many on the Internet will tell you to create a new set of provisioning profiles. That is not necessary. You can add entitlements to existing profiles. Download these modified profiles and re-install them on your development machine.

Add Background Mode

In our case we wanted to use the Wi-Fi Hotspot Authentication API of NEHotspotHelper. This requires the app to run in the background mode. Edit your Info.plist file and add the network-authentication background mode.

Use the Wi-Fi Hotspot Authentication API

The purpose of the authentication API is to implement custom application level logic to authenticate the connection to a WIFI hotspot. This authentication is a two step process:

  1. First connect to the hotspot providing the hotspot’s password.
  2. Then perform custom authentication. For example, this can involve communicating with a server and passing additional credentials.

This process uses a callback based approach. The first thing you do is register a closure or lambda that is invoked at various times with a command object.

let options: [String: NSObject] = [kNEHotspotHelperOptionDisplayName : "Join this WIFI" as NSObject]
let queue: DispatchQueue = DispatchQueue(label: "com.mobiarch", attributes: DispatchQueue.Attributes.concurrent)

NSLog("Started wifi scanning.")

NEHotspotHelper.register(options: options, queue: queue) { (cmd: NEHotspotHelperCommand) in
  NSLog("Received command: \(cmd.commandType.rawValue)")
}

There are three command types that you need to be aware of to perform custom authentication.

  • NEHotspotHelperCommandType.filterScanList – iOS will call your closure with this command type when the user opens the WIFI Settings page. You can obtain a list of all available hotspots from the command. Your code needs to create a filtered list of hotspots that you will like to authenticate with. You also need to set the WIFI password for these hotspots at this point. Once the closure returns, iOS will show the display name below the filtered hotspots. The display name is set using the kNEHotspotHelperOptionDisplayName option as shown in the code above. Note: Filtering does not really remove other hotspots from the list in the WIFI settings page. It is simply meant to identify the networks that your app deems appropriate for authentication.
  • NEHotspotHelperCommandType.evaluate – If the user taps on one of your filtered hotspots and makes a connection the closure is called again with an evaluate command. You can perform custom business logic to evaluate the connected hotspot. If it is appropriate, your code should set a high confidence level for the network.
  • NEHotspotHelperCommandType.authenticate – After the evaluation phase the closure is called again with an authenticate command. Your code can now perform custom authentication logic and respond with a success or failure status. If successful the connection is finally established.

Remember, your callback closure will only be called if the user opens the WIFI Settings page. Also, the user must manually initiate a connection to a hotspot. Your code can not automatically connect.

A sample code for the lambda can look like this.

{ (cmd: NEHotspotHelperCommand) in
    NSLog("Received command: \(cmd.commandType.rawValue)")
    
    if cmd.commandType == NEHotspotHelperCommandType.filterScanList {
        //Get all available hotspots
        var list: [NEHotspotNetwork] = cmd.networkList! 
        //Figure out the hotspot you wish to connect to
        let desiredNetwork : NEHotspotNetwork? = getBestScanResult(list) 

        if let network = desiredNetwork {
            network.setPassword("password") //Set the WIFI password

            let response = cmd.createResponse(NEHotspotHelperResult.success)

            response.setNetworkList([network])
            response.deliver() //Respond back with the filtered list
        }
    } else if cmd.commandType == NEHotspotHelperCommandType.evaluate {
        if let network = cmd.network {
            //Set high confidence for the network
            network.setConfidence(NEHotspotHelperConfidence.high) 

            let response = cmd.createResponse(NEHotspotHelperResult.success)
            response.setNetwork(network)
            response.deliver() //Respond back
        }
    } else if cmd.commandType == NEHotspotHelperCommandType.authenticate {
        //Perform custom authentication and respond back with success
        // if all is OK
        let response = cmd.createResponse(NEHotspotHelperResult.success)
        response.deliver() //Respond back
    }
}

For additional details about the different command types, see the official document.

Running Instrumented Test in Android

An instrumented test is a fancy name for a test that runs within the Android device in the same process space as your app. This lets you test code that relies on Android SDK calls. The official guide is horridly incomplete. Here are a few quick notes.

Package Conflict

Android Studio builds a separate APK just for instrumented test. This runs in the same process space as the APK for the main app. Unfortunately this means both APKs must have no conflicting package dependencies. But the Internet is full of example of conflict with the com.android.support:support-annotations package. You will need to force both APK to use a higher version.

androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'

//Force same version
androidTestCompile 'com.android.support:support-annotations:23.2.0'
compile 'com.android.support:support-annotations:23.2.0'

This is just an example only. By the time you read this newer versions may be available.

Location of the Test Java File

You have to create the test Java file in the androidTest folder. This way it will get packaged with the test APK.

Annotation

An instrumented test class needs to have @RunWith and @SmallTest annotation.

A sample template class:

import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class InstrumentedTests {
 @Test
 public void testCaching() {
   assertNotNull("Hello");
   assertTrue(true);
   assertEquals("One", "One");
 }
}

Simplify Sqlite Access from Swift

Using the SQLite C API has always been a pain. Now with Swift it’s practically unworkable. I think most people are using some kind of a wrapper library like FMDB. I took a few hours to evaluate various libraries available:

Out of these I liked GRDB the most. Here’s a quick tutorial on how to do the most common tasks in GRDB. We will assume a schema like this.

create table if not exists Employee (
    id INTEGER NOT NULL PRIMARY KEY,
    name TEXT NOT NULL,
    salary real not null,
    last_update datetime NOT NULL
);

Using GRDB

I use Cocoapod to add GRDB to my project. And then from any Swift file where you need to use GRDB add:

import GRDB

Opening a Connection

A connection is represented by a DatabasePool object. Here we connect to a file database.dat within the app’s Documents directory.

let paths = NSSearchPathForDirectoriesInDomains(
    .DocumentDirectory, .UserDomainMask, true);
let docsDir = paths[0];
let dbFile = docsDir + "/database.dat";

let db = try! DatabasePool(path: dbFile)

A connection is closed when the DatabasePool object gets destroyed.

Inserting a Row

This will add a new row to the Employee table.

try! db.execute(
  "INSERT INTO Employee (name, salary, last_update) VALUES (?, ?, ?)", 
  arguments: ["Daffy Duck", 24000.00, NSDate()])

Note how the Swift data types in arguments: match the SQLite data types.

Query

To query by primary key or any other clause that is expected to return a single row do this.

if let row = Row.fetchOne(db, 
  "select * from Employee where id=?", 
  arguments: [1]) {
    let name : String = row.value(named: "name")
    let lastUpdate : NSDate = row.value(named: "last_update")
    let salary : Double = row.value(named: "salary")

    print("Found employee: \(name) \(lastUpdate) \(salary)")
} else {
    print("Could not find employee with that ID.")
}

The Row.fetchOne() method returns an optional Row object. Using the options makes it super easy to tell if the query returned anything or not.

The Row class has different value(named:) methods that return different data types. Here the compiler has automatically picked the correct value(named:) based on the data type of the variable on the left hand side. Type inference has made things safer and easier.

When a query returns multiple rows, do this:

let rows = Row.fetchAll(db,
    "select * from Employee where salary > ?",
    arguments: [25000.00])

for row in rows {
    let name : String = row.value(named: "name")
    let lastUpdate : NSDate = row.value(named: "last_update")
    let salary : Double = row.value(named: "salary")

    print("Found employee: \(name) \(lastUpdate) \(salary)")
}

Updating a Row

Updates are done using the same db.execute() method that we have used to insert rows.

try! db.execute("update Employee set salary=? where id=?", 
  arguments: [40000.00, 4])

Deleting Rows

Deleting a single row using primary key:

try! db.execute(
  "delete from Employee where id = ?", arguments: [1])

Bulk delete is done the same way:

try! db.execute(
  "delete from Employee where salary > ?", 
  arguments: [25000.00])

Dependency Management Using Cocoapods

Cocoapods is a Swift and Objective-C dependency management tool like NPM is for Node and Gem is for Ruby. Swift now has its own official package manager. But it’s still very new. Until it matures fully you can keep using Cocoapods.

Installing Cocoapods

Use Gem to install Cocoapods

sudo gem install cocoapods

A few things may go wrong.

You may see this error:

ERROR:  While executing gem ... (Errno::EPERM) Operation not permitted

If you see that try installing Cocoapod like this:

sudo gem install -n /usr/local/bin cocoapods

You might see a Insecure world writable dir warning. This can be safely ignored.

enter image description here

Declaring Dependencies

Create an Xcode project if you don’t already have one. Here, we will assume that the name of your project is MyApp. In the root folder of the project create a file called Podfile.

platform :ios, '9.0'
use_frameworks!

target 'MyApp' do
    pod 'AFNetworking', '~> 2.0'
    pod 'FLKAutoLayout'
end

This states that our project requires AFNetworking version 2.0 or higher. It also depends on the latest version of FLKAutoLayout.

Installing Packages

When you install a package Cocoapod downloads the source files of the package and any other packages that it depends on. Cocoapod creates a new project called Pods and adds these source files there. It then creates a new workspace and adds your project and the Pods project to the workspace.

Since Cocoapod modifies your Xcode workspace, it is better that you shutdown Xcode while you are installing a package.

Make sure that your Podfile is properly defined. From the root folder of your project run:

pod install

enter image description here

There are a few things you have to do for your project to compile correctly:

  1. Shutdown Xcode if it is running.
  2. Double click the workspace file to open it and not the project file. In our case that will be the MyApp.xcworkspace file.

enter image description here

Now you will see the Pods project added to the workspace. Source code for the downloaded packages will be there.

enter image description here

Cocoapod will also modify your project to link in the code from all packages in the Pods project.

You are now ready to use classes from these packages.

Removing Packages

To remove a package simply delete it from Podfile. Then from the root of the project run:

pod update

Using Pod Packages in Unit Tests

So far in this article we have added packages only to the application’s main target. If you try to use these packages from unit tests you will get a compilation error. The solution is to also add the packages to the unit test targets. Find out the name of the unit test target and specify the packages used from there.

platform :ios, '9.0'
use_frameworks!

target 'MyApp' do
    pod 'AFNetworking', '~> 2.0'
    pod 'FLKAutoLayout'
end

#Add any package you need to the unit test target
target 'MyAppTests' do
    pod 'AFNetworking', '~> 2.0'
    pod 'FLKAutoLayout'
end

Run pod update to set things up.