So! Much! Progress!

I started doing the #100daysofcode challenge on Tuesday morning. It was a modest start, just did about an hour of stuff before work, since I was inexplicably up at 4:30am or something dumb. And yet, I was able to actually tackle true email uniqueness.

So I had two concerns here:

  1. Prevent people from creating multiple accounts with the same email address. Like, user @ gmail.com is the same as u.s.e.r @ gmail.com or user+game @gmail.com. So I didn’t want that to be possible.
  2. Not mess up people’s given email addresses so I can actually send them communication about the game. What if someone’s not on gmail and, I don’t know, the period between their first and last names actually matters? What if someone set up a mail filter for the game using the plus sign? I definitely wanted to send mail to the address they had provided, but I didn’t want to have that address be the unique address.

What I did is save the given email address, but also normalized it (strtolower). Then, I made it unique by virtue of, well, here’s the code and I’ll explain it below.

Code to normalize and sanitize emails
Code to normalize and sanitize emails

Breaking the email up into its component parts of username @ and domain by exploding on the @ sign made things easy for me to modify just the username and then reconstruct the email address as a new variable called $uniqueEmail. So I then explode on any + sign. Then, by focusing on the first part of the resulting array ($sanitizingUsername), which is to say anything before any + sign that might exist in it, I’m now dealing with just the username. Then, I replace anything that isn’t a-z, A-Z or 0-9 with nothing (“”). Then, I rebuild the email address with the sanitized username I just created, concatenated with the @ sign and the previously-split apart domain.

This allows for an email address like julie.m.a.r.t.i.n+game @domain to be viewed by my program as juliemartin @domain for the uniqueEmail() check function, but, I’m still emailing that specific julie.m.a.r.t.i.n+game @domain address for any game communications.

Bonus: julie.martin @domain works fine, as does juliemartin @domain. Exploding on a + that may or may not exist has no ill-effects if it doesn’t.

So that’s how Day 1 of #100daysofcode went.

I’m logging my daily progress in a log file on GitHub, so you can check it out here:

https://github.com/juliebugmtl/100-days-of-code/blob/master/log.md

If you read it, you’ll see that, on day 1, I had neglected to change my email variable to the all-important email1 when I made the change for JavaScript validation purposes. I snag a bunch of information from the user’s submitted form on POST, but I forgot to change email to email1 when I changed the form ID/name for that field.

Guess what else I forgot to change?

The password field. I’m validating the password too, so I made two fields, one called password1 and one called password2 but at no point in time did I change my snagging information from the POST to snag from password1, so it was still pulling from the (non-existent) password.

Do you know how much fun it is to try to log in with a password that doesn’t actually exist when you don’t know it doesn’t exist?

Answer: not a lot, let me tell you! You can read about that in Day 4’s entry.

What’s hilarious is that the issue with the password storage and hashing comes on the heels of resounding success on Day 3 where I basically coded a whole function blindly and, to my utter shock, it worked perfectly on the first try.

Day 3 was dedicated to getting SendGrid to send out emails for validation and for blacklisting and I’d set up the validation workflow on Day 2 and finally got the link mailed out on Day 3, whereupon I then coded the blacklisting function without testing it at all until the end and it worked.

But Julie, you may ask, why the hell would you use a blacklist function? Surely people who are signing up for your game are, you know, actually interested in playing your game, no?

NO.

I have a Gmail address. I’ve had it since April 29, 2004. Unfortunately, being an early adopter means that I got my first choice of email address. As such, everyone else who wants that email address has to modify it, like if it were julie @gmail (it’s not), then everyone after me had to do julie1 @gmail or juliea @gmail or julie01 etc, etc, etc.

Do you know how often people forget that they have appended something to their email username?

It’s often.

Like, multiple-times-a-day-often, sometimes. Certainly multiple times a week. In the past, I have received emails from banks, airlines, universities, family and friends of other Julies, real estate agents and, the worst of them all, REPUBLICAN CAMPAIGN NEWSLETTERS.

All because these… these… these bozos, can’t properly understand what the hell their email address is.

So many of them are important messages so I try to write back with a canned response going “hey, wrong person” basically.

Just slightly above the Republican campaign newsletter crap I get, in terms of annoyance, is the stuff other people have signed me up for. Not actually me, obviously, but like an acquaintance, friend, family member of someone else out there has signed up my email address for Blue Apron in the past. Multiple times. This woman Susan signed me up to Blue Apron in March of 2016. Three. Separate. Times.

Thankfully, they listened to me and blacklisted my address, but the point here is that I don’t ever want anyone to have to deal with that pain in the ass when it comes to my game.

Hence, a blacklist system. My blacklist function does the following:

  • looks up the user
  • snags the unique email
  • adds the unique email to a voluntary blacklist
  • deletes the user
  • deletes the token associated with that user

You can only get to the blacklist page by virtue of clicking the link in the email sent. The URL adds the token and the user ID in its parameters, so it’s like domain.com/blacklist.php?t=TOKENHERE&user=USERIDHERE. If the token doesn’t match the user ID, it won’t work. And I do refresh the tokens once someone validates, so they can’t accidentally delete themselves.

Gotta say, I’m pretty pleased with that functionality. Plus, if someone wants to register and uses a blacklisted email, they get asked to email me to remove the email from the blacklist. If the email doesn’t match, then I won’t remove it, simply.

So there’s been a lot of progress. Registration is effectively done. Login works. Time to clean up and refine All The Things and then work on:

  • identifying an admin user
  • adding menu options for logged-in users (admin and not)
  • working out what the hell logged-in users should be able to do! hahaha

Some planning to do, for sure, but this stuff is getting interesting. Keep up to date with me on Instagram, where I’m posting stories when I sit down to code and post a pic when I’m done working for that day.

#100daysofcode

I’ve been thinking about it for at least a couple of months and I’ve decided to embark upon #100daysofcode. Why? Because it’s there!

No, truthfully, I’ve wanted to do this since I first saw the tags on various Instagram posts that I’ve seen. The thing that’s been stopping me is that I literally cannot commit to 100 days straight of code. Probably the soonest I could do that is December 1.

So while I’m starting the #100daysofcode challenge today, September 4, there are two major changes I’m making to the rules for myself. The rules state you need to code one hour a day for 100 days and you can only skip one day every two weeks, adding that skipped day to the end of the 100 original days to ensure that you are actually doing 100 days.

The first rule change here is that I am not going to code from September 25 until the 29th (may or may not be inclusive). Why? I have a work trip. I definitely do not think I can get away with sitting in my room coding for an hour a day when the rest of my colleagues are hanging out and chatting and getting to know one another. As such, instead of this challenge ending for me on December 13, it’ll end much closer to December 18. Or possibly later.

The second is that every November, I participate in National Novel Writing Month. That means that I should be striving to hit 1667 words of creative writing during every day of November. It rarely actually turns out like that — I’ll sometimes go several days without writing and then will suddenly write 7,500 words and will catch up. However, the goal is 50,000 words in 30 days and so because of this, I’m giving myself permission to skip coding 1-2 times a week during November.

So that’s an additional 4-8 days, which beings me to December 22 to December 26. Obviously, you have Christmas in there, too, which needs to be accounted for, so here’s my thinking: in the 119 days between today and December 31 (inclusive), my aim is to reach 100 days of coding for at least one hour a day. That’s totally doable. I may even come in ahead of that projection, depending on how well the writing goes in November.

19 days is a bit of a buffer, definitely, but I think this is an achievable, albeit challenging goal. I did think about putting this off until December 1, when I could conceivably actually do the challenge as intended. But what’s the point of putting off something I want to do that will encourage me to do something I should be doing? While I’m a life-long procrastinator, it seemed silly to me to hold off on this challenge for another three months.

I’ll be primarily posting to Instagram, but those posts cross-post automatically to Twitter. Follow me on either: the username for both is juliebugmtl.

And now, to get a cup of tea and start my first hour of coding in this challenge, since it’s 7:14am and I’ve inexplicably been awake since 4:30.

I built a computer!

On Monday, August 27th, for the first time in my life, I assembled a computer from scratch. It even booted on the first attempt! I documented it on Instagram, in my stories, and here are some of the pics, including some of the comments I made on the pics.

Photo of my new case
And so it begins.
Something like 8 power cables from the power supply.
So. Many. Power. Cables.
Power supply installed.
Power supply: check!
Motherboard map.
Honestly, this was the most useful piece of paper.
The spot on the motherboard for the CPU.
The seat for the CPU. This was the most nerve-wracking portion of the whole thing.
Image of the CPU.
More than $400 right here.
CPU in its seat.
Seated!
CPU locked into place with the frame.
Locked in.
Fan installed in the front of the case.
Installed the fan for my CPU cooler.
Container of Arctic Silver thermal paste with the CPU and motherboard in the background.
Okay, this was also terrifying — applying thermal paste to the CPU in preparation to put the cooler on top.
Corsair CPU cooler in place on the motherboard.
Cooler installed!
Power cables plugged into the power supply.
Remember all those power cables? hahaha
Video card seated in motherboard.
Video card in!
Shot of the left side of the case, showing the interior of the computer.
Done!

There were a couple of small issues, though:

a) The case fans weren’t running. I had completely forgotten to hook them up to power. There was this wire coming down in the case with the old four-pin system and I’m like “what does this even connect to??” since it wasn’t terribly obvious, so I’d ignored it. But I knew to hook up the peripheral power cable to the peripheral power source in the power supply and then connect that cable to the four-pin wire. So that wasn’t a big deal. And, it being 1:30am when I finally booted the thing, it was something I could deal with Tuesday.

b) My SSD wasn’t recognized. I’d actually thought this might be an issue. My friend, Andrew, who was on the phone (well, FaceTime Audio) with me for like, 90 minutes on Monday evening) had indicated that he wasn’t sure that was the right slot for the SSD M2 and I looked at my motherboard map (YES THERE WAS A FREAKING MAP) and saw that the other slot was underneath some branded plastic casing. So I kept it in the original slot and figured that if it wasn’t recognized, I’d fix it the next day. Sure enough, wrong slot.

SSD in the wrong M2 slot on the board.
But this ended up being the wrong slot.

So on Tuesday, I connected the power for the fans and then uninstalled the video card, pulled off the casing hiding the M2 slot, moved the SSD there, then reinstalled my video card and crossed my fingers and it booted into the Windows setup (courtesy of my USB key with the Windows installation on it) and it recognized my SSD!

I installed Windows (that was a whole Thing, too, but eventually got resolved) and then started the painful process of copying stuff over. Fun fact: I’m still not done copying and installing things, but the vast majority of important stuff is done. I haven’t yet installed my writing program (Scrivener), don’t think I’ve installed Dropbox, etc, but most of my actual files are copied — creative writing stuff, my programming stuff, photos, other documents… That said, my old computer is still sitting on my dining room table, hooked up to the router via ethernet cable and the drives are shared, so I can just copy as needed.

Overall, it went a LOT better than I thought it would. I also engaged in some light cable management on Saturday, and this is the end result.

Photo of my workspace.
Clean! Sort of!

In terms of the game, I haven’t done a ton of stuff, owing to, you know, computer building and copying stuff over. That said, my dev environment with Docker used to take in excess of 8.5 minutes to boot up on the old computer.

It takes 27 seconds on the new one. Just let that sink in for a sec. Or 27.

But even without that blazing speed, I’m pleased to say that I solved the problem with the password strength script last weekend! The issue was that I was calling the script too early, so I shoved it to the bottom of the form and it worked just fine at that point. Since building the computer, I’ve made some modifications to it and to my own registration validation script, so now I have JavaScript checks for:

  • username length (must be at least 5 characters, no more than 16)
  • username allowable characters (a-zA-Z and 0-9, but can’t start with a number)
  • password1 matching password2 (you know, your typical re-enter to verify password thing)
  • password strength must be at least “good”, as per the password strength check
  • email1 matching email2 (verify your email)

Plus, I have PHP checks for:

  • username uniqueness
  • email uniqueness (this still needs work)
  • spammer/disposable domain emails
  • disallowed usernames (admin and such)
  • profane usernames
  • voluntary blacklist (to prevent people from accidentally getting signed up because how are people so stupid as to not know their own email address? Trust me, this happens to me constantly.)

I also added some styling. Just some basic CSS to make sure the form looks nice as well as making sure error messages are easily shown.

Screenshot of registration screen where the user is asked to input a stronger password.
See? Error messages!
Screenshot of the registration form, Sublime Text 3 and my Docker container log.
Here’s a better pic.

So that’s what’s up with me. I’ve got a four-day weekend this weekend, due to Labour Day on Monday and I also took the Friday off, so it’s been a pretty glorious weekend for me. My living room is a disaster, so my goal tonight is to clean that up and put away all the documentation for all my components, my spare cables, spare screws, etc. Then, while my old computer will still be on my dining room table, at least it won’t be surrounded by an insane amount of empty boxes, ripped plastic bags, electronic cables and screwdrivers and such.

More updates as I make progress in the game, certainly. My next task is to clean up the unique email check and move on to sending out validation emails. And then login stuff! Man, this stuff is really starting to come together and I am psyched, dudes. Psyched.