Tip #1 – Unlicensed npm packages

Every day is a learning experience for me, so I’ve decided to keep a log of very short tips on this blog for things that I discover here and there. I frequently stumble across little quirks and details in software that I want to talk about but aren’t deserving of traditional posts or deep dives. Plus, I don’t enjoy writing long pieces about mundane things. Win-win!

Today’s tip relates to Node.js, or, more precisely, package managers like npm and yarn.

Use the word UNLICENSED in the license field of your package.json file when you don’t have an explicit license for your codebase. This is an officially supported feature in both npm and yarn. See the following example:

{
  "name": "my-package",
  "version": "1.0.0",
  "description": "This is what my package does",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/username/my-package.git"
  },
  "author": {
    "name": "Awesome Person",
    "email": "awesomeperson@hotmail.com",
    "url": "https://awesomeperson.info"
  },
  "license": "UNLICENSED",
  "bugs": {
    "url": "https://github.com/username/my-package/issues"
  },
  "homepage": "https://github.com/username/my-package#readme"
}

Note: Please do not confuse this with another supported value, Unlicense, which is the official SPDX identifier for the Unlicense, a public domain dedication document.

Importing GnuPG Keys From an Existing .gnupg Folder

Many of us computery people, myself included, use GNU Privacy Guard‘s (GnuPG’s) implementation of Pretty Good Privacy (PGP) to do things like signing and encrypting files on our systems. I have some mixed opinions about PGP and just how practical webs of trust have proven to be in 2020, but I’m setting them aside for this short post.

I recently installed elementaryOS on my home desktop, and I’m loving it so far as a daily driver. One hitch I had, though, and also the topic of this post, was importing my PGP private key that I use for signing my git commits (2DEC0103). This was a time where I was annoyed with my past self, as I had done a pretty ham-fisted job with backing up data from my last OS. I basically just shoveled files and folders onto another hard drive, and I didn’t make any effort to export my private keys. I just threw the whole .gnupg folder in there! (I have other copies of my key, but they’re inconvenient to access.)

I said this would be a short post, so let’s just jump to the command.

gpg --export-secret-keys --homedir=/path/to/another/.gnupg | gpg --import

This command uses the flag --homedir, which was the crucial bit here. I spent a good half hour looking around for an exact solution to my conundrum, but ultimately the GnuPG documentation came through (imagine that 🤦‍♂️). This flag specifies an alternative .gnupg folder to use for that particular GnuPG process. In total, the command says to export all secret keys from /path/to/another/.gnupg and import them defaultly (probably to ~/.gnupg).

By the way, defaultly needs to be a word. I’ve had to use it a few times recently…

Adding Strange DNS Records to Cloudflare

This is a post about a really niche problem that I ran into a few days ago. I am writing about it just it in case somebody else hits it.

It looks like the Cloudflare DNS app does not like it when your subdomains are named too similarly to your apex. It’s very possible this is a user-friendliness measure and they’re trying to protect you from making a mistake, but I had to work around it.

Let’s be a bit more concrete here.

The Problem

Consider the name tylerfilla.com, and assume it is on Cloudflare.

A screenshot of my Cloudflare homepage showing just one site I can administer named "tylerfilla.com".
The site listed on my Cloudflare home page.

Now let’s go to the DNS app for the site.

A screenshot of the list of DNS records on my Cloudflare site. There is only one record, a TXT record for Keybase verification, in fact, but it does not pertain to this blog post.
The site’s existing DNS records. The TXT record you see here is a Keybase proof and does not have anything to do with this blog post.

A Contrived Example

Let’s make blog.tylerfilla.com point to some IPv4 address, say 192.168.1.1. (This is a reserved IP address meant for local networks, but that’s not a DNS concern. This would potentially resolve to a device on the visitor’s own home network or something.)

A screenshot of the dialog Cloudflare shows to add a new record. I am adding an A record that points to the IP address "192.168.1.1".
I am adding an A record that points to “192.168.1.1”.

Now here is the list of records:

A screenshot of the list of DNS records on my Cloudflare site. Now there are two records since the A record for the blog subdomain has been added.
The DNS records for the site now that the blog subdomain has been added.

Aside: We can see that the Cloudflare web UI is not super concerned with consistency in the name column: blog and tylerfilla.com are hierarchical, yet they are presented flatly. In my opinion, either blog should be presented as blog.tylerfilla.com, or tylerfilla.com should be presented as the special symbol @ which is frequently used to represent the apex.

But what happens if we want to map the name tylerfilla.com.tylerfilla.com to some resource on the internet? You know, for science?

An animated screenshot of the name field in the Cloudflare DNS dashboard where I typed in the text "tylerfilla.com". As I type, a nearby label updates letter-by-letter with a preview of the final record name. When I start typing, this preview is behaving as expected. When I finish typing, however, the preview reads "tylerfilla.com" instead of the expected "tylerfilla.com.tylerfilla.com" as if Cloudflare had tried to autocorrect a mistake.
This animation shows what it’s like to name a subdomain on Cloudflare.

Now that is not something I expected to happen. Cloudflare detects that the name field compares equal to the apex name, and then they assume you meant the apex. (For the record, they also accept the symbol @ for the apex, so this is not a technically necessary behavior.)

This is a contrived example, so let’s un-contrive it a bit.

An Uncontrived Example

Let’s say I have created a GitHub organization called tylerfilla-com that I can use to hold some repositories for my personal website.

A screenshot of the home page of my new GitHub organization.
This is the home page for my new GitHub organization.

Let’s add the website URL to the organization.

A screenshot of a textbox labelled "URL" and containing the text "https://tylerfilla.com".

Now let’s go get a sweet “verified” badge for it.

A screenshot of the info box GitHub shows that tells you the steps you need to take to get a green "Verified" badge on your organization's profile page. In my case, it tells me to verify the domain name "tylerfilla.com".
This is a little info box that GitHub shows in the organization settings about getting verified.

GitHub tells me to add a TXT record called _github-challenge-tylerfilla-com.tylerfilla.com. to the DNS with the value a9f432e7cb. (We can ignore the dot at the end of the record name, as that’s just a DNS formalism.)

A screenshot of a box on GitHub that gives instructions for how to complete the verification challenge for my domain name, "tylerfilla.com". I need to create a TXT record with a specific code as a value to verify the domain and, by extension, my GitHub organization.
These are the instructions for completing the verification challenge.

That should be easy! What say you, Cloudflare?

An animated screenshot of the name field in the Cloudflare DNS dashboard where I typed in the text "_github-challenge-tylerfilla-com". As I type, a nearby label updates letter-by-letter with a preview of the final record name. When I start typing, this preview is behaving as expected. When I finish typing, however, the preview reads "_github-challenge.tylerfilla.com" instead of the expected "_github-challenge-tylerfilla-com.tylerfilla.com" as if Cloudflare had tried to autocorrect a mistake.
Animation of me trying to type in the challenge record name and getting Cloudflared.

😐

Cloudflare refuses to accept _github-challenge-tylerfilla-com.tylerfilla.com and autocorrects it to _github-challenge.tylerfilla.com.

The Workaround

It turns out that this is just a UI limitation on the website, and I worked around the issue using the Cloudflare API, so let’s check that out. The relevant API endpoint is specified under the section called DNS Records for a Zone.

A snippet of documentation for the API endpoint used for creating DNS records.

That’s pretty simple. I grabbed an API token from my Cloudflare account settings and the zone identifier from the landing page for my site on the Cloudflare web app. With all of that info, I ran the following command in a Linux shell:

curl -X POST "https://api.cloudflare.com/client/v4/zones/{ZONE}/dns_records" \ 
    -H "Content-Type: application/json" \ 
    -H "Authorization: Bearer {TOKEN}" \
    --data '{"type":"TXT","name":"_github-challenge-tylerfilla-com.tylerfilla.com","content":"a9f432e7cb","ttl":1}'

(Replace {ZONE} with your zone identifier, {TOKEN} with your API token, and, of course, the record details as you need.)

And all was well 😀

Hello, world!

I’m Tyler, and I am a software and hardware hobbyist in the greater St. Louis area. I have decided to keep a blog as a notebook for my personal projects.

Some time in December 2019, I decided that I wanted to start jotting stuff down when I’m doing something like wrangling with a tech problem or when tearing down a device or when writing a fun little app or even when soldering a tiny thing to a circuit board. These notes would be little more than something upon which I could look back from time to time, and I planned to start jotting immediately. That did not happen.

Fast-forward to March 2020, and I’ve refreshed all of my prior experience with web development (not much) trying to plan and build my ideal website. Initially, I dove head-first into the frontend realm with React, and, after three months, I can say that I’ve learned way more about SPAs, virtual DOMs, static site generation, and the Jamstack than I even knew existed. I’ve deployed to both Netlify and ZEIT Now, and I’ve followed guides for GatsbyJS and Next.js (both React frameworks) as well as for Sapper, which is a Svelte framework. This space is mind-bogglingly huge, and I’ve only scratched the surface. I come from the systems programming realm where the most exciting thing is complaining about the new bloat features added to C++ every few years. (I kid of course!)

I realized pretty early on that I wanted something custom. I’ve made physical caveman drawings of how I want the site to look since I’m too stubborn to accept any of the prior art I’ve seen for themes. Crucially, however, I realized that I want to jot stuff down about the designing and building processes, as the website will probably never be finished per se (what is, really?). So, in a refreshing bout of getting things done, I used what I knew and set up a LAMP stack on an Amazon virtual machine (t2.micro free tier 😎). I also got an auto-renewing TLS certificate from Let’s Encrypt with the EFF’s certbot tool, and then I just set up WordPress on it. It works for now, and I’ll migrate my content later instead of trying to play both user and developer on a new project.

This blog is, admittedly, selfish to the extent that it’s merely my notebook and not a place for projected advice or in-depth tutorials. However, I am publishing in the hope that someone finds use for something I’ve created like a piece of code that I’ve written or like an Arduino project I’ve wired up or even something like an idea I’ve hinted at that got amplified by the search engines for the one person who needs it.

I don’t know what the future holds. I don’t know what, if anything, on this site will see greater use. But, at least for now, it’s Googlebot and I. And Robert Graham’s masscan.

And that’s okay with me.