rodauth 1.16.0 → 1.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3e8136954b7c89f30d79ddde2b4741f52f79e20f37419eadd6d41318f9a7307
4
- data.tar.gz: 4c24e750803018e9213111cc7b2542dee126ffa824b2eee340cac431450cce68
3
+ metadata.gz: b1798ddc466406349db5af1aade5b74cc46996c13c2fa67deaba0b4dd868f5a8
4
+ data.tar.gz: fc4232e2eefd30d947285667355fe67bfcd3cd8bb8271d5137f812da525b7ff2
5
5
  SHA512:
6
- metadata.gz: 8920079043a45421794ac3dac2b4c7e2adc24b0c2a5a53c272fd53341c8148e0848020aeea2113d1cea6ab793c93f30bc59ad6a2a82fdd3d533a8988110fcc8a
7
- data.tar.gz: 1d6f4b1efc597efb5ffda44b9725d1768e13117d954f465a09cc4af8bbe28be8c455980db8a8fc778ac6c5aa974812684c619c4fd9743b0c3559ac44db6e2999
6
+ metadata.gz: cb68af1641b0c62f21ac2c0dca6fff2384e4fd45e6110e0bf4ef7ebf7d037475aa0a6f2caa84218303c49be23fc0d05a0735e484374bc9bb4b229967cd9574b2
7
+ data.tar.gz: e2d63f243e0ebfded4b2145cec4b2ae6c9f27980e4a41c9de2b2726aeb22fa4e488a1ae68defb33adfe724666aa6d41649694d06aec06b7de8fd6abe85b57304
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ === 1.17.0 (2018-06-11)
2
+
3
+ * Support Roda route_csrf plugin for request-specific CSRF tokens (jeremyevans)
4
+
1
5
  === 1.16.0 (2018-03-09)
2
6
 
3
7
  * Add disallow_common_passwords feature, for disallowing the usage of the most common passwords (jeremyevans)
@@ -59,11 +59,15 @@ There are some dependencies that Rodauth uses by default, but are
59
59
  development dependencies instead of runtime dependencies in the
60
60
  gem as it is possible to run without them:
61
61
 
62
- tilt, rack_csrf :: Used by all features unless in JSON API only mode.
62
+ tilt :: Used by all features unless in JSON API only mode.
63
+ rack_csrf :: Used by all features unless in JSON API only mode
64
+ or the :csrf=>false|:route_csrf option is used when
65
+ loading the Rodauth plugin.
63
66
  bcrypt :: Used by default for password matching, can be skipped
64
67
  if password_match? is overridden for custom authentication.
65
68
  mail :: Used by default for mailing in the reset password, verify
66
- account, and lockout features.
69
+ account, verify_login_change, change_password_notify, and
70
+ lockout features.
67
71
  rotp, rqrcode :: Used by the otp feature
68
72
  jwt :: Used by the jwt feature
69
73
 
@@ -545,6 +549,32 @@ One thing to notice in the above migrations is that Rodauth uses additional
545
549
  tables for additional features, instead of additional columns in a single
546
550
  table.
547
551
 
552
+ === Locking Down (PostgreSQL only)
553
+
554
+ After running the migrations, you can increase security slightly by making
555
+ it not possible for the +ph+ account to login to the database directly.
556
+ This can be accomplished by modifying the +pg_hba.conf+ file. You can also
557
+ consider restricting access using GRANT/REVOKE.
558
+
559
+ You can restrict access to the database itself to just the +app+ account. You
560
+ can run this using the +app+ account, since that account owns the database:
561
+
562
+ GRANT ALL ON DATABASE ${DATABASE_NAME} TO ${DATABASE_NAME};
563
+ REVOKE ALL ON DATABASE ${DATABASE_NAME} FROM public;
564
+
565
+ You can also restrict access to the public schema (this is not needed if you
566
+ are using a custom schema). Note that by default, the database superuser
567
+ owns the public schema, so you have to run this as the database superuser
568
+ account (generally +postgres+):
569
+
570
+ GRANT ALL ON SCHEMA public TO ${DATABASE_NAME};
571
+ GRANT USAGE ON SCHEMA public TO ${DATABASE_NAME}_password;
572
+ REVOKE ALL ON SCHEMA public FROM public;
573
+
574
+ If you are using MySQL or Microsoft SQL Server, please consult their
575
+ documentation for how to restrict access so that the +ph+ account cannot
576
+ login directly.
577
+
548
578
  == Usage
549
579
 
550
580
  === Basic Usage
@@ -588,7 +618,7 @@ response :: RodaResponse instance
588
618
  scope :: Roda instance
589
619
  session :: session hash
590
620
  flash :: flash message hash
591
- account :: account model instance (if set by an earlier Rodauth method)
621
+ account :: account hash (if set by an earlier Rodauth method)
592
622
 
593
623
  So if you want to log the IP address for the user during login:
594
624
 
@@ -625,6 +655,23 @@ overriding for all behavior, using any information from the request:
625
655
  By allowing every configuration method to take a block, Rodauth
626
656
  should be flexible enough to integrate into most legacy systems.
627
657
 
658
+ === Plugin Options
659
+
660
+ When loading the rodauth plugin, you can also pass an options hash,
661
+ which configures which dependent plugins should be loaded. Options:
662
+
663
+ :csrf :: Set to +false+ to not load a csrf plugin. Set to +:route_csrf+
664
+ to use the route_csrf plugin instead of the csrf plugin. It is
665
+ recommended to set the +:route_csrf+ option as that allows
666
+ for more secure request-specific CSRF tokens.
667
+ :flash :: Set to +false+ to not load the flash plugin
668
+ :json :: Set to +true+ to load the json and json_parser plugins. Set
669
+ to +:only+ to only load those plugins and not any other plugins.
670
+ Note that if you are enabling features that send email, you
671
+ still need to load the render plugin manually.
672
+ :name :: Provide a name for the given Rodauth configuration, used to
673
+ support multiple Rodauth configurations in a given Roda application.
674
+
628
675
  === Feature Documentation
629
676
 
630
677
  The options/methods for the supported features are listed on a
@@ -85,7 +85,12 @@ use_date_arithmetic? :: Whether the date_arithmetic extension should be loaded i
85
85
  the database. Defaults to whether deadline values should
86
86
  be set.
87
87
  use_database_authentication_functions? :: Whether to use functions to do authentication.
88
- True by default on PostgreSQL, false otherwise.
88
+ True by default on PostgreSQL, MySQL, and
89
+ Microsoft SQL Server, false otherwise.
90
+ use_request_specific_csrf_tokens? :: Whether to use request-specific CSRF tokens.
91
+ True if the :csrf=>:route_csrf option is used when
92
+ loading the plugin, and the Roda route_csrf plugin
93
+ is configured to use request-specific CSRF tokens.
89
94
 
90
95
  == Auth Methods
91
96
 
@@ -97,9 +102,9 @@ before_login :: Run arbitrary code after password has been checked, but
97
102
  before_login_attempt :: Run arbitrary code after an account has been
98
103
  located, but before the password has been checked.
99
104
  before_rodauth :: Run arbitrary code before handling any rodauth route.
100
- account_from_login(login) :: Retrieve the account model instance related to the
105
+ account_from_login(login) :: Retrieve the account hash related to the
101
106
  given login or nil if no login matches.
102
- account_from_session :: Retrieve the account model instance related to the currently
107
+ account_from_session :: Retrieve the account hash related to the currently
103
108
  logged in session.
104
109
  account_id :: The primary key value of the current account
105
110
  account_session_value :: The primary value of the account currently stored in the
@@ -110,7 +115,7 @@ authenticated? :: Whether the user has been authenticated. If 2 factor authentic
110
115
  has not been enabled for the account, this is true only if both
111
116
  factors have been authenticated.
112
117
  clear_session :: Clears the current session.
113
- csrf_tag :: The HTML fragment containing the CSRF tag to use, if any.
118
+ csrf_tag(path=request.path) :: The HTML fragment containing the CSRF tag to use, if any.
114
119
  function_name(name) :: The name of the database function to call. It's passed either
115
120
  :rodauth_get_salt or :rodauth_valid_password_hash.
116
121
  logged_in? :: Whether there is an account currently logged in.
@@ -29,7 +29,7 @@ create_account_autologin? :: Whether to autologin the user upon
29
29
  create_account_link :: HTML fragment to display with a link to the create
30
30
  account form.
31
31
  create_account_view :: The HTML to use for the create account form.
32
- new_account(login) :: Instantiate a new account model instance for the
32
+ new_account(login) :: Instantiate a new account hash for the
33
33
  given login, without saving it.
34
34
  save_account :: Insert the account into the database, or return nil/false if that
35
35
  was not successful.
@@ -0,0 +1,23 @@
1
+ = Improvements
2
+
3
+ * Support has been added for using Roda's route_csrf plugin with
4
+ request-specific CSRF tokens. When loading the Rodauth into
5
+ your Roda app, specify the :csrf=>:route_csrf plugin option
6
+ so that Rodauth will load the route_csrf plugin instead of
7
+ the csrf plugin.
8
+
9
+ * The use_request_specific_csrf_tokens? configuration option
10
+ has been added, it defaults to true when the the
11
+ :csrf=>:route_csrf option is used when loading the plugin.
12
+
13
+ * If you have custom templates for the reset password request,
14
+ unlock account request, or verify account resend link
15
+ request, you will have to update them to use the new
16
+ request-specific CSRF token feature.
17
+
18
+ = Backwards Compatibility
19
+
20
+ * The csrf_tag configuration method now accepts the path as
21
+ an optional argument, previously it accepted no arguments.
22
+ The optional argument defaults to the path of the current
23
+ request.
@@ -4,15 +4,27 @@ require 'securerandom'
4
4
 
5
5
  module Rodauth
6
6
  def self.load_dependencies(app, opts={})
7
- if opts[:json]
7
+ json_opt = opts.fetch(:json, app.opts[:rodauth_json])
8
+ if json_opt
8
9
  app.plugin :json
9
10
  app.plugin :json_parser
10
11
  end
11
12
 
12
- unless opts[:json] == :only
13
+ unless json_opt == :only
13
14
  require 'tilt/string'
14
15
  app.plugin :render
15
- app.plugin :csrf unless opts[:csrf] == false
16
+
17
+ case opts.fetch(:csrf, app.opts[:rodauth_route_csrf])
18
+ when false
19
+ # nothing
20
+ when :route_csrf
21
+ # :nocov:
22
+ app.plugin :route_csrf
23
+ # :nocov:
24
+ else
25
+ app.plugin :csrf
26
+ end
27
+
16
28
  app.plugin :flash unless opts[:flash] == false
17
29
  app.plugin :h
18
30
  end
@@ -20,6 +32,7 @@ module Rodauth
20
32
 
21
33
  def self.configure(app, opts={}, &block)
22
34
  app.opts[:rodauth_json] = opts.fetch(:json, app.opts[:rodauth_json])
35
+ app.opts[:rodauth_csrf] = opts.fetch(:csrf, app.opts[:rodauth_route_csrf])
23
36
  auth_class = (app.opts[:rodauths] ||= {})[opts[:name]] ||= Class.new(Auth)
24
37
  if !auth_class.roda_class
25
38
  auth_class.roda_class = app
@@ -53,7 +53,8 @@ module Rodauth
53
53
  :require_login_redirect,
54
54
  :set_deadline_values?,
55
55
  :use_date_arithmetic?,
56
- :use_database_authentication_functions?
56
+ :use_database_authentication_functions?,
57
+ :use_request_specific_csrf_tokens?
57
58
  )
58
59
 
59
60
  auth_methods(
@@ -231,8 +232,16 @@ module Rodauth
231
232
  @account = _account_from_session
232
233
  end
233
234
 
234
- def csrf_tag
235
- scope.csrf_tag if scope.respond_to?(:csrf_tag)
235
+ def csrf_tag(path=request.path)
236
+ return unless scope.respond_to?(:csrf_tag)
237
+
238
+ if use_request_specific_csrf_tokens?
239
+ # :nocov:
240
+ scope.csrf_tag(path)
241
+ # :nocov:
242
+ else
243
+ scope.csrf_tag
244
+ end
236
245
  end
237
246
 
238
247
  def button_opts(value, opts)
@@ -379,6 +388,10 @@ module Rodauth
379
388
  end
380
389
  end
381
390
 
391
+ def use_request_specific_csrf_tokens?
392
+ scope.opts[:rodauth_csrf] == :route_csrf && scope.use_request_specific_csrf_tokens?
393
+ end
394
+
382
395
  def function_name(name)
383
396
  if db.database_type == :mssql
384
397
  # :nocov:
@@ -1,7 +1,22 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Rodauth
4
- VERSION = '1.16.0'.freeze
4
+ # The major version of Rodauth, updated only for major changes that are
5
+ # likely to require modification to apps using Rodauth.
6
+ MAJOR = 1
7
+
8
+ # The minor version of Rodauth, updated for new feature releases of Rodauth.
9
+ MINOR = 17
10
+
11
+ # The patch version of Rodauth, updated only for bug fixes from the last
12
+ # feature release.
13
+ TINY = 0
14
+
15
+ # The full version of Rodauth as a string
16
+ VERSION = "#{MAJOR}.#{MINOR}.#{TINY}".freeze
17
+
18
+ # The full version of Rodauth as a number (1.17.0 => 11700)
19
+ VERSION_NUMBER = MAJOR*10000 + MINOR*100 + TINY
5
20
 
6
21
  def self.version
7
22
  VERSION
@@ -92,7 +92,6 @@ describe 'Rodauth change_password feature' do
92
92
  end
93
93
 
94
94
  it "should support invalid_previous_password_message" do
95
- require_password = true
96
95
  rodauth do
97
96
  enable :login, :logout, :change_password
98
97
  invalid_previous_password_message "Previous password not correct"
@@ -152,7 +152,7 @@ describe 'Rodauth password expiration feature' do
152
152
  rodauth do
153
153
  enable :login, :change_password, :password_expiration
154
154
  password_expiration_default true
155
- allow_password_change_after -1000
155
+ allow_password_change_after(-1000)
156
156
  change_password_requires_password? false
157
157
  require_password_change_after 3600
158
158
  end
@@ -184,7 +184,7 @@ describe 'Rodauth' do
184
184
 
185
185
  it "should support multiple rodauth configurations in an app" do
186
186
  app = Class.new(Base)
187
- app.plugin(:rodauth) do
187
+ app.plugin(:rodauth, rodauth_opts) do
188
188
  enable :login
189
189
  if ENV['RODAUTH_SEPARATE_SCHEMA']
190
190
  password_hash_table Sequel[:rodauth_test_password][:account_password_hashes]
@@ -193,10 +193,18 @@ describe 'Rodauth' do
193
193
  end
194
194
  end
195
195
  end
196
- app.plugin(:rodauth, :name=>:r2) do
196
+ app.plugin(:rodauth, rodauth_opts.merge(:name=>:r2)) do
197
197
  enable :logout
198
198
  end
199
+
200
+ if Minitest::HooksSpec::USE_ROUTE_CSRF
201
+ app.plugin :route_csrf, Minitest::HooksSpec::ROUTE_CSRF_OPTS
202
+ end
203
+
199
204
  app.route do |r|
205
+ if Minitest::HooksSpec::USE_ROUTE_CSRF
206
+ check_csrf!
207
+ end
200
208
  r.on 'r1' do
201
209
  r.rodauth
202
210
  'r1'
@@ -2,7 +2,7 @@ $: << 'lib'
2
2
 
3
3
  if ENV['WARNING']
4
4
  require 'warning'
5
- Warning.ignore([:missing_ivar, :missing_gvar, :fixnum])
5
+ Warning.ignore([:missing_ivar, :missing_gvar, :fixnum, :not_reached])
6
6
  #Warning.ignore(/warning: URI\.escape is obsolete\n\z/)
7
7
  Warning.ignore(:method_redefined, File.dirname(File.dirname(__FILE__)))
8
8
  end
@@ -29,6 +29,8 @@ require 'capybara'
29
29
  require 'capybara/dsl'
30
30
  require 'rack/test'
31
31
  require 'stringio'
32
+
33
+ ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
32
34
  gem 'minitest'
33
35
  require 'minitest/autorun'
34
36
  require 'minitest/hooks/default'
@@ -83,6 +85,17 @@ JsonBase.plugin(:not_found){raise "path #{request.path_info} not found"}
83
85
  class Minitest::HooksSpec
84
86
  include Rack::Test::Methods
85
87
  include Capybara::DSL
88
+
89
+ case ENV['RODA_ROUTE_CSRF']
90
+ when '1'
91
+ USE_ROUTE_CSRF = true
92
+ ROUTE_CSRF_OPTS = {}
93
+ when '2'
94
+ USE_ROUTE_CSRF = true
95
+ ROUTE_CSRF_OPTS = {:require_request_specific_tokens=>false}
96
+ else
97
+ USE_ROUTE_CSRF = false
98
+ end
86
99
 
87
100
  attr_reader :app
88
101
 
@@ -98,6 +111,14 @@ class Minitest::HooksSpec
98
111
  @rodauth_block = block
99
112
  end
100
113
 
114
+ def rodauth_opts(type={})
115
+ opts = type.is_a?(Hash) ? type : {}
116
+ if USE_ROUTE_CSRF && !opts.has_key?(:csrf)
117
+ opts[:csrf] = :route_csrf
118
+ end
119
+ opts
120
+ end
121
+
101
122
  def roda(type=nil, &block)
102
123
  jwt_only = type == :jwt
103
124
  jwt = type == :jwt || type == :jwt_html
@@ -111,7 +132,7 @@ class Minitest::HooksSpec
111
132
  app.opts[:unsupported_matcher] = :raise
112
133
  app.opts[:verbatim_string_matcher] = true
113
134
  rodauth_block = @rodauth_block
114
- opts = type.is_a?(Hash) ? type : {}
135
+ opts = rodauth_opts(type)
115
136
 
116
137
  if jwt
117
138
  opts[:json] = jwt_only ? :only : true
@@ -133,6 +154,14 @@ class Minitest::HooksSpec
133
154
  end
134
155
  instance_exec(&rodauth_block)
135
156
  end
157
+ if USE_ROUTE_CSRF && !jwt_only && opts[:csrf] != false
158
+ app.plugin(:route_csrf, ROUTE_CSRF_OPTS)
159
+ orig_block = block
160
+ block = proc do |r|
161
+ check_csrf!
162
+ instance_exec(r, &orig_block)
163
+ end
164
+ end
136
165
  app.route(&block)
137
166
  app.precompile_rodauth_templates unless @no_precompile || jwt_only
138
167
  app.freeze unless @no_freeze
@@ -102,7 +102,7 @@ describe 'Rodauth verify_login_change feature' do
102
102
  fill_in 'Login', :with=>'foo@example2.com'
103
103
  fill_in 'Confirm Login', :with=>'foo@example2.com'
104
104
  click_button 'Change Login'
105
- link = email_link(/(\/verify-login-change\?key=.+)$/, 'foo@example2.com')
105
+ email_link(/(\/verify-login-change\?key=.+)$/, 'foo@example2.com')
106
106
  page.find('#notice_flash').text.must_equal "An email has been sent to you with a link to verify your login change"
107
107
 
108
108
  unique = lambda{DB[:account_login_change_keys].update(:login=>'foo@example3.com'); true}
@@ -1,6 +1,6 @@
1
1
  <form action="#{rodauth.prefix}/#{rodauth.reset_password_request_route}" method="post" class="rodauth form-horizontal" role="form" id="reset-password-request-form">
2
2
  #{rodauth.reset_password_request_additional_form_tags}
3
- #{rodauth.csrf_tag}
3
+ #{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.reset_password_request_route}")}
4
4
  <p>If you have forgotten your password, you can request a password reset: </p>
5
5
  #{(login = rodauth.param_or_nil(rodauth.login_param)) ? "<input type=\"hidden\" name=\"#{rodauth.login_param}\" value=\"#{h login}\"/>" : rodauth.render('login-field')}
6
6
  #{rodauth.button(rodauth.reset_password_request_button)}
@@ -1,6 +1,6 @@
1
1
  <form action="#{rodauth.prefix}/#{rodauth.unlock_account_request_route}" method="post" class="rodauth form-horizontal" role="form" id="unlock-account-request-form">
2
2
  #{rodauth.unlock_account_request_additional_form_tags}
3
- #{rodauth.csrf_tag}
3
+ #{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.unlock_account_request_route}")}
4
4
  <input type="hidden" name="#{rodauth.login_param}" value="#{h rodauth.param(rodauth.login_param)}"/>
5
5
  This account is currently locked out. You can request that the account be unlocked:
6
6
  <input type="submit" class="btn btn-primary inline" value="#{rodauth.unlock_account_request_button}"/>
@@ -1,6 +1,6 @@
1
1
  <form action="#{rodauth.prefix}/#{rodauth.verify_account_resend_route}" method="post" class="rodauth form-horizontal" role="form" id="verify-account-resend-form">
2
2
  #{rodauth.verify_account_resend_additional_form_tags}
3
- #{rodauth.csrf_tag}
3
+ #{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.verify_account_resend_route}")}
4
4
  <p>If you no longer have the email to verify the account, you can request that it be resent to you:</p>
5
5
  #{(login = rodauth.param_or_nil(rodauth.login_param)) ? "<input type=\"hidden\" name=\"#{rodauth.login_param}\" value=\"#{h login}\"/>" : rodauth.render('login-field')}
6
6
  #{rodauth.button(rodauth.verify_account_resend_button)}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.0
4
+ version: 1.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-09 00:00:00.000000000 Z
11
+ date: 2018-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -196,42 +196,50 @@ extra_rdoc_files:
196
196
  - README.rdoc
197
197
  - CHANGELOG
198
198
  - MIT-LICENSE
199
+ - doc/change_password_notify.rdoc
200
+ - doc/account_expiration.rdoc
199
201
  - doc/base.rdoc
200
- - doc/login.rdoc
201
- - doc/logout.rdoc
202
+ - doc/change_login.rdoc
202
203
  - doc/change_password.rdoc
203
- - doc/reset_password.rdoc
204
- - doc/remember.rdoc
205
- - doc/create_account.rdoc
204
+ - doc/confirm_password.rdoc
206
205
  - doc/close_account.rdoc
207
- - doc/verify_account.rdoc
206
+ - doc/http_basic_auth.rdoc
207
+ - doc/create_account.rdoc
208
+ - doc/email_base.rdoc
209
+ - doc/internals.rdoc
210
+ - doc/disallow_common_passwords.rdoc
211
+ - doc/disallow_password_reuse.rdoc
212
+ - doc/password_complexity.rdoc
213
+ - doc/jwt.rdoc
208
214
  - doc/lockout.rdoc
215
+ - doc/login.rdoc
216
+ - doc/logout.rdoc
209
217
  - doc/otp.rdoc
210
- - doc/change_login.rdoc
211
- - doc/password_complexity.rdoc
212
- - doc/disallow_password_reuse.rdoc
218
+ - doc/login_password_requirements_base.rdoc
219
+ - doc/verify_change_login.rdoc
213
220
  - doc/password_expiration.rdoc
214
- - doc/account_expiration.rdoc
215
- - doc/single_session.rdoc
221
+ - doc/password_grace_period.rdoc
216
222
  - doc/recovery_codes.rdoc
223
+ - doc/remember.rdoc
224
+ - doc/reset_password.rdoc
225
+ - doc/session_expiration.rdoc
226
+ - doc/single_session.rdoc
217
227
  - doc/sms_codes.rdoc
218
- - doc/email_base.rdoc
219
228
  - doc/two_factor_base.rdoc
220
- - doc/jwt.rdoc
221
- - doc/password_grace_period.rdoc
222
- - doc/session_expiration.rdoc
223
- - doc/login_password_requirements_base.rdoc
224
- - doc/verify_account_grace_period.rdoc
225
- - doc/confirm_password.rdoc
226
- - doc/verify_change_login.rdoc
227
229
  - doc/update_password_hash.rdoc
228
- - doc/http_basic_auth.rdoc
230
+ - doc/verify_account.rdoc
231
+ - doc/verify_account_grace_period.rdoc
229
232
  - doc/verify_login_change.rdoc
230
- - doc/internals.rdoc
231
- - doc/change_password_notify.rdoc
232
- - doc/disallow_common_passwords.rdoc
233
+ - doc/release_notes/1.17.0.txt
233
234
  - doc/release_notes/1.0.0.txt
234
235
  - doc/release_notes/1.1.0.txt
236
+ - doc/release_notes/1.10.0.txt
237
+ - doc/release_notes/1.11.0.txt
238
+ - doc/release_notes/1.12.0.txt
239
+ - doc/release_notes/1.13.0.txt
240
+ - doc/release_notes/1.14.0.txt
241
+ - doc/release_notes/1.15.0.txt
242
+ - doc/release_notes/1.16.0.txt
235
243
  - doc/release_notes/1.2.0.txt
236
244
  - doc/release_notes/1.3.0.txt
237
245
  - doc/release_notes/1.4.0.txt
@@ -240,13 +248,6 @@ extra_rdoc_files:
240
248
  - doc/release_notes/1.7.0.txt
241
249
  - doc/release_notes/1.8.0.txt
242
250
  - doc/release_notes/1.9.0.txt
243
- - doc/release_notes/1.10.0.txt
244
- - doc/release_notes/1.11.0.txt
245
- - doc/release_notes/1.12.0.txt
246
- - doc/release_notes/1.13.0.txt
247
- - doc/release_notes/1.14.0.txt
248
- - doc/release_notes/1.15.0.txt
249
- - doc/release_notes/1.16.0.txt
250
251
  files:
251
252
  - CHANGELOG
252
253
  - MIT-LICENSE
@@ -285,6 +286,7 @@ files:
285
286
  - doc/release_notes/1.14.0.txt
286
287
  - doc/release_notes/1.15.0.txt
287
288
  - doc/release_notes/1.16.0.txt
289
+ - doc/release_notes/1.17.0.txt
288
290
  - doc/release_notes/1.2.0.txt
289
291
  - doc/release_notes/1.3.0.txt
290
292
  - doc/release_notes/1.4.0.txt
@@ -442,7 +444,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
442
444
  version: '0'
443
445
  requirements: []
444
446
  rubyforge_project:
445
- rubygems_version: 2.7.3
447
+ rubygems_version: 2.7.6
446
448
  signing_key:
447
449
  specification_version: 4
448
450
  summary: Authentication and Account Management Framework for Rack Applications