isStrongPassword.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = isStrongPassword;
  6. var _merge = _interopRequireDefault(require("./util/merge"));
  7. var _assertString = _interopRequireDefault(require("./util/assertString"));
  8. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  9. var upperCaseRegex = /^[A-Z]$/;
  10. var lowerCaseRegex = /^[a-z]$/;
  11. var numberRegex = /^[0-9]$/;
  12. var symbolRegex = /^[-#!$@%^&*()_+|~=`{}\[\]:";'<>?,.\/ ]$/;
  13. var defaultOptions = {
  14. minLength: 8,
  15. minLowercase: 1,
  16. minUppercase: 1,
  17. minNumbers: 1,
  18. minSymbols: 1,
  19. returnScore: false,
  20. pointsPerUnique: 1,
  21. pointsPerRepeat: 0.5,
  22. pointsForContainingLower: 10,
  23. pointsForContainingUpper: 10,
  24. pointsForContainingNumber: 10,
  25. pointsForContainingSymbol: 10
  26. };
  27. /* Counts number of occurrences of each char in a string
  28. * could be moved to util/ ?
  29. */
  30. function countChars(str) {
  31. var result = {};
  32. Array.from(str).forEach(function (char) {
  33. var curVal = result[char];
  34. if (curVal) {
  35. result[char] += 1;
  36. } else {
  37. result[char] = 1;
  38. }
  39. });
  40. return result;
  41. }
  42. /* Return information about a password */
  43. function analyzePassword(password) {
  44. var charMap = countChars(password);
  45. var analysis = {
  46. length: password.length,
  47. uniqueChars: Object.keys(charMap).length,
  48. uppercaseCount: 0,
  49. lowercaseCount: 0,
  50. numberCount: 0,
  51. symbolCount: 0
  52. };
  53. Object.keys(charMap).forEach(function (char) {
  54. /* istanbul ignore else */
  55. if (upperCaseRegex.test(char)) {
  56. analysis.uppercaseCount += charMap[char];
  57. } else if (lowerCaseRegex.test(char)) {
  58. analysis.lowercaseCount += charMap[char];
  59. } else if (numberRegex.test(char)) {
  60. analysis.numberCount += charMap[char];
  61. } else if (symbolRegex.test(char)) {
  62. analysis.symbolCount += charMap[char];
  63. }
  64. });
  65. return analysis;
  66. }
  67. function scorePassword(analysis, scoringOptions) {
  68. var points = 0;
  69. points += analysis.uniqueChars * scoringOptions.pointsPerUnique;
  70. points += (analysis.length - analysis.uniqueChars) * scoringOptions.pointsPerRepeat;
  71. if (analysis.lowercaseCount > 0) {
  72. points += scoringOptions.pointsForContainingLower;
  73. }
  74. if (analysis.uppercaseCount > 0) {
  75. points += scoringOptions.pointsForContainingUpper;
  76. }
  77. if (analysis.numberCount > 0) {
  78. points += scoringOptions.pointsForContainingNumber;
  79. }
  80. if (analysis.symbolCount > 0) {
  81. points += scoringOptions.pointsForContainingSymbol;
  82. }
  83. return points;
  84. }
  85. function isStrongPassword(str) {
  86. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  87. (0, _assertString.default)(str);
  88. var analysis = analyzePassword(str);
  89. options = (0, _merge.default)(options || {}, defaultOptions);
  90. if (options.returnScore) {
  91. return scorePassword(analysis, options);
  92. }
  93. return analysis.length >= options.minLength && analysis.lowercaseCount >= options.minLowercase && analysis.uppercaseCount >= options.minUppercase && analysis.numberCount >= options.minNumbers && analysis.symbolCount >= options.minSymbols;
  94. }
  95. module.exports = exports.default;
  96. module.exports.default = exports.default;