Skip to content

Instantly share code, notes, and snippets.

@ajmas
Last active February 2, 2017 18:54
Show Gist options
  • Save ajmas/8d862358ab902d6e77f7fcae5d63da3e to your computer and use it in GitHub Desktop.
Save ajmas/8d862358ab902d6e77f7fcae5d63da3e to your computer and use it in GitHub Desktop.
Configurable Password Checker
// This version work on simply checking something that fails a rule, though
// it may be useful to check based on estimated password strength. For this
// each function would return a value indicating strength. This value could
// be positive or negative. For example, a string longer than 16 characters
// could get a rating of +5, but being digit only get a -5. Other methods
// could simply return 0/+1.
var ruleFunctions = {
duplicateChars: function(password, min) {
var prevChar, i;
var dupCount = 1;
var duplicates = false;
for (i=0; i < password.length; i++) {
if (password.charAt(i) === prevChar) {
dupCount++;
if (dupCount >= (min||2)) {
duplicates = true;
break;
}
} else {
prevChar = password.charAt(i);
dupCount = 1;
}
}
if (duplicates) {
throw 'DUPLICATE_CHARS';
}
},
requiresDigit: function(password) {
var result = password.match(/[0-9]/);
if (!result || result === null) {
throw 'REQUIRES_DIGIT'
}
},
requiresRomanCharacter: function(password) {
password = password.toLowerCase();
var result = password.match(/[a-z]/);
if (!result || result === null) {
throw 'REQUIRES_LETTER'
}
},
requiresRomanUppercase: function(password) {
var result = password.match(/[A-Z]/);
if (!result || result === null) {
throw 'REQUIRES_UPPERCASE'
}
},
requiresRomanLowercase: function(password) {
var result = password.match(/[a-z]/);
if (!result || result === null) {
throw 'REQUIRES_LOWERCASE'
}
},
notDigitsOnly: function(password) {
var result = password.match(/^[0-9]+$/);
if (result) {
throw 'REQUIRES_NON_DIGITS'
}
},
tooShort: function() {
throw 'TOO_SHORT';
}
};
var rules = [
{ min: 0,
max: 8,
rules:['tooShort']
}, {
min: 9,
max: 16,
rules: [['duplicateChars', 3], 'requiresDigit', 'requiresRomanCharacter',
'requiresRomanUppercase', 'requiresRomanLowercase']
}, {
min: 17,
rules: [['duplicateChars', 3], 'notDigitsOnly']
}
];
function getRules(passwordLength) {
var i;
for (i = 0; i < rules.length; i++) {
if (passwordLength >= rules[i].min) {
if (rules[i].max && passwordLength <= rules[i].max) {
// if no max, max sure it less than
return rules[i].rules;
} else if (rules[i].max === undefined) {
// if no max just return current entry
return rules[i].rules;
}
}
}
}
function validatePassword(password) {
password = password.normalize();
var rules = getRules(password.length);
// TODO limit checks to
for (i = 0; i < rules.length; i++) {
var rule = rules[i];
if (Array.isArray(rule)) {
ruleFunctions[rule[0]](password, rule[1]);
}
else {
ruleFunctions[rule](password);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment