password_strength 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/password_strength.js +43 -4
- data/lib/password_strength.rb +1 -0
- data/lib/password_strength/base.rb +2 -2
- data/lib/password_strength/version.rb +1 -1
- data/test/password_strength_test.js +19 -0
- data/test/password_strength_test.rb +11 -0
- data/test/test_helper.rb +1 -0
- metadata +25 -7
data/lib/password_strength.js
CHANGED
@@ -22,6 +22,7 @@ var PasswordStrength = function() {
|
|
22
22
|
this.score += this.scoreFor("only_numbers");
|
23
23
|
this.score += this.scoreFor("username");
|
24
24
|
this.score += this.scoreFor("sequences");
|
25
|
+
this.score += this.scoreFor("repetitions");
|
25
26
|
|
26
27
|
if (this.score < 0) {
|
27
28
|
this.score = 0;
|
@@ -115,9 +116,15 @@ var PasswordStrength = function() {
|
|
115
116
|
break;
|
116
117
|
|
117
118
|
case "sequences":
|
118
|
-
score += -15 * this.
|
119
|
-
score += -15 * this.
|
120
|
-
break
|
119
|
+
score += -15 * this.sequences(this.password);
|
120
|
+
score += -15 * this.sequences(this.reversed(this.password));
|
121
|
+
break;
|
122
|
+
|
123
|
+
case "repetitions":
|
124
|
+
score += -(this.repetitions(this.password, 2) * 4);
|
125
|
+
score += -(this.repetitions(this.password, 3) * 3);
|
126
|
+
score += -(this.repetitions(this.password, 4) * 2);
|
127
|
+
break;
|
121
128
|
};
|
122
129
|
|
123
130
|
return score;
|
@@ -145,7 +152,7 @@ var PasswordStrength = function() {
|
|
145
152
|
}
|
146
153
|
};
|
147
154
|
|
148
|
-
this.
|
155
|
+
this.sequences = function(text) {
|
149
156
|
var matches = 0;
|
150
157
|
var sequenceSize = 0;
|
151
158
|
var codes = [];
|
@@ -173,6 +180,38 @@ var PasswordStrength = function() {
|
|
173
180
|
return matches;
|
174
181
|
};
|
175
182
|
|
183
|
+
this.repetitions = function(text, size) {
|
184
|
+
var count = 0;
|
185
|
+
var matches = {};
|
186
|
+
var len = text.length;
|
187
|
+
var substring;
|
188
|
+
var occurrences;
|
189
|
+
var tmpText;
|
190
|
+
|
191
|
+
for (var i = 0; i < len; i++) {
|
192
|
+
substring = text.substr(i, size);
|
193
|
+
occurrences = 0;
|
194
|
+
tmpText = text;
|
195
|
+
|
196
|
+
if (matches[substring] || substring.length < size) {
|
197
|
+
continue;
|
198
|
+
}
|
199
|
+
|
200
|
+
matches[substring] = true;
|
201
|
+
|
202
|
+
while ((i = tmpText.indexOf(substring)) != -1) {
|
203
|
+
occurrences += 1;
|
204
|
+
tmpText = tmpText.substr(i + 1);
|
205
|
+
};
|
206
|
+
|
207
|
+
if (occurrences > 1) {
|
208
|
+
count += 1;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
return count;
|
213
|
+
};
|
214
|
+
|
176
215
|
this.reversed = function(text) {
|
177
216
|
var newText = "";
|
178
217
|
var len = text.length;
|
data/lib/password_strength.rb
CHANGED
@@ -135,6 +135,7 @@ module PasswordStrength
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def repetitions(text, size) # :nodoc:
|
138
|
+
text = text.mb_chars
|
138
139
|
count = 0
|
139
140
|
matches = []
|
140
141
|
|
@@ -144,8 +145,7 @@ module PasswordStrength
|
|
144
145
|
next if matches.include?(substring) || substring.size < size
|
145
146
|
|
146
147
|
matches << substring
|
147
|
-
occurrences = text.scan(substring).length
|
148
|
-
|
148
|
+
occurrences = text.scan(/#{Regexp.escape(substring)}/).length
|
149
149
|
count += 1 if occurrences > 1
|
150
150
|
end
|
151
151
|
|
@@ -179,6 +179,12 @@ new Test.Unit.Runner({
|
|
179
179
|
assertEqual(-100, strength.scoreFor("password_size"));
|
180
180
|
}},
|
181
181
|
|
182
|
+
// Penalize repetitions
|
183
|
+
testPenalizeRepetitions: function() { with(this) {
|
184
|
+
strength.password = "abcdabcdabcd";
|
185
|
+
assertEqual(-36, strength.scoreFor("repetitions"));
|
186
|
+
}},
|
187
|
+
|
182
188
|
// Password length
|
183
189
|
testPasswordLength: function() { with(this) {
|
184
190
|
strength.password = "12345";
|
@@ -221,5 +227,18 @@ new Test.Unit.Runner({
|
|
221
227
|
assertEqual(15, strength.scoreFor("symbols_chars"));
|
222
228
|
}},
|
223
229
|
|
230
|
+
// Two char repetition
|
231
|
+
testTwoCharRepetition: function() { with(this) {
|
232
|
+
assertEqual(3, strength.repetitions("11221122", 2));
|
233
|
+
}},
|
234
|
+
|
235
|
+
// Three char repetition
|
236
|
+
testThreeCharRepetition: function() { with(this) {
|
237
|
+
assertEqual(3, strength.repetitions("123123123", 3));
|
238
|
+
}},
|
224
239
|
|
240
|
+
// Four char repetition
|
241
|
+
testFourCharRepetition: function() { with(this) {
|
242
|
+
assertEqual(4, strength.repetitions("abcdabcdabcd", 4));
|
243
|
+
}}
|
225
244
|
});
|
@@ -212,4 +212,15 @@ class TestPasswordStrength < Test::Unit::TestCase
|
|
212
212
|
# expected: abcd, bcda, cdab, dabc
|
213
213
|
assert_equal 4, @strength.repetitions("abcdabcdabcd", 4)
|
214
214
|
end
|
215
|
+
|
216
|
+
def test_special_chars_repetition
|
217
|
+
# expected: §§, ££, §£
|
218
|
+
assert_equal 3, @strength.repetitions("§§££§§££", 2)
|
219
|
+
|
220
|
+
# expected: §£€, £€§, €§£
|
221
|
+
assert_equal 3, @strength.repetitions("§£€§£€§£€", 3)
|
222
|
+
|
223
|
+
# expected: §£€à, £€à§, €à§£, à§£€
|
224
|
+
assert_equal 4, @strength.repetitions("§£€à§£€à§£€à", 4)
|
225
|
+
end
|
215
226
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: password_strength
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 5
|
9
|
+
version: 0.1.5
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Nando Vieira
|
@@ -9,10 +14,21 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-23 00:00:00 -03:00
|
13
18
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: activesupport
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
16
32
|
description: |
|
17
33
|
Validates the strength of a password according to several rules:
|
18
34
|
|
@@ -69,18 +85,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
85
|
requirements:
|
70
86
|
- - ">="
|
71
87
|
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
72
90
|
version: "0"
|
73
|
-
version:
|
74
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
92
|
requirements:
|
76
93
|
- - ">="
|
77
94
|
- !ruby/object:Gem::Version
|
95
|
+
segments:
|
96
|
+
- 0
|
78
97
|
version: "0"
|
79
|
-
version:
|
80
98
|
requirements: []
|
81
99
|
|
82
100
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.3.
|
101
|
+
rubygems_version: 1.3.6
|
84
102
|
signing_key:
|
85
103
|
specification_version: 3
|
86
104
|
summary: Check password strength against several rules. Includes ActiveRecord support.
|