zxcvbn-ruby 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36aa566fe4268e91239c2232628e3eb7397cdf06c99608efa63670842a5b5b4c
4
- data.tar.gz: 8c736d0a2f84507600e9ba3da51a368f056c2e8918672238415f636bffcd6ca3
3
+ metadata.gz: 43a759e1040848c8da4bea8d1e871eb7d811d5cab0ebf962255990963b796f75
4
+ data.tar.gz: c78d0453bb8c92d1f3b21c37f1493f305a6667f24e6ae85a621841a9396fb584
5
5
  SHA512:
6
- metadata.gz: f569dc2cee3a3eee7c8b1adad5f924d74c0b5d2aac11eb61ec4e3330f3043f89d5543a74f073b508b0820bde71e0473b7e096c4d10138fb459fd90dcd7461667
7
- data.tar.gz: f5873e8cdf377c6e30097025c5e8b3c02a4a8c65da2fd2051ef14791ee0123a8224e1c1627a0559338e1e16aa6808e1691afd3d00515057ba79732c62737247a
6
+ metadata.gz: 552d40a11c071613eefb14819b4dabbd3abc6a1f2d336e6bf9bfbc873a34640a229b3bedcc0bd77aca6ffe5e43e31fefec74fe94d74f3cdaebd4e7169610ec02
7
+ data.tar.gz: 84c006df22e0224da4a891f8fa923c81b69229f2b99e5d60ba29104473e566c83a36fbcc404defe980d80cfb176964864f00dbdfa02d655e05eaac7753e64360
data/CHANGELOG.md CHANGED
@@ -6,7 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- [Unreleased]: https://github.com/envato/zxcvbn-ruby/compare/v1.3.0...HEAD
9
+ [Unreleased]: https://github.com/envato/zxcvbn-ruby/compare/v1.4.0...HEAD
10
+
11
+ ## [1.4.0] - 2026-01-15
12
+
13
+ ### Added
14
+ - RBS type signatures for improved type checking and IDE support ([#68])
15
+
16
+ ### Changed
17
+ - Minor fixups in gem metadata ([#67]).
18
+
19
+ [1.4.0]: https://github.com/envato/zxcvbn-ruby/compare/v1.3.0...v1.4.0
20
+ [#67]: https://github.com/envato/zxcvbn-ruby/pull/67
21
+ [#68]: https://github.com/envato/zxcvbn-ruby/pull/68
10
22
 
11
23
  ## [1.3.0] - 2026-01-02
12
24
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zxcvbn
4
- VERSION = '1.3.0'
4
+ VERSION = '1.4.0'
5
5
  end
data/sig/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # RBS Type Signatures
2
+
3
+ This directory contains [RBS](https://github.com/ruby/rbs) type signatures for the zxcvbn-ruby gem.
4
+
5
+ ## What is RBS?
6
+
7
+ RBS is Ruby's type signature language. It provides a way to describe the structure of Ruby programs with:
8
+ - Class and module definitions
9
+ - Method signatures with parameter and return types
10
+ - Instance variables and constants
11
+ - Duck typing and union types
12
+
13
+ ## Usage
14
+
15
+ ### Validating Type Signatures
16
+
17
+ To validate that the RBS files are syntactically correct:
18
+
19
+ ```bash
20
+ bundle exec rake rbs:validate
21
+ ```
22
+
23
+ ### Runtime Type Checking
24
+
25
+ To run runtime type checking against the actual Ruby code during tests:
26
+
27
+ ```bash
28
+ bundle exec rake rbs:test
29
+ ```
30
+
31
+ This runs the RSpec test suite with RBS type checking enabled, verifying that method calls match their type signatures at runtime. Note: This takes about 2 minutes to run.
32
+
33
+ ### Other Useful Commands
34
+
35
+ List all Zxcvbn types:
36
+ ```bash
37
+ bundle exec rake rbs:list
38
+ ```
39
+
40
+ Check syntax of RBS files:
41
+ ```bash
42
+ bundle exec rake rbs:parse
43
+ ```
44
+
45
+ ## File Structure
46
+
47
+ The signatures mirror the structure of the `lib/` directory:
48
+
49
+ - `sig/zxcvbn.rbs` - Main Zxcvbn module
50
+ - `sig/zxcvbn/*.rbs` - Core classes (Tester, Score, Match, etc.)
51
+ - `sig/zxcvbn/matchers/*.rbs` - Pattern matcher classes
52
+
53
+ ## Adding New Signatures
54
+
55
+ When adding new classes or methods to the codebase, remember to:
56
+
57
+ 1. Create or update the corresponding `.rbs` file in the `sig/` directory
58
+ 2. Run `bundle exec rake rbs_validate` to ensure the syntax is correct
59
+ 3. Keep type signatures in sync with the actual implementation
60
+
61
+ ## Resources
62
+
63
+ - [RBS Documentation](https://github.com/ruby/rbs)
64
+ - [RBS Syntax Guide](https://github.com/ruby/rbs/blob/master/docs/syntax.md)
65
+ - [Ruby Signature Collection](https://github.com/ruby/gem_rbs_collection)
@@ -0,0 +1,13 @@
1
+ module Zxcvbn
2
+ module CrackTime
3
+ SINGLE_GUESS: Float
4
+ NUM_ATTACKERS: Integer
5
+ SECONDS_PER_GUESS: Float
6
+
7
+ def entropy_to_crack_time: (Numeric entropy) -> Float
8
+
9
+ def crack_time_to_score: (Numeric seconds) -> Integer
10
+
11
+ def display_time: (Numeric seconds) -> String
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ module Zxcvbn
2
+ class Data
3
+ type ranked_dictionary = Hash[String, Integer]
4
+ type adjacency_graph = Hash[String, Array[String?]]
5
+ type graph_stats = Hash[String, { average_degree: Float, starting_positions: Integer }]
6
+
7
+ @ranked_dictionaries: Hash[String, ranked_dictionary]
8
+ @adjacency_graphs: Hash[String, adjacency_graph]
9
+ @dictionary_tries: Hash[String, Trie]
10
+ @graph_stats: graph_stats
11
+
12
+ attr_reader ranked_dictionaries: Hash[String, ranked_dictionary]
13
+ attr_reader adjacency_graphs: Hash[String, adjacency_graph]
14
+ attr_reader dictionary_tries: Hash[String, Trie]
15
+ attr_reader graph_stats: graph_stats
16
+
17
+ def initialize: () -> void
18
+
19
+ def add_word_list: (String name, Array[String] list) -> void
20
+
21
+ private
22
+
23
+ def read_word_list: (String file) -> Array[String]
24
+
25
+ def build_tries: () -> Hash[String, Trie]
26
+
27
+ def build_trie: (ranked_dictionary ranked_dictionary) -> Trie
28
+
29
+ def compute_graph_stats: () -> graph_stats
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ module Zxcvbn
2
+ class DictionaryRanker
3
+ def self.rank_dictionaries: (Hash[String | Symbol, Array[String]] lists) -> Hash[String | Symbol, Hash[String, Integer]]
4
+
5
+ def self.rank_dictionary: (Array[String] words) -> Hash[String, Integer]
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ module Zxcvbn
2
+ module Entropy
3
+ include Zxcvbn::Math
4
+
5
+ def calc_entropy: (Match match) -> Float
6
+
7
+ def repeat_entropy: (Match match) -> Float
8
+
9
+ def sequence_entropy: (Match match) -> Float
10
+
11
+ def digits_entropy: (Match match) -> Float
12
+
13
+ def year_entropy: (Match? match) -> Float
14
+
15
+ def date_entropy: (Match match) -> Float
16
+
17
+ def dictionary_entropy: (Match match) -> Float
18
+
19
+ def extra_uppercase_entropy: (Match match) -> Numeric
20
+
21
+ def extra_l33t_entropy: (Match match) -> Numeric
22
+
23
+ def spatial_entropy: (Match match) -> Float
24
+
25
+ NUM_YEARS: Integer
26
+ NUM_MONTHS: Integer
27
+ NUM_DAYS: Integer
28
+ START_UPPER: Regexp
29
+ END_UPPER: Regexp
30
+ ALL_UPPER: Regexp
31
+ ALL_LOWER: Regexp
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ module Zxcvbn
2
+ class Feedback
3
+ attr_accessor warning: String?
4
+ attr_accessor suggestions: Array[String]
5
+
6
+ def initialize: (?warning: String?, ?suggestions: Array[String]) -> void
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ module Zxcvbn
2
+ class FeedbackGiver
3
+ NAME_DICTIONARIES: Array[String]
4
+ DEFAULT_FEEDBACK: Feedback
5
+ EMPTY_FEEDBACK: Feedback
6
+
7
+ def self.get_feedback: (Integer? score, Array[Match] sequence) -> Feedback
8
+
9
+ def self.get_match_feedback: (Match match, bool is_sole_match) -> Feedback?
10
+
11
+ def self.get_dictionary_match_feedback: (Match match, bool is_sole_match) -> Feedback
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ module Zxcvbn
2
+ class Match
3
+ attr_accessor pattern: String?
4
+ attr_accessor i: Integer?
5
+ attr_accessor j: Integer?
6
+ attr_accessor token: String?
7
+ attr_accessor matched_word: String?
8
+ attr_accessor rank: Integer?
9
+ attr_accessor dictionary_name: String?
10
+ attr_accessor reversed: bool?
11
+ attr_accessor l33t: bool?
12
+ attr_accessor sub: Hash[String, String]?
13
+ attr_accessor sub_display: String?
14
+ attr_accessor l: Integer?
15
+ attr_accessor entropy: Numeric?
16
+ attr_accessor base_entropy: Numeric?
17
+ attr_accessor uppercase_entropy: Numeric?
18
+ attr_accessor l33t_entropy: Numeric?
19
+ attr_accessor repeated_char: String?
20
+ attr_accessor sequence_name: String?
21
+ attr_accessor sequence_space: Integer?
22
+ attr_accessor ascending: bool?
23
+ attr_accessor graph: String?
24
+ attr_accessor turns: Integer?
25
+ attr_accessor shifted_count: Integer?
26
+ attr_accessor shiffted_count: Integer?
27
+ attr_accessor year: Integer?
28
+ attr_accessor month: Integer?
29
+ attr_accessor day: Integer?
30
+ attr_accessor separator: String?
31
+ attr_accessor cardinality: Integer?
32
+ attr_accessor offset: Integer?
33
+
34
+ def initialize: (**untyped attributes) -> void
35
+
36
+ def to_hash: () -> Hash[String, untyped]
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ module Zxcvbn
2
+ module Math
3
+ def bruteforce_cardinality: (String password) -> Integer
4
+
5
+ def lg: (Numeric n) -> Float
6
+
7
+ def nCk: (Integer n, Integer k) -> Integer
8
+
9
+ def average_degree_for_graph: (String graph_name) -> Float
10
+
11
+ def starting_positions_for_graph: (String graph_name) -> Integer
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module Zxcvbn
2
+ class Omnimatch
3
+ @data: Data
4
+ @matchers: Array[untyped]
5
+
6
+ def initialize: (Data data) -> void
7
+
8
+ def matches: (String password, ?Array[String] user_inputs) -> Array[Match]
9
+
10
+ private
11
+
12
+ def user_input_matchers: (Array[String] user_inputs) -> Array[untyped]
13
+
14
+ def build_matchers: () -> Array[untyped]
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ module Zxcvbn
2
+ class PasswordStrength
3
+ @omnimatch: Omnimatch
4
+ @scorer: Scorer
5
+
6
+ def initialize: (Data data) -> void
7
+
8
+ def test: (String? password, ?Array[untyped] user_inputs) -> Score
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ module Zxcvbn
2
+ class Score
3
+ attr_accessor entropy: Numeric?
4
+ attr_accessor crack_time: Numeric?
5
+ attr_accessor crack_time_display: String?
6
+ attr_accessor score: Integer?
7
+ attr_accessor pattern: String?
8
+ attr_accessor match_sequence: Array[Match]?
9
+ attr_accessor password: String?
10
+ attr_accessor calc_time: Float?
11
+ attr_accessor feedback: Feedback?
12
+
13
+ def initialize: (?entropy: Numeric?, ?crack_time: Numeric?, ?crack_time_display: String?, ?score: Integer?, ?match_sequence: Array[Match]?, ?password: String?) -> void
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ module Zxcvbn
2
+ class Scorer
3
+ include Entropy
4
+ include CrackTime
5
+
6
+ @data: Data
7
+
8
+ attr_reader data: Data
9
+
10
+ def initialize: (Data data) -> void
11
+
12
+ def minimum_entropy_match_sequence: (String password, Array[Match] matches) -> Score
13
+
14
+ def score_for: (String password, Array[Match] match_sequence, Array[Float] up_to_k) -> Score
15
+
16
+ def pad_with_bruteforce_matches: (Array[Match] match_sequence, String password, Integer bruteforce_cardinality) -> Array[Match]
17
+
18
+ def make_bruteforce_match: (String password, Integer i, Integer j, Integer bruteforce_cardinality) -> Match
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module Zxcvbn
2
+ class Tester
3
+ @data: Data
4
+
5
+ def initialize: () -> void
6
+
7
+ def test: (String? password, ?Array[untyped] user_inputs) -> Score
8
+
9
+ def add_word_lists: (Hash[String, Array[untyped]] lists) -> void
10
+
11
+ def inspect: () -> String
12
+
13
+ private
14
+
15
+ def sanitize: (Array[untyped] user_inputs) -> Array[String]
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module Zxcvbn
2
+ class Trie
3
+ type node = Hash[untyped, untyped]
4
+
5
+ @root: node
6
+
7
+ def initialize: () -> void
8
+
9
+ def insert: (String word, Integer rank) -> void
10
+
11
+ def search_prefixes: (String text, Integer start_pos) -> Array[[String, Integer?, Integer, Integer]]
12
+ end
13
+ end
data/sig/zxcvbn.rbs ADDED
@@ -0,0 +1,10 @@
1
+ module Zxcvbn
2
+ VERSION: String
3
+
4
+ DATA_PATH: Pathname
5
+
6
+ type word_list = Hash[String, Array[String]]
7
+ type user_inputs = Array[String]
8
+
9
+ def self.test: (String? password, ?user_inputs user_inputs, ?word_list word_lists) -> Score
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zxcvbn-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Hodgkiss
@@ -54,15 +54,32 @@ files:
54
54
  - lib/zxcvbn/tester.rb
55
55
  - lib/zxcvbn/trie.rb
56
56
  - lib/zxcvbn/version.rb
57
- homepage: http://github.com/envato/zxcvbn-ruby
57
+ - sig/README.md
58
+ - sig/zxcvbn.rbs
59
+ - sig/zxcvbn/crack_time.rbs
60
+ - sig/zxcvbn/data.rbs
61
+ - sig/zxcvbn/dictionary_ranker.rbs
62
+ - sig/zxcvbn/entropy.rbs
63
+ - sig/zxcvbn/feedback.rbs
64
+ - sig/zxcvbn/feedback_giver.rbs
65
+ - sig/zxcvbn/match.rbs
66
+ - sig/zxcvbn/math.rbs
67
+ - sig/zxcvbn/omnimatch.rbs
68
+ - sig/zxcvbn/password_strength.rbs
69
+ - sig/zxcvbn/score.rbs
70
+ - sig/zxcvbn/scorer.rbs
71
+ - sig/zxcvbn/tester.rbs
72
+ - sig/zxcvbn/trie.rbs
73
+ homepage: https://github.com/envato/zxcvbn-ruby
58
74
  licenses:
59
75
  - MIT
60
76
  metadata:
77
+ allowed_push_host: https://rubygems.org
61
78
  bug_tracker_uri: https://github.com/envato/zxcvbn-ruby/issues
62
79
  changelog_uri: https://github.com/envato/zxcvbn-ruby/blob/HEAD/CHANGELOG.md
63
- documentation_uri: https://github.com/envato/zxcvbn-ruby/blob/HEAD/README.md
80
+ documentation_uri: https://www.rubydoc.info/gems/zxcvbn-ruby/1.4.0
64
81
  homepage_uri: https://github.com/envato/zxcvbn-ruby
65
- source_code_uri: https://github.com/envato/zxcvbn-ruby
82
+ source_code_uri: https://github.com/envato/zxcvbn-ruby/tree/v1.4.0
66
83
  rdoc_options: []
67
84
  require_paths:
68
85
  - lib
@@ -77,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
94
  - !ruby/object:Gem::Version
78
95
  version: '0'
79
96
  requirements: []
80
- rubygems_version: 4.0.3
97
+ rubygems_version: 4.0.4
81
98
  specification_version: 4
82
99
  summary: ''
83
100
  test_files: []