devise-secure_password 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +18 -4
  3. data/Gemfile.lock +8 -8
  4. data/README.md +17 -3
  5. data/app/controllers/devise/passwords_with_policy_controller.rb +52 -10
  6. data/app/views/devise/passwords_with_policy/edit.html.erb +5 -1
  7. data/config/locales/en.yml +40 -0
  8. data/coverage/assets/0.10.2/application.css +799 -0
  9. data/coverage/assets/0.10.2/application.js +1707 -0
  10. data/coverage/assets/0.10.2/colorbox/border.png +0 -0
  11. data/coverage/assets/0.10.2/colorbox/controls.png +0 -0
  12. data/coverage/assets/0.10.2/colorbox/loading.gif +0 -0
  13. data/coverage/assets/0.10.2/colorbox/loading_background.png +0 -0
  14. data/coverage/assets/0.10.2/favicon_green.png +0 -0
  15. data/coverage/assets/0.10.2/favicon_red.png +0 -0
  16. data/coverage/assets/0.10.2/favicon_yellow.png +0 -0
  17. data/coverage/assets/0.10.2/loading.gif +0 -0
  18. data/coverage/assets/0.10.2/magnify.png +0 -0
  19. data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  20. data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  21. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  22. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  23. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  24. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  25. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  26. data/coverage/assets/0.10.2/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  27. data/coverage/assets/0.10.2/smoothness/images/ui-icons_222222_256x240.png +0 -0
  28. data/coverage/assets/0.10.2/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  29. data/coverage/assets/0.10.2/smoothness/images/ui-icons_454545_256x240.png +0 -0
  30. data/coverage/assets/0.10.2/smoothness/images/ui-icons_888888_256x240.png +0 -0
  31. data/coverage/assets/0.10.2/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  32. data/coverage/index.html +4115 -0
  33. data/devise-secure_password-1.0.0.gem +0 -0
  34. data/gemfiles/rails-5_0.gemfile +2 -2
  35. data/gemfiles/rails-5_0.gemfile.lock +288 -0
  36. data/gemfiles/rails-5_0_6.gemfile.lock +286 -0
  37. data/gemfiles/rails-5_1.gemfile.lock +9 -7
  38. data/gemfiles/rails-5_1_4.gemfile.lock +282 -0
  39. data/lib/devise/secure_password.rb +1 -0
  40. data/lib/devise/secure_password/controllers/helpers.rb +3 -1
  41. data/lib/devise/secure_password/grammar.rb +13 -0
  42. data/lib/devise/secure_password/models/password_disallows_frequent_changes.rb +3 -1
  43. data/lib/devise/secure_password/models/password_has_required_content.rb +40 -4
  44. data/lib/devise/secure_password/version.rb +1 -1
  45. data/lib/support/string/character_counter.rb +2 -0
  46. metadata +32 -3
  47. data/pkg/devise-secure_password-1.0.7.gem +0 -0
@@ -9,7 +9,7 @@ GIT
9
9
  PATH
10
10
  remote: ..
11
11
  specs:
12
- devise-secure_password (1.0.6)
12
+ devise-secure_password (1.0.8)
13
13
  devise (>= 4.0.0, < 5.0.0)
14
14
  railties (>= 5.0.0, < 6.0.0)
15
15
 
@@ -94,7 +94,7 @@ GEM
94
94
  erubi (1.7.1)
95
95
  erubis (2.7.0)
96
96
  execjs (2.7.0)
97
- ffi (1.9.23)
97
+ ffi (1.9.25)
98
98
  flay (2.12.0)
99
99
  erubis (~> 2.7.0)
100
100
  path_expander (~> 1.0)
@@ -105,6 +105,7 @@ GEM
105
105
  hirb (0.7.3)
106
106
  i18n (1.0.1)
107
107
  concurrent-ruby (~> 1.0)
108
+ jaro_winkler (1.5.1)
108
109
  json (2.1.0)
109
110
  launchy (2.4.3)
110
111
  addressable (~> 2.3)
@@ -126,7 +127,7 @@ GEM
126
127
  parser (2.5.1.0)
127
128
  ast (~> 2.4.0)
128
129
  path_expander (1.0.3)
129
- powerpack (0.1.1)
130
+ powerpack (0.1.2)
130
131
  public_suffix (3.0.2)
131
132
  rack (2.0.5)
132
133
  rack-test (1.0.0)
@@ -184,9 +185,10 @@ GEM
184
185
  rspec-mocks (~> 3.7.0)
185
186
  rspec-support (~> 3.7.0)
186
187
  rspec-support (3.7.1)
187
- rspec_junit_formatter (0.3.0)
188
+ rspec_junit_formatter (0.4.1)
188
189
  rspec-core (>= 2, < 4, != 2.12.0)
189
- rubocop (0.56.0)
190
+ rubocop (0.57.2)
191
+ jaro_winkler (~> 1.5.1)
190
192
  parallel (~> 1.10)
191
193
  parser (>= 2.5)
192
194
  powerpack (~> 0.1)
@@ -240,13 +242,13 @@ GEM
240
242
  tilt (2.0.8)
241
243
  tzinfo (1.2.5)
242
244
  thread_safe (~> 0.1)
243
- unicode-display_width (1.3.2)
245
+ unicode-display_width (1.4.0)
244
246
  warden (1.2.7)
245
247
  rack (>= 1.0)
246
248
  websocket-driver (0.6.5)
247
249
  websocket-extensions (>= 0.1.0)
248
250
  websocket-extensions (0.1.3)
249
- xpath (3.0.0)
251
+ xpath (3.1.0)
250
252
  nokogiri (~> 1.8)
251
253
 
252
254
  PLATFORMS
@@ -0,0 +1,282 @@
1
+ GIT
2
+ remote: https://github.com/thoughtbot/shoulda-matchers.git
3
+ revision: 4b160bd19ecca7f97d7ac22dccd5fde9b0da5a9f
4
+ branch: rails-5
5
+ specs:
6
+ shoulda-matchers (3.1.2)
7
+ activesupport (>= 4.2.0)
8
+
9
+ PATH
10
+ remote: ..
11
+ specs:
12
+ devise-secure_password (1.0.5)
13
+ devise (>= 4.0.0, < 5.0.0)
14
+ railties (>= 5.0.0, < 6.0.0)
15
+
16
+ GEM
17
+ remote: https://rubygems.org/
18
+ specs:
19
+ actioncable (5.1.6)
20
+ actionpack (= 5.1.6)
21
+ nio4r (~> 2.0)
22
+ websocket-driver (~> 0.6.1)
23
+ actionmailer (5.1.6)
24
+ actionpack (= 5.1.6)
25
+ actionview (= 5.1.6)
26
+ activejob (= 5.1.6)
27
+ mail (~> 2.5, >= 2.5.4)
28
+ rails-dom-testing (~> 2.0)
29
+ actionpack (5.1.6)
30
+ actionview (= 5.1.6)
31
+ activesupport (= 5.1.6)
32
+ rack (~> 2.0)
33
+ rack-test (>= 0.6.3)
34
+ rails-dom-testing (~> 2.0)
35
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
36
+ actionview (5.1.6)
37
+ activesupport (= 5.1.6)
38
+ builder (~> 3.1)
39
+ erubi (~> 1.4)
40
+ rails-dom-testing (~> 2.0)
41
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
42
+ activejob (5.1.6)
43
+ activesupport (= 5.1.6)
44
+ globalid (>= 0.3.6)
45
+ activemodel (5.1.6)
46
+ activesupport (= 5.1.6)
47
+ activerecord (5.1.6)
48
+ activemodel (= 5.1.6)
49
+ activesupport (= 5.1.6)
50
+ arel (~> 8.0)
51
+ activesupport (5.1.6)
52
+ concurrent-ruby (~> 1.0, >= 1.0.2)
53
+ i18n (>= 0.7, < 2)
54
+ minitest (~> 5.1)
55
+ tzinfo (~> 1.1)
56
+ addressable (2.5.2)
57
+ public_suffix (>= 2.0.2, < 4.0)
58
+ ansi (1.5.0)
59
+ arel (8.0.0)
60
+ ast (2.4.0)
61
+ bcrypt (3.1.11)
62
+ builder (3.2.3)
63
+ byebug (10.0.2)
64
+ capybara (2.18.0)
65
+ addressable
66
+ mini_mime (>= 0.1.3)
67
+ nokogiri (>= 1.3.3)
68
+ rack (>= 1.0.0)
69
+ rack-test (>= 0.5.4)
70
+ xpath (>= 2.0, < 4.0)
71
+ capybara-screenshot (1.0.19)
72
+ capybara (>= 1.0, < 4)
73
+ launchy
74
+ childprocess (0.9.0)
75
+ ffi (~> 1.0, >= 1.0.11)
76
+ coffee-rails (4.2.2)
77
+ coffee-script (>= 2.2.0)
78
+ railties (>= 4.0.0)
79
+ coffee-script (2.4.1)
80
+ coffee-script-source
81
+ execjs
82
+ coffee-script-source (1.12.2)
83
+ concurrent-ruby (1.0.5)
84
+ crass (1.0.4)
85
+ database_cleaner (1.7.0)
86
+ devise (4.4.3)
87
+ bcrypt (~> 3.0)
88
+ orm_adapter (~> 0.1)
89
+ railties (>= 4.1.0, < 6.0)
90
+ responders
91
+ warden (~> 1.2.3)
92
+ diff-lcs (1.3)
93
+ docile (1.1.5)
94
+ erubi (1.7.1)
95
+ erubis (2.7.0)
96
+ execjs (2.7.0)
97
+ ffi (1.9.23)
98
+ flay (2.11.0)
99
+ erubis (~> 2.7.0)
100
+ path_expander (~> 1.0)
101
+ ruby_parser (~> 3.0)
102
+ sexp_processor (~> 4.0)
103
+ globalid (0.4.1)
104
+ activesupport (>= 4.2.0)
105
+ hirb (0.7.3)
106
+ i18n (1.0.1)
107
+ concurrent-ruby (~> 1.0)
108
+ json (2.1.0)
109
+ launchy (2.4.3)
110
+ addressable (~> 2.3)
111
+ libv8 (3.16.14.19)
112
+ loofah (2.2.2)
113
+ crass (~> 1.0.2)
114
+ nokogiri (>= 1.5.9)
115
+ mail (2.7.0)
116
+ mini_mime (>= 0.1.1)
117
+ method_source (0.9.0)
118
+ mini_mime (1.0.0)
119
+ mini_portile2 (2.3.0)
120
+ minitest (5.11.3)
121
+ nio4r (2.3.0)
122
+ nokogiri (1.8.2)
123
+ mini_portile2 (~> 2.3.0)
124
+ orm_adapter (0.5.0)
125
+ parallel (1.12.1)
126
+ parser (2.5.1.0)
127
+ ast (~> 2.4.0)
128
+ path_expander (1.0.3)
129
+ powerpack (0.1.1)
130
+ public_suffix (3.0.2)
131
+ rack (2.0.5)
132
+ rack-test (1.0.0)
133
+ rack (>= 1.0, < 3)
134
+ rails (5.1.6)
135
+ actioncable (= 5.1.6)
136
+ actionmailer (= 5.1.6)
137
+ actionpack (= 5.1.6)
138
+ actionview (= 5.1.6)
139
+ activejob (= 5.1.6)
140
+ activemodel (= 5.1.6)
141
+ activerecord (= 5.1.6)
142
+ activesupport (= 5.1.6)
143
+ bundler (>= 1.3.0)
144
+ railties (= 5.1.6)
145
+ sprockets-rails (>= 2.0.0)
146
+ rails-dom-testing (2.0.3)
147
+ activesupport (>= 4.2.0)
148
+ nokogiri (>= 1.6)
149
+ rails-html-sanitizer (1.0.4)
150
+ loofah (~> 2.2, >= 2.2.2)
151
+ railties (5.1.6)
152
+ actionpack (= 5.1.6)
153
+ activesupport (= 5.1.6)
154
+ method_source
155
+ rake (>= 0.8.7)
156
+ thor (>= 0.18.1, < 2.0)
157
+ rainbow (3.0.0)
158
+ rake (12.3.1)
159
+ rb-fsevent (0.10.3)
160
+ rb-inotify (0.9.10)
161
+ ffi (>= 0.5.0, < 2)
162
+ ref (2.0.0)
163
+ responders (2.4.0)
164
+ actionpack (>= 4.2.0, < 5.3)
165
+ railties (>= 4.2.0, < 5.3)
166
+ rspec (3.7.0)
167
+ rspec-core (~> 3.7.0)
168
+ rspec-expectations (~> 3.7.0)
169
+ rspec-mocks (~> 3.7.0)
170
+ rspec-core (3.7.1)
171
+ rspec-support (~> 3.7.0)
172
+ rspec-expectations (3.7.0)
173
+ diff-lcs (>= 1.2.0, < 2.0)
174
+ rspec-support (~> 3.7.0)
175
+ rspec-mocks (3.7.0)
176
+ diff-lcs (>= 1.2.0, < 2.0)
177
+ rspec-support (~> 3.7.0)
178
+ rspec-rails (3.7.2)
179
+ actionpack (>= 3.0)
180
+ activesupport (>= 3.0)
181
+ railties (>= 3.0)
182
+ rspec-core (~> 3.7.0)
183
+ rspec-expectations (~> 3.7.0)
184
+ rspec-mocks (~> 3.7.0)
185
+ rspec-support (~> 3.7.0)
186
+ rspec-support (3.7.1)
187
+ rspec_junit_formatter (0.3.0)
188
+ rspec-core (>= 2, < 4, != 2.12.0)
189
+ rubocop (0.55.0)
190
+ parallel (~> 1.10)
191
+ parser (>= 2.5)
192
+ powerpack (~> 0.1)
193
+ rainbow (>= 2.2.2, < 4.0)
194
+ ruby-progressbar (~> 1.7)
195
+ unicode-display_width (~> 1.0, >= 1.0.1)
196
+ ruby-progressbar (1.9.0)
197
+ ruby2ruby (2.4.1)
198
+ ruby_parser (~> 3.1)
199
+ sexp_processor (~> 4.6)
200
+ ruby_parser (3.11.0)
201
+ sexp_processor (~> 4.9)
202
+ rubyzip (1.2.1)
203
+ sass (3.5.6)
204
+ sass-listen (~> 4.0.0)
205
+ sass-listen (4.0.0)
206
+ rb-fsevent (~> 0.9, >= 0.9.4)
207
+ rb-inotify (~> 0.9, >= 0.9.7)
208
+ sass-rails (5.0.7)
209
+ railties (>= 4.0.0, < 6)
210
+ sass (~> 3.1)
211
+ sprockets (>= 2.8, < 4.0)
212
+ sprockets-rails (>= 2.0, < 4.0)
213
+ tilt (>= 1.1, < 3)
214
+ selenium-webdriver (3.11.0)
215
+ childprocess (~> 0.5)
216
+ rubyzip (~> 1.2)
217
+ sexp_processor (4.11.0)
218
+ simplecov (0.15.1)
219
+ docile (~> 1.1.0)
220
+ json (>= 1.8, < 3)
221
+ simplecov-html (~> 0.10.0)
222
+ simplecov-console (0.4.2)
223
+ ansi
224
+ hirb
225
+ simplecov
226
+ simplecov-html (0.10.2)
227
+ sprockets (3.7.1)
228
+ concurrent-ruby (~> 1.0)
229
+ rack (> 1, < 3)
230
+ sprockets-rails (3.2.1)
231
+ actionpack (>= 4.0)
232
+ activesupport (>= 4.0)
233
+ sprockets (>= 3.0.0)
234
+ sqlite3 (1.3.13)
235
+ therubyracer (0.12.3)
236
+ libv8 (~> 3.16.14.15)
237
+ ref
238
+ thor (0.20.0)
239
+ thread_safe (0.3.6)
240
+ tilt (2.0.8)
241
+ tzinfo (1.2.5)
242
+ thread_safe (~> 0.1)
243
+ unicode-display_width (1.3.2)
244
+ warden (1.2.7)
245
+ rack (>= 1.0)
246
+ websocket-driver (0.6.5)
247
+ websocket-extensions (>= 0.1.0)
248
+ websocket-extensions (0.1.3)
249
+ xpath (3.0.0)
250
+ nokogiri (~> 1.8)
251
+
252
+ PLATFORMS
253
+ ruby
254
+
255
+ DEPENDENCIES
256
+ bundler (~> 1.16, >= 1.16.1)
257
+ byebug
258
+ capybara (~> 2.16, >= 2.16.1)
259
+ capybara-screenshot (~> 1.0, >= 1.0.18)
260
+ coffee-rails (~> 4.2)
261
+ database_cleaner (~> 1.6, >= 1.6.2)
262
+ devise (~> 4.0)
263
+ devise-secure_password!
264
+ flay (~> 2.10, >= 2.10.0)
265
+ launchy (~> 2.4, >= 2.4.3)
266
+ rails (~> 5.1.0)
267
+ rake (~> 12.3)
268
+ rspec (~> 3.7)
269
+ rspec-rails (~> 3.7)
270
+ rspec_junit_formatter (~> 0.3)
271
+ rubocop (>= 0.49.0)
272
+ ruby2ruby (~> 2.4, >= 2.4.0)
273
+ sass-rails (~> 5.0)
274
+ selenium-webdriver (~> 3.7, >= 3.7.0)
275
+ shoulda-matchers!
276
+ simplecov (~> 0.15.1)
277
+ simplecov-console (~> 0.4.2)
278
+ sqlite3 (~> 1.3, >= 1.3.13)
279
+ therubyracer (~> 0.12.3)
280
+
281
+ BUNDLED WITH
282
+ 1.16.1
@@ -9,6 +9,7 @@ require 'devise/secure_password/models/password_has_required_content'
9
9
  require 'devise/secure_password/models/password_disallows_frequent_reuse'
10
10
  require 'devise/secure_password/models/password_disallows_frequent_changes'
11
11
  require 'devise/secure_password/models/password_requires_regular_updates'
12
+ require 'devise/secure_password/grammar'
12
13
 
13
14
  module Devise
14
15
  # password_content_enforcement configuration parameters
@@ -5,6 +5,8 @@ module Devise
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
+ include Devise::SecurePassword::Grammar
9
+
8
10
  before_action :authenticate_secure_password!, unless: :devise_controller?
9
11
  end
10
12
 
@@ -32,7 +34,7 @@ module Devise
32
34
  def error_string_for_password_expired
33
35
  I18n.t(
34
36
  'secure_password.password_requires_regular_updates.errors.messages.password_expired',
35
- timeframe: distance_of_time_in_words(warden.user.class.password_maximum_age)
37
+ timeframe: precise_distance_of_time_in_words(warden.user.class.password_maximum_age)
36
38
  )
37
39
  end
38
40
 
@@ -0,0 +1,13 @@
1
+ # lib/support/string/grammar.rb
2
+ #
3
+ module Devise
4
+ module SecurePassword
5
+ module Grammar
6
+ # distance_in_words without determiner words: about, almost, over, etc.
7
+ def precise_distance_of_time_in_words(from_time, to_time = 0, options = {})
8
+ precise_options = { scope: :'secure_password.datetime.precise_distance_in_words' }
9
+ distance_of_time_in_words(from_time, to_time, options.merge!(precise_options))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -7,6 +7,8 @@ module Devise
7
7
 
8
8
  included do
9
9
  include ActionView::Helpers::DateHelper
10
+ include Devise::SecurePassword::Grammar
11
+
10
12
  validate :validate_password_frequent_change, if: :password_required?
11
13
 
12
14
  set_callback(:initialize, :before, :before_resource_initialized)
@@ -17,7 +19,7 @@ module Devise
17
19
  if encrypted_password_changed? && password_recent?
18
20
  error_string = I18n.t(
19
21
  'secure_password.password_disallows_frequent_changes.errors.messages.password_is_recent',
20
- timeframe: distance_of_time_in_words(self.class.password_minimum_age)
22
+ timeframe: precise_distance_of_time_in_words(self.class.password_minimum_age)
21
23
  )
22
24
  errors.add(:base, error_string)
23
25
  end
@@ -10,24 +10,37 @@ module Devise
10
10
  included do
11
11
  validate :validate_password_content, if: :password_required?
12
12
  validate :validate_password_confirmation_content, if: :password_required?
13
+ validate :validate_password_confirmation, if: :password_required?
13
14
  end
14
15
 
15
16
  def validate_password_content
16
17
  self.password ||= ''
18
+ errors.delete(:password)
17
19
  validate_password_content_for(:password)
18
20
  errors[:password].count.zero?
19
21
  end
20
22
 
21
23
  def validate_password_confirmation_content
22
- self.password_confirmation ||= ''
24
+ return true if password_confirmation.nil? # rails skips password_confirmation validation if nil!
25
+ errors.delete(:password_confirmation)
23
26
  validate_password_content_for(:password_confirmation)
24
27
  errors[:password_confirmation].count.zero?
25
28
  end
26
29
 
30
+ def validate_password_confirmation
31
+ return true if password_confirmation.nil? # rails skips password_confirmation validation if nil!
32
+ unless password == password_confirmation
33
+ human_attribute_name = self.class.human_attribute_name(:password)
34
+ errors.add(:password_confirmation, :confirmation, attribute: human_attribute_name)
35
+ end
36
+ errors[:password_confirmation].count.zero?
37
+ end
38
+
27
39
  def validate_password_content_for(attr)
28
40
  return unless respond_to?(attr) && !(password_obj = send(attr)).nil?
29
41
  ::Support::String::CharacterCounter.new.count(password_obj).each do |type, dict|
30
42
  error_string = case type
43
+ when :length then validate_length(dict[:count])
31
44
  when :unknown then validate_unknown(dict)
32
45
  else validate_type(type, dict)
33
46
  end
@@ -47,14 +60,33 @@ module Devise
47
60
  def validate_type(type, dict)
48
61
  type_total = dict.values.reduce(0, :+)
49
62
  error_string = if type_total < required_char_counts_for_type(type)[:min]
50
- error_string_for_length(type, :min)
63
+ error_string_for_type_length(type, :min)
51
64
  elsif type_total > required_char_counts_for_type(type)[:max]
52
- error_string_for_length(type, :max)
65
+ error_string_for_type_length(type, :max)
53
66
  end
54
67
  error_string
55
68
  end
56
69
 
57
- def error_string_for_length(type, threshold = :min)
70
+ def validate_length(dict)
71
+ if dict < Devise.password_length.min
72
+ error_string_for_length(:min)
73
+ elsif dict > Devise.password_length.max
74
+ error_string_for_length(:max)
75
+ end
76
+ end
77
+
78
+ def error_string_for_length(threshold = :min)
79
+ lang_key = case threshold
80
+ when :min then 'secure_password.password_has_required_content.errors.messages.minimum_length'
81
+ when :max then 'secure_password.password_has_required_content.errors.messages.maximum_length'
82
+ else return ''
83
+ end
84
+
85
+ count = required_char_counts_for_type(:length)[threshold]
86
+ I18n.t(lang_key, count: count, subject: 'character'.pluralize(count))
87
+ end
88
+
89
+ def error_string_for_type_length(type, threshold = :min)
58
90
  lang_key = case threshold
59
91
  when :min then 'secure_password.password_has_required_content.errors.messages.minimum_characters'
60
92
  when :max then 'secure_password.password_has_required_content.errors.messages.maximum_characters'
@@ -101,6 +133,10 @@ module Devise
101
133
  def config
102
134
  {
103
135
  REQUIRED_CHAR_COUNTS: {
136
+ length: {
137
+ min: Devise.password_length.min,
138
+ max: Devise.password_length.max
139
+ },
104
140
  uppercase: {
105
141
  min: password_required_uppercase_count,
106
142
  max: LENGTH_MAX