rodauth 1.23.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +184 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +221 -79
- data/doc/account_expiration.rdoc +12 -26
- data/doc/active_sessions.rdoc +49 -0
- data/doc/audit_logging.rdoc +44 -0
- data/doc/base.rdoc +76 -128
- data/doc/change_login.rdoc +7 -14
- data/doc/change_password.rdoc +9 -13
- data/doc/change_password_notify.rdoc +2 -2
- data/doc/close_account.rdoc +9 -16
- data/doc/confirm_password.rdoc +12 -5
- data/doc/create_account.rdoc +11 -22
- data/doc/disallow_password_reuse.rdoc +6 -13
- data/doc/email_auth.rdoc +15 -14
- data/doc/email_base.rdoc +5 -15
- data/doc/guides/admin_activation.rdoc +46 -0
- data/doc/guides/already_authenticated.rdoc +10 -0
- data/doc/guides/alternative_login.rdoc +46 -0
- data/doc/guides/create_account_programmatically.rdoc +38 -0
- data/doc/guides/delay_password.rdoc +25 -0
- data/doc/guides/email_only.rdoc +16 -0
- data/doc/guides/i18n.rdoc +26 -0
- data/doc/{internals.rdoc → guides/internals.rdoc} +0 -0
- data/doc/guides/links.rdoc +12 -0
- data/doc/guides/login_return.rdoc +37 -0
- data/doc/guides/password_column.rdoc +25 -0
- data/doc/guides/password_confirmation.rdoc +37 -0
- data/doc/guides/password_requirements.rdoc +30 -0
- data/doc/guides/paths.rdoc +36 -0
- data/doc/guides/query_params.rdoc +9 -0
- data/doc/guides/redirects.rdoc +17 -0
- data/doc/guides/registration_field.rdoc +68 -0
- data/doc/guides/require_mfa.rdoc +30 -0
- data/doc/guides/reset_password_autologin.rdoc +21 -0
- data/doc/guides/status_column.rdoc +28 -0
- data/doc/guides/totp_or_recovery.rdoc +16 -0
- data/doc/http_basic_auth.rdoc +10 -1
- data/doc/jwt.rdoc +22 -22
- data/doc/jwt_cors.rdoc +2 -3
- data/doc/jwt_refresh.rdoc +23 -8
- data/doc/lockout.rdoc +17 -15
- data/doc/login.rdoc +17 -2
- data/doc/login_password_requirements_base.rdoc +18 -37
- data/doc/logout.rdoc +2 -2
- data/doc/otp.rdoc +25 -19
- data/doc/password_complexity.rdoc +10 -26
- data/doc/password_expiration.rdoc +11 -25
- data/doc/password_grace_period.rdoc +16 -2
- data/doc/password_pepper.rdoc +44 -0
- data/doc/recovery_codes.rdoc +18 -12
- data/doc/release_notes/2.0.0.txt +361 -0
- data/doc/release_notes/2.1.0.txt +31 -0
- data/doc/release_notes/2.2.0.txt +39 -0
- data/doc/release_notes/2.3.0.txt +37 -0
- data/doc/release_notes/2.4.0.txt +22 -0
- data/doc/remember.rdoc +40 -64
- data/doc/reset_password.rdoc +12 -9
- data/doc/session_expiration.rdoc +1 -0
- data/doc/single_session.rdoc +16 -25
- data/doc/sms_codes.rdoc +24 -14
- data/doc/two_factor_base.rdoc +60 -22
- data/doc/verify_account.rdoc +14 -12
- data/doc/verify_account_grace_period.rdoc +6 -2
- data/doc/verify_login_change.rdoc +9 -8
- data/doc/webauthn.rdoc +115 -0
- data/doc/webauthn_login.rdoc +15 -0
- data/doc/webauthn_verify_account.rdoc +9 -0
- data/javascript/webauthn_auth.js +45 -0
- data/javascript/webauthn_setup.js +35 -0
- data/lib/roda/plugins/rodauth.rb +1 -1
- data/lib/rodauth.rb +33 -28
- data/lib/rodauth/features/account_expiration.rb +5 -5
- data/lib/rodauth/features/active_sessions.rb +158 -0
- data/lib/rodauth/features/audit_logging.rb +98 -0
- data/lib/rodauth/features/base.rb +152 -49
- data/lib/rodauth/features/change_password_notify.rb +1 -1
- data/lib/rodauth/features/close_account.rb +8 -6
- data/lib/rodauth/features/confirm_password.rb +40 -2
- data/lib/rodauth/features/create_account.rb +8 -13
- data/lib/rodauth/features/disallow_common_passwords.rb +1 -1
- data/lib/rodauth/features/disallow_password_reuse.rb +5 -3
- data/lib/rodauth/features/email_auth.rb +30 -28
- data/lib/rodauth/features/email_base.rb +3 -3
- data/lib/rodauth/features/http_basic_auth.rb +55 -35
- data/lib/rodauth/features/jwt.rb +63 -16
- data/lib/rodauth/features/jwt_cors.rb +15 -15
- data/lib/rodauth/features/jwt_refresh.rb +42 -13
- data/lib/rodauth/features/lockout.rb +11 -13
- data/lib/rodauth/features/login.rb +58 -13
- data/lib/rodauth/features/login_password_requirements_base.rb +13 -8
- data/lib/rodauth/features/otp.rb +76 -82
- data/lib/rodauth/features/password_complexity.rb +8 -13
- data/lib/rodauth/features/password_expiration.rb +1 -1
- data/lib/rodauth/features/password_grace_period.rb +17 -10
- data/lib/rodauth/features/password_pepper.rb +45 -0
- data/lib/rodauth/features/recovery_codes.rb +47 -51
- data/lib/rodauth/features/remember.rb +13 -27
- data/lib/rodauth/features/reset_password.rb +25 -25
- data/lib/rodauth/features/session_expiration.rb +7 -10
- data/lib/rodauth/features/single_session.rb +8 -6
- data/lib/rodauth/features/sms_codes.rb +58 -68
- data/lib/rodauth/features/two_factor_base.rb +134 -30
- data/lib/rodauth/features/verify_account.rb +28 -20
- data/lib/rodauth/features/verify_account_grace_period.rb +18 -9
- data/lib/rodauth/features/verify_login_change.rb +11 -10
- data/lib/rodauth/features/webauthn.rb +505 -0
- data/lib/rodauth/features/webauthn_login.rb +70 -0
- data/lib/rodauth/features/webauthn_verify_account.rb +46 -0
- data/lib/rodauth/migrations.rb +16 -5
- data/lib/rodauth/version.rb +2 -2
- data/templates/button.str +1 -3
- data/templates/change-login.str +1 -2
- data/templates/change-password.str +3 -5
- data/templates/close-account.str +2 -2
- data/templates/confirm-password.str +1 -1
- data/templates/create-account.str +1 -1
- data/templates/email-auth-request-form.str +1 -2
- data/templates/email-auth.str +1 -1
- data/templates/global-logout-field.str +6 -0
- data/templates/login-confirm-field.str +2 -4
- data/templates/login-display.str +3 -2
- data/templates/login-field.str +2 -4
- data/templates/login-form-footer.str +6 -0
- data/templates/login-form.str +7 -0
- data/templates/login.str +1 -9
- data/templates/logout.str +1 -1
- data/templates/multi-phase-login.str +3 -0
- data/templates/otp-auth-code-field.str +5 -3
- data/templates/otp-auth.str +1 -1
- data/templates/otp-disable.str +1 -1
- data/templates/otp-setup.str +3 -3
- data/templates/password-confirm-field.str +2 -4
- data/templates/password-field.str +2 -4
- data/templates/recovery-auth.str +3 -6
- data/templates/recovery-codes.str +1 -1
- data/templates/remember.str +15 -20
- data/templates/reset-password-request.str +2 -2
- data/templates/reset-password.str +1 -2
- data/templates/sms-auth.str +1 -1
- data/templates/sms-code-field.str +5 -3
- data/templates/sms-confirm.str +1 -2
- data/templates/sms-disable.str +1 -2
- data/templates/sms-request.str +1 -1
- data/templates/sms-setup.str +6 -4
- data/templates/two-factor-auth.str +5 -0
- data/templates/two-factor-disable.str +6 -0
- data/templates/two-factor-manage.str +16 -0
- data/templates/unlock-account-request.str +2 -2
- data/templates/unlock-account.str +1 -1
- data/templates/verify-account-resend.str +1 -1
- data/templates/verify-account.str +1 -2
- data/templates/verify-login-change.str +1 -1
- data/templates/webauthn-auth.str +11 -0
- data/templates/webauthn-remove.str +14 -0
- data/templates/webauthn-setup.str +12 -0
- metadata +96 -13
- data/doc/verify_change_login.rdoc +0 -11
- data/lib/rodauth/features/verify_change_login.rb +0 -20
@@ -0,0 +1,26 @@
|
|
1
|
+
= Translate with i18n gem
|
2
|
+
|
3
|
+
Rodauth allows transforming user-facing text configuration such as flash
|
4
|
+
messages, validation errors, labels etc. via the +translate+ configuration
|
5
|
+
method. This method receives a name of a configuration along with its default
|
6
|
+
value, and is expected to return the result text.
|
7
|
+
|
8
|
+
You can use this to perform translations using the
|
9
|
+
{i18n gem}[https://github.com/ruby-i18n/i18n]:
|
10
|
+
|
11
|
+
plugin :rodauth do
|
12
|
+
enable :login, :logout, :reset_password
|
13
|
+
|
14
|
+
translate do |key, default|
|
15
|
+
I18n.translate("rodauth.#{key}") || default
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Your translation file may then look something like this:
|
20
|
+
|
21
|
+
en:
|
22
|
+
rodauth:
|
23
|
+
login_notice_flash: "You have been signed in"
|
24
|
+
require_login_error_flash: "Login is required for accessing this page"
|
25
|
+
no_matching_login_message: "user with this email address doesn't exist"
|
26
|
+
reset_password_email_subject: "Password Reset Instructions"
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
= Display authentication links
|
2
|
+
|
3
|
+
You can retrieve a relative URL to any Rodauth action by calling the
|
4
|
+
corresponding <tt>*_path</tt> method on the Rodauth instance:
|
5
|
+
|
6
|
+
<a href="<%= rodauth.login_path %>">Sign in</a>
|
7
|
+
<a href="<%= rodauth.create_account_path %>">Sign up</a>
|
8
|
+
|
9
|
+
For absolute URLs instead of paths, you can use the <tt>*_url</tt> methods:
|
10
|
+
|
11
|
+
<a href="<%= rodauth.login_url %>">Sign in</a>
|
12
|
+
<a href="<%= rodauth.create_account_url %>">Sign up</a>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
= Redirect to original page after login
|
2
|
+
|
3
|
+
When the user attempts to open a page that requires authentication, Rodauth
|
4
|
+
redirects them to the login page. It can be useful to redirect them back to
|
5
|
+
the page they originally requested after successful login. Similarly, you
|
6
|
+
can do this for pages requiring multifactor authentication.
|
7
|
+
|
8
|
+
plugin :rodauth do
|
9
|
+
enable :login, :logout, :otp
|
10
|
+
|
11
|
+
# Have successful login redirect back to originally requested page
|
12
|
+
login_return_to_requested_location? true
|
13
|
+
|
14
|
+
# Have successful multifactor authentication redirect back to
|
15
|
+
# originally requested page
|
16
|
+
two_factor_auth_return_to_requested_location? true
|
17
|
+
end
|
18
|
+
|
19
|
+
You can manually set which page to redirect after login or multifactor
|
20
|
+
authentication, though it is questionable whether the user will desire
|
21
|
+
this behavior compared to the default.
|
22
|
+
|
23
|
+
route do |r|
|
24
|
+
r.rodauth
|
25
|
+
|
26
|
+
# Return the last visited path after login
|
27
|
+
if rodauth.logged_in?
|
28
|
+
# Return to the last visited page after multifactor authentication
|
29
|
+
unless rodauth.two_factor_authenticated?
|
30
|
+
session[rodauth.two_factor_auth_redirect_session_key] = request.fullpath
|
31
|
+
end
|
32
|
+
else
|
33
|
+
session[rodauth.login_redirect_session_key] = request.fullpath
|
34
|
+
end
|
35
|
+
|
36
|
+
# rest of routes
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
= Store password hash in accounts table
|
2
|
+
|
3
|
+
By default, Rodauth stores the password hash in a separate
|
4
|
+
+account_password_hashes+ table. This makes it a lot less likely that the
|
5
|
+
password hashes will be leaked, especially if you use Rodauth's default
|
6
|
+
approach of using database functions for checking the hashes.
|
7
|
+
|
8
|
+
However, if you have reasons for storing the password hashes in +accounts+
|
9
|
+
table that outweigh the security benefits of Rodauth's default approach,
|
10
|
+
Rodauth supports that.
|
11
|
+
|
12
|
+
To do this, add the password hash column to the +accounts+ table:
|
13
|
+
|
14
|
+
alter_table :accounts do
|
15
|
+
add_column :password_hash, String
|
16
|
+
end
|
17
|
+
|
18
|
+
And then tell Rodauth to use it:
|
19
|
+
|
20
|
+
plugin :rodauth do
|
21
|
+
enable :login, :logout
|
22
|
+
|
23
|
+
# Use the password_hash column in the accounts table
|
24
|
+
account_password_hash_column :password_hash
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
= Require password confirmation for certain actions
|
2
|
+
|
3
|
+
You might want to require the user to enter their password before accessing
|
4
|
+
sensitive sections of the app. This functionality is provided by the confirm
|
5
|
+
password feature, which accompanied with the password grace period feature will
|
6
|
+
remember the entered password for a period of time:
|
7
|
+
|
8
|
+
plugin :rodauth do
|
9
|
+
enable :confirm_password, :password_grace_period
|
10
|
+
|
11
|
+
# Remember the password for 1 hour
|
12
|
+
password_grace_period 60*60
|
13
|
+
end
|
14
|
+
|
15
|
+
route do |r|
|
16
|
+
r.rodauth
|
17
|
+
|
18
|
+
r.is 'some-action' do
|
19
|
+
# Require password authentication if the password has not been
|
20
|
+
# input recently.
|
21
|
+
rodauth.require_password_authentication
|
22
|
+
|
23
|
+
# ...
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
You can also do this for Rodauth actions that normally require a password.
|
28
|
+
Which essentially moves the password confirmation into a separate step, as
|
29
|
+
Rodauth's behavior with the password grace period feature is to ask for the
|
30
|
+
password on the same form.
|
31
|
+
|
32
|
+
plugin :rodauth do
|
33
|
+
enable :confirm_password, :password_grace_period, :change_login, :change_password
|
34
|
+
|
35
|
+
before_change_login_route { require_password_authentication }
|
36
|
+
before_change_password_route { require_password_authentication }
|
37
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
= Customize password requirements
|
2
|
+
|
3
|
+
By default, Rodauth requires passwords to have at least 6 characters. You can
|
4
|
+
modify the minimum length:
|
5
|
+
|
6
|
+
plugin :rodauth do
|
7
|
+
enable :login, :logout, :create_account
|
8
|
+
|
9
|
+
# Require passwords to have at least 8 characters
|
10
|
+
password_minimum_length 8
|
11
|
+
end
|
12
|
+
|
13
|
+
You can use the {disallow common passwords feature}[rdoc-ref:doc/disallow_common_passwords.rdoc]
|
14
|
+
to prevent the usage of common passwords (the most common 10,000 by default).
|
15
|
+
|
16
|
+
You can use additional complexity checks on passwords via the {password
|
17
|
+
complexity feature}[rdoc-ref:doc/password_complexity.rdoc], though most of
|
18
|
+
those complexity checks are no longer considered modern security best
|
19
|
+
practices and are likely to decrease overall security.
|
20
|
+
|
21
|
+
If you want complete control over whether passwords meet requirements, you
|
22
|
+
can use the <tt>password_meets_requirements?</tt> configuration method.
|
23
|
+
|
24
|
+
plugin :rodauth do
|
25
|
+
enable :login, :logout, :create_account
|
26
|
+
|
27
|
+
password_meets_requirements? do |password|
|
28
|
+
#true if password meets requirements, false otherwise
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
= Change route path
|
2
|
+
|
3
|
+
You can change the URL path of any Rodauth route by overriding the
|
4
|
+
corresponding <tt>*_route</tt> method:
|
5
|
+
|
6
|
+
plugin :rodauth do
|
7
|
+
enable :login, :logout, :create_account, :reset_password
|
8
|
+
|
9
|
+
# Change login route to "/signin"
|
10
|
+
login_route "signin"
|
11
|
+
|
12
|
+
# Change create account route to "/register"
|
13
|
+
create_account_route "register"
|
14
|
+
|
15
|
+
# Change password reset request route to "/reset-password/request"
|
16
|
+
reset_password_request_route "reset-password/request"
|
17
|
+
end
|
18
|
+
|
19
|
+
If you want to add a prefix to all Rodauth routes, you should use the +prefix+
|
20
|
+
setting:
|
21
|
+
|
22
|
+
plugin :rodauth do
|
23
|
+
enable :login, :logout
|
24
|
+
|
25
|
+
# Use /auth prefix to each Rodauth route
|
26
|
+
prefix "/auth"
|
27
|
+
end
|
28
|
+
|
29
|
+
route do |r|
|
30
|
+
r.on "auth" do
|
31
|
+
# Serve Rodauth routes under the /auth branch of the routing tree
|
32
|
+
r.rodauth
|
33
|
+
end
|
34
|
+
|
35
|
+
# ...
|
36
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
= Pass query parameters to auth URLs
|
2
|
+
|
3
|
+
The <tt>*_path</tt> and <tt>*_url</tt> methods allow passing additional query parameters:
|
4
|
+
|
5
|
+
rodauth.create_account_path(type: "seller")
|
6
|
+
#=> "/create-account?type=seller"
|
7
|
+
|
8
|
+
rodauth.login_url(type: "operator")
|
9
|
+
#=> "https//example.com/login?type=operator"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
= Change redirect destination
|
2
|
+
|
3
|
+
You can change the redirect destination for any Rodauth action by overriding
|
4
|
+
the corresponding <tt>*_redirect</tt> method:
|
5
|
+
|
6
|
+
plugin :rodauth do
|
7
|
+
enable :login, :logout, :create_account, :reset_password
|
8
|
+
|
9
|
+
# Redirect to "/dashboard" after login
|
10
|
+
login_redirect "/dashboard"
|
11
|
+
|
12
|
+
# Redirect to wherever login redirects to after creating account
|
13
|
+
create_account_redirect { login_redirect }
|
14
|
+
|
15
|
+
# Redirect to login page after password reset
|
16
|
+
reset_password_redirect { login_path }
|
17
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
= Add new field during account creation
|
2
|
+
|
3
|
+
The create account form only handles login and password parameters by
|
4
|
+
default. However, you might want to ask for additional information during
|
5
|
+
account creation, such as requiring the user to also enter their full name
|
6
|
+
or their company's name.
|
7
|
+
|
8
|
+
== A) Accounts table
|
9
|
+
|
10
|
+
Let's assume you wanted to wanted to store the additional field(s) directly on
|
11
|
+
the +accounts+ table:
|
12
|
+
|
13
|
+
atler_table :accounts do
|
14
|
+
add_column :name, String
|
15
|
+
end
|
16
|
+
|
17
|
+
You need to override the <tt>create-account</tt> template, which by default in
|
18
|
+
Rodauth you can do by adding a <tt>create-account.erb</tt> template in your
|
19
|
+
Roda +views+ directory.
|
20
|
+
|
21
|
+
Once you've added the <tt>create-account.erb</tt> template, and had it include
|
22
|
+
a field for the +name+, you can handle the submission of that field in a before
|
23
|
+
create account hook:
|
24
|
+
|
25
|
+
plugin :rodauth do
|
26
|
+
enable :login, :logout, :create_account
|
27
|
+
|
28
|
+
before_create_account do
|
29
|
+
# Validate presence of the name field
|
30
|
+
unless name = param_or_nil("name")
|
31
|
+
throw_error_status(422, "name", "must be present")
|
32
|
+
end
|
33
|
+
|
34
|
+
# Assign the new field to the account record
|
35
|
+
account[:name] = name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
== B) Separate table
|
40
|
+
|
41
|
+
Alternatively, you can store the additional field(s) in separate table, for
|
42
|
+
example:
|
43
|
+
|
44
|
+
create_table :account_names do
|
45
|
+
foreign_key :account_id, :accounts, primary_key: true, type: :Bignum
|
46
|
+
String :name, null: false
|
47
|
+
end
|
48
|
+
|
49
|
+
You can then handle the new submitted field as follows:
|
50
|
+
|
51
|
+
plugin :rodauth do
|
52
|
+
enable :login, :logout, :create_account
|
53
|
+
|
54
|
+
before_create_account do
|
55
|
+
# Validate presence of the name field
|
56
|
+
throw_error_status(422, "name", "must be present") unless param_or_nil("name")
|
57
|
+
end
|
58
|
+
|
59
|
+
after_create_account do
|
60
|
+
# Create the associated record
|
61
|
+
db[:account_names].insert(account_id: account[:id], name: param("name"))
|
62
|
+
end
|
63
|
+
|
64
|
+
after_close_account do
|
65
|
+
# Delete the associated record
|
66
|
+
db[:account_names].where(account_id: account[:id]).delete
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
= Require multifactor authentication after login
|
2
|
+
|
3
|
+
You may want to require multifactor authentication on login for people
|
4
|
+
that have multifactor authentication set up. The +require_authentication+
|
5
|
+
Rodauth method works for pages that require an authenticated user, but not for
|
6
|
+
pages where authentication is optional.
|
7
|
+
|
8
|
+
You can set this up as follows:
|
9
|
+
|
10
|
+
plugin :rodauth do
|
11
|
+
enable :login, :logout, :otp
|
12
|
+
|
13
|
+
# If you don't want to show an error message when redirecting
|
14
|
+
# to the multifactor authentication page.
|
15
|
+
two_factor_need_authentication_error_flash nil
|
16
|
+
|
17
|
+
# Display the same flash message after multifactor
|
18
|
+
# authentication than is displayed after login
|
19
|
+
two_factor_auth_notice_flash { login_notice_flash }
|
20
|
+
end
|
21
|
+
|
22
|
+
route do |r|
|
23
|
+
r.rodauth
|
24
|
+
|
25
|
+
if rodauth.logged_in? && rodauth.two_factor_authentication_setup?
|
26
|
+
rodauth.require_two_factor_authenticated
|
27
|
+
end
|
28
|
+
|
29
|
+
# ...
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
= Autologin after password reset
|
2
|
+
|
3
|
+
When the user resets their password, by default they are not automatically
|
4
|
+
logged in. You can change this behaviour and login the user automatically
|
5
|
+
after password reset.
|
6
|
+
|
7
|
+
plugin :rodauth do
|
8
|
+
enable :login, :logout, :reset_password
|
9
|
+
|
10
|
+
reset_password_autologin? true
|
11
|
+
end
|
12
|
+
|
13
|
+
Similarly, when the verify login change feature is used, the user is not
|
14
|
+
automatically logged in after verifying the login change. You can configure
|
15
|
+
Rodauth to automatically log the user in in this case:
|
16
|
+
|
17
|
+
plugin :rodauth do
|
18
|
+
enable :login, :logout, :verify_login_change
|
19
|
+
|
20
|
+
verify_login_change_autologin? true
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
= Store account status in a text column
|
2
|
+
|
3
|
+
By default, Rodauth recommends using a separate table for account statuses, and
|
4
|
+
linking them via foreign keys. This is useful as it achieves an enum-like
|
5
|
+
behaviour, where the database ensures a constrained set of status values.
|
6
|
+
|
7
|
+
However, if you use a testing environment that starts with a blank database,
|
8
|
+
and don't want to fix your testing environment to support real foreign keys,
|
9
|
+
you can configure Rodauth to store the account status in a text column.
|
10
|
+
Doing so results in problems if a text value you do not expect gets stored
|
11
|
+
in the column. We can mitigate the problems by using a CHECK constraint
|
12
|
+
on the column.
|
13
|
+
|
14
|
+
create_table :accounts do
|
15
|
+
# ...
|
16
|
+
String :status, null: false, default: "verified",
|
17
|
+
check: {status: %w'unverified verified closed'}
|
18
|
+
end
|
19
|
+
|
20
|
+
Then we can configure Rodauth to support this.
|
21
|
+
|
22
|
+
plugin :rodauth do
|
23
|
+
# ...
|
24
|
+
account_status_column :status
|
25
|
+
account_unverified_status_value "unverified"
|
26
|
+
account_open_status_value "verified"
|
27
|
+
account_closed_status_value "closed"
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
= Allow recovery code on TOTP code field
|
2
|
+
|
3
|
+
If using the otp feature, for convenience you might want to allow
|
4
|
+
the user to enter the recovery code into the TOTP code field, instead
|
5
|
+
of requiring they use the separate recovery codes form. You can
|
6
|
+
implement this using the following configuration:
|
7
|
+
|
8
|
+
plugin :rodauth do
|
9
|
+
enable :login, :logout, :otp, :recovery_codes
|
10
|
+
|
11
|
+
before_otp_auth_route do
|
12
|
+
if recovery_code_match?(param(otp_auth_param))
|
13
|
+
two_factor_authenticate("recovery_code")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/doc/http_basic_auth.rdoc
CHANGED
@@ -3,7 +3,16 @@
|
|
3
3
|
The HTTP basic auth feature allows logins using HTTP basic authentication,
|
4
4
|
described in RFC 1945.
|
5
5
|
|
6
|
+
In your routing block, you can require HTTP basic authentication via:
|
7
|
+
|
8
|
+
rodauth.require_http_basic_auth
|
9
|
+
|
10
|
+
If you want to allow HTTP basic authentication but not require it, you can
|
11
|
+
call:
|
12
|
+
|
13
|
+
rodauth.http_basic_auth
|
14
|
+
|
6
15
|
== Auth Value Methods
|
7
16
|
|
8
17
|
http_basic_auth_realm :: The realm to return in the WWW-Authenticate header.
|
9
|
-
require_http_basic_auth :: If true, when +rodauth.require_authentication+ is used, return a 401 status if basic auth has not been provided, instead of redirecting to the login page. False by default.
|
18
|
+
require_http_basic_auth? :: If true, when +rodauth.require_login+ or +rodauth.require_authentication+ is used, return a 401 status page if basic auth has not been provided, instead of redirecting to the login page. If false, +rodauth.require_login+ or +rodauth.require_authentication+ will check for HTTP basic authentication if not already logged in. False by default.
|
data/doc/jwt.rdoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
The jwt feature adds support for JSON API access for all other features
|
4
4
|
that ship with Rodauth, using JWT (JSON Web Tokens) to hold the
|
5
|
-
|
5
|
+
session information.
|
6
6
|
|
7
7
|
When this feature is used, all other features become accessible via a
|
8
8
|
JSON API. The JSON API uses the POST method for all requests, using
|
@@ -10,10 +10,10 @@ the same parameter names as the features uses. JSON API requests to
|
|
10
10
|
Rodauth endpoints that use a method other than POST will result in a
|
11
11
|
405 Method Not Allowed response.
|
12
12
|
|
13
|
-
Responses are returned as JSON hashes. In case of an error, the
|
14
|
-
entry is set to an error message, and the
|
13
|
+
Responses are returned as JSON hashes. In case of an error, the +error+
|
14
|
+
entry is set to an error message, and the <tt>field-error</tt> entry is set to
|
15
15
|
an array containing the field name and the error message for that field.
|
16
|
-
Successful requests by default store a
|
16
|
+
Successful requests by default store a +success+ entry with a success
|
17
17
|
message, though that can be disabled.
|
18
18
|
|
19
19
|
In order to use this feature, you have to set the +jwt_secret+ configuration
|
@@ -26,42 +26,42 @@ future requests, if the response Authorization header is set. If the
|
|
26
26
|
response Authorization header is not set, then continue to use the
|
27
27
|
previous Authorization header.
|
28
28
|
|
29
|
-
When using this feature, consider using the :
|
29
|
+
When using this feature, consider using the <tt>json: :only</tt> option when
|
30
30
|
loading the rodauth plugin, if you want Rodauth to only handle
|
31
|
-
JSON requests. If you don't use the :
|
31
|
+
JSON requests. If you don't use the <tt>json: :only</tt> option, the jwt feature
|
32
32
|
will probably result in an error if a request to a Rodauth endpoint comes
|
33
33
|
in with a Content-Type that isn't application/json, unless you also set
|
34
34
|
<tt>only_json? false</tt> in your rodauth configuration.
|
35
35
|
|
36
36
|
If you would like to check if a valid JWT was submitted with the current
|
37
|
-
request in your Roda app, you can call the rodauth.valid_jwt
|
38
|
-
rodauth.valid_jwt
|
39
|
-
from rodauth.session
|
37
|
+
request in your Roda app, you can call the +rodauth.valid_jwt?+ method. If
|
38
|
+
+rodauth.valid_jwt?+ returns true, the contents of the jwt can be retrieved
|
39
|
+
from +rodauth.session+.
|
40
40
|
|
41
41
|
== Auth Value Methods
|
42
42
|
|
43
43
|
invalid_jwt_format_error_message :: The error message to use when a JWT with an invalid format is submitted in the Authorization header.
|
44
|
-
json_accept_regexp :: The regexp to use to check the Accept header for JSON if jwt_check_accept
|
44
|
+
json_accept_regexp :: The regexp to use to check the Accept header for JSON if +jwt_check_accept?+ is true.
|
45
45
|
json_non_post_error_message :: The error message to use when a JSON non-POST request is sent.
|
46
|
-
json_not_accepted_error_message :: The error message to display if jwt_check_accept
|
46
|
+
json_not_accepted_error_message :: The error message to display if +jwt_check_accept?+ is true and the Accept header is present but does not match +json_request_content_type_regexp+.
|
47
47
|
json_request_content_type_regexp :: The regexp to use to recognize a request as a json request.
|
48
|
-
json_response_content_type :: The content type to set for json responses, application/json by default.
|
49
|
-
json_response_custom_error_status? :: Whether to use custom error statuses, instead of always using +json_response_error_status+,
|
50
|
-
json_response_error_key :: The JSON result key containing an error message,
|
51
|
-
json_response_error_status :: The HTTP status code to use for JSON error responses, 400 by default.
|
52
|
-
json_response_field_error_key :: The JSON result key containing an field error message,
|
53
|
-
json_response_success_key :: The JSON result key containing a success message for successful request, if set.
|
54
|
-
jwt_algorithm :: The JWT algorithm to use,
|
48
|
+
json_response_content_type :: The content type to set for json responses, <tt>application/json</tt> by default.
|
49
|
+
json_response_custom_error_status? :: Whether to use custom error statuses, instead of always using +json_response_error_status+, true by default, can be set to false for backwards compatibility with Rodauth 1.
|
50
|
+
json_response_error_key :: The JSON result key containing an error message, +error+ by default.
|
51
|
+
json_response_error_status :: The HTTP status code to use for JSON error responses if not using custom error statuses, 400 by default.
|
52
|
+
json_response_field_error_key :: The JSON result key containing an field error message, <tt>field-error</tt> by default.
|
53
|
+
json_response_success_key :: The JSON result key containing a success message for successful request, if set. +success+ by default.
|
54
|
+
jwt_algorithm :: The JWT algorithm to use, +HS256+ by default.
|
55
55
|
jwt_authorization_ignore :: A regexp matched against the Authorization header, which skips JWT processing if it matches. By default, HTTP Basic and Digest authentication are ignored.
|
56
56
|
jwt_authorization_remove :: A regexp to remove from the Authorization header before processing the JWT. By default, a Bearer prefix is removed.
|
57
|
-
jwt_check_accept? :: Whether to check the Accept header to see if the client supports JSON responses,
|
58
|
-
jwt_decode_opts :: An optional hash to pass to JWT.decode
|
57
|
+
jwt_check_accept? :: Whether to check the Accept header to see if the client supports JSON responses, true by default, can be set to false for backwards compatibility with Rodauth 1.
|
58
|
+
jwt_decode_opts :: An optional hash to pass to +JWT.decode+. Can be used to set JWT verifiers.
|
59
59
|
jwt_secret :: The JWT secret to use. Access to this should be protected the same as a session secret.
|
60
60
|
jwt_session_key :: A key to nest the session hash under in the JWT payload. nil by default, for no nesting.
|
61
61
|
jwt_symbolize_deeply? :: Whether to symbolize the session hash deeply. false by default.
|
62
62
|
non_json_request_error_message :: The error message to use when a non-JSON request is sent and +only_json?+ is set.
|
63
|
-
only_json? :: Whether to have Rodauth only allow JSON requests. True by default if :
|
64
|
-
use_jwt? :: Whether to use the JWT in the Authorization header for authentication information. If false, falls back to using the rack session. By default, the Authorization header is used if it is present, if only_json
|
63
|
+
only_json? :: Whether to have Rodauth only allow JSON requests. True by default if <tt>json: :only</tt> option was given when loading the plugin. If set, rodauth endpoints will issue an error for non-JSON requests.
|
64
|
+
use_jwt? :: Whether to use the JWT in the Authorization header for authentication information. If false, falls back to using the rack session. By default, the Authorization header is used if it is present, if +only_json?+ is true, or if the request uses a json content type.
|
65
65
|
|
66
66
|
== Auth Methods
|
67
67
|
|