My website can still be found at, but I have not been posting on this blog as I've been primarily focused on - please head over there and take a look!

Monday 23 September 2019

@mysql/xdevapi joy!

after hitting a wall last night with the existing node.js mysql packages, which for some reason have been years behind integrating with mysql 8's authentication, i discovered @mysql/xdevapi. the documentation's a bit heavy and not really comprehensive, but now that i've figured out how to use it, i'm very pleased with how it operates! unfortunately, i'm going to have to roll my own migrations management, but that's a small price to pay for being able to interface with the latest mysql databases in an intelligent way.

in the interests of reducing friction for other adopters, i've rolled some sample queries into my database creation script. enjoy!

UPDATE: i've subsequently learned that table joins have not been implemented, so to perform those you'd have to use the session.sql method and use it in the same way (the same promise chaining) as the CRUD methods. seems like a serious oversight, but whatever.

Friday 23 August 2019

Handling emails with node.js and Mailparser

After sorting out mail forwarding and piping emails with postfix, I then needed to understand how to handle emails being POSTed to an API endpoint.

To parse an email with node.js, I recommend using Mailparser's simpleParser. I'm using express with bodyParser configured as follows:
 limit : config.bodyLimit
In your handler:
const express = require('express');
const router = express.Router();
const simpleParser = require('mailparser').simpleParser;
import { Router } from 'express';
import { simpleParser } from 'mailparser';
and then'/', (req, res) => {
        .then(parsed => {
        .catch(err => {
            res.json(500, err);
Mailparser is excellent, and documented, but the documentation assumes that we're familiar with the email format. Fortunately, oblac's example email exists for those of us who aren't!

To test, send the example email to the endpoint via curl:

curl --data-binary "@./example.eml" http://your-domain-name/api/email

or Postman (attach file to "binary").

And we're good to go!

Thursday 22 August 2019

Mail forwarding and piping emails with Postfix for multiple domains

The past few weeks I've been learning about mail servers, and the biggest takeaway for me is that it's generally worth paying someone else to handle the headache. As usual, the obstacles to configuring a mail server correctly are primarily in the lack of useful documentation and examples, so I'm putting this down here in the hopes that it'll be helpful to like-minded constructively-lazy devs.

While I'm happily using mailgun for mail sending (after much frustration I threw in the towel trying to integrate DKIM packages with Postfix to get my outgoing emails secured) I was certain that I could at least have my mail server handle mail-forwarding for my multiple domains, and while that proved to be fairly straightforward I then tumbled down a rabbit-hole trying to get Postfix to pipe certain emails to a node.js script for processing.

    Here are the steps you'll need to take:

  • Set up your A and MX records for your domain, the A record @ pointing to the IP address of the server you’re going to be receiving emails on and MX with the hostname @ and the value 10 mail.your-domain-name

    If your mail server is not the same as your primary A record, simply create an additional A record mail pointing to the correct IP address.
  • sudo apt-get install postfix
    Select "Internet Site" and enter your-domain-name (fully qualified)
  • sudo vi /etc/postfix/
    • Add mail.your-domain-name to the list of mydestination values
    • Append
      virtual_alias_domains = hash:/etc/postfix/virtual_domains
      virtual_alias_maps = hash:/etc/postfix/virtual
      to the end of the file
  • sudo vi /etc/aliases
    curl_email: "|curl --data-binary @- http://your-domain-name/email"
  • sudo newaliases
  • sudo vi /etc/postfix/virtual_domains   #domain   #domain
    your-domain-name   #domain
    (the #domain fields suppress warnings)
  • sudo postmap /etc/postfix/virtual_domains
  • sudo vi /etc/postfix/virtual
    email_processor@your-domain-name curl_email@localhost
  • sudo postmap /etc/postfix/virtual
  • sudo /etc/init.d/postfix reload

You should be able to find your postfix logs at /var/log/mail.log. Good luck!

Monday 5 August 2019

FreeVote: anonymous Q&A app

I can't believe something like this doesn't exist already! It's far from a polished product, but it's already pretty functional. Feel free to send me feedback, it'll help me prioritize the long list of improvements I've already come up with. This was inspired by my coworkers, every retrospective we all write down answers to sensitive questions "anonymously" on folded papers that one team member gathers and reviews... this way we can do it truly anonymously and all see the results.


Saturday 6 April 2019

Hosting my own podcast

I've been having trouble with podcast garden, turns out they're a really unprofessional outfit; more than half the time their website is inaccessible, and they have poor customer service. Also, they've taken a lot more money off me than I agreed to and I've opened a dispute with PayPal, hopefully they'll sort this all out.

In the meanwhile, I've spent the last couple of days migrating to a custom solution, I honestly don't know what I'd do if I wasn't a software developer. The Shakespeare's Sonnets Exposed podcast is now being hosted right here on industrial curiosity, and not only am I no longer at the mercy of other people's incompetence, it's a much cheaper solution, too!

Now I just need to find the time to make my solution easily available to the public...

Tuesday 19 February 2019

Effective Technical Interviewing with GitHub

Throughout my career I've encountered many problems with hiring processes, some mildly annoying, some decidedly infuriating, and some utterly baffling. Of all of those issues, few have pressed my buttons as consistently as those relating to how technical assessments are generally handled.

The cost of an ineffective technical interview to the company can be greater than the hours invested in interviewing or the lack of resources until the right candidate is found, with many regulations making it difficult to get rid of a low-performing employee and most situations requiring a learning curve that extends beyond legal probation periods.

The cost of a technical interview to the applicant can be even greater, as interviewing at multiple companies or when already employed leaves little time to do the assessments and it's usually a lot of effort, for no compensation, that produces nothing of value.

The bigger companies have found a reasonably good solution to the technical assessment, but phone screening and days full of whiteboard interviews are simply not affordable for the smaller players. The focus of this article is on technical assessments wherein the candidate is expected to produce a solution, or set of solutions, within a set period of time.

There are two major downsides to these coding assessments:

1. It is of little consequence whether this is done in an in-office setting or as a take-home assignment, it is very difficult to extract meaningful information about the strengths and weaknesses of a candidate from the results of an assessment done in this manner. There are many variables that may influence the results of this kind of an assessment, the candidate's ability to code under stressful conditions for a start, and usually there's not enough interaction with the candidate during the coding process to assess collaborative behaviour.

2. The work done in producing these solutions is, for all intents and purposes, wasted effort. Candidates are consistently asked to demonstrate their skills by producing arbitrary code that would not be of use or interest to anyone going forward.

In this article I'd like to address two possible strategies using GitHub that could significantly improve the effectiveness and overall outcomes of this important step in a candidate's application.

First strategy: Existing GitHub issues

The world of open-source is full of real problems that require solving, and nine times out of ten (for smaller organizations in particular) in software packages that are used by the interviewing company.

One possible strategy is to break down the technical skills you require from your candidates - not just the languages and frameworks, but problem spaces as well - and find open issues on GitHub with similar profiles.

Second Strategy: Porting an issue to GitHub

It is a common misconception that everything in a proprietary codebase must be kept under lock and key. With the right license, there are plenty of issues that a company might have that can be isolated from the codebase, ported to GitHub, and then reincorporated once solved.

Similarly to the first strategy, it is important to break down the technical skills you require from your candidates and find issues that would highlight their relevant strengths and weaknesses. The act of "open-sourcing" this code would be as simple as establishing the right license and creating a repo. Ideally, it would be code that others might find useful, too!

With this strategy, there would need to be a different problem for each individual candidate, as the moment one candidate has come up with a solution there would be little to stop another from taking a peek and little value in multiple developers repeating the same effort.

The advantage, obviously, is that work put into interviewing would directly benefit the company, but the moment you're benefitting from the candidate's efforts they would be entitled to at least some compensation, in addition to being able to show their work in other job applications.

When an applicant has successfully delivered a solution, you could compensate them directly, which may be preferable, or you could use Gitcoin, where you can set a bounty on your issues for immediate payment on the acceptance of a PR.

Either way, it'd be a small price to pay for development, the candidate would have earned a little money (which most candidates desperately need), and you'd have useful information for your hiring process.


Contributing to GitHub projects will show more than just a candidate's code quality; it can also show communication skills and collaborative behaviour. Additionally, choosing or defining projects with strict requirements for code conventions and unit tests will push your candidate more significantly than just mentioning that you'd like to see testing done.

An accepted PR (pull request) will make the world a (slightly) better place; it would be a good deed on your part, a good deed on the candidate's part, and the resulting effort would have actual value.

It is also far more likely that a candidate will be motivated to solve a real problem than a fictitious one, and their efforts will be rewarded by becoming a part of their portfolio. As somebody who has predominantly worked on proprietary code, I can testify to the utility of being able to direct a potential employer to my GitHub account!

With either strategy, everybody wins. For the developer, the technical assessment becomes real world experience that they can show off to others, and the employer gets to see real-world coding performed under real-world conditions.

Wins all around!

Sunday 10 February 2019


A long time ago, I posted about importing and exporting Javascript-compatible RSA certificates to and from C#. Last night I realized that I needed a simple and reliable way to shared encrypted code with non-technical folk and decided to put everything I've learned into a comprehensive package called simple-free-encryption-tool that runs on a node.js backend, in your browser, and doesn't even need to be cloned for quick abuse.

This makes strong RSA key generation and encryption and AES encryption simple to implement, and practical to use for client-server communications. It also allows me to give someone an encryption package on a stick (just copy the dist folder) that they can open on any machine.