Category Archives: davidwalsh

5 Premier Web Hosting Service To Consider Using (Sponsored)

Your website’s performance depends in large part on your hosting service’s performance. Yet for many, selecting a hosting service involves little more than finding one that advertises speed and reliability for a low price.

Many business owners recognize the importance of quality content, responsiveness, and other factors, but few of them recognize the need to take a close look at a prospective hosting service to see what it can actually deliver. If the host provides substandard performance or support, the result can be slow page loading, capacity issues, or an undue amount of unanticipated downtime. 

read more

Create Aliases in Bash

Every developer likes a shortcut — they’re what make us more efficient in our work.  Of course there are good shortcuts and bad shortcuts (lazy coding, lack of security review, etc.), but let’s stick with the positive and talk about a good shortcut:  bash aliases.

We all have commands that we execute regularly but aren’t able to remember or simply don’t care to constantly type, like removing all Docker images and containers or bringing down and instantly bringing up a docker project.  Most commands we execute often each day are boilerplate; maybe one or two parameters change.  Let’s have a look at how easy it is to create aliases so you can be more productive!

Creating a Basic Alias

To create an alias, start by opening ~/.bash_profile in any text editor you have available.  The format for creating an alias is as follows:

# alias-name='command to do thing'

alias docker-refresh='docker-compose down && docker-compose up'
alias serve-dir='python -m SimpleHTTPServer'

I recommend naming your aliases in a way that wont conflict with existing or future executables.  You could add a “namespace” or prefix to them, for example.  To ensure the alias will work in your shell once you’re done editing .bash_profile, execute the following:

source ~/.bash_profile

Creating a basic alias is fairly simple but what if your alias requires the use of arguments?  That case is a bit different.

Aliases with Arguments

If the mostly boilerplate command we want to execute requires an argument or two, we’ll need to use something more advanced that the basic bash alias format — we’ll need a function.

Let’s say we want to execute a command that requires one argument — we’d do something like this:

# Serve a directory on a given port
# https://davidwalsh.name/serve-directory-python
# $1 = port
# Example: servedir 8080
servedir() {
  # Allow myself to change the port ($1)
  python -m SimpleHTTPServer "$1"
}

# Scrape images with wget
# https://davidwalsh.name/scrape-images-wget
# $1 = url
# Example: scrapeimages https://davidwalsh.name/
scrapeimages() {
  wget -nd -H -p -A jpg,jpeg,png,gif -e robots=off $1
}

# Remove audio from video
# https://davidwalsh.name/remove-audio-video
# $1 = source file
# $2 = destination
# Example: removeaudio myvideo.webm myvideo-silent.mp4
removeaudio() {
  ffmpeg -i $1 -vcodec copy -an $2
}

read more

Two-Factor Authentication with Node.js

Google Authenticator

There are a variety of strategies for protecting your important online credentials.  We often hear about password managers and generators, but for me, the more important strategy is using two-factor authentication (2FA).  Passwords can be guessed, phone numbers can be spoofed, but using two-factor authentication essentially requires that user be in possession of a physical device with an app like Google Authenticator, loaded with a secret key for the given app, which provides an extra layer of security.

I didn’t use to take two-factor authentication seriously, until someone stole my domain name and tried to launder it to a safe haven for thieved domains.  While I don’t know how exactly they did it, I’m fairly certain they got access to my email address, created filters so I wouldn’t see the emails, etc.  Had I used two-factor authentication, neither my email or GoDaddy accounts could have been accessed.  Or you could take it from Cody Brown who had $8,000 in cryptocurrency stolen in minutes because the vendor used phone number validation to allow transactions to be approved.  Today I use two-factor authentication for all of my important email, work, and financial accounts.

Since I use 2FA so often, I wanted to see how the process is managed by a developer for its users.  That would include generating the secret key, creating its QR code representation, scanning the code into Google Authenticator (done by the user), and then validating that GA-given code against the user’s key.  I found an easy to use Node.js library, speakeasy, to do so!

Setup Step 1:  Generate a Secret Key

Assuming you’ve installed speakeasy via npm install speakeasy, the two-factor authentication setup is kicked off by generating a unique secret key for the user:

var speakeasy = require('speakeasy');

var secret = speakeasy.generateSecret({length: 20});
console.log(secret.base32); // Save this value to your DB for the user

// Example:  JFBVG4R7ORKHEZCFHZFW26L5F55SSP2Y

This secret key should be stored with the user’s record in your database, as it will be used as a reference to validate 2FA codes in the future.

Setup Step 2:  Generate a QR Image

Apps like Google Authenticator allow users to scan a QR code or enter the text key.  Scanning an image is much faster so offering the QR code will be of great convenience to your user:

var QRCode = require('qrcode');

QRCode.toDataURL(secret.otpauth_url, function(err, image_data) {
  console.log(image_data); // A data URI for the QR code image
});

QRCode.toDataURL provides an image data URI that you can use for the img src attribute.  If you aren’t familiar with a QR code, it will look something like this:

QR Code

User Step 1:  Scan the QR Code / Add Site to Authenticator

At this point the user should have opened Google Authenticator (or Authy, etc.) and scanned the QR code; an entry for your web app will be added within the device’s app.  From this point forward, whenever the user wants to log in (or perform any action you’d like to be protected), your system should recognize the user wants to use 2FA and you should require they enter the token from their app.

Google Authenticator

For the purposes of debugging, you can get what should be the user code value at a given time via:

// Load the secret.base32 from their user record in database
var secret = ...

var token = speakeasy.totp({
  secret: secret,
  encoding: 'base32'
});

read more

Address Validation API with streetlayer

There is so much of our web and eCommerce that consumers take for granted: payment types and validation, exchange rates, etc.  One of the aspects of eCommerce that should be a given, from both a developer and consumer perspective, is address handling.  We’d like to think the consumer enters their address correctly but the risk is if the don’t that their experiences gets ruined by the shipping company not finding the address or, worse yet, a situation where the package is lost and you need to incur a loss shipping them another item (assuming you’d prefer to avoid a contentious fight with the consumer about whose fault the problem is).

Of course eCommerce isn’t the only reason for address validation and lookup.  You may want coordinates to load a Google Map, you may want to get the user’s county, you may want to get zip code information for sales tax calculation — the use cases are endless.  streetlayer is the service than can perform all address validation needs.

Quick Hits

  • The streetlayer API is super easy to use
  • Get address validation, autocompletion, and geocoding
  • Provides international address information
  • streetlayer allows JSONP requests
  • Provides HTTPS API usage
  • Clear documentation and code samples
  • Very competitive pricing

Using streetlayer

streetlayer offers free signup with a generous request allotment for testing.  After you sign up you’ll be given an API key to begin development.  Let’s have a look at the different ways you can use streetlayer!

streetlayer Usage Tips

A few constants when using the streetlayer API:

  • All requests are GET requests
  • All requests require an access_key key/value parameter for the API key
  • Adding format=1 to the query string for streetlayer to indent the JSON response

Validating an Address

Validating an address is the most common use of address APIs.  Trusting consumers to input information (outside of payment, which is instantly verifiable) can lead to trouble.  If you’re going to verify payment information, why wouldn’t you verify delivery address information if you can?

Once your customer provides your web or native app with their address information, the first step should be verifying that information, as it’s an easy HTTP request to save you shipping and billing trouble down the road.  Shoot their given address information to streetlayer with one simple request:

http://apilayer.net/api/validate
    ? access_key = YOUR_ACCESS_KEY
    & address1 = 767 5th Ave  
    & postal_code = 10153  
    & locality = New York  
    & country_code = USA  

In the case of address verification from streetlayer, you’ll see the following response:

{
  "validation_status": "valid",
  "address_components": {
     "country_code_alpha2": "US",
     "country_code_alpha3": "USA",
     "country": "United States",
     "county": "New York County",
     "locality": "New York",
     "postal_code": "10153",
     "region": "New York",
     "street": "5 Avenue",
     "housenumber": "767",
     "neighbourhood": "Midtown"
  },
  "validation_result": {
     "locality": true,
     "county": null,
     "region": null,
     "postal_code": true,
     "street": true,
     "housenumber": true
  },
  "formatted_address": [
     "5 Avenue 767",
     "New York, 10153",
     "United States"
  ],
  "coordinates": {
     "latitude": 40.763554,
     "longitude": -73.972839
  }
}

read more

Create GitHub Pull Request and Issue Templates

There’s nothing more frustrating than getting an incomplete bug report.  I’ve often seen bug reports containing a useless “{x} feature doesn’t work”; no steps to reproduce, no URL, no browser or device information, just a hopelessly vague message.  Similar is receiving a pull request or patch which doesn’t state its intent and doesn’t provide steps to test (and what about unit tests?).  Now that many projects are public, most on GitHub, I’ve seen a massive rise in these types of sparsely documented issues and pull requests.

read more