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:
- 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.
- 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.
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.