rodauth 2.36.0 → 2.37.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.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rodauth/features/base.rb +15 -1
  3. data/lib/rodauth/features/change_login.rb +2 -2
  4. data/lib/rodauth/features/create_account.rb +2 -2
  5. data/lib/rodauth/features/email_auth.rb +1 -1
  6. data/lib/rodauth/features/internal_request.rb +4 -4
  7. data/lib/rodauth/features/json.rb +5 -0
  8. data/lib/rodauth/features/jwt.rb +5 -9
  9. data/lib/rodauth/features/lockout.rb +1 -1
  10. data/lib/rodauth/features/login.rb +1 -1
  11. data/lib/rodauth/features/login_password_requirements_base.rb +13 -0
  12. data/lib/rodauth/features/reset_password.rb +1 -1
  13. data/lib/rodauth/features/two_factor_base.rb +6 -13
  14. data/lib/rodauth/features/verify_account.rb +2 -2
  15. data/lib/rodauth/features/webauthn_autofill.rb +2 -1
  16. data/lib/rodauth/features/webauthn_login.rb +1 -1
  17. data/lib/rodauth/version.rb +1 -1
  18. data/lib/rodauth.rb +6 -2
  19. metadata +3 -258
  20. data/CHANGELOG +0 -521
  21. data/README.rdoc +0 -1555
  22. data/doc/account_expiration.rdoc +0 -41
  23. data/doc/active_sessions.rdoc +0 -56
  24. data/doc/argon2.rdoc +0 -54
  25. data/doc/audit_logging.rdoc +0 -44
  26. data/doc/base.rdoc +0 -123
  27. data/doc/change_login.rdoc +0 -25
  28. data/doc/change_password.rdoc +0 -26
  29. data/doc/change_password_notify.rdoc +0 -14
  30. data/doc/close_account.rdoc +0 -26
  31. data/doc/confirm_password.rdoc +0 -32
  32. data/doc/create_account.rdoc +0 -27
  33. data/doc/disallow_common_passwords.rdoc +0 -17
  34. data/doc/disallow_password_reuse.rdoc +0 -30
  35. data/doc/email_auth.rdoc +0 -55
  36. data/doc/email_base.rdoc +0 -18
  37. data/doc/error_reasons.rdoc +0 -77
  38. data/doc/guides/admin_activation.rdoc +0 -46
  39. data/doc/guides/already_authenticated.rdoc +0 -10
  40. data/doc/guides/alternative_login.rdoc +0 -46
  41. data/doc/guides/change_table_and_column_names.rdoc +0 -19
  42. data/doc/guides/create_account_programmatically.rdoc +0 -38
  43. data/doc/guides/delay_password.rdoc +0 -25
  44. data/doc/guides/email_only.rdoc +0 -16
  45. data/doc/guides/i18n.rdoc +0 -29
  46. data/doc/guides/internals.rdoc +0 -233
  47. data/doc/guides/links.rdoc +0 -12
  48. data/doc/guides/login_return.rdoc +0 -37
  49. data/doc/guides/migrate_password_hash_algorithm.rdoc +0 -15
  50. data/doc/guides/password_column.rdoc +0 -25
  51. data/doc/guides/password_confirmation.rdoc +0 -37
  52. data/doc/guides/password_requirements.rdoc +0 -43
  53. data/doc/guides/paths.rdoc +0 -51
  54. data/doc/guides/query_params.rdoc +0 -9
  55. data/doc/guides/redirects.rdoc +0 -17
  56. data/doc/guides/registration_field.rdoc +0 -68
  57. data/doc/guides/render_confirmation.rdoc +0 -17
  58. data/doc/guides/require_mfa.rdoc +0 -30
  59. data/doc/guides/reset_password_autologin.rdoc +0 -21
  60. data/doc/guides/share_configuration.rdoc +0 -34
  61. data/doc/guides/status_column.rdoc +0 -28
  62. data/doc/guides/totp_or_recovery.rdoc +0 -16
  63. data/doc/http_basic_auth.rdoc +0 -18
  64. data/doc/internal_request.rdoc +0 -539
  65. data/doc/json.rdoc +0 -56
  66. data/doc/jwt.rdoc +0 -52
  67. data/doc/jwt_cors.rdoc +0 -22
  68. data/doc/jwt_refresh.rdoc +0 -58
  69. data/doc/lockout.rdoc +0 -73
  70. data/doc/login.rdoc +0 -39
  71. data/doc/login_password_requirements_base.rdoc +0 -44
  72. data/doc/logout.rdoc +0 -22
  73. data/doc/otp.rdoc +0 -93
  74. data/doc/otp_lockout_email.rdoc +0 -30
  75. data/doc/otp_modify_email.rdoc +0 -19
  76. data/doc/otp_unlock.rdoc +0 -58
  77. data/doc/password_complexity.rdoc +0 -34
  78. data/doc/password_expiration.rdoc +0 -38
  79. data/doc/password_grace_period.rdoc +0 -24
  80. data/doc/password_pepper.rdoc +0 -52
  81. data/doc/path_class_methods.rdoc +0 -10
  82. data/doc/recovery_codes.rdoc +0 -61
  83. data/doc/release_notes/1.0.0.txt +0 -443
  84. data/doc/release_notes/1.1.0.txt +0 -8
  85. data/doc/release_notes/1.10.0.txt +0 -80
  86. data/doc/release_notes/1.11.0.txt +0 -32
  87. data/doc/release_notes/1.12.0.txt +0 -61
  88. data/doc/release_notes/1.13.0.txt +0 -34
  89. data/doc/release_notes/1.14.0.txt +0 -19
  90. data/doc/release_notes/1.15.0.txt +0 -21
  91. data/doc/release_notes/1.16.0.txt +0 -31
  92. data/doc/release_notes/1.17.0.txt +0 -23
  93. data/doc/release_notes/1.18.0.txt +0 -26
  94. data/doc/release_notes/1.19.0.txt +0 -116
  95. data/doc/release_notes/1.2.0.txt +0 -18
  96. data/doc/release_notes/1.20.0.txt +0 -175
  97. data/doc/release_notes/1.21.0.txt +0 -12
  98. data/doc/release_notes/1.22.0.txt +0 -11
  99. data/doc/release_notes/1.23.0.txt +0 -32
  100. data/doc/release_notes/1.3.0.txt +0 -21
  101. data/doc/release_notes/1.4.0.txt +0 -11
  102. data/doc/release_notes/1.5.0.txt +0 -74
  103. data/doc/release_notes/1.6.0.txt +0 -37
  104. data/doc/release_notes/1.7.0.txt +0 -6
  105. data/doc/release_notes/1.8.0.txt +0 -14
  106. data/doc/release_notes/1.9.0.txt +0 -15
  107. data/doc/release_notes/2.0.0.txt +0 -361
  108. data/doc/release_notes/2.1.0.txt +0 -31
  109. data/doc/release_notes/2.10.0.txt +0 -47
  110. data/doc/release_notes/2.11.0.txt +0 -31
  111. data/doc/release_notes/2.12.0.txt +0 -17
  112. data/doc/release_notes/2.13.0.txt +0 -19
  113. data/doc/release_notes/2.14.0.txt +0 -17
  114. data/doc/release_notes/2.15.0.txt +0 -48
  115. data/doc/release_notes/2.16.0.txt +0 -20
  116. data/doc/release_notes/2.17.0.txt +0 -10
  117. data/doc/release_notes/2.18.0.txt +0 -27
  118. data/doc/release_notes/2.19.0.txt +0 -61
  119. data/doc/release_notes/2.2.0.txt +0 -39
  120. data/doc/release_notes/2.20.0.txt +0 -10
  121. data/doc/release_notes/2.21.0.txt +0 -28
  122. data/doc/release_notes/2.22.0.txt +0 -43
  123. data/doc/release_notes/2.23.0.txt +0 -15
  124. data/doc/release_notes/2.24.0.txt +0 -15
  125. data/doc/release_notes/2.25.0.txt +0 -8
  126. data/doc/release_notes/2.26.0.txt +0 -45
  127. data/doc/release_notes/2.27.0.txt +0 -35
  128. data/doc/release_notes/2.28.0.txt +0 -16
  129. data/doc/release_notes/2.29.0.txt +0 -27
  130. data/doc/release_notes/2.3.0.txt +0 -37
  131. data/doc/release_notes/2.30.0.txt +0 -15
  132. data/doc/release_notes/2.31.0.txt +0 -47
  133. data/doc/release_notes/2.32.0.txt +0 -65
  134. data/doc/release_notes/2.33.0.txt +0 -18
  135. data/doc/release_notes/2.34.0.txt +0 -36
  136. data/doc/release_notes/2.35.0.txt +0 -22
  137. data/doc/release_notes/2.36.0.txt +0 -35
  138. data/doc/release_notes/2.4.0.txt +0 -22
  139. data/doc/release_notes/2.5.0.txt +0 -20
  140. data/doc/release_notes/2.6.0.txt +0 -37
  141. data/doc/release_notes/2.7.0.txt +0 -33
  142. data/doc/release_notes/2.8.0.txt +0 -20
  143. data/doc/release_notes/2.9.0.txt +0 -21
  144. data/doc/remember.rdoc +0 -79
  145. data/doc/reset_password.rdoc +0 -66
  146. data/doc/reset_password_notify.rdoc +0 -17
  147. data/doc/session_expiration.rdoc +0 -28
  148. data/doc/single_session.rdoc +0 -37
  149. data/doc/sms_codes.rdoc +0 -138
  150. data/doc/two_factor_base.rdoc +0 -70
  151. data/doc/update_password_hash.rdoc +0 -7
  152. data/doc/verify_account.rdoc +0 -67
  153. data/doc/verify_account_grace_period.rdoc +0 -19
  154. data/doc/verify_login_change.rdoc +0 -59
  155. data/doc/webauthn.rdoc +0 -118
  156. data/doc/webauthn_autofill.rdoc +0 -19
  157. data/doc/webauthn_login.rdoc +0 -16
  158. data/doc/webauthn_modify_email.rdoc +0 -19
  159. data/doc/webauthn_verify_account.rdoc +0 -9
@@ -1,77 +0,0 @@
1
- = Error Reasons
2
-
3
- Rodauth allows for customizing response status codes and error
4
- messages for each type of error. However, in some cases, the
5
- response status code is too coarse for desired error handling
6
- by the application (since many error types use the same status
7
- code), and using the error message is too fragile since it may
8
- be translated.
9
-
10
- For this reason, Rodauth associates a fine grained reason for
11
- each type of error. If an error occurs in Rodauth, it will
12
- call the +set_error_reason+ method with a symbol for the
13
- specific type of error. By default, this method does not do
14
- anything, but you can use the +set_error_reason+ configuration
15
- method to customize the error handling.
16
-
17
- These are the currently supported error type symbols that
18
- Rodauth will call +set_error_reason+ with:
19
-
20
- * :account_locked_out
21
- * :already_an_account_with_this_login
22
- * :already_an_unverified_account_with_this_login
23
- * :duplicate_webauthn_id
24
- * :inactive_session
25
- * :invalid_email_auth_key
26
- * :invalid_otp_auth_code
27
- * :invalid_otp_secret
28
- * :invalid_password
29
- * :invalid_password_pattern
30
- * :invalid_phone_number
31
- * :invalid_previous_password
32
- * :invalid_recovery_code
33
- * :invalid_remember_param
34
- * :invalid_reset_password_key
35
- * :invalid_sms_code
36
- * :invalid_sms_confirmation_code
37
- * :invalid_unlock_account_key
38
- * :invalid_verify_account_key
39
- * :invalid_verify_login_change_key
40
- * :invalid_webauthn_auth_param
41
- * :invalid_webauthn_id
42
- * :invalid_webauthn_remove_param
43
- * :invalid_webauthn_setup_param
44
- * :invalid_webauthn_sign_count
45
- * :login_not_valid_email
46
- * :login_required
47
- * :login_too_long
48
- * :login_too_many_bytes
49
- * :login_too_short
50
- * :logins_do_not_match
51
- * :no_current_sms_code
52
- * :no_matching_login
53
- * :not_enough_character_groups_in_password
54
- * :otp_locked_out
55
- * :password_authentication_required
56
- * :password_contains_null_byte
57
- * :password_does_not_meet_requirements
58
- * :password_in_dictionary
59
- * :password_is_one_of_the_most_common
60
- * :password_same_as_previous_password
61
- * :password_too_long
62
- * :password_too_many_bytes
63
- * :password_too_short
64
- * :passwords_do_not_match
65
- * :same_as_current_login
66
- * :same_as_existing_password
67
- * :session_expired
68
- * :sms_already_setup
69
- * :sms_locked_out
70
- * :sms_needs_confirmation
71
- * :sms_not_setup
72
- * :too_many_repeating_characters_in_password
73
- * :two_factor_already_authenticated
74
- * :two_factor_need_authentication
75
- * :two_factor_not_setup
76
- * :unverified_account
77
- * :webauthn_not_setup
@@ -1,46 +0,0 @@
1
- = Require account verification by admin
2
-
3
- There are scenarios in which, instead of allowing the user to verify they have
4
- access to the email for the account, you may want to have an admin or moderator
5
- approve new accounts manually. One way this can be achieved by sending the
6
- account verification email to the admin:
7
-
8
- plugin :rodauth do
9
- enable :login, :logout, :verify_account, :reset_password
10
-
11
- # Send account verification email to the admin
12
- email_to do
13
- if account[account_status_column] == account_unverified_status_value
14
- "admin@myapp.com"
15
- else
16
- super()
17
- end
18
- end
19
-
20
- # Do not ask for password when creating or verifying account
21
- verify_account_set_password? false
22
- create_account_set_password? false
23
-
24
- # Adjust the account verification email subject and body
25
- verify_account_email_subject "New User Awaiting Admin Approval"
26
- verify_account_email_body do
27
- "The user #{account[login_column]} has created an account. Click here to approve it: #{verify_account_email_link}."
28
- end
29
-
30
- # Display this message to the user after they've created their account
31
- verify_account_email_sent_notice_flash "Your account has been created and is awaiting approval"
32
-
33
- # Prevent the admin from being logged in after confirming the account
34
- verify_account_autologin? false
35
- verify_account_notice_flash "The account has been approved"
36
-
37
- # Send a reset password email after verifying the account.
38
- # This allows the user to choose the password for the account,
39
- # and also makes sure the user can only log in if they have
40
- # access to the email address for the account.
41
- after_verify_account do
42
- generate_reset_password_key_value
43
- create_reset_password_key
44
- send_reset_password_email
45
- end
46
- end
@@ -1,10 +0,0 @@
1
- = Skip login page if already authenticated
2
-
3
- In some cases it may be useful to skip login/registration pages when the user
4
- is already logged in. This can be achieved as follows. Note that this only
5
- matters if the user manually navigates to the login or create account pages.
6
-
7
- plugin :rodauth do
8
- # Redirect logged in users to the wherever login redirects to
9
- already_logged_in { redirect login_redirect }
10
- end
@@ -1,46 +0,0 @@
1
- = Use a non-email login
2
-
3
- Rodauth's by default uses email addresses for identifying users, since that is
4
- the most common form of identifier currently. In some cases, you might want
5
- to allow logging in via alternative identifiers, such as a username. In this
6
- case, it is best to choose a different column name for the login, such as
7
- +:username+. Among other things, this also makes it so that the login field
8
- does not expect an email address to be provided.
9
-
10
- plugin :rodauth do
11
- enable :login, :logout
12
- login_column :username
13
- end
14
-
15
- Note that Rodauth features that require sending email need an email address, and
16
- that defaults to the value of the login column. If you have both a username and
17
- an email for an account, you can have the login column be the user, and use the
18
- value of the email colummn for the email address.
19
-
20
- plugin :rodauth do
21
- enable :login, :logout, :reset_password
22
-
23
- login_column :username
24
- email_to do
25
- account[:email]
26
- end
27
- end
28
-
29
- An alternative approach would be to accept a login and automatically change it
30
- to an email address. If you have a +username+ field on the +accounts+ table,
31
- then you can configure Rodauth to allow entering a username instead of email
32
- during login. See the {Adding new registration field}[rdoc-ref:doc/guides/registration_field.rdoc]
33
- guide for instructions on requiring add an additional field during registration.
34
-
35
- plugin :rodauth do
36
- enable :login, :logout
37
-
38
- account_from_login do |login|
39
- # handle the case when login parameter is a username
40
- unless login.include?("@")
41
- login = db[:accounts].where(username: login).get(:email)
42
- end
43
-
44
- super(login)
45
- end
46
- end
@@ -1,19 +0,0 @@
1
- = Change table and column names
2
-
3
- All tables that Rodauth uses will have a configuration method that ends with
4
- +_table+ for configuring the table name. For example, if you store user accounts
5
- in the +users+ table instead of +accounts+ table, you can use the following
6
- in your configuration:
7
-
8
- accounts_table :users
9
-
10
- All columns that Rodauth uses will have a configuration method that ends with
11
- +_column+ for configuring the column name. For example, if you are storing the
12
- login for accounts in the +login+ column instead of the +email+ column, you
13
- can use the following in your configuration:
14
-
15
- login_column :login
16
-
17
- Please see the documentation for Rodauth features for the names of the
18
- configuration methods that you can use. You can see the default values for
19
- the tables and columns in the {"Creating tables" section of the README}[rdoc-ref:README.rdoc].
@@ -1,38 +0,0 @@
1
- = Create an account record programmatically
2
-
3
- In some scenarios you might want to create an account records programmatically,
4
- for example in your tests.
5
-
6
- If you're storing passwords in a separate table, you can create an account
7
- records as follows:
8
-
9
- account_id = DB[:accounts].insert(
10
- email: "name@example.com",
11
- status_id: 2, # verified
12
- )
13
-
14
- DB[:account_password_hashes].insert(
15
- id: account_id,
16
- password_hash: BCrypt::Password.create("secret").to_s,
17
- )
18
-
19
- If the password is stored in a column in the accounts table:
20
-
21
- account_id = DB[:accounts].insert(
22
- email: "name@example.com",
23
- password_hash: BCrypt::Password.create("secret").to_s,
24
- status_id: 2, # verified
25
- )
26
-
27
- If you are creating accounts in your tests, you probably want to use
28
- the +:cost+ option, otherwise you will have very slow tests:
29
-
30
- account_id = DB[:accounts].insert(
31
- email: "name@example.com",
32
- status_id: 2, # verified
33
- )
34
-
35
- DB[:account_password_hashes].insert(
36
- id: account_id,
37
- password_hash: BCrypt::Password.create("secret", cost: BCrypt::Engine::MIN_COST).to_s,
38
- )
@@ -1,25 +0,0 @@
1
- = Set password when verifying account
2
-
3
- If you want to request less information from the user on registration, you can
4
- ask the user to set their password only when they verify their account:
5
-
6
- plugin :rodauth do
7
- enable :login, :logout, :verify_account
8
- verify_account_set_password? true
9
- end
10
-
11
- Note that this is already the default behaviour when verify account feature is
12
- loaded, but it's not when verify account grace period is used, because it would
13
- prevent the account from logging in during the grace period. You can work around
14
- this by automatically remebering their login during account creation using the
15
- remember feature. Be aware that remembering accounts has effects beyond the
16
- verification period, and this would only allow automatic logins from the browser
17
- that created the account.
18
-
19
- plugin :rodauth do
20
- enable :login, :logout, :verify_account_grace_period, :remember
21
- verify_account_set_password? true
22
- after_create_account do
23
- remember_login
24
- end
25
- end
@@ -1,16 +0,0 @@
1
- = Allow only email authentication
2
-
3
- When using the email authentication feature, you can avoid other authentication
4
- mechanisms entirely as follows:
5
-
6
- plugin :rodauth do
7
- enable :login, :email_auth, :create_account, :verify_account
8
-
9
- create_account_set_password? false
10
- verify_account_set_password? false
11
- force_email_auth? true
12
- end
13
-
14
- With this configuration, users won't be required to enter a password on
15
- registration, and on login the email authentication link will automatically be
16
- sent after the email address is entered.
data/doc/guides/i18n.rdoc DELETED
@@ -1,29 +0,0 @@
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"
27
-
28
- Alternatively, you can use the
29
- {rodauth-i18n}[https://github.com/janko/rodauth-i18n] gem.
@@ -1,233 +0,0 @@
1
- = Rodauth Internals
2
-
3
- Rodauth's implementation heavily uses metaprogramming in order to DRY up the codebase, which can be a little intimidating 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 rodauth feature you load is an instance of this class, which 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
- # This defines the following methods related to sending email:
147
- #
148
- # * foo_email_subject: uses given subject
149
- # * foo_email_body: renders foo-email template
150
- # * create_foo_email: creates Mail::Message using subject and body
151
- # * send_foo_email: sends created email
152
- #
153
- # The foo-email template should be included in the loaded_templates call to make sure
154
- # template precompilation works.
155
- email :foo, 'Foo Subject'
156
-
157
- # auth_value_method is a generic method that takes two arguments, a method to define
158
- # and a default value. It is similar to the methods above, except that it allows
159
- # arbitrary method names. The notice_flash, error_flash, button, and additional_form_tags
160
- # methods are actually defined in terms of this method.
161
- #
162
- # So this particular method defines a foo_error_status method that will return 401 by
163
- # default, but also adds a configuration method that allows you to override the default.
164
- auth_value_method :foo_error_status, 401
165
-
166
- # This is similar to auth_value_method, but it only adds the configuration method.
167
- # Using this should only be done if you have defining the method in the feature
168
- # separately (see below).
169
- auth_value_methods :foo_bar
170
-
171
- # This is similar to auth_value_methods, but it changes the configuration method so that
172
- # a block is required and you cannot provide an argument. This is used for the cases
173
- # where a statically defined value would never make sense, such as when any correct
174
- # behavior would depend on accessing request-specific information.
175
- auth_methods :foo
176
-
177
- # route defines a route used for the feature. This is the code that will be executed
178
- # if a user goes to /foo in the Roda app.
179
- route do |r|
180
- # Inside the block, you are in the context of the Rodauth::Auth subclass instance.
181
- # r is the Roda::RodaRequest subclass instance, just as it would be for a Roda
182
- # route block.
183
-
184
- # route adds a before_foo_route method that by default does nothing. It also
185
- # adds a configuration method that you can call to set behavior that will be
186
- # executed before routing.
187
- before_foo_route
188
-
189
- # Just like in Roda, r.get is called for GET requests
190
- r.get do
191
- # This will render a view to the user, using the foo.erb template from the
192
- # templates directory (unless the user has overridden it), inside the Roda
193
- # application's layout.
194
- foo_view
195
- end
196
-
197
- # Just like in Roda, r.post is called for POST requests
198
- r.post do
199
- # This is called before performing the foo action
200
- before_foo
201
-
202
- # This assumes foo returns false or nil on failure, or otherwise on
203
- # success.
204
- if foo
205
- # In general, Rodauth only calls after_foo if foo is successful.
206
- after_foo
207
-
208
- # Successful form submission will usually set the notice flash,
209
- # the redirect to the appropriate page.
210
- set_notice_flash foo_notice_flash
211
- redirect foo_redirect
212
- else
213
- # Unsucessful form subsmission will usually set the error flash,
214
- # the redisplay the page so that the submission can be fixed.
215
- set_error_flash foo_error_flash
216
- foo_view
217
- end
218
- end
219
- end
220
-
221
- # This is the default behavior for the foo method, if a user doesn't
222
- # call the foo method inside the configuration block.
223
- def foo
224
- # Do Something
225
- end
226
-
227
- # This is the default behavior for the foo_bar method, if a user doesn't
228
- # call the foo_bar method inside the configuration block.
229
- def foo_bar
230
- 42
231
- end
232
- end
233
- end
@@ -1,12 +0,0 @@
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>
@@ -1,37 +0,0 @@
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
@@ -1,15 +0,0 @@
1
- = Migrate users passwords from bcrypt to argon2 or back
2
-
3
- If you are currently using the default bcrypt password hash algorithm, and want to
4
- gradually migrate to the argon2 password hash algorithm, you can use both the argon2
5
- and update_password_hash features:
6
-
7
- plugin :rodauth do
8
- enable :login, :update_password_hash, :argon2
9
- end
10
-
11
- When a user with a current bcrypt password hash next successfully uses their
12
- password, their password hash will be migrated to argon2.
13
-
14
- If for some reason you want to migrate back from argon2 to bcrypt, you can set
15
- <tt>use_argon2? false</tt> in your Rodauth configuration.
@@ -1,25 +0,0 @@
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