Category Archives: Node.js

SSL on Localhost with Express

11 Nov 2019

There are times when you will need to have your local app reach out to a service via SSL, such as, say a Postgres Database out on AWS. If your local app is not configured to run SSL it simply wont work as SSL is likely enforced at the endpoint you’re trying to hit.

The following is the process I followed to get SSL running for my local app on OSX. This is a summary of multiple things that I found while researching / trying to resolve the issue. In the end my particular solution is comprised of bits of information from various sources.

There are many SSL tutorials all running through a range of console commands. I landed on an NPM package called “devcert-cli” which greatly reduces the number of steps.

To begin, install devcert-cli:

$ npm i devcert-cli –g

Devcert-cli will be installed globally. Run this command in in your project root to generate the needed cert and key:

$ devcert generate test.local

Where test.local will be the alias for localhost on your computer. This is necessary since SSL can only be applied to a domain, not localhost itself. Thus we are going to attach SSL to this arbitrary domain.

The caveat is that the test.local domain has no DNS records associated with it. This means that if you try to navigate to it in your browser that it wont appear. To resolve this Devcert will attempt to update your host file so that your computer will know how to resolve requests to “test.local”. The hosts file will point “test.local” to “127.0.0.1” (localhost).

Run this command to see what domains devcert has setup:

$ devcert list

“test.local” will appear.

Its worthwhile to check your host file for sanity’s sake to see if “test.local” appears:

$ cat /etc/hosts

Should show the following as part of the contents of your hosts file:

“127.0.0.1 test.local”

Perfect.

You may have noticed that a couple of files have appeared in your project root. First thing to do is to add those files to your .gitignore so that you accidentally commit them to source control.

Next you will load up those files using fs and hand them to the Express via an “ssl” object which holds the contents of the key and cert files.

Note the modules required into the file and where the “ssl” object is inserted when https.createServer is called.

const app = express()
const https = require('https');
const fs = require('fs');
const ssl = {
    key: fs.readFileSync('test.local.key'),
    cert: fs.readFileSync('test.local.cert')
}

app.get('/', (req, res) => {
  res.send('HTTPS-enabled!')
})

https.createServer(ssl, app).listen(3000, () => {
  console.log('Listening at https://test.local:3000...')
})

Nunjucks and Koa-route

19 Sep 2019

Here’s how to get Nunjucks templates working with Koa’s default router Koa-route.

Assuming you have Koa setup you’ll want to install nunjucks via:

$ npm install nunjucks

Then include Nunjucks in your route. In my case, I have a /routes directory within my project root and so I’m requiring Nunjucks into the index.js that is sitting there.

As well, I’ve written a “render” function that will render the nunjucks template to be served up through the route configured for it via koa-route.

Below is the code snippet showing the above-mentioned scenario.

const nunjucks = require('nunjucks');
const route = require('koa-route');

const render = function (path, params = {}) {
  return new Promise(function(resolve, reject) {
    const env = nunjucks.configure(
      [
        `${__dirname}/../src`, // PATH TO YOUR TEMPLATES
      ],
      {
        autoescape: false,
      },
    );
    resolve(env.render(path));
  });
};


module.exports = [
  route.get('/', async (ctx) => {
    ctx.body = await render(`${__dirname}/../src/pages/home.njc`);
  }),
  route.get('/some_directory', async (ctx) => {
    ctx.body = await render(`${__dirname}/../src/pages/some_directory/index.njc`);
  }),
];

As you can see route.get(‘/server-path-here’ specifies the path that the end user would browse to. As well, I’m using ctx.body to send back the rendered Nunjucks template via the render function which passes in the path to the template that matches the route.

SQLITE_CANTOPEN

21 Aug 2019

While working with a SQLite3 database in Node using KNEX and Objection I encountered this error:

UnhandledPromiseRejectionWarning:
Error: SQLITE_CANTOPEN: unable to open database file

Seems that using relative paths isn’t a good idea. Setting the absolute path to the SQLite file instead resolves this using Node’s __dirname variable. From there simply construct the rest of your path to the database.

Your knexfile.js file can stay as-is, where you specify the path to where the database should be created. Instead look at the file you use to setup Knex/Objection and specify the absolute path there. For example:

const { Model } = require('objection');
const Knex = require('knex');

const knex = Knex({
  client: 'sqlite3',
  useNullAsDefault: true,
  connection: {
    filename: `${__dirname}/path/to/db.sqlite3`,
  },
});

Another error related to not finding the database is one which claims to not being able to find the specified table when in fact it does exist.

UnhandledPromiseRejectionWarning:
Error: SQLITE_ERROR: no such table: [table name]

As above, set the absolute path to the SQLite file.