Public Solving: Generating secure password

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
Search for a command to run...

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
No comments yet. Be the first to comment.
Most of you know me for my consistency, a golden arrow in my blog series. I've written 1000 articles in 1008 days! Almost an article a day, and my honeymoon was the only holiday I ever took. I'm super proud of this achievement; it has been a fantasti...

It's not the first time I'll be talking about community. I think it's an essential aspect of any successful tool. This shows in my previous explorations of Astro, Medusa, and now Vendure as well. All these products thrive in a super open, welcoming, ...

The cool part about Vendure is how easy it is to set up and how abstract each layer is. Basically, we get the following elements: External database Server Worker Admin UI Frontend While this is amazing, it also brings a bit of complexity when it co...

The previous article looked at customizing Vendure on a data and process level. In this article, we'll look at customizing emails, as they are often a big part of a webshop system. We'll be looking at two different layers of customization for customi...

Even though Vendure is a pretty significant project out of the box, in some cases, we might want to go in and modify some elements to work to our specific use case. In this article, I'll take a high-level look at some elements we can customize within...

Santa's head elf is one of those old-school dudes who creates passwords from the top of his head instead of using a password manager.
The board of elves has asked us to create a password generator to help the head elf come up with unique and secure passwords.
And they came to the right place!
You can find the complete puzzle here.
Before we can dive into the solution, let's see what we have to work with.
There are two parameters the function should take:
The options are as follows:
lowercase: Lowercase letters (a-z)uppercase: Uppercase letters (A-Z)numbers: Numbers (0-9)specialCharacters: Special characters (only !@#$%^&*())Knowing this, we should be able to help the elves.
Two side notes are essential and will help us:
Alright, let's get right into it.
The first thing I did, check the two errors we should throw.
Since the options are an object, and we want to check the length, I've converted it with Object.keys.
This will convert it into an array.
const optionKeys = Object.keys(options);
if (!optionKeys.length) throw Error('NOT_ENOUGH_OPTIONS');
if (length < optionKeys.length) throw Error('PASSWORD_TOO_SHORT');
That will make sure the errors are thrown when needed.
Then I've decided to create a new object with the option values.
const optionValues = {
lowercase: 'abcdefghijklmnopqrstuvwxyz',
numbers: '0123456789',
specialCharacters: '!@#$%^&*()',
get uppercase() {
return this.lowercase.toUpperCase();
},
};
You can see all the alphabetic characters defined in the lowercase property, all numbers, and the special characters. For the uppercase version, I've decided to use a function to leverage our existing input.
Note: The keys here match the option keys we should support.
Since we want to mix a random password with the options, I want to loop over each option and get a random number from that option.
We can check the main password length with a basic while loop like so.
let password = '';
while (password.length < length) {
// password += 'SOMETHING';
}
This will loop until the length of the password is long enough.
As mentioned above, I want to use an equal number of options for each password.
So I've decided to use a for...of loop. I've chosen this particular loop because we can break out of it.
We need to break out of it because we could push too many letters.
For example, we want to generate a 3 character password with 2 options. The while loop will fire 2 times, and the options will loop 2 times as well, meaning we get a 4 character password.
while (password.length < length) {
for (let option of optionKeys) {
if (password.length >= length) break;
// Add a character
}
}
As you can see, I break the loop if we hit the length inside the for loop.
Now we just need to grab a random character for the current looped option and add it to the password.
password += optionValues[option][Math.floor(Math.random() * optionValues[option].length)];
Some things to note:
Math.floor(Math.random() * optionValues[option].length) picks a random item from the current option arrayWith this in place we finished our function, so it looks like this:
export const generatePassword = (length, options = {}) => {
const optionKeys = Object.keys(options);
if (!optionKeys.length) throw Error('NOT_ENOUGH_OPTIONS');
if (length < optionKeys.length) throw Error('PASSWORD_TOO_SHORT');
let password = '';
while (password.length < length) {
for (let option of optionKeys) {
if (password.length >= length) break;
password += optionValues[option][Math.floor(Math.random() * optionValues[option].length)];
}
}
return password;
};
One last thing, the test should turn green.

And yes, we did it!
I'm always looking forward to hearing what you would have done differently and why.
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter