forked from dropbox/zxcvbn
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfeedback.coffee
More file actions
120 lines (105 loc) · 3.74 KB
/
Copy pathfeedback.coffee
File metadata and controls
120 lines (105 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
scoring = require('./scoring')
feedback =
default_feedback:
warning: ''
suggestions: [
"Use a few words, avoid common phrases"
"No need for symbols, digits, or uppercase letters"
]
get_feedback: (score, sequence) ->
# starting feedback
return @default_feedback if sequence.length == 0
# no feedback if score is good or great.
return if score > 2
warning: ''
suggestions: []
# tie feedback to the longest match for longer sequences
longest_match = sequence[0]
for match in sequence[1..]
longest_match = match if match.token.length > longest_match.token.length
feedback = @get_match_feedback(longest_match, sequence.length == 1)
extra_feedback = 'Add another word or two. Uncommon words are better.'
if feedback?
feedback.suggestions.unshift extra_feedback
feedback.warning = '' unless feedback.warning?
else
feedback =
warning: ''
suggestions: [extra_feedback]
feedback
get_match_feedback: (match, is_sole_match) ->
switch match.pattern
when 'dictionary'
@get_dictionary_match_feedback match, is_sole_match
when 'spatial'
layout = match.graph.toUpperCase()
warning = if match.turns == 1
'Straight rows of keys are easy to guess'
else
'Short keyboard patterns are easy to guess'
warning: warning
suggestions: [
'Use a longer keyboard pattern with more turns'
]
when 'repeat'
warning = if match.base_token.length == 1
'Repeats like "aaa" are easy to guess'
else
'Repeats like "abcabcabc" are only slightly harder to guess than "abc"'
warning: warning
suggestions: [
'Avoid repeated words and characters'
]
when 'sequence'
warning: "Sequences like abc or 6543 are easy to guess"
suggestions: [
'Avoid sequences'
]
when 'regex'
if match.regex_name == 'recent_year'
warning: "Recent years are easy to guess"
suggestions: [
'Avoid recent years'
'Avoid years that are associated with you'
]
when 'date'
warning: "Dates are often easy to guess"
suggestions: [
'Avoid dates and years that are associated with you'
]
get_dictionary_match_feedback: (match, is_sole_match) ->
warning = if match.dictionary_name == 'passwords'
if is_sole_match and not match.l33t and not match.reversed
if match.rank <= 10
'This is a top-10 common password'
else if match.rank <= 100
'This is a top-100 common password'
else
'This is a very common password'
else if match.guesses_log10 <= 4
'This is similar to a commonly used password'
else if match.dictionary_name == 'english'
if is_sole_match
'A word by itself is easy to guess'
else if match.dictionary_name in ['surnames', 'male_names', 'female_names']
if is_sole_match
'Names and surnames by themselves are easy to guess'
else
'Common names and surnames are easy to guess'
else
''
suggestions = []
word = match.token
if word.match(scoring.START_UPPER)
suggestions.push "Capitalization doesn't help very much"
else if word.match(scoring.ALL_UPPER)
suggestions.push "All-uppercase is almost as easy to guess as all-lowercase"
if match.reversed and 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"
result =
warning: warning
suggestions: suggestions
result
module.exports = feedback