UNPKG

zxcvbn-typescript

Version:

realistic password strength estimation, updated and ported to Typescript from Dan Wheeler's zxcvbn

140 lines 5.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.get_dictionary_match_feedback = exports.get_match_feedback = exports.get_feedback = exports.default_feedback = void 0; var dictionary_guesses_1 = require("./scoring/dictionary_guesses"); exports.default_feedback = { warning: "", suggestions: [ "Use a few words, avoid common phrases", "No need for symbols, digits, or uppercase letters", ], }; function get_feedback(score, sequence) { // starting feedback if (sequence.length === 0) return exports.default_feedback; // no feedback if score is good or great. if (score > 2) { return { warning: "", suggestions: [], }; } // tie feedback to the longest match for longer sequences var first = sequence[0], rest = sequence.slice(1); var longest_match = first; for (var _i = 0, rest_1 = rest; _i < rest_1.length; _i++) { var match = rest_1[_i]; if (match.token.length > longest_match.token.length) { longest_match = match; } } var feedback = get_match_feedback(longest_match, sequence.length === 1); var extra_feedback = "Add another word or two. Uncommon words are better."; if (feedback) { feedback.suggestions.unshift(extra_feedback); } else { feedback = { warning: "", suggestions: [extra_feedback], }; } return feedback; } exports.get_feedback = get_feedback; function get_match_feedback(match, is_sole_match) { switch (match.pattern) { case "dictionary": return get_dictionary_match_feedback(match, is_sole_match); case "spatial": return { warning: match.turns === 1 ? "Straight rows of keys are easy to guess" : "Short keyboard patterns are easy to guess", suggestions: ["Use a longer keyboard pattern with more turns"], }; case "repeat": return { warning: match.base_token.length === 1 ? 'Repeats like "aaa" are easy to guess' : 'Repeats like "abcabcabc" are only slightly harder to guess than "abc"', suggestions: ["Avoid repeated words and characters"], }; case "sequence": return { warning: "Sequences like abc or 6543 are easy to guess", suggestions: ["Avoid sequences"], }; case "regex": if (match.regex_name === "recent_year") { return { warning: "Recent years are easy to guess", suggestions: [ "Avoid recent years", "Avoid years that are associated with you", ], }; } break; case "date": return { warning: "Dates are often easy to guess", suggestions: ["Avoid dates and years that are associated with you"], }; } return; } exports.get_match_feedback = get_match_feedback; function get_dictionary_match_feedback(match, is_sole_match) { var warning = ""; if (match.dictionary_name === "passwords") { if (is_sole_match && !match.l33t && !match.reversed) { if (match.rank <= 10) { warning = "This is a top-10 common password"; } else if (match.rank <= 100) { warning = "This is a top-100 common password"; } else { warning = "This is a very common password"; } } else if (match.guesses_log10 != undefined && match.guesses_log10 <= 4) { warning = "This is similar to a commonly used password"; } } else if (match.dictionary_name === "english_wikipedia") { if (is_sole_match) { warning = "A word by itself is easy to guess"; } } else if (["surnames", "male_names", "female_names"].includes(match.dictionary_name)) { if (is_sole_match) { warning = "Names and surnames by themselves are easy to guess"; } else { warning = "Common names and surnames are easy to guess"; } } var suggestions = []; var word = match.token; if (word.match(dictionary_guesses_1.START_UPPER)) { suggestions.push("Capitalization doesn't help very much"); } else if (word.match(dictionary_guesses_1.ALL_UPPER) && word.toLowerCase() !== word) { suggestions.push("All-uppercase is almost as easy to guess as all-lowercase"); } if (match.reversed && match.token.length >= 4) { suggestions.push("Reversed words aren't much harder to guess"); } if (match.l33t) { suggestions.push("Predictable substitutions like '@' instead of 'a' don't help very much"); } return { warning: warning, suggestions: suggestions, }; } exports.get_dictionary_match_feedback = get_dictionary_match_feedback; //# sourceMappingURL=feedback.js.map