#95 Swapped mellt code for zxcvbn code

master
Keith Irwin 2017-06-30 13:14:59 -04:00
parent 6126e6210b
commit 72b91da74e
No known key found for this signature in database
GPG Key ID: 378933C743E2BBC0
15 changed files with 2042 additions and 1107 deletions

View File

@ -296,9 +296,9 @@ router.route('/password/:token')
.post( (req,res,next)=>{
// Validate password
let daysToCrack = mellt.CheckPassword(req.body.password);
if (daysToCrack<10) {
mw.throwErr(new Error(`That password could be cracked in ${daysToCrack} days! Come up with a more complex password that would take at least 10 days to crack. `));
let zxcvbnResult = zxcvbn(req.body.password);
if (zxcvbnResult.crack_times_seconds.online_no_throttling_10_per_second < 864000) { // Less than ten days
mw.throwErr(new Error(`That password could be cracked in ${zxcvbnResult.crack_times_display.online_no_throttling_10_per_second}! Come up with a more complex password that would take at least 10 days to crack. `));
res.redirect(`/settings/password/${req.params.token}`);
}

View File

@ -29,9 +29,9 @@ router
res.render('password');
})
.post('/password', (req,res,next)=>{
let daysToCrack = mellt.CheckPassword(req.body.password);
if (daysToCrack<10) {
let err = new Error(`That password could be cracked in ${daysToCrack} days! Come up with a more complex password that would take at least 10 days to crack. `);
let zxcvbnResult = zxcvbn(req.body.password);
if (zxcvbnResult.crack_times_seconds.online_no_throttling_10_per_second < 864000) { // Less than ten days
let err = new Error(`That password could be cracked in ${zxcvbnResult.crack_times_display.online_no_throttling_10_per_second}! Come up with a more complex password that would take at least 10 days to crack. `);
mw.throwErr(err,req);
next(err);
}

File diff suppressed because one or more lines are too long

View File

@ -60,12 +60,12 @@
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 52);
/******/ return __webpack_require__(__webpack_require__.s = 53);
/******/ })
/************************************************************************/
/******/ ({
/***/ 52:
/***/ 53:
/***/ (function(module, exports, __webpack_require__) {
"use strict";

View File

@ -60,12 +60,12 @@
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 22);
/******/ return __webpack_require__(__webpack_require__.s = 23);
/******/ })
/************************************************************************/
/******/ ({
/***/ 22:
/***/ 23:
/***/ (function(module, exports, __webpack_require__) {
"use strict";

View File

@ -60,12 +60,12 @@
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 21);
/******/ return __webpack_require__(__webpack_require__.s = 22);
/******/ })
/************************************************************************/
/******/ ({
/***/ 21:
/***/ 22:
/***/ (function(module, exports, __webpack_require__) {
"use strict";

770
static/js/dist/map.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,285 +0,0 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 55);
/******/ })
/************************************************************************/
/******/ ({
/***/ 55:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Mellt
*
* Tests the strength of a password by calculating how long it would take to
* brute force it.
*
* @version 0.1.0
* @link http://mel.lt/ The homepage for this script.
* @link http://www.hammerofgod.com/passwordcheck.aspx Much of this is based
* on the description of Thor's Godly Privacy password strength checker,
* however the actual code below is all my own.
* @link http://xato.net/passwords/more-top-worst-passwords/ The included
* common passwords list is from Mark Burnett's password collection (which
* is excellent). You can of course use your own password file instead.
*/
var Mellt = function() {
/**
* @var integer HashesPerSecond The number of attempts per second you expect
* an attacker to be able to attempt. Set to 1 billion by default.
*/
this.HashesPerSecond = 1000000000;
/**
* @var string CommonPasswords A variable containing an array of common
* passwords to check against. If you include common-passwords.js in your
* HTML after including Mellt.js, the contents of that file will be used
* if this isn't set.
* Set this to null (and don't include common-passwords.js) to skip
* checking common passwords.
*/
this.CommonPasswords = null;
/**
* @var array $CharacterSets An array of strings, each string containing a
* character set. These should proceed in the order of simplest (0-9) to most
* complex (all characters). More complex = more characters.
*/
this.CharacterSets = [
// We're making some guesses here about human nature (again much of this is
// based on the TGP password strength checker, and Timothy "Thor" Mullen
// deserves the credit for the thinking behind this). Basically we're combining
// what we know about users (SHIFT+numbers are more common than other
// punctuation for example) combined with how an attacker will attack a
// password (most common letters first, expanding outwards).
//
// If you want to support passwords that use non-english characters, and
// your attacker knows this (for example, a Russian site would be expected
// to contain passwords in Russian characters) add your characters to one of
// the sets below, or create new sets and insert them in the right places.
"0123456789",
"abcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyz0123456789",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+[]\"{}|;':,./<>?`~"
];
};
Mellt.prototype = {
CommonPasswords: null,
/**
* Tests password strength by simulating how long it would take a cracker to
* brute force your password.
*
* Also optionally tests against a list of common passwords (contained in an
* external file) to weed out things like "password", which from a pure brute
* force perspective would be harder to break if it wasn't so common.
*
* The character sets being used in this checker assume English (ASCII)
* characters (no umlauts for example). If you run a non-english site, and you
* suspect the crackers will realize this, you may want to modify the
* character set to include the characters in your language.
*
* @param string $password The password to test the strength of
* @return integer Returns an integer specifying how many days it would take
* to brute force the password (at 1 billion checks a second) or -1 to
* indicate the password was found in the common passwords file. Obviously if
* they don't have direct access to the hashed passwords this time would be
* longer, and even then most computers (at the time of this writing) won't be
* able to test 1 billion hashes a second, but this function measures worst
* case scenario, so... I would recommend you require at least 30 days to brute
* force a password, obviously more if you're a bank or other secure system.
* @throws Exception If an error is encountered.
*/
CheckPassword: function(password) {
// First check passwords in the common password file if available.
// We do this because "password" takes 129 seconds, but is the first
// thing an attacker will try.
if (!this.CommonPasswords && Mellt.prototype.CommonPasswords) {
this.CommonPasswords = Mellt.prototype.CommonPasswords;
}
if (this.CommonPasswords) {
var text = password.toLowerCase();
for (var t=0; t<this.CommonPasswords.length; t++) {
if (this.CommonPasswords[t]==text) {
// If their password exists in the common file, then it's
// zero time to crack this terrible password.
return -1;
}
}
}
// Figure out which character set the password is using (based on the most
// "complex" character in it).
var base = '';
var baseKey = null;
for (var t=0; t<password.length; t++) {
var char = password[t];
var foundChar = false;
for (var characterSetKey=0; characterSetKey<this.CharacterSets.length; characterSetKey++) {
var characterSet = this.CharacterSets[characterSetKey];
if (baseKey<=characterSetKey && characterSet.indexOf(char)>-1) {
baseKey = characterSetKey;
base = characterSet;
foundChar = true;
break;
}
}
// If the character we were looking for wasn't anywhere in any of the
// character sets, assign the largest (last) character set as default.
if (!foundChar) {
base = this.CharacterSets[this.CharacterSets.length-1];
break;
}
}
// Starting at the first character, figure out it's position in the character set
// and how many attempts will take to get there. For example, say your password
// was an integer (a bank card PIN number for example):
// 0 (or 0000 if you prefer) would be the very first password they attempted by the attacker.
// 9999 would be the last password they attempted (assuming 4 characters).
// Thus a password/PIN of 6529 would take 6529 attempts until the attacker found
// the proper combination. The same logic words for alphanumeric passwords, just
// with a larger number of possibilities for each position in the password. The
// key thing to note is the attacker doesn't need to test the entire range (every
// possible combination of all characters) they just need to get to the point in
// the list of possibilities that is your password. They can (in this example)
// ignore anything between 6530 and 9999. Using this logic, 'aaa' would be a worse
// password than 'zzz', because the attacker would encounter 'aaa' first.
var attempts = 0;
var charactersInBase = base.length;
var charactersInPassword = password.length;
for (var position=0; position<charactersInPassword; position++) {
// We power up to the reverse position in the string. For example, if we're trying
// to hack the 4 character PING code in the example above:
// First number * (number of characters possible in the charset ^ length of password)
// ie: 6 * (10^4) = 6000
// then add that same equation for the second number:
// 5 * (10^3) = 500
// then the third numbers
// 2 * (10^2) = 20
// and add on the last number
// 9
// Totals: 6000 + 500 + 20 + 9 = 6529 attempts before we encounter the correct password.
var powerOf = charactersInPassword - position - 1;
// Character position within the base set. We add one on because strpos is base
// 0, we want base 1.
var charAtPosition = base.indexOf(password[position])+1;
// If we're at the last character, simply add it's position in the character set
// this would be the "9" in the pin code example above.
if (powerOf==0) {
attempts = attempts + charAtPosition;
}
// Otherwise we need to iterate through all the other characters positions to
// get here. For example, to find the 5 in 25 we can't just guess 2 and then 5
// (even though Hollywood seems to insist this is possible), we need to try 0,1,
// 2,3...15,16,17...23,24,25 (got it).
else {
// This means we have to try every combination of values up to this point for
// all previous characters. Which means we need to iterate through the entire
// character set, X times, where X is our position -1. Then we need to multiply
// that by this character's position.
// Multiplier is the (10^4) or (10^3), etc in the pin code example above.
var multiplier = Math.pow(charactersInBase,powerOf);
// New attempts is the number of attempts we're adding for this position.
var newAttempts = charAtPosition * multiplier;
// Add that on to our existing number of attempts.
attempts = attempts + newAttempts;
}
}
// We can (worst case) try a billion passwords a second. Calculate how many days it
// will take us to get to the password.
var perDay = this.HashesPerSecond*60*60*24;
// This allows us to calculate a number of days to crack. We use days because anything
// that can be cracked in less than a day is basically useless, so there's no point in
// having a smaller granularity (hours for example).
var days = attempts / perDay;
// If it's going to take more than a billion days to crack, just return a billion. This
// helps when code outside this function isn't using bcmath. Besides, if the password
// can survive 2.7 million years it's probably ok.
if (days>1000000000) {
return 1000000000;
}
return Math.round(days);
}
};
/***/ })
/******/ });

File diff suppressed because one or more lines are too long

View File

@ -60,12 +60,12 @@
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 53);
/******/ return __webpack_require__(__webpack_require__.s = 54);
/******/ })
/************************************************************************/
/******/ ({
/***/ 53:
/***/ 54:
/***/ (function(module, exports, __webpack_require__) {
"use strict";

File diff suppressed because one or more lines are too long

View File

@ -1,209 +0,0 @@
'use strict';
/**
* Mellt
*
* Tests the strength of a password by calculating how long it would take to
* brute force it.
*
* @version 0.1.0
* @link http://mel.lt/ The homepage for this script.
* @link http://www.hammerofgod.com/passwordcheck.aspx Much of this is based
* on the description of Thor's Godly Privacy password strength checker,
* however the actual code below is all my own.
* @link http://xato.net/passwords/more-top-worst-passwords/ The included
* common passwords list is from Mark Burnett's password collection (which
* is excellent). You can of course use your own password file instead.
*/
var Mellt = function() {
/**
* @var integer HashesPerSecond The number of attempts per second you expect
* an attacker to be able to attempt. Set to 1 billion by default.
*/
this.HashesPerSecond = 1000000000;
/**
* @var string CommonPasswords A variable containing an array of common
* passwords to check against. If you include common-passwords.js in your
* HTML after including Mellt.js, the contents of that file will be used
* if this isn't set.
* Set this to null (and don't include common-passwords.js) to skip
* checking common passwords.
*/
this.CommonPasswords = null;
/**
* @var array $CharacterSets An array of strings, each string containing a
* character set. These should proceed in the order of simplest (0-9) to most
* complex (all characters). More complex = more characters.
*/
this.CharacterSets = [
// We're making some guesses here about human nature (again much of this is
// based on the TGP password strength checker, and Timothy "Thor" Mullen
// deserves the credit for the thinking behind this). Basically we're combining
// what we know about users (SHIFT+numbers are more common than other
// punctuation for example) combined with how an attacker will attack a
// password (most common letters first, expanding outwards).
//
// If you want to support passwords that use non-english characters, and
// your attacker knows this (for example, a Russian site would be expected
// to contain passwords in Russian characters) add your characters to one of
// the sets below, or create new sets and insert them in the right places.
"0123456789",
"abcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyz0123456789",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+[]\"{}|;':,./<>?`~"
];
};
Mellt.prototype = {
CommonPasswords: null,
/**
* Tests password strength by simulating how long it would take a cracker to
* brute force your password.
*
* Also optionally tests against a list of common passwords (contained in an
* external file) to weed out things like "password", which from a pure brute
* force perspective would be harder to break if it wasn't so common.
*
* The character sets being used in this checker assume English (ASCII)
* characters (no umlauts for example). If you run a non-english site, and you
* suspect the crackers will realize this, you may want to modify the
* character set to include the characters in your language.
*
* @param string $password The password to test the strength of
* @return integer Returns an integer specifying how many days it would take
* to brute force the password (at 1 billion checks a second) or -1 to
* indicate the password was found in the common passwords file. Obviously if
* they don't have direct access to the hashed passwords this time would be
* longer, and even then most computers (at the time of this writing) won't be
* able to test 1 billion hashes a second, but this function measures worst
* case scenario, so... I would recommend you require at least 30 days to brute
* force a password, obviously more if you're a bank or other secure system.
* @throws Exception If an error is encountered.
*/
CheckPassword: function(password) {
// First check passwords in the common password file if available.
// We do this because "password" takes 129 seconds, but is the first
// thing an attacker will try.
if (!this.CommonPasswords && Mellt.prototype.CommonPasswords) {
this.CommonPasswords = Mellt.prototype.CommonPasswords;
}
if (this.CommonPasswords) {
var text = password.toLowerCase();
for (var t=0; t<this.CommonPasswords.length; t++) {
if (this.CommonPasswords[t]==text) {
// If their password exists in the common file, then it's
// zero time to crack this terrible password.
return -1;
}
}
}
// Figure out which character set the password is using (based on the most
// "complex" character in it).
var base = '';
var baseKey = null;
for (var t=0; t<password.length; t++) {
var char = password[t];
var foundChar = false;
for (var characterSetKey=0; characterSetKey<this.CharacterSets.length; characterSetKey++) {
var characterSet = this.CharacterSets[characterSetKey];
if (baseKey<=characterSetKey && characterSet.indexOf(char)>-1) {
baseKey = characterSetKey;
base = characterSet;
foundChar = true;
break;
}
}
// If the character we were looking for wasn't anywhere in any of the
// character sets, assign the largest (last) character set as default.
if (!foundChar) {
base = this.CharacterSets[this.CharacterSets.length-1];
break;
}
}
// Starting at the first character, figure out it's position in the character set
// and how many attempts will take to get there. For example, say your password
// was an integer (a bank card PIN number for example):
// 0 (or 0000 if you prefer) would be the very first password they attempted by the attacker.
// 9999 would be the last password they attempted (assuming 4 characters).
// Thus a password/PIN of 6529 would take 6529 attempts until the attacker found
// the proper combination. The same logic words for alphanumeric passwords, just
// with a larger number of possibilities for each position in the password. The
// key thing to note is the attacker doesn't need to test the entire range (every
// possible combination of all characters) they just need to get to the point in
// the list of possibilities that is your password. They can (in this example)
// ignore anything between 6530 and 9999. Using this logic, 'aaa' would be a worse
// password than 'zzz', because the attacker would encounter 'aaa' first.
var attempts = 0;
var charactersInBase = base.length;
var charactersInPassword = password.length;
for (var position=0; position<charactersInPassword; position++) {
// We power up to the reverse position in the string. For example, if we're trying
// to hack the 4 character PING code in the example above:
// First number * (number of characters possible in the charset ^ length of password)
// ie: 6 * (10^4) = 6000
// then add that same equation for the second number:
// 5 * (10^3) = 500
// then the third numbers
// 2 * (10^2) = 20
// and add on the last number
// 9
// Totals: 6000 + 500 + 20 + 9 = 6529 attempts before we encounter the correct password.
var powerOf = charactersInPassword - position - 1;
// Character position within the base set. We add one on because strpos is base
// 0, we want base 1.
var charAtPosition = base.indexOf(password[position])+1;
// If we're at the last character, simply add it's position in the character set
// this would be the "9" in the pin code example above.
if (powerOf==0) {
attempts = attempts + charAtPosition;
}
// Otherwise we need to iterate through all the other characters positions to
// get here. For example, to find the 5 in 25 we can't just guess 2 and then 5
// (even though Hollywood seems to insist this is possible), we need to try 0,1,
// 2,3...15,16,17...23,24,25 (got it).
else {
// This means we have to try every combination of values up to this point for
// all previous characters. Which means we need to iterate through the entire
// character set, X times, where X is our position -1. Then we need to multiply
// that by this character's position.
// Multiplier is the (10^4) or (10^3), etc in the pin code example above.
var multiplier = Math.pow(charactersInBase,powerOf);
// New attempts is the number of attempts we're adding for this position.
var newAttempts = charAtPosition * multiplier;
// Add that on to our existing number of attempts.
attempts = attempts + newAttempts;
}
}
// We can (worst case) try a billion passwords a second. Calculate how many days it
// will take us to get to the password.
var perDay = this.HashesPerSecond*60*60*24;
// This allows us to calculate a number of days to crack. We use days because anything
// that can be cracked in less than a day is basically useless, so there's no point in
// having a smaller granularity (hours for example).
var days = attempts / perDay;
// If it's going to take more than a billion days to crack, just return a billion. This
// helps when code outside this function isn't using bcmath. Besides, if the password
// can survive 2.7 million years it's probably ok.
if (days>1000000000) {
return 1000000000;
}
return Math.round(days);
}
};

View File

@ -42,44 +42,33 @@ $(function(){
$('#password-help').show();
// Check first password
var daysToCrack = mellt.CheckPassword($('#p1').val());
var zxcvbnResult = zxcvbn($('#p1').val());
// Not good enough
if (daysToCrack<0) {
$('#password-help').text("That's is one of the world's most commonly used passwords. You may not use it for Tracman and should not use it anywhere. ").css({'color':'#fb6e3d'});
if (zxcvbnResult.crack_times_seconds.online_no_throttling_10_per_second < 3600) { // Less than an hour
$('#password-help').text("That password is way too common or simple. You may not use it for Tracman and should not use it anywhere. ").css({'color':'#fb6e3d'});
$('#submit').prop('disabled',true).prop('title',"You need to come up with a better password. ");
}
else if (daysToCrack<1) {
$('#password-help').text("That password is pretty bad. It could be cracked in less than a day. Try adding more words, numbers, or symbols. ").css({'color':'#fb6e3d'});
else if (zxcvbnResult.crack_times_seconds.online_no_throttling_10_per_second < 86400) { // Less than a day
$('#password-help').text("That password is pretty bad. It could be cracked in "+zxcvbnResult.crack_times_display.online_no_throttling_10_per_second+". Try adding more words, numbers, or symbols. ").css({'color':'#fb6e3d'});
$('#submit').prop('disabled',true).prop('title',"You need to come up with a better password. ");
}
else if (daysToCrack<10) {
$('#password-help').text("That password isn't good enough. It could be cracked in "+daysToCrack+" day"+(daysToCrack!=1?'s':'')+". Try adding another word, number, or symbol. ").css({'color':'#fb6e3d'});
else if (zxcvbnResult.crack_times_seconds.online_no_throttling_10_per_second < 864000) { // Less than ten days
$('#password-help').text("That password isn't good enough. It could be cracked in "+zxcvbnResult.crack_times_display.online_no_throttling_10_per_second+". Try adding another word, number, or symbol. ").css({'color':'#fb6e3d'});
$('#submit').prop('disabled',true).prop('title',"You need to come up with a better password. ");
}
// Good enough
else if (daysToCrack<=30) {
$('#password-help').text("That password is good enough, but it could still be cracked in "+daysToCrack+" days. ").css({'color':'#eee'});
else if (zxcvbnResult.crack_times_seconds.online_no_throttling_10_per_second <= 2592000) { // Less than thirty days
$('#password-help').text("That password is good enough, but it could still be cracked in "+zxcvbnResult.crack_times_display.online_no_throttling_10_per_second+". ").css({'color':'#eee'});
checkMatch();
}
else if (daysToCrack<=365) {
$('#password-help').text("That password is good. It would take "+daysToCrack+" days to crack. ").css({'color':'#8ae137'});
else if (zxcvbnResult.crack_times_seconds.online_no_throttling_10_per_second <= 1314000) { // Less than a year
$('#password-help').text("That password is good. It would take "+zxcvbnResult.crack_times_display.online_no_throttling_10_per_second+" to crack. ").css({'color':'#8ae137'});
checkMatch();
}
else if (daysToCrack<1000000000) {
var years = Math.round(daysToCrack / 365 * 10) / 10;
if (years>1000000) {
years = (Math.round(years/1000000*10)/10)+' million';
}
if (years>1000) {
years = (Math.round(years/1000))+' thousand';
}
$('#password-help').text("That password is great! It could take up to "+years+" years to crack!").css({'color':'#8ae137'});
checkMatch();
}
else {
$('#password-help').text("That password is amazing! It is virtually impossible to crack!").css({'color':'#8ae137'});
else { // Long ass time
$('#password-help').text("That password is great! It could take "+zxcvbnResult.crack_times_display.online_no_throttling_10_per_second+" to crack!").css({'color':'#8ae137'});
checkMatch();
}
}

View File

@ -27,7 +27,7 @@
}
</style>
<p>Your password must be at least 8 characters long. You can use any letter, number, symbol, emoji, or spaces. Your password will be stored as a salted hash on the server. </p>
<p>Your password must be at least 8 characters long. You can use any letter, number, symbol, emoji, or spaces. Your password will be checked using <a href="https://github.com/dropbox/zxcvbn">zxcvbn</a>. All passwords are stored stored on the server as salted hashes. </p>
<div class='form-group' style="flex-wrap:wrap">
<span title="Enter your new password here" style="flex-grow:1; max-width:70vw">
@ -40,7 +40,7 @@
</span>
</div>
<p id='password-help' title="Your passwords are checked using Mellt password cracker. "></p>
<p id='password-help' title="Your passwords are checked using zxcvbn. "></p>
<div id='submit-group' class='form-group flexbox' style="justify-content:space-around">
<input id='submit' class='btn main' style="min-width:50%" type="submit" value="Save" title="You need to enter a password first. " disabled>

View File

@ -1,4 +1,4 @@
var path = require('path');
const path = require('path');
module.exports = {
entry: {