Skip to content
This repository was archived by the owner on Feb 20, 2019. It is now read-only.

Commit e4f1b7f

Browse files
RobAnthony01Kent C. Dodds
authored and
Kent C. Dodds
committed
feat(generatePassword): Add generatePassword function with tests (#175)
1 parent daf8b4e commit e4f1b7f

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

src/generate-password.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
export default generatePassword
2+
3+
/**
4+
* Original source: https://stackoverflow.com/questions/12635652/generate-a-secure-password-in-javascript
5+
* This function would generate a password
6+
* it is a modified copy
7+
* @param {int}len - The minimum length of the returned password
8+
* @param {int}capitals - The number of characters which must be capitalised
9+
* @param {int}lowercases - The number of characters which must be lowercase
10+
* @param {int}specials - the number of characters which must be special characters
11+
* @param {int}digits - The number of characters which must be digits
12+
* @return {string} - The randomised password
13+
**/
14+
function generatePassword(len = 8, capitals = 1, lowercases = 1, specials = 1, digits = 1) {
15+
let password = ''
16+
const specialChars = '!@#$%^&*()_+{}:"<>?\\|[];\',./`~'
17+
const lowercaseChars = 'abcdefghijklmnopqrstuvwxyz'
18+
const uppercaseChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
19+
const digitChars = '0123456789'
20+
21+
const allChars = specialChars + lowercaseChars + uppercaseChars + digitChars
22+
23+
password += pick(specialChars, specials)
24+
password += pick(lowercaseChars, lowercases)
25+
password += pick(uppercaseChars, capitals)
26+
password += pick(digitChars, digits)
27+
password += pick(allChars, Math.max(len - capitals - lowercases - specials - digits, 0))
28+
password = shuffle(password)
29+
30+
return password
31+
}
32+
33+
function pick(characterList, count) {
34+
let chars = ''
35+
for (let i = 0; i < count; i++) {
36+
chars += characterList.charAt(Math.floor(Math.random() * characterList.length))
37+
}
38+
39+
return chars
40+
}
41+
42+
// Credit to @Christoph: http://stackoverflow.com/a/962890/464744
43+
function shuffle(str) {
44+
const array = str.split('')
45+
let tmp, current
46+
let top = array.length
47+
48+
if (top) {
49+
while (--top) {
50+
current = Math.floor(Math.random() * (top + 1))
51+
tmp = array[current]
52+
array[current] = array[top]
53+
array[top] = tmp
54+
}
55+
}
56+
57+
return array.join('')
58+
}

src/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import removeAccents from './remove-accents'
6262
import getQueryStringValue from './get-query-string-value'
6363
import isLeapYear from './leap-year'
6464
import removeElementFromArray from './removeElementFromArray'
65+
import generatePassword from './generate-password'
6566

6667
export {
6768
reverseArrayInPlace,
@@ -128,4 +129,5 @@ export {
128129
lessThan,
129130
isLeapYear,
130131
removeElementFromArray,
132+
generatePassword,
131133
}

test/generate-password.test.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import test from 'ava'
2+
import {generatePassword} from '../src'
3+
4+
test('returns a string', t => {
5+
const expected = 'string'
6+
const actual = typeof generatePassword(10)
7+
t.deepEqual(actual, expected)
8+
})
9+
10+
test('returns an empty string', t => {
11+
const expected = ''
12+
const actual = generatePassword(0, 0, 0, 0, 0)
13+
t.deepEqual(actual, expected)
14+
})
15+
16+
test('Returns a password of the correct length', t => {
17+
const expected = 10
18+
const actual = generatePassword(10).length
19+
t.deepEqual(actual, expected)
20+
})
21+
22+
test('Returns a password of the default length', t => {
23+
const expected = 8
24+
const actual = generatePassword().length
25+
t.deepEqual(actual, expected)
26+
})
27+
28+
test('Returns a password with CAPITALS', t => {
29+
const expected = 'X'
30+
const regex = /[A-Z]{10}/
31+
const actual = generatePassword(10, 10, 0, 0, 0).replace(regex, 'X')
32+
t.deepEqual(actual, expected)
33+
})
34+
35+
test('Returns a password with lowercase', t => {
36+
const expected = 'X'
37+
const regex = /[a-z]{10}/
38+
const actual = generatePassword(10, 0, 10, 0, 0).replace(regex, 'X')
39+
t.deepEqual(actual, expected)
40+
})
41+
42+
test('Returns a password with digits', t => {
43+
const expected = 'X'
44+
const regex = /[0-9]{10}/
45+
const actual = generatePassword(10, 0, 0, 0, 10).replace(regex, 'X')
46+
t.deepEqual(actual, expected)
47+
})
48+
49+
test('Returns a password with specialchars', t => {
50+
const expected = 'X'
51+
const regex = /[!@#$%^&*()_+{}:"<>?\\|\[\];',./`~]{10}/
52+
const actual = generatePassword(10, 0, 0, 10, 0).replace(regex, 'X')
53+
t.deepEqual(actual, expected)
54+
})

0 commit comments

Comments
 (0)