mirror of
https://github.com/sigmasternchen/jsPasswordChecker
synced 2025-03-16 00:08:55 +00:00
first commit
This commit is contained in:
parent
3fbc53effb
commit
8cabeb55dc
3 changed files with 372 additions and 0 deletions
82
jsPasswordChecker.js
Normal file
82
jsPasswordChecker.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
console.log("jsPasswordChecker");
|
||||
|
||||
var PasswordChecker = function(policies) {
|
||||
this.policies = policies;
|
||||
}
|
||||
|
||||
PasswordChecker.prototype.policies;
|
||||
|
||||
PasswordChecker.prototype.check = function(password) {
|
||||
if (this.policies.minLength !== undefined)
|
||||
this.checkMinLength(password);
|
||||
if (this.policies.maxLength !== undefined)
|
||||
this.checkMaxLength(password);
|
||||
if (this.policies.containsNumbers !== undefined)
|
||||
this.checkContains(password, this.policies.containsNumbers, /[0-9]/g, "numbers");
|
||||
if (this.policies.containsLowerCaseLetters !== undefined)
|
||||
this.checkContains(password, this.policies.containsLowerCaseLetters, /[a-z]/g, "lowercase characters");
|
||||
if (this.policies.containsUpperCaseLetters !== undefined)
|
||||
this.checkContains(password, this.policies.containsUpperCaseLetters, /[A-Z]/g, "uppercase characters");
|
||||
if (this.policies.containsWhiteSpaces !== undefined)
|
||||
this.checkContains(password, this.policies.containsWhiteSpaces, /\s/g, "whitespaces");
|
||||
if (this.policies.containsSpecialCharacters !== undefined)
|
||||
this.checkContains(password, this.policies.containsSpecialCharacters, /[^a-zA-Z\d\s]/g, "special characters");
|
||||
|
||||
if (this.policies.dictionary !== undefined)
|
||||
this.checkDictionary(password);
|
||||
if (this.policies.maxCharacterRepetition !== undefined)
|
||||
this.checkCharacterRepetition(password);
|
||||
}
|
||||
|
||||
PasswordChecker.prototype.checkMinLength = function(password) {
|
||||
if (password.length < this.policies.minLength)
|
||||
throw "Password is too short.";
|
||||
}
|
||||
|
||||
PasswordChecker.prototype.checkMaxLength = function(password) {
|
||||
if (password.length > this.policies.maxLength)
|
||||
throw "Password is too long.";
|
||||
}
|
||||
|
||||
PasswordChecker.prototype.checkContains = function(password, attribute, regex, name) {
|
||||
var contains = password.match(regex);
|
||||
if (attribute === true && contains === null)
|
||||
throw "Password does not contain " + name + ".";
|
||||
if (attribute === false && contains !== null)
|
||||
throw "Password does contain " + name + ".";
|
||||
if (typeof attribute === "number" && attribute > contains.length)
|
||||
throw "Password contains too few " + name + ".";
|
||||
}
|
||||
|
||||
PasswordChecker.prototype.checkDictionary = function(password) {
|
||||
var dictionary = this.policies.dictionary;
|
||||
if (typeof dictionary !== "object") // array
|
||||
dictionary = [dictionary];
|
||||
|
||||
for (var i = 0; i < dictionary.length; i++) {
|
||||
if (password.toLowerCase().indexOf(dictionary[i].toLowerCase()) >= 0)
|
||||
throw "Password contains " + dictionary[i].toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
PasswordChecker.prototype.checkCharacterRepetition = function(password) {
|
||||
var repitition = this.policies.maxCharacterRepetition;
|
||||
|
||||
if (password.length > 0 && repitition <= 1)
|
||||
return; // policies don't make any sense
|
||||
|
||||
var currentChar = password.charAt(0);
|
||||
var currentRepitition = 1;
|
||||
|
||||
for (var i = 1; i < password.length; i++) {
|
||||
var tmp = password.charAt(i);
|
||||
if (tmp === currentChar) {
|
||||
currentRepitition++;
|
||||
if (currentRepitition > repitition)
|
||||
throw "The password contains to many identical characters in a row.";
|
||||
} else {
|
||||
currentChar = tmp;
|
||||
currentRepitition = 1;
|
||||
}
|
||||
}
|
||||
}
|
39
test.html
Normal file
39
test.html
Normal file
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<script src="jsPasswordChecker.js"></script>
|
||||
<script src="testcases.js"></script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
for (var i = 0; i < testcases.length; i++) {
|
||||
var testcase = testcases[i];
|
||||
|
||||
var checker = new PasswordChecker(testcase.policies);
|
||||
|
||||
var result = true;
|
||||
var error = "success";
|
||||
try {
|
||||
checker.check(testcase.password);
|
||||
} catch (e) {
|
||||
result = false;
|
||||
error = e;
|
||||
}
|
||||
|
||||
var el = document.createElement("div");
|
||||
el.innerHTML = "Test Case " + i + " "
|
||||
if (result != testcase.result) {
|
||||
el.style.color = "red";
|
||||
el.innerHTML += "failed (" + result + "; " + testcase.result + " expected)<br />";
|
||||
el.innerHTML += " Password: " + testcase.password + "; Policies: " + testcase.policies + "; result: " + error;
|
||||
} else {
|
||||
el.style.color = "green";
|
||||
el.innerHTML += "was successful.<br />";
|
||||
el.innerHTML += " Password: " + testcase.password + "; Policies: " + testcase.policies + "; result: " + error;
|
||||
}
|
||||
|
||||
document.body.appendChild(el);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
251
testcases.js
Normal file
251
testcases.js
Normal file
|
@ -0,0 +1,251 @@
|
|||
console.log("testcases.js");
|
||||
|
||||
var testcases = [
|
||||
{
|
||||
password: "test",
|
||||
policies: {
|
||||
minLength: 8
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "testtest",
|
||||
policies: {
|
||||
minLength: 8
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
maxLength: 8
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "testtest",
|
||||
policies: {
|
||||
maxLength: 7
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsNumbers: true
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsNumbers: false
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "test1",
|
||||
policies: {
|
||||
containsNumbers: true
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "test1",
|
||||
policies: {
|
||||
containsNumbers: false
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test1",
|
||||
policies: {
|
||||
containsNumbers: 2
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test11",
|
||||
policies: {
|
||||
containsNumbers: 2
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsLowerCaseLetters: true
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsLowerCaseLetters: false
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "TEST",
|
||||
policies: {
|
||||
containsLowerCaseLetters: true
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "TEST",
|
||||
policies: {
|
||||
containsLowerCaseLetters: false
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "tesT",
|
||||
policies: {
|
||||
containsUpperCaseLetters: true
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "tesT",
|
||||
policies: {
|
||||
containsUpperCaseLetters: false
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsUpperCaseLetters: true
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsUpperCaseLetters: false
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsSpecialCharacters: true
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsSpecialCharacters: false
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "test&",
|
||||
policies: {
|
||||
containsSpecialCharacters: true
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "test&",
|
||||
policies: {
|
||||
containsSpecialCharacters: false
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsWhiteSpaces: true
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "test",
|
||||
policies: {
|
||||
containsWhiteSpaces: false
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "te st",
|
||||
policies: {
|
||||
containsWhiteSpaces: true
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "te st",
|
||||
policies: {
|
||||
containsWhiteSpaces: false
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "teest",
|
||||
policies: {
|
||||
maxCharacterRepetition: 2
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "teeest",
|
||||
policies: {
|
||||
maxCharacterRepetition: 2
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "testUserName",
|
||||
policies: {
|
||||
dictionary: [
|
||||
"UserName"
|
||||
]
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "testUseName",
|
||||
policies: {
|
||||
dictionary: [
|
||||
"UserName"
|
||||
]
|
||||
},
|
||||
result: true
|
||||
},
|
||||
|
||||
{
|
||||
password: "RealyG00d&Password",
|
||||
policies: {
|
||||
minLength: 10,
|
||||
containsLowerCaseLetters: true,
|
||||
containsUpperCaseLetters: true,
|
||||
containsNumbers: true,
|
||||
containsSpecialCharacters: true,
|
||||
maxCharacterRepetition: 2,
|
||||
dictionary: [
|
||||
"username",
|
||||
"1994"
|
||||
]
|
||||
},
|
||||
result: true
|
||||
},{
|
||||
password: "NotSoG00d&Password1994",
|
||||
policies: {
|
||||
minLength: 10,
|
||||
containsLowerCaseLetters: true,
|
||||
containsUpperCaseLetters: true,
|
||||
containsNumbers: true,
|
||||
containsSpecialCharacters: true,
|
||||
maxCharacterRepetition: 2,
|
||||
dictionary: [
|
||||
"username",
|
||||
"1994"
|
||||
]
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "NotSoG000d&Password",
|
||||
policies: {
|
||||
minLength: 10,
|
||||
containsLowerCaseLetters: true,
|
||||
containsUpperCaseLetters: true,
|
||||
containsNumbers: true,
|
||||
containsSpecialCharacters: true,
|
||||
maxCharacterRepetition: 2,
|
||||
dictionary: [
|
||||
"username",
|
||||
"1994"
|
||||
]
|
||||
},
|
||||
result: false
|
||||
},{
|
||||
password: "NotSoG00dPassword",
|
||||
policies: {
|
||||
minLength: 10,
|
||||
containsLowerCaseLetters: true,
|
||||
containsUpperCaseLetters: true,
|
||||
containsNumbers: true,
|
||||
containsSpecialCharacters: true,
|
||||
maxCharacterRepetition: 2,
|
||||
dictionary: [
|
||||
"username",
|
||||
"1994"
|
||||
]
|
||||
},
|
||||
result: false
|
||||
}
|
||||
]
|
Loading…
Reference in a new issue