A basic plugin that can do scoring
of password strength as a user types within an input field.
See it live in action on this jsfiddle here or this one.
Get MooTools (1.4.5+, ideally 1.5.1). No mootools-more required. Have a password field and some CSS.
<input type="password" id="foo" />
div.pass-container {
height: 30px;
}
div.pass-bar {
height: 11px;
margin-top: 2px;
}
div.pass-hint {
font-family: arial;
font-size: 11px;
}
Create your instance
new StrongPass("foo", {
onReady: function() {
console.log('you can begin typing');
},
onPass: function(score, verdict) {
console.log('pass', score, verdict)
},
onFail: function(score, verdict) {
console.log('fail', score, verdict);
},
onBanned: function(word) {
console.warn(word, 'is not allowed as it is on the bannedPasswords list');
}
});
Alternatively, you can just use it as a tool to check and feed back scores without output - so you can script your own via the events instead.
var indicator = document.getElement('span.pwStrengthResult'),
colourIndicate = function(level, label) {
indicator.set({
html: label,
styles: {
color: this.options.colors[level] || this.options.colors.getLast()
}
})
}
new StrongPass('foo', {
bannedPass: 'Very weak (too common)',
verdicts: [
'Too Short',
'Weak',
'Good',
'Strong'
],
colors: [
'#777',
'#900',
'#070',
'#0c0'
],
// tweak scores here
scores: [
10,
30,
40,
100
],
render: false,
onPass: function() {
colourIndicate.apply(this, arguments);
},
onFail: function() {
colourIndicate.apply(this, arguments);
}
});
A series of tests and definitions dictate the total scoring
of the string in the input (or an arbitrary string) as a password. Certain logic is applied to do with best practices that helps in the scoring. In terms of configuration of how lax the plugin is, you can use several things.
options
- can setscores
as ranges that map to verdicts. In the example above, anything scoring below 10 will be deemedToo short
, between 10 and 30 -Weak
and so forth. By upping these values, you can make it more demanding - or less demanding, dependent on what your users are like.length
- there are some extra bonuses added for each extra character over the minimum length as the longer a password is, the more time it will take to brute force. The values added here are somewhat arbitrary but you can edit thecheckPassword
method and set your own values.regex scoring
- the class has a static array of simple objects that looks like this:
checks: [
/* alphaLower */ {
re: /[a-z]/,
score: 1
},
/* alphaUpper */ {
re: /[A-Z]/,
score: 5
},
/* mixture of upper and lowercase */ {
re: /([a-z].*[A-Z])|([A-Z].*[a-z])/,
score: 2
},
/* threeNumbers */ {
re: /(.*[0-9].*[0-9].*[0-9])/,
score: 7
},
/* special chars */ {
re: /.[!@#$%^&*?_~]/,
score: 5
},
/* multiple special chars */ {
re: /(.*[!@#$%^&*?_~].*[!@#$%^&*?_~])/,
score: 7
},
/* all together now, does it look nice? */ {
re: /([a-zA-Z0-9].*[!@#$%^&*?_~])|([!@#$%^&*?_~].*[a-zA-Z0-9])/,
score: 3
},
/* password of a single repeated char sucks */ {
re: /(.)\1+$/,
score: 2
}
],
You can add / push to this array to add further changes or you can edit the regex or the scoring applied. A score can also be negative. For instance, we add 2
bonus points if the password has more than 1 letter so it's not just something like aaaaaa
to make it pass. This is a 'positive' score that awards variety but you can easily reverse the check and the result of the regex to a penalising one by doing:
/* password of a single char sucks A LOT */ {
re: /^(.)\1+$/,
score: -20
}
Via Buster.js, go to test/index.html
to run.
You can also test via node and Grunt. To install buster:
$ npm install -g buster phantomjs
To install locally:
$ npm install
To test, either of these works (via PhantomJS):
$ npm test
$ grunt
To start in capture mode for multiple browsers:
$ buster-server &
Once you have captured your target browsers, just run:
$ open http://localhost:1111/capture
$ buster-test -r specification
You can now just use RequireJS or Almond or similar to load the Class:
require(['js/StrongPass'], function(StrongPass){
new StrongPass({});
});
// or mixin / extend and do your own
define(['js/StrongPass'], function(StrongPass){
return new Class({
Extends: StrongPass,
});
});
If an AMD compatible define
is found, it will be preferred to global object.
Licensed under the MIT License. You are not allowed to use for evil