password_strength 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|