zxcvbn-ruby 0.0.3 → 1.1.0
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.
- checksums.yaml +7 -0
- data/.travis.yml +12 -0
- data/CHANGELOG.md +42 -0
- data/CODE_OF_CONDUCT.md +130 -0
- data/Gemfile +8 -1
- data/Guardfile +26 -0
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +165 -9
- data/Rakefile +5 -1
- data/lib/zxcvbn.rb +10 -36
- data/lib/zxcvbn/crack_time.rb +44 -42
- data/lib/zxcvbn/data.rb +29 -0
- data/lib/zxcvbn/dictionary_ranker.rb +0 -2
- data/lib/zxcvbn/entropy.rb +3 -1
- data/lib/zxcvbn/feedback.rb +10 -0
- data/lib/zxcvbn/feedback_giver.rb +133 -0
- data/lib/zxcvbn/matchers/date.rb +2 -0
- data/lib/zxcvbn/matchers/dictionary.rb +2 -0
- data/lib/zxcvbn/matchers/digits.rb +2 -0
- data/lib/zxcvbn/matchers/l33t.rb +2 -2
- data/lib/zxcvbn/matchers/regex_helpers.rb +2 -0
- data/lib/zxcvbn/matchers/repeat.rb +2 -0
- data/lib/zxcvbn/matchers/sequences.rb +2 -0
- data/lib/zxcvbn/matchers/spatial.rb +2 -0
- data/lib/zxcvbn/matchers/year.rb +2 -0
- data/lib/zxcvbn/math.rb +2 -2
- data/lib/zxcvbn/omnimatch.rb +14 -3
- data/lib/zxcvbn/password_strength.rb +7 -3
- data/lib/zxcvbn/score.rb +1 -1
- data/lib/zxcvbn/scorer.rb +11 -0
- data/lib/zxcvbn/tester.rb +43 -0
- data/lib/zxcvbn/version.rb +1 -1
- data/spec/dictionary_ranker_spec.rb +2 -2
- data/spec/feedback_giver_spec.rb +212 -0
- data/spec/matchers/date_spec.rb +8 -8
- data/spec/matchers/dictionary_spec.rb +25 -14
- data/spec/matchers/digits_spec.rb +3 -3
- data/spec/matchers/l33t_spec.rb +15 -13
- data/spec/matchers/repeat_spec.rb +6 -6
- data/spec/matchers/sequences_spec.rb +5 -5
- data/spec/matchers/spatial_spec.rb +8 -8
- data/spec/matchers/year_spec.rb +3 -3
- data/spec/omnimatch_spec.rb +2 -2
- data/spec/scoring/crack_time_spec.rb +13 -13
- data/spec/scoring/entropy_spec.rb +28 -25
- data/spec/scoring/math_spec.rb +22 -18
- data/spec/support/matcher.rb +1 -1
- data/spec/tester_spec.rb +99 -0
- data/spec/zxcvbn_spec.rb +14 -39
- data/zxcvbn-ruby.gemspec +11 -0
- metadata +34 -29
data/spec/support/matcher.rb
CHANGED
@@ -17,7 +17,7 @@ RSpec::Matchers.define :match_js_results do |expected_js_results|
|
|
17
17
|
@missing.empty? && @extra.empty?
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
failure_message do |actual|
|
21
21
|
"Matches missing from ruby results:\n#{@missing.inspect}\nMatches unique to ruby results:\n#{@extra.inspect}"
|
22
22
|
end
|
23
23
|
|
data/spec/tester_spec.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "spec_helper"
|
5
|
+
|
6
|
+
describe Zxcvbn::Tester do
|
7
|
+
let(:tester) { Zxcvbn::Tester.new }
|
8
|
+
|
9
|
+
TEST_PASSWORDS.each do |password|
|
10
|
+
it "gives back the same score for #{password}" do
|
11
|
+
ruby_result = tester.test(password)
|
12
|
+
js_result = js_zxcvbn(password)
|
13
|
+
|
14
|
+
expect(ruby_result.calc_time).not_to be_nil
|
15
|
+
expect(ruby_result.password).to eq js_result["password"]
|
16
|
+
expect(ruby_result.entropy).to eq js_result["entropy"]
|
17
|
+
expect(ruby_result.crack_time).to eq js_result["crack_time"]
|
18
|
+
expect(ruby_result.crack_time_display).to eq js_result["crack_time_display"]
|
19
|
+
expect(ruby_result.score).to eq js_result["score"]
|
20
|
+
expect(ruby_result.pattern).to eq js_result["pattern"]
|
21
|
+
expect(ruby_result.match_sequence.count).to eq js_result["match_sequence"].count
|
22
|
+
|
23
|
+
# NOTE: feedback didn't exist in the version of the JS library this gem
|
24
|
+
# is based on, so instead we just check that it put `Feedback` in
|
25
|
+
# there. Real tests for its values go in `feedback_giver_spec.rb`.
|
26
|
+
expect(ruby_result.feedback).to be_a Zxcvbn::Feedback
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with a custom user dictionary" do
|
31
|
+
it "scores them against the user dictionary" do
|
32
|
+
result = tester.test("themeforest", ["themeforest"])
|
33
|
+
expect(result.entropy).to eq 0
|
34
|
+
expect(result.score).to eq 0
|
35
|
+
end
|
36
|
+
|
37
|
+
it "matches l33t substitutions on this dictionary" do
|
38
|
+
result = tester.test("th3m3for3st", ["themeforest"])
|
39
|
+
expect(result.entropy).to eq 1
|
40
|
+
expect(result.score).to eq 0
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with Unicode entries in the password" do
|
45
|
+
it "validates the password" do
|
46
|
+
result = tester.test("✅🐴🔋staple", %w[Theme Forest themeforest])
|
47
|
+
expect(result.entropy).to be_positive
|
48
|
+
expect(result.score).to be_positive
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with Unicode entries in the dictionary" do
|
53
|
+
it "validates the password" do
|
54
|
+
result = tester.test("correct horse battery staple", %w[✅ 🐴 🔋])
|
55
|
+
expect(result.entropy).to be_positive
|
56
|
+
expect(result.score).to be_positive
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with Unicode entries in the password and the dictionary" do
|
61
|
+
it "validates the password" do
|
62
|
+
result = tester.test("✅🐴🔋staple", %w[✅ 🐴 🔋])
|
63
|
+
expect(result.entropy).to be_positive
|
64
|
+
expect(result.score).to be_zero
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with invalid entries in the dictionary" do
|
69
|
+
it "ignores those entries" do
|
70
|
+
result = tester.test("themeforest", [nil, 1, "themeforest"])
|
71
|
+
expect(result.entropy).to eq 0
|
72
|
+
expect(result.score).to eq 0
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "with a custom global dictionary" do
|
77
|
+
before { tester.add_word_lists("envato" => ["envato"]) }
|
78
|
+
|
79
|
+
it "scores them against the dictionary" do
|
80
|
+
result = tester.test("envato")
|
81
|
+
expect(result.entropy).to eq 0
|
82
|
+
expect(result.score).to eq 0
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with invalid entries in a custom dictionary" do
|
86
|
+
before { tester.add_word_lists("themeforest" => [nil, 1, "themeforest"]) }
|
87
|
+
|
88
|
+
it "ignores those entries" do
|
89
|
+
expect(tester.test("themeforest")).to have_attributes(entropy: 0, score: 0, crack_time: 0)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "nil password" do
|
95
|
+
specify do
|
96
|
+
expect(tester.test(nil)).to have_attributes(entropy: 0, score: 0, crack_time: 0)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/spec/zxcvbn_spec.rb
CHANGED
@@ -1,49 +1,24 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe '
|
4
|
-
|
5
|
-
it
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
ruby_result.calc_time.should_not be_nil
|
10
|
-
ruby_result.password.should eq js_result['password']
|
11
|
-
ruby_result.entropy.should eq js_result['entropy']
|
12
|
-
ruby_result.crack_time.should eq js_result['crack_time']
|
13
|
-
ruby_result.crack_time_display.should eq js_result['crack_time_display']
|
14
|
-
ruby_result.score.should eq js_result['score']
|
15
|
-
ruby_result.pattern.should eq js_result['pattern']
|
16
|
-
ruby_result.match_sequence.count.should eq js_result['match_sequence'].count
|
3
|
+
describe 'Zxcvbn.test' do
|
4
|
+
context 'with a password' do
|
5
|
+
it 'returns a result' do
|
6
|
+
result = Zxcvbn.test('password')
|
7
|
+
expect(result.entropy).to_not be_nil
|
17
8
|
end
|
18
9
|
end
|
19
10
|
|
20
|
-
context 'with a
|
21
|
-
it '
|
22
|
-
result = Zxcvbn.test('
|
23
|
-
result.entropy.
|
24
|
-
result.score.should eq 0
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'matches l33t substitutions on this dictionary' do
|
28
|
-
result = Zxcvbn.test('th3m3for3st', ['themeforest'])
|
29
|
-
result.entropy.should eq 1
|
30
|
-
result.score.should eq 0
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'with a custom global dictionary' do
|
35
|
-
before { Zxcvbn.add_word_list('envato', ['envato']) }
|
36
|
-
|
37
|
-
it 'scores them against the dictionary' do
|
38
|
-
result = Zxcvbn.test('envato')
|
39
|
-
result.entropy.should eq 0
|
40
|
-
result.score.should eq 0
|
11
|
+
context 'with a password and user input' do
|
12
|
+
it 'returns a result' do
|
13
|
+
result = Zxcvbn.test('password', ['inputs'])
|
14
|
+
expect(result.entropy).to_not be_nil
|
41
15
|
end
|
42
16
|
end
|
43
17
|
|
44
|
-
context '
|
45
|
-
|
46
|
-
|
18
|
+
context 'with a password, user input and custom word lists' do
|
19
|
+
it 'returns a result' do
|
20
|
+
result = Zxcvbn.test('password', ['inputs'], {'list' => ['words']})
|
21
|
+
expect(result.entropy).to_not be_nil
|
47
22
|
end
|
48
23
|
end
|
49
|
-
end
|
24
|
+
end
|
data/zxcvbn-ruby.gemspec
CHANGED
@@ -14,7 +14,18 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.name = "zxcvbn-ruby"
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Zxcvbn::VERSION
|
17
|
+
gem.license = 'MIT'
|
18
|
+
|
19
|
+
gem.required_ruby_version = '~> 2.5'
|
17
20
|
|
18
21
|
gem.add_development_dependency 'therubyracer'
|
19
22
|
gem.add_development_dependency 'rspec'
|
23
|
+
|
24
|
+
gem.metadata = {
|
25
|
+
"bug_tracker_uri" => "https://github.com/envato/zxcvbn-ruby/issues",
|
26
|
+
"changelog_uri" => "https://github.com/envato/zxcvbn-ruby/blob/master/CHANGELOG.md",
|
27
|
+
"documentation_uri" => "https://github.com/envato/zxcvbn-ruby/blob/master/README.md",
|
28
|
+
"homepage_uri" => "https://github.com/envato/zxcvbn-ruby",
|
29
|
+
"source_code_uri" => "https://github.com/envato/zxcvbn-ruby"
|
30
|
+
}
|
20
31
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zxcvbn-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Steve Hodgkiss
|
@@ -10,38 +9,34 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2020-07-15 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: therubyracer
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
|
-
- -
|
18
|
+
- - ">="
|
21
19
|
- !ruby/object:Gem::Version
|
22
20
|
version: '0'
|
23
21
|
type: :development
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
|
-
- -
|
25
|
+
- - ">="
|
29
26
|
- !ruby/object:Gem::Version
|
30
27
|
version: '0'
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
29
|
name: rspec
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
|
-
- -
|
32
|
+
- - ">="
|
37
33
|
- !ruby/object:Gem::Version
|
38
34
|
version: '0'
|
39
35
|
type: :development
|
40
36
|
prerelease: false
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
38
|
requirements:
|
44
|
-
- -
|
39
|
+
- - ">="
|
45
40
|
- !ruby/object:Gem::Version
|
46
41
|
version: '0'
|
47
42
|
description: Ruby port of Dropboxs zxcvbn.js
|
@@ -52,10 +47,14 @@ executables: []
|
|
52
47
|
extensions: []
|
53
48
|
extra_rdoc_files: []
|
54
49
|
files:
|
55
|
-
- .gitignore
|
56
|
-
- .rspec
|
50
|
+
- ".gitignore"
|
51
|
+
- ".rspec"
|
52
|
+
- ".travis.yml"
|
53
|
+
- CHANGELOG.md
|
54
|
+
- CODE_OF_CONDUCT.md
|
57
55
|
- Gemfile
|
58
|
-
-
|
56
|
+
- Guardfile
|
57
|
+
- LICENSE.txt
|
59
58
|
- README.md
|
60
59
|
- Rakefile
|
61
60
|
- data/adjacency_graphs.json
|
@@ -66,8 +65,11 @@ files:
|
|
66
65
|
- data/frequency_lists/surnames.txt
|
67
66
|
- lib/zxcvbn.rb
|
68
67
|
- lib/zxcvbn/crack_time.rb
|
68
|
+
- lib/zxcvbn/data.rb
|
69
69
|
- lib/zxcvbn/dictionary_ranker.rb
|
70
70
|
- lib/zxcvbn/entropy.rb
|
71
|
+
- lib/zxcvbn/feedback.rb
|
72
|
+
- lib/zxcvbn/feedback_giver.rb
|
71
73
|
- lib/zxcvbn/match.rb
|
72
74
|
- lib/zxcvbn/matchers/date.rb
|
73
75
|
- lib/zxcvbn/matchers/dictionary.rb
|
@@ -84,8 +86,10 @@ files:
|
|
84
86
|
- lib/zxcvbn/password_strength.rb
|
85
87
|
- lib/zxcvbn/score.rb
|
86
88
|
- lib/zxcvbn/scorer.rb
|
89
|
+
- lib/zxcvbn/tester.rb
|
87
90
|
- lib/zxcvbn/version.rb
|
88
91
|
- spec/dictionary_ranker_spec.rb
|
92
|
+
- spec/feedback_giver_spec.rb
|
89
93
|
- spec/matchers/date_spec.rb
|
90
94
|
- spec/matchers/dictionary_spec.rb
|
91
95
|
- spec/matchers/digits_spec.rb
|
@@ -111,40 +115,40 @@ files:
|
|
111
115
|
- spec/support/js_source/scoring.coffee
|
112
116
|
- spec/support/js_source/scoring.js
|
113
117
|
- spec/support/matcher.rb
|
118
|
+
- spec/tester_spec.rb
|
114
119
|
- spec/zxcvbn_spec.rb
|
115
120
|
- zxcvbn-ruby.gemspec
|
116
121
|
homepage: http://github.com/envato/zxcvbn-ruby
|
117
|
-
licenses:
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
metadata:
|
125
|
+
bug_tracker_uri: https://github.com/envato/zxcvbn-ruby/issues
|
126
|
+
changelog_uri: https://github.com/envato/zxcvbn-ruby/blob/master/CHANGELOG.md
|
127
|
+
documentation_uri: https://github.com/envato/zxcvbn-ruby/blob/master/README.md
|
128
|
+
homepage_uri: https://github.com/envato/zxcvbn-ruby
|
129
|
+
source_code_uri: https://github.com/envato/zxcvbn-ruby
|
118
130
|
post_install_message:
|
119
131
|
rdoc_options: []
|
120
132
|
require_paths:
|
121
133
|
- lib
|
122
134
|
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
135
|
requirements:
|
125
|
-
- -
|
136
|
+
- - "~>"
|
126
137
|
- !ruby/object:Gem::Version
|
127
|
-
version: '
|
128
|
-
segments:
|
129
|
-
- 0
|
130
|
-
hash: -1798543645320205772
|
138
|
+
version: '2.5'
|
131
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
-
none: false
|
133
140
|
requirements:
|
134
|
-
- -
|
141
|
+
- - ">="
|
135
142
|
- !ruby/object:Gem::Version
|
136
143
|
version: '0'
|
137
|
-
segments:
|
138
|
-
- 0
|
139
|
-
hash: -1798543645320205772
|
140
144
|
requirements: []
|
141
|
-
|
142
|
-
rubygems_version: 1.8.23.2
|
145
|
+
rubygems_version: 3.1.2
|
143
146
|
signing_key:
|
144
|
-
specification_version:
|
147
|
+
specification_version: 4
|
145
148
|
summary: ''
|
146
149
|
test_files:
|
147
150
|
- spec/dictionary_ranker_spec.rb
|
151
|
+
- spec/feedback_giver_spec.rb
|
148
152
|
- spec/matchers/date_spec.rb
|
149
153
|
- spec/matchers/dictionary_spec.rb
|
150
154
|
- spec/matchers/digits_spec.rb
|
@@ -170,4 +174,5 @@ test_files:
|
|
170
174
|
- spec/support/js_source/scoring.coffee
|
171
175
|
- spec/support/js_source/scoring.js
|
172
176
|
- spec/support/matcher.rb
|
177
|
+
- spec/tester_spec.rb
|
173
178
|
- spec/zxcvbn_spec.rb
|