rodauth 1.9.0 → 1.10.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 +4 -4
- data/CHANGELOG +20 -0
- data/README.rdoc +14 -3
- data/Rakefile +2 -2
- data/doc/base.rdoc +1 -1
- data/doc/internals.rdoc +222 -0
- data/doc/release_notes/1.10.0.txt +80 -0
- data/doc/reset_password.rdoc +8 -2
- data/doc/verify_account.rdoc +7 -1
- data/doc/verify_change_login.rdoc +8 -6
- data/doc/verify_login_change.rdoc +52 -0
- data/lib/rodauth/features/account_expiration.rb +1 -1
- data/lib/rodauth/features/base.rb +1 -1
- data/lib/rodauth/features/change_login.rb +9 -2
- data/lib/rodauth/features/change_password.rb +1 -1
- data/lib/rodauth/features/close_account.rb +1 -1
- data/lib/rodauth/features/confirm_password.rb +1 -1
- data/lib/rodauth/features/create_account.rb +1 -1
- data/lib/rodauth/features/disallow_password_reuse.rb +1 -1
- data/lib/rodauth/features/email_base.rb +6 -2
- data/lib/rodauth/features/http_basic_auth.rb +1 -1
- data/lib/rodauth/features/jwt.rb +1 -1
- data/lib/rodauth/features/lockout.rb +1 -1
- data/lib/rodauth/features/login.rb +1 -1
- data/lib/rodauth/features/login_password_requirements_base.rb +1 -1
- data/lib/rodauth/features/logout.rb +1 -1
- data/lib/rodauth/features/otp.rb +1 -1
- data/lib/rodauth/features/password_complexity.rb +1 -1
- data/lib/rodauth/features/password_expiration.rb +1 -1
- data/lib/rodauth/features/password_grace_period.rb +1 -1
- data/lib/rodauth/features/recovery_codes.rb +1 -1
- data/lib/rodauth/features/remember.rb +1 -1
- data/lib/rodauth/features/reset_password.rb +22 -4
- data/lib/rodauth/features/session_expiration.rb +1 -1
- data/lib/rodauth/features/single_session.rb +1 -1
- data/lib/rodauth/features/sms_codes.rb +1 -1
- data/lib/rodauth/features/two_factor_base.rb +1 -1
- data/lib/rodauth/features/update_password_hash.rb +1 -1
- data/lib/rodauth/features/verify_account.rb +23 -5
- data/lib/rodauth/features/verify_account_grace_period.rb +1 -1
- data/lib/rodauth/features/verify_change_login.rb +1 -1
- data/lib/rodauth/features/verify_login_change.rb +189 -0
- data/lib/rodauth/version.rb +1 -1
- data/lib/rodauth.rb +16 -2
- data/spec/migrate/001_tables.rb +10 -0
- data/spec/migrate_travis/001_tables.rb +7 -0
- data/spec/reset_password_spec.rb +8 -1
- data/spec/rodauth_spec.rb +27 -0
- data/spec/spec_helper.rb +11 -7
- data/spec/verify_account_grace_period_spec.rb +36 -0
- data/spec/verify_account_spec.rb +6 -0
- data/spec/verify_login_change_spec.rb +179 -0
- data/templates/reset-password-request.str +3 -3
- data/templates/verify-account-resend.str +3 -3
- data/templates/verify-login-change-email.str +9 -0
- data/templates/verify-login-change.str +5 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1741b1db3b830dd1edde47d251c388e51901d85
|
4
|
+
data.tar.gz: 1066a17b7b2a3565335cbcd47ef6903d3c1f5a93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76b1d26463432bb939565f09b3779cbdf6f8d7b632079115eaf62288c2817f80c1f24752e3847893e17242eadb21eccfae5cc7d7df54a45f4f7be2032207e751
|
7
|
+
data.tar.gz: 59c18ab583fde50543c9284a7831d2fbf2087d64bb8e5c33a257b82cd3b3ded7c6d28f1a38a6a32cbba04d1c34ff9d2d87264a9356fc44cc40c02ceac8298454
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
=== 1.10.0 (2017-03-23)
|
2
|
+
|
3
|
+
* Add Internals Guide (jeremyevans)
|
4
|
+
|
5
|
+
* Set FeatureConfiguration instances to constants, just like Feature instances (jeremyevans)
|
6
|
+
|
7
|
+
* When reopening rodauth configuration in roda subclass, automatically subclass rodauth configuration so it doesn't modify superclass (jeremyevans)
|
8
|
+
|
9
|
+
* Add verify_login_change feature as an alternative to verify_change_login, where the change doesn't take affect until after verification (jeremyevans) (#31)
|
10
|
+
|
11
|
+
* Add login_failed_reset_password_request_form for customizing the HTML used for the request password request form on login failures (jeremyevans)
|
12
|
+
|
13
|
+
* Make reset password request form available without requiring a login attempt, and provide a login field in that case (jeremyevans) (#30)
|
14
|
+
|
15
|
+
* Make resending verify account email request form available without requiring a login/account creation attempt, and provide a login field in that case (jeremyevans) (#30)
|
16
|
+
|
17
|
+
* Fix resending verify account email when attempting to create a new account with same login as unverified account when using verify_account_grace_period feature (jeremyevans) (#30)
|
18
|
+
|
19
|
+
* Fix precompile_rodauth_templates usage with reset_password feature (jeremyevans)
|
20
|
+
|
1
21
|
=== 1.9.0 (2017-02-22)
|
2
22
|
|
3
23
|
* Make reset-password use existing password reset key if one is present (jeremyevans) (#26)
|
data/README.rdoc
CHANGED
@@ -29,7 +29,7 @@ hashes by protecting access via database functions.
|
|
29
29
|
* OTP (2 factor authentication via TOTP)
|
30
30
|
* Recovery Codes (2 factor authentication via backup codes)
|
31
31
|
* SMS Codes (2 factor authentication via SMS)
|
32
|
-
* Verify Change
|
32
|
+
* Verify Login Change (Verify new login before changing login)
|
33
33
|
* Verify Account Grace Period (Don't require verification before login)
|
34
34
|
* Password Grace Period (Don't require password entry if recently entered)
|
35
35
|
* Password Complexity (More sophisticated checks)
|
@@ -280,6 +280,14 @@ versions of Sequel, switch the :Bignum symbols to Bignum constants.
|
|
280
280
|
DateTime :requested_at, :null=>false, :default=>Sequel::CURRENT_TIMESTAMP
|
281
281
|
end
|
282
282
|
|
283
|
+
# Used by the verify login change feature
|
284
|
+
create_table(:account_login_change_keys) do
|
285
|
+
foreign_key :id, :accounts, :primary_key=>true, :type=>:Bignum
|
286
|
+
String :key, :null=>false
|
287
|
+
String :login, :null=>false
|
288
|
+
DateTime :deadline, deadline_opts[1]
|
289
|
+
end
|
290
|
+
|
283
291
|
# Used by the remember me feature
|
284
292
|
create_table(:account_remember_keys) do
|
285
293
|
foreign_key :id, :accounts, :primary_key=>true, :type=>:Bignum
|
@@ -356,6 +364,7 @@ versions of Sequel, switch the :Bignum symbols to Bignum constants.
|
|
356
364
|
run "GRANT ALL ON accounts TO #{user}"
|
357
365
|
run "GRANT ALL ON account_password_reset_keys TO #{user}"
|
358
366
|
run "GRANT ALL ON account_verification_keys TO #{user}"
|
367
|
+
run "GRANT ALL ON account_login_change_keys TO #{user}"
|
359
368
|
run "GRANT ALL ON account_remember_keys TO #{user}"
|
360
369
|
run "GRANT ALL ON account_login_failures TO #{user}"
|
361
370
|
run "GRANT ALL ON account_lockouts TO #{user}"
|
@@ -378,6 +387,7 @@ versions of Sequel, switch the :Bignum symbols to Bignum constants.
|
|
378
387
|
:account_lockouts,
|
379
388
|
:account_login_failures,
|
380
389
|
:account_remember_keys,
|
390
|
+
:account_login_change_keys,
|
381
391
|
:account_verification_keys,
|
382
392
|
:account_password_reset_keys,
|
383
393
|
:accounts,
|
@@ -993,8 +1003,9 @@ use the following basic structure
|
|
993
1003
|
|
994
1004
|
module Rodauth
|
995
1005
|
# :feature_name will be the argument given to enable to
|
996
|
-
# load the feature
|
997
|
-
|
1006
|
+
# load the feature, :FeatureName is optional and will be used to
|
1007
|
+
# set a constant name for prettier inspect output.
|
1008
|
+
Feature.define(:feature_name, :FeatureName) do
|
998
1009
|
# Shortcut for defining auth value methods with static values
|
999
1010
|
auth_value_method :method_name, 1 # method_value
|
1000
1011
|
|
data/Rakefile
CHANGED
@@ -116,10 +116,10 @@ task :db_setup_mssql do
|
|
116
116
|
$: << 'lib'
|
117
117
|
require 'sequel'
|
118
118
|
Sequel.extension :migration
|
119
|
-
Sequel.tinytds('rodauth_test', :user=>'rodauth_test_password', :password=>'
|
119
|
+
Sequel.tinytds('rodauth_test', :host=>'localhost', :user=>'rodauth_test_password', :password=>'Rodauth1.') do |db|
|
120
120
|
Sequel::Migrator.run(db, 'spec/migrate')
|
121
121
|
end
|
122
|
-
Sequel.tinytds('rodauth_test', :user=>'rodauth_test_password', :password=>'
|
122
|
+
Sequel.tinytds('rodauth_test', :host=>'localhost', :user=>'rodauth_test_password', :password=>'Rodauth1.') do |db|
|
123
123
|
Sequel::Migrator.run(db, 'spec/migrate_password', :table=>'schema_info_password')
|
124
124
|
end
|
125
125
|
end
|
data/doc/base.rdoc
CHANGED
@@ -116,7 +116,7 @@ password_match?(password) :: Check whether the given password matches the
|
|
116
116
|
stored password hash.
|
117
117
|
random_key :: A randomly generated string, used for creating tokens.
|
118
118
|
redirect(path) :: Redirect the request to the given path.
|
119
|
-
session_value ::
|
119
|
+
session_value :: The value for session_key in the current session.
|
120
120
|
set_error_flash(message) :: Set the current error flash to the given message.
|
121
121
|
set_notice_flash(message) :: Set the next notice flash to the given message.
|
122
122
|
set_notice_now_flash(message) :: Set the current notice flash to the given message.
|
data/doc/internals.rdoc
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
= Rodauth Internals
|
2
|
+
|
3
|
+
Rodauth's implementation heavily uses metaprogramming in order to DRY up the codebase, which can be a little intimiting to developers who are not familiar with the codebase. This guide explains how Rodauth is built, which should make the internals easier to understand.
|
4
|
+
|
5
|
+
== Object Model
|
6
|
+
|
7
|
+
First, let's talk about the basic parts of Rodauth.
|
8
|
+
|
9
|
+
=== Rodauth::Auth
|
10
|
+
|
11
|
+
Rodauth::Auth is the core of rodauth. If a user calls +rodauth+ inside their Roda application, they get a Rodauth::Auth subclass instance. Rodauth's configuration DSL is designed to build a Rodauth::Auth subclass appropriate to the application, by loading only the features that are needed, and overriding defaults as appropriate.
|
12
|
+
|
13
|
+
=== Rodauth::Configuration
|
14
|
+
|
15
|
+
Inside the block you pass to <tt>plugin :rodauth</tt>, +self+ is an instance of this class. This class is mostly empty, as most of Rodauth is implemented as separate features, and the configuration for each feature is loaded as a separate module into this instance.
|
16
|
+
|
17
|
+
=== Rodauth::Feature
|
18
|
+
|
19
|
+
Each of the parts of rodauth that you can use is going to be a separate feature. Rodauth::Feature is a Module subclass, and every feature you load is included in the Rodauth::Auth subclass used by the Roda application. Rodauth::Feature has many methods designed to make building Rodauth features easier by defining methods in the Rodauth::Feature instance.
|
20
|
+
|
21
|
+
=== Rodauth::FeatureConfiguration
|
22
|
+
|
23
|
+
Just as each feature is a module included in the Rodauth::Auth subclass for the application, each feature also contains a configuration module that is an instance of Rodauth::FeatureConfiguration (also a module subclass). For each feature you load into the Rodauth configuration, the Rodauth::Configuration instance is extended with the feature's Rodauth::FeatureConfiguration instance, which is what makes the feature's configuration methods available inside the <tt>plugin :rodauth</tt> block. This is why you need to enable the features in Rodauth before configuring them.
|
24
|
+
|
25
|
+
|
26
|
+
== Object Model Example
|
27
|
+
|
28
|
+
Here's some commented output hopefully showing the relation between the different parts
|
29
|
+
|
30
|
+
Roda.plugin :rodauth do
|
31
|
+
self # => #<Rodauth::Configuration> (instance)
|
32
|
+
auth # => Rodauth::Auth subclass
|
33
|
+
|
34
|
+
singleton_class.ancestors # => [#<Class:#<Rodauth::Configuration>> (singleton class of self),
|
35
|
+
# Rodauth::FeatureConfiguration::Base (instance of Rodauth::FeatureConfiguration),
|
36
|
+
# Rodauth::Configuration,
|
37
|
+
# ...]
|
38
|
+
auth.ancestors # => [Rodauth::Auth subclass,
|
39
|
+
# Rodauth::Base (instance of Rodauth::Feature),
|
40
|
+
# Rodauth::Auth,
|
41
|
+
# ...]
|
42
|
+
|
43
|
+
enable :login
|
44
|
+
|
45
|
+
singleton_class.ancestors # => [#<Class:#<Rodauth::Configuration>> (singleton class of self),
|
46
|
+
# Rodauth::FeatureConfiguration::Login (instance of Rodauth::FeatureConfiguration),
|
47
|
+
# Rodauth::FeatureConfiguration::Base (instance of Rodauth::FeatureConfiguration),
|
48
|
+
# Rodauth::Configuration,
|
49
|
+
# ...]
|
50
|
+
auth.ancestors # => [Rodauth::Auth subclass,
|
51
|
+
# Rodauth::Login (instance of Rodauth::Feature),
|
52
|
+
# Rodauth::Base (instance of Rodauth::Feature),
|
53
|
+
# Rodauth::Auth,
|
54
|
+
# ...]
|
55
|
+
end
|
56
|
+
|
57
|
+
Roda.rodauth # => Rodauth::Auth subclass
|
58
|
+
Roda.rodauth.ancestors # => [Rodauth::Auth subclass,
|
59
|
+
# Rodauth::Login (instance of Rodauth::Feature),
|
60
|
+
# Rodauth::Base (instance of Rodauth::Feature),
|
61
|
+
# Rodauth::Auth,
|
62
|
+
# ...]
|
63
|
+
|
64
|
+
Roda.route do |r|
|
65
|
+
rodauth # => Rodauth::Auth subclass instance
|
66
|
+
end
|
67
|
+
|
68
|
+
== Feature Creation Example
|
69
|
+
|
70
|
+
Here's a heavily commented example showing what is going on inside a Rodauth feature.
|
71
|
+
|
72
|
+
module Rodauth
|
73
|
+
# Feature.define takes a symbol, specifying the name of the feature. This
|
74
|
+
# is the same symbol you would pass to enable when loading the feature into
|
75
|
+
# the Rodauth configuration. Feature is a module subclass, and Feature.define
|
76
|
+
# is a class method that creates an instance of Feature (a module) and executes
|
77
|
+
# the block in the context of the Feature instance.
|
78
|
+
#
|
79
|
+
# The second argument is optional, and sets the Feature instance and related
|
80
|
+
# FeatureConfiguration instance to a constant in the Rodauth namespace, which
|
81
|
+
# makes it easier to locate via inspect.
|
82
|
+
Feature.define(:foo, :Foo) do
|
83
|
+
# Inside this block, self is an instance of Feature. As this instance of
|
84
|
+
# Feature will be included in the Rodauth::Auth subclass instance if
|
85
|
+
# the feature is loaded into the rodauth configuration, methods you define
|
86
|
+
# in this block (via def or define_method) will be callable on any
|
87
|
+
# rodauth object if this feature is loaded into the rodauth configuration.
|
88
|
+
|
89
|
+
# Feature has many instance methods that define methods in the Feature
|
90
|
+
# instance. This is one of those methods, which sets the text of the notice
|
91
|
+
# flash, shown after successful submission of the form. It's basically
|
92
|
+
# equivalent to executing this code in the feature:
|
93
|
+
#
|
94
|
+
# def foo_notice_flash
|
95
|
+
# "It worked!"
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
# while also adding a method to the configuration which does:
|
99
|
+
#
|
100
|
+
# def foo_notice_flash(v=nil, &block)
|
101
|
+
# block ||= proc{v}
|
102
|
+
# @auth.class_eval do
|
103
|
+
# define_method(:foo_notice_flash, &block)
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# This is what easily allows you to modify any part of Rodauth during
|
108
|
+
# configuration. The Rodauth::Auth subclass has the default behavior
|
109
|
+
# added via a method in an included module (the Feature instance), and the
|
110
|
+
# Rodauth::Configuration instance has a method that when called defines
|
111
|
+
# a method in the Rodauth::Auth subclass itself, which will take precedence
|
112
|
+
# over the default method, which defined in the included Feature instance.
|
113
|
+
notice_flash "It worked!"
|
114
|
+
|
115
|
+
# The rest of these method calls are fairly similar to notice_flash.
|
116
|
+
# This defines the foo_error_flash method, for the error flash message to
|
117
|
+
# show if the form submission wasn't successful.
|
118
|
+
error_flash "There was an error"
|
119
|
+
|
120
|
+
# This defines the foo_view method to use template 'foo.str' in the templates
|
121
|
+
# folder, and set the title of the page to 'Foo'.
|
122
|
+
view 'foo', 'Foo'
|
123
|
+
|
124
|
+
# This defines the foo_additional_form_tags method, which would generally be called
|
125
|
+
# inside the foo.str template.
|
126
|
+
additional_form_tags
|
127
|
+
|
128
|
+
# This defines the foo_button method, for the text to use on the submit button
|
129
|
+
# for the form in foo.str.
|
130
|
+
button 'Submit'
|
131
|
+
|
132
|
+
# This defines the foo_redirect method, for where to redirect after successful submission
|
133
|
+
# of the form.
|
134
|
+
redirect
|
135
|
+
|
136
|
+
# This defines the before_foo method, called before performing the foo action.
|
137
|
+
before
|
138
|
+
|
139
|
+
# This defines the after_foo method, called after successfully performing the foo action.
|
140
|
+
after
|
141
|
+
|
142
|
+
# This defines a loaded_templates method that calls super and adds 'foo' as one of the
|
143
|
+
# templates. This is necessary for precompilation of templates to work.
|
144
|
+
loaded_templates ['foo']
|
145
|
+
|
146
|
+
# auth_value_method is a generic method that takes two arguments, a method to define
|
147
|
+
# and a default value. It is similar to the methods above, except that it allows
|
148
|
+
# arbitrary method names. The notice_flash, error_flash, button, and additional_form_tags
|
149
|
+
# methods are actually defined in terms of this method.
|
150
|
+
#
|
151
|
+
# So this particular method defines a foo_error_status method that will return 401 by
|
152
|
+
# default, but also adds a cofniguration method that allows you to override the default.
|
153
|
+
auth_value_method :foo_error_status, 401
|
154
|
+
|
155
|
+
# This is similar to auth_value_method, but it only adds the configuration method.
|
156
|
+
# Using this should only be done if you have defining the method in the feature
|
157
|
+
# separately (see below).
|
158
|
+
auth_value_methods :foo_bar
|
159
|
+
|
160
|
+
# This is similar to auth_value_methods, but it changes the configuration method so that
|
161
|
+
# a block is required and you cannot provide an argument. This is used for the cases
|
162
|
+
# where a statically defined value would never make sense, such as when any correct
|
163
|
+
# behavior would depend on accessing request-specific information.
|
164
|
+
auth_methods :foo
|
165
|
+
|
166
|
+
# route defines a route used for the feature. This is the code that will be executed
|
167
|
+
# if a user goes to /foo in the Roda app.
|
168
|
+
route do |r|
|
169
|
+
# Inside the block, you are in the context of the Roda instance, just as you would
|
170
|
+
# be inside a Roda route block. r is the RodaRequest instance, just as it would
|
171
|
+
# be for a Roda route block.
|
172
|
+
|
173
|
+
# route adds a before_foo_route method that by default does nothing. It also
|
174
|
+
# adds a configuration method that you can call to set behavior that will be
|
175
|
+
# executed before routing.
|
176
|
+
before_foo_route
|
177
|
+
|
178
|
+
# Just like in Roda, r.get is called for GET requests
|
179
|
+
r.get do
|
180
|
+
# This will render a view to the user, using the foo.erb template from the
|
181
|
+
# templates directory (unless the user has overridden it), inside the Roda
|
182
|
+
# application's layout.
|
183
|
+
foo_view
|
184
|
+
end
|
185
|
+
|
186
|
+
# Just like in Roda, r.post is called for GET requests
|
187
|
+
r.post do
|
188
|
+
# This is called before performing the foo action
|
189
|
+
before_foo
|
190
|
+
|
191
|
+
# This assumes foo returns false or nil on failure, or otherwise on
|
192
|
+
# success.
|
193
|
+
if foo
|
194
|
+
# In general, Rodauth only calls after_foo if foo is successful.
|
195
|
+
after_foo
|
196
|
+
|
197
|
+
# Successful form submission will usually set the notice flash,
|
198
|
+
# the redirect to the appropriate page.
|
199
|
+
set_notice_flash foo_notice_flash
|
200
|
+
redirect foo_redirect
|
201
|
+
else
|
202
|
+
# Unsucessful form subsmission will usually set the error flash,
|
203
|
+
# the redisplay the page so that the submission can be fixed.
|
204
|
+
set_error_flash foo_error_flash
|
205
|
+
foo_view
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# This is the default behavior for the foo method, if a user doesn't
|
211
|
+
# call the foo method inside the configuration block.
|
212
|
+
def foo
|
213
|
+
# Do Something
|
214
|
+
end
|
215
|
+
|
216
|
+
# This is the default behavior for the foo_bar method, if a user doesn't
|
217
|
+
# call the foo_bar method inside the configuration block.
|
218
|
+
def foo_bar
|
219
|
+
42
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A verify_login_change feature has been added. This is designed
|
4
|
+
as a replacement for the previous verify_change_login feature,
|
5
|
+
which was problematic as it could result in a user being unable
|
6
|
+
to access their account if they used an incorrect email when
|
7
|
+
changing their login.
|
8
|
+
|
9
|
+
The verify_login_change feature does not change the user's login
|
10
|
+
until after the user has confirmed that they can receive email
|
11
|
+
using the new login.
|
12
|
+
|
13
|
+
The verify_login_change feature requires an additional database
|
14
|
+
table to store information on login changes, so it is not a
|
15
|
+
drop in replacement for the verify_change_login feature. However,
|
16
|
+
it is recommended that all users of verify_change_login switch
|
17
|
+
to verify_login_change.
|
18
|
+
|
19
|
+
* If using the reset_password feature, there is now a link on the
|
20
|
+
login page to a page that will allow you to request a password
|
21
|
+
reset. Previously you had to attempt to login with the account
|
22
|
+
in order to request a password reset.
|
23
|
+
|
24
|
+
* If using the verify_account feature, there is now a link on the
|
25
|
+
login page to a page that will allow you to request that the
|
26
|
+
account verification email be resent. Previously you had to
|
27
|
+
attempt to login with the account or attempt to create a new
|
28
|
+
account with the same login in order to get an account verification
|
29
|
+
email resent.
|
30
|
+
|
31
|
+
* If using the reset_password feature, there is now a
|
32
|
+
login_failed_reset_password_request_form configuration method for
|
33
|
+
customizing the HTML used for the request password reset form shown
|
34
|
+
when there is a login failure.
|
35
|
+
|
36
|
+
= Improvements
|
37
|
+
|
38
|
+
* When using the verify_account_grace_period feature, attempting to
|
39
|
+
create a new account using the same login as an existing
|
40
|
+
unverified account now correctly offers the ability to resend the
|
41
|
+
account verification email.
|
42
|
+
|
43
|
+
* The precompile_rodauth_templates method now works with the
|
44
|
+
reset_password feature.
|
45
|
+
|
46
|
+
* When attempting to reopen a rodauth configuration in a subclass
|
47
|
+
of the Roda class that created the rodauth configuration, a
|
48
|
+
subclass of the rodauth configuration is now automatically
|
49
|
+
created. This makes it so changes to the rodauth configuration
|
50
|
+
in the Roda subclass no longer affect the rodauth configuration
|
51
|
+
of the superclass.
|
52
|
+
|
53
|
+
* The FeatureConfiguration instances for each feature are now
|
54
|
+
assigned to constants, making inspect output more descriptive.
|
55
|
+
|
56
|
+
* An internals guide has been added, which explains the
|
57
|
+
metaprogramming used to implement Rodauth.
|
58
|
+
|
59
|
+
= Backwards Compatibility
|
60
|
+
|
61
|
+
* Any external features should start providing two arguments to
|
62
|
+
Feature.define, with the second argument being the constant
|
63
|
+
name to use. So instead of:
|
64
|
+
|
65
|
+
module Rodauth
|
66
|
+
Foo = Feature.define(:foo) do
|
67
|
+
# ...
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
switch to:
|
72
|
+
|
73
|
+
module Rodauth
|
74
|
+
Feature.define(:foo, :Foo) do
|
75
|
+
# ...
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
This will ensure that the related FeatureConfiguration instance
|
80
|
+
is assigned to a constant.
|
data/doc/reset_password.rdoc
CHANGED
@@ -38,6 +38,8 @@ reset_password_request_additional_form_tags :: HTML fragment containing addition
|
|
38
38
|
reset_password_request_button :: The text to use for the reset password request button.
|
39
39
|
reset_password_request_error_flash :: The flash error to show if not able to send a reset
|
40
40
|
password email.
|
41
|
+
reset_password_request_link :: The HTML to use for a link to the page to request a password
|
42
|
+
reset.
|
41
43
|
reset_password_request_route :: The route to the reset password request action.
|
42
44
|
Defaults to +reset-password-request+.
|
43
45
|
reset_password_route :: The route to the reset password action. Defaults to
|
@@ -57,10 +59,13 @@ before_reset_password :: Run arbitrary code before resetting a password.
|
|
57
59
|
before_reset_password_request :: Run arbitrary code before sending the reset password
|
58
60
|
email.
|
59
61
|
before_reset_password_route :: Run arbitrary code before handling a reset password route.
|
60
|
-
create_reset_password_key ::
|
62
|
+
create_reset_password_key :: Add the reset password key data to the database.
|
63
|
+
create_reset_password_email :: A Mail::Message for the reset password email.
|
61
64
|
get_reset_password_key(id) :: Get the password reset key for the given account id
|
62
65
|
from the database.
|
63
|
-
|
66
|
+
login_failed_reset_password_request_form :: The HTML to use for a form to request a password
|
67
|
+
reset, shown on the login page after the user
|
68
|
+
tries to login with an invalid password.
|
64
69
|
remove_reset_password_key :: Remove the reset password key for the current account,
|
65
70
|
run after successful password reset.
|
66
71
|
reset_password_email_body :: The body to use for the reset password email.
|
@@ -69,5 +74,6 @@ reset_password_email_link :: The link to the reset password form in the reset
|
|
69
74
|
reset_password_key_insert_hash :: The hash to insert into the reset password keys
|
70
75
|
table.
|
71
76
|
reset_password_key_value :: The reset password key for the current account.
|
77
|
+
reset_password_request_view :: The HTML to use for the reset password request form.
|
72
78
|
reset_password_view :: The HTML to use for the reset password form.
|
73
79
|
send_reset_password_email :: Send the reset password email.
|
data/doc/verify_account.rdoc
CHANGED
@@ -38,6 +38,8 @@ verify_account_resend_button :: The text to use for the verify account resend bu
|
|
38
38
|
verify_account_redirect :: Where to redirect after verifying the account.
|
39
39
|
verify_account_resend_error_flash :: The flash error to show if unable to resend a
|
40
40
|
verify account email.
|
41
|
+
verify_account_resend_link :: The HTML to use for a link to the page to request
|
42
|
+
the account verification email be resent.
|
41
43
|
verify_account_resend_route :: The route to the verify account resend action.
|
42
44
|
Defaults to +verify-account-resend+.
|
43
45
|
verify_account_route :: The route to the verify account action. Defaults to
|
@@ -52,10 +54,13 @@ account_from_verify_account_key(key) :: Retrieve the account using the given ver
|
|
52
54
|
matches.
|
53
55
|
after_verify_account :: Run arbitrary code after verifying the account.
|
54
56
|
after_verify_account_resend :: Run arbitrary code after resending a verify account email.
|
57
|
+
allow_resending_verify_account_email? :: Whether to allow sending the verify account email
|
58
|
+
for the account, true by default only if the
|
59
|
+
account has not been verified.
|
55
60
|
before_verify_account :: Run arbitrary code before verifying the account.
|
56
61
|
before_verify_account_resend :: Run arbitrary code before resending a verify account email.
|
57
62
|
before_verify_account_route :: Run arbitrary code before handling a verify account route.
|
58
|
-
create_verify_account_key ::
|
63
|
+
create_verify_account_key :: Add the verify account key data to the database.
|
59
64
|
create_verify_account_email :: A Mail::Message for the verify account email.
|
60
65
|
get_verify_account_key(id) :: Get the verify account key for the given account id
|
61
66
|
from the database.
|
@@ -70,4 +75,5 @@ verify_account_email_link :: The link to the verify account form in the verify
|
|
70
75
|
account email.
|
71
76
|
verify_account_key_insert_hash :: The hash to insert into the verify account keys
|
72
77
|
table.
|
78
|
+
verify_account_key_value :: The value of the verify account key.
|
73
79
|
verify_account_view :: The HTML to use for the verify account form.
|
@@ -1,9 +1,11 @@
|
|
1
1
|
= Documentation for Verify Change Login Feature
|
2
2
|
|
3
|
+
This feature is deprecated, because it is possible for a user to get
|
4
|
+
locked out of their account if they use the wrong address on the
|
5
|
+
change login page. It is recommended that users switch to using the
|
6
|
+
verify login change feature, which doesn't change the login until
|
7
|
+
after it has been verified.
|
8
|
+
|
3
9
|
The verify change login feature implements account reverification after
|
4
|
-
change login.
|
5
|
-
features
|
6
|
-
for users to work around account verification by creating an account with
|
7
|
-
an email address they control, and the changing the login to an email
|
8
|
-
address they don't control. Depends on the change login and verify
|
9
|
-
account grace period features.
|
10
|
+
change login. Depends on the change login and verify account grace
|
11
|
+
period features.
|
@@ -0,0 +1,52 @@
|
|
1
|
+
= Documentation for Verify Login Change Feature
|
2
|
+
|
3
|
+
The verify login change feature implements login verification after
|
4
|
+
a login change. With this feature, login changes do not take effect
|
5
|
+
until after the user has verified the new login. Until the new
|
6
|
+
login has been verified, the old login continues to work.
|
7
|
+
|
8
|
+
Any time you use the verify login change and change login features together,
|
9
|
+
you should probably use this, otherwise it is trivial for users to work
|
10
|
+
around account verification by creating an account with an email address
|
11
|
+
they control, and the changing the login to an email address they don't
|
12
|
+
control. Depends on the change login and email base features.
|
13
|
+
|
14
|
+
== Auth Value Methods
|
15
|
+
|
16
|
+
no_matching_verify_login_change_key_message :: The flash error message to show when an invalid verify login change key is used.
|
17
|
+
verify_login_change_additional_form_tags :: HTML fragment containing additional form tags to use on the verify login change form.
|
18
|
+
verify_login_change_autologin? :: Whether to autologin the user after successful login change verification, false by default.
|
19
|
+
verify_login_change_button :: The text to use for the verify login change button.
|
20
|
+
verify_login_change_deadline_column :: The column name in the verify login change keys table storing the deadline after which the token will be ignored.
|
21
|
+
verify_login_change_deadline_interval :: The amount of time for which to allow users to verify login changes, 1 day by default.
|
22
|
+
verify_login_change_email_subject :: The subject to use for the verify login change email.
|
23
|
+
verify_login_change_error_flash :: The flash error to show if no matching key is submitted when verifying login change.
|
24
|
+
verify_login_change_id_column :: The id column in the verify login change keys table, should be a foreign key referencing the accounts table.
|
25
|
+
verify_login_change_key_column :: The verify login change key/token column in the verify login change keys table.
|
26
|
+
verify_login_change_key_param :: The parameter name to use for the verify login change key.
|
27
|
+
verify_login_change_login_column :: The login column in the verify login change keys table, containing the new login.
|
28
|
+
verify_login_change_notice_flash :: The flash notice to show after verifying the login change.
|
29
|
+
verify_login_change_redirect :: Where to redirect after verifying the login change.
|
30
|
+
verify_login_change_route :: The route to the verify login change action. Defaults to +verify-login-change+.
|
31
|
+
verify_login_change_session_key :: The key in the session to hold the verify login change key temporarily.
|
32
|
+
verify_login_change_table :: The name of the verify login change keys table.
|
33
|
+
|
34
|
+
== Auth Methods
|
35
|
+
|
36
|
+
account_from_verify_login_change_key(key) :: Retrieve the account using the given verify account key, or return nil if no account matches. Should also override verify_login_change_new_login if overriding this method.
|
37
|
+
after_verify_login_change :: Run arbitrary code after verifying the login change.
|
38
|
+
before_verify_login_change :: Run arbitrary code before verifying the login change.
|
39
|
+
before_verify_login_change_route :: Run arbitrary code before handling a verify login change route.
|
40
|
+
create_verify_login_change_email(login) :: A Mail::Message for the verify login change email.
|
41
|
+
create_verify_login_change_key(login) :: Add the verify login change key data to the database.
|
42
|
+
get_verify_login_change_login_and_key(id) :: Get the verify login change login and key for the given account id from the database.
|
43
|
+
remove_verify_login_change_key :: Remove the verify login change key for the current account, run after successful login change verification.
|
44
|
+
send_verify_login_change_email(login) :: Send the verify login change email.
|
45
|
+
verify_login_change :: Change the login for the given account to the new login.
|
46
|
+
verify_login_change_email_body :: The body to use for the verify login change email.
|
47
|
+
verify_login_change_email_link :: The link to the verify login change form in the verify login change email.
|
48
|
+
verify_login_change_key_insert_hash(login) :: The hash to insert into the verify login change keys table.
|
49
|
+
verify_login_change_key_value :: The value of the verify login change key.
|
50
|
+
verify_login_change_new_login :: The new login to use when the login change is verified.
|
51
|
+
verify_login_change_old_login :: The old login to display in the verify login change email.
|
52
|
+
verify_login_change_view :: The HTML to use for the verify login change form.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
3
|
module Rodauth
|
4
|
-
|
4
|
+
Feature.define(:change_login, :ChangeLogin) do
|
5
5
|
depends :login_password_requirements_base
|
6
6
|
|
7
7
|
notice_flash 'Your login has been changed'
|
@@ -63,11 +63,18 @@ module Rodauth
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def change_login(login)
|
66
|
-
updated = nil
|
67
66
|
if account_ds.get(login_column).downcase == login.downcase
|
68
67
|
@login_requirement_message = 'same as current login'
|
69
68
|
return false
|
70
69
|
end
|
70
|
+
|
71
|
+
update_login(login)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def update_login(login)
|
77
|
+
updated = nil
|
71
78
|
raised = raises_uniqueness_violation?{updated = update_account({login_column=>login}, account_ds.exclude(login_column=>login)) == 1}
|
72
79
|
if raised
|
73
80
|
@login_requirement_message = 'already an account with this login'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
3
|
module Rodauth
|
4
|
-
|
4
|
+
Feature.define(:close_account, :CloseAccount) do
|
5
5
|
notice_flash 'Your account has been closed'
|
6
6
|
error_flash 'There was an error closing your account'
|
7
7
|
loaded_templates %w'close-account password-field'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
3
|
module Rodauth
|
4
|
-
|
4
|
+
Feature.define(:confirm_password, :ConfirmPassword) do
|
5
5
|
notice_flash "Your password has been confirmed"
|
6
6
|
error_flash "There was an error confirming your password"
|
7
7
|
loaded_templates %w'confirm-password password-field'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
3
|
module Rodauth
|
4
|
-
|
4
|
+
Feature.define(:disallow_password_reuse, :DisallowPasswordReuse) do
|
5
5
|
depends :login_password_requirements_base
|
6
6
|
|
7
7
|
auth_value_method :password_same_as_previous_password_message, "same as previous password"
|