rodauth 1.21.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +182 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +211 -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 +75 -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 +6 -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 +22 -0
- data/doc/jwt_refresh.rdoc +18 -8
- data/doc/lockout.rdoc +17 -15
- data/doc/login.rdoc +10 -2
- data/doc/login_password_requirements_base.rdoc +15 -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/recovery_codes.rdoc +18 -12
- data/doc/release_notes/1.22.0.txt +11 -0
- data/doc/release_notes/1.23.0.txt +32 -0
- 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/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 +36 -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 +144 -43
- data/lib/rodauth/features/change_password_notify.rb +2 -2
- 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 +1 -1
- data/lib/rodauth/features/email_auth.rb +31 -30
- data/lib/rodauth/features/email_base.rb +9 -4
- 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 +53 -0
- data/lib/rodauth/features/jwt_refresh.rb +32 -9
- data/lib/rodauth/features/lockout.rb +12 -14
- data/lib/rodauth/features/login.rb +54 -10
- data/lib/rodauth/features/login_password_requirements_base.rb +4 -4
- data/lib/rodauth/features/otp.rb +77 -80
- data/lib/rodauth/features/password_complexity.rb +8 -13
- data/lib/rodauth/features/password_expiration.rb +2 -2
- data/lib/rodauth/features/password_grace_period.rb +17 -10
- data/lib/rodauth/features/recovery_codes.rb +49 -53
- data/lib/rodauth/features/remember.rb +11 -27
- data/lib/rodauth/features/reset_password.rb +26 -26
- data/lib/rodauth/features/session_expiration.rb +6 -4
- data/lib/rodauth/features/single_session.rb +8 -6
- data/lib/rodauth/features/sms_codes.rb +62 -72
- data/lib/rodauth/features/two_factor_base.rb +134 -30
- data/lib/rodauth/features/verify_account.rb +29 -21
- data/lib/rodauth/features/verify_account_grace_period.rb +18 -9
- data/lib/rodauth/features/verify_login_change.rb +12 -11
- 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/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-email.str +1 -1
- data/templates/email-auth-request-form.str +2 -3
- 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-email.str +1 -1
- data/templates/reset-password-request.str +3 -3
- 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-email.str +1 -1
- data/templates/unlock-account-request.str +4 -4
- data/templates/unlock-account.str +1 -1
- data/templates/verify-account-email.str +1 -1
- data/templates/verify-account-resend.str +3 -3
- data/templates/verify-account.str +1 -2
- data/templates/verify-login-change-email.str +2 -1
- 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 +110 -52
- data/Rakefile +0 -179
- data/doc/verify_change_login.rdoc +0 -11
- data/lib/rodauth/features/verify_change_login.rb +0 -20
- data/spec/account_expiration_spec.rb +0 -225
- data/spec/all.rb +0 -1
- data/spec/change_login_spec.rb +0 -156
- data/spec/change_password_notify_spec.rb +0 -33
- data/spec/change_password_spec.rb +0 -202
- data/spec/close_account_spec.rb +0 -162
- data/spec/confirm_password_spec.rb +0 -70
- data/spec/create_account_spec.rb +0 -127
- data/spec/disallow_common_passwords_spec.rb +0 -93
- data/spec/disallow_password_reuse_spec.rb +0 -179
- data/spec/email_auth_spec.rb +0 -285
- data/spec/http_basic_auth_spec.rb +0 -143
- data/spec/jwt_refresh_spec.rb +0 -256
- data/spec/jwt_spec.rb +0 -235
- data/spec/lockout_spec.rb +0 -250
- data/spec/login_spec.rb +0 -328
- data/spec/migrate/001_tables.rb +0 -184
- data/spec/migrate/002_account_password_hash_column.rb +0 -11
- data/spec/migrate_password/001_tables.rb +0 -73
- data/spec/migrate_travis/001_tables.rb +0 -141
- data/spec/password_complexity_spec.rb +0 -109
- data/spec/password_expiration_spec.rb +0 -244
- data/spec/password_grace_period_spec.rb +0 -93
- data/spec/remember_spec.rb +0 -451
- data/spec/reset_password_spec.rb +0 -229
- data/spec/rodauth_spec.rb +0 -343
- data/spec/session_expiration_spec.rb +0 -58
- data/spec/single_session_spec.rb +0 -127
- data/spec/spec_helper.rb +0 -327
- data/spec/two_factor_spec.rb +0 -1462
- data/spec/update_password_hash_spec.rb +0 -40
- data/spec/verify_account_grace_period_spec.rb +0 -171
- data/spec/verify_account_spec.rb +0 -240
- data/spec/verify_change_login_spec.rb +0 -46
- data/spec/verify_login_change_spec.rb +0 -232
- data/spec/views/layout-other.str +0 -11
- data/spec/views/layout.str +0 -11
- data/spec/views/login.str +0 -21
data/doc/verify_account.rdoc
CHANGED
@@ -10,30 +10,32 @@ after verifying the account. Depends on the login and create account features.
|
|
10
10
|
attempt_to_create_unverified_account_error_flash :: The flash error message to show when attempting to create an account awaiting verification.
|
11
11
|
attempt_to_login_to_unverified_account_error_flash :: The flash error message to show when attempting to login to an account awaiting verification.
|
12
12
|
no_matching_verify_account_key_error_flash :: The flash error message to show when an invalid verify account key is used.
|
13
|
+
resend_verify_account_page_title :: The page title to use on page requesting resending the verify account email.
|
13
14
|
verify_account_additional_form_tags :: HTML fragment containing additional form tags to use on the verify account form.
|
14
15
|
verify_account_autologin? :: Whether to autologin the user after successful account verification, true by default.
|
15
16
|
verify_account_button :: The text to use for the verify account button.
|
17
|
+
verify_account_email_last_sent_column :: The email last sent column in the +verify_account_table+. Set to nil to always send a verify account email when requested.
|
16
18
|
verify_account_email_recently_sent_error_flash :: The flash error to show if not sending verify account email because one has been sent recently.
|
17
19
|
verify_account_email_recently_sent_redirect :: Where to redirect if not sending verify account email because one has been sent recently.
|
18
|
-
verify_account_email_subject :: The subject to use for the verify account email.
|
19
|
-
verify_account_email_sent_redirect :: Where to redirect after sending the verify account email.
|
20
20
|
verify_account_email_sent_notice_flash :: The flash notice to set after sending the verify account email.
|
21
|
-
|
21
|
+
verify_account_email_sent_redirect :: Where to redirect after sending the verify account email.
|
22
|
+
verify_account_email_subject :: The subject to use for the verify account email.
|
22
23
|
verify_account_error_flash :: The flash error to show if no matching key is submitted when verifying an account.
|
23
|
-
verify_account_id_column :: The id column in the
|
24
|
-
verify_account_key_column :: The verify account key/token column in the
|
24
|
+
verify_account_id_column :: The id column in the +verify_account_table+, should be a foreign key referencing the accounts table.
|
25
|
+
verify_account_key_column :: The verify account key/token column in the +verify_account_table+.
|
25
26
|
verify_account_key_param :: The parameter name to use for the verify account key.
|
26
27
|
verify_account_notice_flash :: The flash notice to show after verifying the account.
|
28
|
+
verify_account_page_title :: The page title to use on the verify account form.
|
29
|
+
verify_account_redirect :: Where to redirect after verifying the account.
|
27
30
|
verify_account_resend_additional_form_tags :: HTML fragment containing additional form tags to use on the page requesting resending the verify account email.
|
28
31
|
verify_account_resend_button :: The text to use for the verify account resend button.
|
29
|
-
verify_account_redirect :: Where to redirect after verifying the account.
|
30
32
|
verify_account_resend_error_flash :: The flash error to show if unable to resend a verify account email.
|
31
33
|
verify_account_resend_explanatory_text :: The text to display above the button to resend the verify account email.
|
32
|
-
|
34
|
+
verify_account_resend_link_text :: The text to use for a link to the page to request the account verification email be resent.
|
33
35
|
verify_account_resend_route :: The route to the verify account resend action. Defaults to +verify-account-resend+.
|
34
36
|
verify_account_route :: The route to the verify account action. Defaults to +verify-account+.
|
35
37
|
verify_account_session_key :: The key in the session to hold the verify account key temporarily.
|
36
|
-
verify_account_set_password? :: Whether to ask for a password to be set on the verify account form.
|
38
|
+
verify_account_set_password? :: Whether to ask for a password to be set on the verify account form. True by default. If set to false, will ask for password when creating the account instead of when verifying.
|
37
39
|
verify_account_skip_resend_email_within :: The number of seconds before sending another verify account email, if +verify_account_email_last_sent_column+ is set.
|
38
40
|
verify_account_table :: The name of the verify account keys table.
|
39
41
|
|
@@ -41,14 +43,14 @@ verify_account_table :: The name of the verify account keys table.
|
|
41
43
|
|
42
44
|
account_from_verify_account_key(key) :: Retrieve the account using the given verify account key, or return nil if no account matches.
|
43
45
|
after_verify_account :: Run arbitrary code after verifying the account.
|
44
|
-
|
46
|
+
after_verify_account_email_resend :: Run arbitrary code after resending a verify account email.
|
45
47
|
allow_resending_verify_account_email? :: Whether to allow sending the verify account email for the account, true by default only if the account has not been verified.
|
46
48
|
before_verify_account :: Run arbitrary code before verifying the account.
|
47
|
-
|
49
|
+
before_verify_account_email_resend :: Run arbitrary code before resending a verify account email.
|
48
50
|
before_verify_account_resend_route :: Run arbitrary code before handling a verify account resend route.
|
49
51
|
before_verify_account_route :: Run arbitrary code before handling a verify account route.
|
50
|
-
create_verify_account_key :: Add the verify account key data to the database.
|
51
52
|
create_verify_account_email :: A Mail::Message for the verify account email.
|
53
|
+
create_verify_account_key :: Add the verify account key data to the database.
|
52
54
|
get_verify_account_email_last_sent :: Get the last time a verify account email is sent, or nil if there is no last sent time.
|
53
55
|
get_verify_account_key(id) :: Get the verify account key for the given account id from the database.
|
54
56
|
remove_verify_account_key :: Remove the verify account key for the current account, run after successful account verification.
|
@@ -58,6 +60,6 @@ set_verify_account_email_last_sent :: Set the last time a verify account email i
|
|
58
60
|
verify_account :: Verify the account by changing the status from unverified to open.
|
59
61
|
verify_account_email_body :: The body to use for the verify account email.
|
60
62
|
verify_account_email_link :: The link to the verify account form in the verify account email.
|
61
|
-
verify_account_key_insert_hash :: The hash to insert into the
|
63
|
+
verify_account_key_insert_hash :: The hash to insert into the +verify_account_table+.
|
62
64
|
verify_account_key_value :: The value of the verify account key.
|
63
65
|
verify_account_view :: The HTML to use for the verify account form.
|
@@ -2,12 +2,16 @@
|
|
2
2
|
|
3
3
|
The verify account grace period feature allows users to login for
|
4
4
|
a given period of time (1 day by default) before their account is
|
5
|
-
verified. Depends on the verify account feature.
|
5
|
+
verified. Depends on the verify account feature. This switches
|
6
|
+
the +verify_account_set_password?+ to false so that user can login
|
7
|
+
with a password during the grace period.
|
6
8
|
|
7
9
|
== Auth Value Methods
|
8
10
|
|
9
|
-
verification_requested_at_column :: The column in the +verify_account_table+ table that holds the verification requested timestamp.
|
10
11
|
unverified_account_session_key :: The session key set if the logged in account has not been unverified.
|
12
|
+
unverified_change_login_error_flash :: The flash error to show when an unverified accounts accesses a change login route.
|
13
|
+
unverified_change_login_redirect :: Where to redirect when an unverified accounts accesses a change login route.
|
14
|
+
verification_requested_at_column :: The column in the +verify_account_table+ table that holds the verification requested timestamp.
|
11
15
|
verify_account_grace_period :: The amount of seconds after an account creation that a user will be able to login without verifying (86400 by default).
|
12
16
|
|
13
17
|
== Auth Methods
|
@@ -1,11 +1,11 @@
|
|
1
1
|
= Documentation for Verify Login Change Feature
|
2
2
|
|
3
|
-
The verify login change feature implements
|
4
|
-
|
3
|
+
The verify login change feature implements verification of login
|
4
|
+
changes. With this feature, login changes do not take effect
|
5
5
|
until after the user has verified the new login. Until the new
|
6
6
|
login has been verified, the old login continues to work.
|
7
7
|
|
8
|
-
Any time you use the verify
|
8
|
+
Any time you use the verify account and change login features together,
|
9
9
|
you should probably use this, otherwise it is trivial for users to work
|
10
10
|
around account verification by creating an account with an email address
|
11
11
|
they control, and the changing the login to an email address they don't
|
@@ -17,17 +17,18 @@ no_matching_verify_login_change_key_error_flash :: The flash error message to sh
|
|
17
17
|
verify_login_change_additional_form_tags :: HTML fragment containing additional form tags to use on the verify login change form.
|
18
18
|
verify_login_change_autologin? :: Whether to autologin the user after successful login change verification, false by default.
|
19
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
|
20
|
+
verify_login_change_deadline_column :: The column name in the +verify_login_change_table+ storing the deadline after which the token will be ignored.
|
21
21
|
verify_login_change_deadline_interval :: The amount of time for which to allow users to verify login changes, 1 day by default.
|
22
22
|
verify_login_change_duplicate_account_error_flash :: The flash error message to show when attempting to verify a login change when the login is already taken.
|
23
23
|
verify_login_change_duplicate_account_redirect :: Where to redirect if not changing a login during verification because the new login is already taken.
|
24
24
|
verify_login_change_email_subject :: The subject to use for the verify login change email.
|
25
25
|
verify_login_change_error_flash :: The flash error to show if no matching key is submitted when verifying login change.
|
26
|
-
verify_login_change_id_column :: The id column in the
|
27
|
-
verify_login_change_key_column :: The verify login change key/token column in the
|
26
|
+
verify_login_change_id_column :: The id column in the +verify_login_change_table+, should be a foreign key referencing the accounts table.
|
27
|
+
verify_login_change_key_column :: The verify login change key/token column in the +verify_login_change_table+.
|
28
28
|
verify_login_change_key_param :: The parameter name to use for the verify login change key.
|
29
|
-
verify_login_change_login_column :: The login column in the
|
29
|
+
verify_login_change_login_column :: The login column in the +verify_login_change_table+, containing the new login.
|
30
30
|
verify_login_change_notice_flash :: The flash notice to show after verifying the login change.
|
31
|
+
verify_login_change_page_title :: The page title to use on the verify login change form.
|
31
32
|
verify_login_change_redirect :: Where to redirect after verifying the login change.
|
32
33
|
verify_login_change_route :: The route to the verify login change action. Defaults to +verify-login-change+.
|
33
34
|
verify_login_change_session_key :: The key in the session to hold the verify login change key temporarily.
|
@@ -49,7 +50,7 @@ send_verify_login_change_email(login) :: Send the verify login change email.
|
|
49
50
|
verify_login_change :: Change the login for the given account to the new login.
|
50
51
|
verify_login_change_email_body :: The body to use for the verify login change email.
|
51
52
|
verify_login_change_email_link :: The link to the verify login change form in the verify login change email.
|
52
|
-
verify_login_change_key_insert_hash(login) :: The hash to insert into the
|
53
|
+
verify_login_change_key_insert_hash(login) :: The hash to insert into the +verify_login_change_table+.
|
53
54
|
verify_login_change_key_value :: The value of the verify login change key.
|
54
55
|
verify_login_change_new_login :: The new login to use when the login change is verified.
|
55
56
|
verify_login_change_old_login :: The old login to display in the verify login change email.
|
data/doc/webauthn.rdoc
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
= Documentation for WebAuthn Feature
|
2
|
+
|
3
|
+
The webauthn feature implements multifactor authentication via WebAuthn.
|
4
|
+
It supports registering WebAuthn authenticators, using them for
|
5
|
+
multifactor authentication, and removing WebAuthn authenticators.
|
6
|
+
This feature supports multiple WebAuthn authenticators per user,
|
7
|
+
and users are encouraged to have multiple WebAuthn authenticators
|
8
|
+
so that they have a backup if one is not available.
|
9
|
+
|
10
|
+
WebAuthn authentication requires javascript to work in
|
11
|
+
browsers, for the browser to communicate with the authenticator.
|
12
|
+
This feature offers routes that return the appropriate javascript.
|
13
|
+
However, the javascript works by setting a hidden form field and
|
14
|
+
using normal form submission. This allows testing the feature
|
15
|
+
without using javascript. See Rodauth's tests for how testing
|
16
|
+
without javascript works.
|
17
|
+
|
18
|
+
The webauthn feature requires the webauthn gem.
|
19
|
+
|
20
|
+
== Auth Value Methods
|
21
|
+
|
22
|
+
authenticated_webauthn_id_session_key :: The session key used for storing which WebAuthn ID was used during authentication.
|
23
|
+
webauthn_attestation :: The value of the WebAuthn attestation option when registering a new WebAuthn authenticator.
|
24
|
+
webauthn_auth_additional_form_tags :: HTML fragment containing additional form tags when authenticating via WebAuthn.
|
25
|
+
webauthn_auth_button :: Text to use for button on the form to authenticate via WebAuthn.
|
26
|
+
webauthn_auth_challenge_hmac_param :: The parameter name for the HMAC of the WebAuthn challenge during authentication.
|
27
|
+
webauthn_auth_challenge_param :: The parameter name for the WebAuthn challenge during authentication.
|
28
|
+
webauthn_auth_error_flash :: The flash error to show if unable to authenticate via WebAuthn.
|
29
|
+
webauthn_auth_js :: The javascript code to execute on the page to authenticate via WebAuthn.
|
30
|
+
webauthn_auth_js_route :: The route to the webauthn auth javascript file.
|
31
|
+
webauthn_auth_link_text :: The text to use for the link from the multifactor auth page.
|
32
|
+
webauthn_auth_page_title :: The page title to use on the page for authenticating via WebAuthn.
|
33
|
+
webauthn_auth_param :: The parameter name for the WebAuthn authentication data.
|
34
|
+
webauthn_auth_route :: The route to the webauthn auth action.
|
35
|
+
webauthn_auth_timeout :: The number of milliseconds to wait when authenticating using a WebAuthn authenticator.
|
36
|
+
webauthn_authenticator_selection :: The value of the WebAuthn authenticatorSelection option when registering a new WebAuthn authenticator.
|
37
|
+
webauthn_duplicate_webauthn_id_message :: The error message to when there is an attempt to insert a duplicate WebAuthn authenticator.
|
38
|
+
webauthn_extensions :: The value of the WebAuthn extensions option when registering a new WebAuthn authenticator or authenticating via WebAuthn.
|
39
|
+
webauthn_invalid_auth_param_message :: The error message to show when invalid or missing WebAuthn authentication data is provided.
|
40
|
+
webauthn_invalid_remove_param_message :: The error message to show when invalid WebAuthn ID is provided when removing a WebAuthn authenticator.
|
41
|
+
webauthn_invalid_setup_param_message :: The error message to show when invalid or missing WebAuthn registration data is provided.
|
42
|
+
webauthn_invalid_sign_count_message :: The error message to when there is an attempt to authenticate with WebAuthn authenticator with an invalid sign count.
|
43
|
+
webauthn_js_host :: The protocol and domain if using a separate host for the WebAuthn setup and auth javascript files.
|
44
|
+
webauthn_keys_account_id_column :: The column in the +webauthn_keys_table+ containing the account id.
|
45
|
+
webauthn_keys_last_use_column :: The column in the +webauthn_keys_table+ containing the last time the WebAuthn credential was used.
|
46
|
+
webauthn_keys_public_key_column :: The column in the +webauthn_keys_table+ containing the public key for the WebAuthn credential.
|
47
|
+
webauthn_keys_sign_count_column :: The column in the +webauthn_keys_table+ containing the sign count for the WebAuthn credential.
|
48
|
+
webauthn_keys_table :: The table name containing the WebAuthn public keys.
|
49
|
+
webauthn_keys_webauthn_id_column :: The column in the +webauthn_keys_table+ containing the WebAuthn ID for the WebAuthn credential.
|
50
|
+
webauthn_not_setup_error_flash :: The flash error to show if going to the WebAuthn authentication page without having registered a WebAuthn authenticator.
|
51
|
+
webauthn_not_setup_error_status :: The status code to use if going to the WebAuthn authentication page without having registered a WebAuthn authenticator.
|
52
|
+
webauthn_origin :: The origin to use when verifying a WebAuthn authenticator.
|
53
|
+
webauthn_remove_additional_form_tags :: HTML fragment containing additional form tags when removing an existing WebAuthn authenticator.
|
54
|
+
webauthn_remove_button :: Text to use for button on the form to remove an existing WebAuthn authenticator.
|
55
|
+
webauthn_remove_error_flash :: The flash error to show if unable to remove an existing WebAuthn authenticator.
|
56
|
+
webauthn_remove_link_text :: The text to use for the remove link from the multifactor manage page.
|
57
|
+
webauthn_remove_notice_flash :: The flash notice to show after removing an existing WebAuthn authenticator.
|
58
|
+
webauthn_remove_page_title :: The page title to use on the page for removing an existing WebAuthn authenticator.
|
59
|
+
webauthn_remove_param :: The parameter name for the WebAuthn ID to remove.
|
60
|
+
webauthn_remove_redirect :: Where to redirect after successfully removing an existing WebAuthn authenticator.
|
61
|
+
webauthn_remove_route :: The route to the webauthn remove action.
|
62
|
+
webauthn_rp_id :: The relying party ID to use when registering a WebAuthn authenticator or authenticating via WebAuthn.
|
63
|
+
webauthn_rp_name :: The relying party name to use when registering a WebAuthn authenticator.
|
64
|
+
webauthn_setup_additional_form_tags :: HTML fragment containing additional form tags when registering a new WebAuthn authenticator.
|
65
|
+
webauthn_setup_button :: Text to use for button on the form to register a new WebAuthn authenticator.
|
66
|
+
webauthn_setup_challenge_hmac_param :: The parameter name for the HMAC of the WebAuthn challenge during registration.
|
67
|
+
webauthn_setup_challenge_param :: The parameter name for the WebAuthn challenge during registration.
|
68
|
+
webauthn_setup_error_flash :: The flash error to show if unable to register a new WebAuthn authenticator.
|
69
|
+
webauthn_setup_js :: The javascript code to execute on the page to register a new WebAuthn credential.
|
70
|
+
webauthn_setup_js_route :: The route to the webauthn setup javascript file.
|
71
|
+
webauthn_setup_link_text :: The text to use for the setup link from the multifactor manage page.
|
72
|
+
webauthn_setup_notice_flash :: The flash notice to show after registering a new WebAuthn authenticator.
|
73
|
+
webauthn_setup_page_title :: The page title to use on the page for registering a new WebAuthn authenticator.
|
74
|
+
webauthn_setup_param :: The parameter name for the WebAuthn registration data.
|
75
|
+
webauthn_setup_redirect :: Where to redirect after successfully registering a new WebAuthn authenticator.
|
76
|
+
webauthn_setup_timeout :: The number of milliseconds to wait when registering a new WebAuthn authenticator.
|
77
|
+
webauthn_setup_route :: The route to the webauthn setup action.
|
78
|
+
webauthn_user_ids_account_id_column :: The column in the +webauthn_user_ids_table+ containing the account id.
|
79
|
+
webauthn_user_ids_table :: The table name containing the WebAuthn user IDs.
|
80
|
+
webauthn_user_ids_webauthn_id_column :: The column in the +webauthn_user_ids_table+ containing the accounts WebAuthn user ID.
|
81
|
+
webauthn_user_verification :: The value of the WebAuthn userVerification option when registering a new WebAuthn authenticator.
|
82
|
+
|
83
|
+
== Auth Methods
|
84
|
+
|
85
|
+
account_webauthn_ids :: An array of WebAuthn IDs for registered WebAuthn credentials for the current account.
|
86
|
+
account_webauthn_usage :: A hash mapping WebAuthn IDs to the time of their last use for registered WebAuthn credentials for the current account.
|
87
|
+
account_webauthn_user_id :: The WebAuthn User ID for the current account.
|
88
|
+
add_webauthn_credential(webauthn_credential) :: Register the given WebAuthn credential to current account.
|
89
|
+
after_webauthn_auth_failure :: Any actions to take after a WebAuthn authentication failure.
|
90
|
+
after_webauthn_remove :: Any actions to take after removing an existing WebAuthn authenticator.
|
91
|
+
after_webauthn_setup :: Any actions to take after registering a new WebAuthn authenticator.
|
92
|
+
authenticated_webauthn_id :: The WebAuthn ID for the credential used to authenticate via WebAuthn for the current session.
|
93
|
+
before_webauthn_auth :: Any actions to take before authenticating via WebAuthn.
|
94
|
+
before_webauthn_auth_js_route :: Run arbitrary code before handling a webauthn auth javascript route.
|
95
|
+
before_webauthn_auth_route :: Run arbitrary code before handling a webauthn auth route.
|
96
|
+
before_webauthn_remove :: Any actions to take before removing an existing WebAuthn authenticator.
|
97
|
+
before_webauthn_remove_route :: Run arbitrary code before handling a webauthn remove route.
|
98
|
+
before_webauthn_setup :: Any actions to take before registering a new WebAuthn authenticator.
|
99
|
+
before_webauthn_setup_js_route :: Run arbitrary code before handling a webauthn setup javascript route.
|
100
|
+
before_webauthn_setup_route :: Run arbitrary code before handling a webauthn setup route.
|
101
|
+
handle_webauthn_sign_count_verification_error :: What actions to take if there is an invalid sign count when authenticating. The default results in an error, but overriding without calling super will result in successful WebAuthn authentication.
|
102
|
+
new_webauthn_credential :: WebAuthn credential options to provide to the client during WebAuthn registration.
|
103
|
+
remove_all_webauthn_keys_and_user_ids :: Remove all WebAuthn credentials and the WebAuthn user ID from the current account.
|
104
|
+
remove_webauthn_key(webauthn_id) :: Remove the WebAuthn credential with the given WebAuthn ID from the current account.
|
105
|
+
valid_new_webauthn_credential?(webauthn_credential) :: Check wheck the WebAuthn credential provided by the client during registration is valid.
|
106
|
+
valid_webauthn_credential_auth?(webauthn_credential) :: Check wheck the WebAuthn credential provided by the client during authentication is valid.
|
107
|
+
webauth_credential_options_for_get :: WebAuthn credential options to provide to the client during WebAuthn authentication.
|
108
|
+
webauthn_auth_js_path :: The path to the WebAuthn authentication javascript.
|
109
|
+
webauthn_auth_view :: The HTML to use for the page for authenticating via WebAuthn.
|
110
|
+
webauthn_remove_authenticated_session :: Remove the authenticated WebAuthn ID, used when removing the WebAuthn credential with the ID after authenticating with it.
|
111
|
+
webauthn_remove_view :: The HTML to use for the page for removing an existing WebAuthn authenticator.
|
112
|
+
webauthn_setup_js_path :: The path to the WebAuthn registration javascript.
|
113
|
+
webauthn_setup_view :: The HTML to use for the page for registering a new WebAuthn authenticator.
|
114
|
+
webauthn_update_session(webauthn_id) :: Set the authenticated WebAuthn ID after authenticating via WebAuthn.
|
115
|
+
webauthn_user_name :: The user name to use when registering a new WebAuthn credential, the user's email by default.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
= Documentation for WebAuthn Login Feature
|
2
|
+
|
3
|
+
The webauthn feature implements passwordless authentication via
|
4
|
+
WebAuthn. It depends on the login and webauthn features.
|
5
|
+
|
6
|
+
== Auth Value Methods
|
7
|
+
|
8
|
+
webauthn_login_error_flash :: The flash error to show if there is a failure during passwordless login via WebAuthn.
|
9
|
+
webauthn_login_failure_redirect :: Whether to redirect if there is a failure during passwordless login via WebAuthn.
|
10
|
+
webauthn_login_route :: The route to the webauthn login action.
|
11
|
+
|
12
|
+
== Auth Methods
|
13
|
+
|
14
|
+
before_webauthn_login :: Any actions to take before passwordless login via WebAuthn.
|
15
|
+
before_webauthn_login_route :: Run arbitrary code before handling a webauthn login route.
|
@@ -0,0 +1,9 @@
|
|
1
|
+
= Documentation for WebAuthn Verify Account Feature
|
2
|
+
|
3
|
+
The webauthn feature implements setting up an WebAuthn authenticator
|
4
|
+
during the account verification process, and making such setup
|
5
|
+
a requirement for account verification. By default, it disables
|
6
|
+
asking for a password during account creation and verification,
|
7
|
+
allowing for completely passwordless designs, where the only
|
8
|
+
authentication option is WebAuthn. It depends on the verify_account
|
9
|
+
and webauthn features.
|
@@ -0,0 +1,45 @@
|
|
1
|
+
(function() {
|
2
|
+
var element = document.getElementById('webauthn-auth-form');
|
3
|
+
var f = function(e) {
|
4
|
+
//console.log(e);
|
5
|
+
e.preventDefault();
|
6
|
+
if (navigator.credentials) {
|
7
|
+
var opts = JSON.parse(element.getAttribute("data-credential-options"));
|
8
|
+
opts.challenge = Uint8Array.from(atob(opts.challenge.replace(/-/g, '+').replace(/_/g, '/')), c => c.charCodeAt(0));
|
9
|
+
opts.allowCredentials.forEach(function(cred) {
|
10
|
+
cred.id = Uint8Array.from(atob(cred.id.replace(/-/g, '+').replace(/_/g, '/')), c => c.charCodeAt(0));
|
11
|
+
});
|
12
|
+
//console.log(opts);
|
13
|
+
navigator.credentials.get({publicKey: opts}).
|
14
|
+
then(function(cred){
|
15
|
+
//console.log(cred);
|
16
|
+
//window.cred = cred
|
17
|
+
|
18
|
+
var rawId = btoa(String.fromCharCode.apply(null, new Uint8Array(cred.rawId))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
19
|
+
var authValue = {
|
20
|
+
type: cred.type,
|
21
|
+
id: rawId,
|
22
|
+
rawId: rawId,
|
23
|
+
response: {
|
24
|
+
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(cred.response.authenticatorData))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''),
|
25
|
+
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(cred.response.clientDataJSON))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''),
|
26
|
+
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(cred.response.signature))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
if (cred.response.userHandle) {
|
31
|
+
authValue.response.userHandle = btoa(String.fromCharCode.apply(null, new Uint8Array(cred.response.userHandle))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
32
|
+
}
|
33
|
+
|
34
|
+
document.getElementById('webauthn-auth').value = JSON.stringify(authValue);
|
35
|
+
element.removeEventListener("submit", f);
|
36
|
+
element.submit();
|
37
|
+
}).
|
38
|
+
catch(function(e){document.getElementById('webauthn-auth-button').innerHTML = "Error authenticating using WebAuthn: " + e});
|
39
|
+
} else {
|
40
|
+
document.getElementById('webauthn-auth-button').innerHTML = "WebAuthn not supported by browser, or browser has disabled it on this page";
|
41
|
+
}
|
42
|
+
};
|
43
|
+
element.addEventListener("submit", f);
|
44
|
+
})();
|
45
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
(function() {
|
2
|
+
var element = document.getElementById('webauthn-setup-form');
|
3
|
+
var f = function(e) {
|
4
|
+
//console.log(e);
|
5
|
+
e.preventDefault();
|
6
|
+
if (navigator.credentials) {
|
7
|
+
var opts = JSON.parse(element.getAttribute("data-credential-options"));
|
8
|
+
opts.challenge = Uint8Array.from(atob(opts.challenge.replace(/-/g, '+').replace(/_/g, '/')), c => c.charCodeAt(0));
|
9
|
+
opts.user.id = Uint8Array.from(atob(opts.user.id.replace(/-/g, '+').replace(/_/g, '/')), c => c.charCodeAt(0));
|
10
|
+
//console.log(opts);
|
11
|
+
navigator.credentials.create({publicKey: opts}).
|
12
|
+
then(function(cred){
|
13
|
+
//console.log(cred);
|
14
|
+
//window.cred = cred
|
15
|
+
|
16
|
+
var rawId = btoa(String.fromCharCode.apply(null, new Uint8Array(cred.rawId))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
17
|
+
document.getElementById('webauthn-setup').value = JSON.stringify({
|
18
|
+
type: cred.type,
|
19
|
+
id: rawId,
|
20
|
+
rawId: rawId,
|
21
|
+
response: {
|
22
|
+
attestationObject: btoa(String.fromCharCode.apply(null, new Uint8Array(cred.response.attestationObject))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''),
|
23
|
+
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(cred.response.clientDataJSON))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
|
24
|
+
}
|
25
|
+
});
|
26
|
+
element.removeEventListener("submit", f);
|
27
|
+
element.submit();
|
28
|
+
}).
|
29
|
+
catch(function(e){document.getElementById('webauthn-setup-button').innerHTML = "Error creating public key in authenticator: " + e});
|
30
|
+
} else {
|
31
|
+
document.getElementById('webauthn-setup-button').innerHTML = "WebAuthn not supported by browser, or browser has disabled it on this page";
|
32
|
+
}
|
33
|
+
};
|
34
|
+
element.addEventListener("submit", f);
|
35
|
+
})();
|
data/lib/roda/plugins/rodauth.rb
CHANGED
data/lib/rodauth.rb
CHANGED
@@ -14,15 +14,15 @@ module Rodauth
|
|
14
14
|
require 'tilt/string'
|
15
15
|
app.plugin :render
|
16
16
|
|
17
|
-
case opts.fetch(:csrf, app.opts[:
|
17
|
+
case opts.fetch(:csrf, app.opts[:rodauth_csrf])
|
18
18
|
when false
|
19
19
|
# nothing
|
20
|
-
when :
|
21
|
-
app.plugin :route_csrf
|
22
|
-
else
|
20
|
+
when :rack_csrf
|
23
21
|
# :nocov:
|
24
22
|
app.plugin :csrf
|
25
23
|
# :nocov:
|
24
|
+
else
|
25
|
+
app.plugin :route_csrf
|
26
26
|
end
|
27
27
|
|
28
28
|
app.plugin :flash unless opts[:flash] == false
|
@@ -31,8 +31,14 @@ module Rodauth
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.configure(app, opts={}, &block)
|
34
|
-
app.opts[:rodauth_json] = opts.fetch(:json, app.opts[:rodauth_json])
|
35
|
-
app.opts[:rodauth_csrf] = opts.fetch(:csrf, app.opts[:
|
34
|
+
json_opt = app.opts[:rodauth_json] = opts.fetch(:json, app.opts[:rodauth_json])
|
35
|
+
csrf = app.opts[:rodauth_csrf] = opts.fetch(:csrf, app.opts[:rodauth_csrf])
|
36
|
+
app.opts[:rodauth_route_csrf] = case csrf
|
37
|
+
when false, :rack_csrf
|
38
|
+
false
|
39
|
+
else
|
40
|
+
json_opt != :only
|
41
|
+
end
|
36
42
|
auth_class = (app.opts[:rodauths] ||= {})[opts[:name]] ||= Class.new(Auth)
|
37
43
|
if !auth_class.roda_class
|
38
44
|
auth_class.roda_class = app
|
@@ -72,8 +78,7 @@ module Rodauth
|
|
72
78
|
end
|
73
79
|
|
74
80
|
def def_auth_value_method(meth, priv)
|
75
|
-
define_method(meth) do
|
76
|
-
v = v.first
|
81
|
+
define_method(meth) do |v=nil, &block|
|
77
82
|
block ||= proc{v}
|
78
83
|
@auth.send(:define_method, meth, &block)
|
79
84
|
@auth.send(:private, meth) if priv
|
@@ -101,23 +106,20 @@ module Rodauth
|
|
101
106
|
attr_accessor :configuration
|
102
107
|
|
103
108
|
def route(name=feature_name, default=name.to_s.tr('_', '-'), &block)
|
104
|
-
|
109
|
+
route_meth = :"#{name}_route"
|
110
|
+
auth_value_method route_meth, default
|
111
|
+
|
112
|
+
define_method(:"#{name}_path"){|opts={}| route_path(send(route_meth), opts)}
|
113
|
+
define_method(:"#{name}_url"){|opts={}| route_url(send(route_meth), opts)}
|
105
114
|
|
106
115
|
handle_meth = :"handle_#{name}"
|
107
116
|
internal_handle_meth = :"_#{handle_meth}"
|
108
|
-
route_meth = :"#{name}_route"
|
109
117
|
before route_meth
|
110
|
-
|
111
|
-
unless block.arity == 1
|
112
|
-
# :nocov:
|
113
|
-
b = block
|
114
|
-
block = lambda{|r| instance_exec(r, &b)}
|
115
|
-
# :nocov:
|
116
|
-
end
|
117
118
|
define_method(internal_handle_meth, &block)
|
118
119
|
|
119
120
|
define_method(handle_meth) do
|
120
121
|
request.is send(route_meth) do
|
122
|
+
check_csrf if check_csrf?
|
121
123
|
before_rodauth
|
122
124
|
send(internal_handle_meth, request)
|
123
125
|
end
|
@@ -135,7 +137,9 @@ module Rodauth
|
|
135
137
|
feature.module_eval(&block)
|
136
138
|
configuration.def_configuration_methods(feature)
|
137
139
|
|
140
|
+
# :nocov:
|
138
141
|
if constant
|
142
|
+
# :nocov:
|
139
143
|
Rodauth.const_set(constant, feature)
|
140
144
|
Rodauth::FeatureConfiguration.const_set(constant, configuration)
|
141
145
|
end
|
@@ -177,8 +181,10 @@ module Rodauth
|
|
177
181
|
|
178
182
|
def view(page, title, name=feature_name)
|
179
183
|
meth = :"#{name}_view"
|
184
|
+
title_meth = :"#{name}_page_title"
|
185
|
+
translatable_method(title_meth, title)
|
180
186
|
define_method(meth) do
|
181
|
-
view(page,
|
187
|
+
view(page, send(title_meth))
|
182
188
|
end
|
183
189
|
auth_methods meth
|
184
190
|
end
|
@@ -187,6 +193,7 @@ module Rodauth
|
|
187
193
|
define_method(:loaded_templates) do
|
188
194
|
super().concat(v)
|
189
195
|
end
|
196
|
+
private :loaded_templates
|
190
197
|
end
|
191
198
|
|
192
199
|
def depends(*deps)
|
@@ -194,10 +201,9 @@ module Rodauth
|
|
194
201
|
end
|
195
202
|
|
196
203
|
%w'after before'.each do |hook|
|
197
|
-
define_method(hook) do
|
198
|
-
name = args[0] || feature_name
|
204
|
+
define_method(hook) do |name=feature_name|
|
199
205
|
meth = "#{hook}_#{name}"
|
200
|
-
class_eval("def #{meth}; super if defined?(super); _#{meth} end", __FILE__, __LINE__)
|
206
|
+
class_eval("def #{meth}; super if defined?(super); _#{meth}; hook_action(:#{hook}, :#{name}); nil end", __FILE__, __LINE__)
|
201
207
|
class_eval("def _#{meth}; nil end", __FILE__, __LINE__)
|
202
208
|
private meth, :"_#{meth}"
|
203
209
|
auth_private_methods(meth)
|
@@ -218,6 +224,11 @@ module Rodauth
|
|
218
224
|
auth_value_methods(meth)
|
219
225
|
end
|
220
226
|
|
227
|
+
def translatable_method(meth, value)
|
228
|
+
define_method(meth){translate(meth, value)}
|
229
|
+
auth_value_methods(meth)
|
230
|
+
end
|
231
|
+
|
221
232
|
def auth_cached_method(meth, iv=:"@#{meth}")
|
222
233
|
umeth = :"_#{meth}"
|
223
234
|
define_method(meth) do
|
@@ -231,9 +242,8 @@ module Rodauth
|
|
231
242
|
end
|
232
243
|
|
233
244
|
[:notice_flash, :error_flash, :button].each do |meth|
|
234
|
-
define_method(meth) do |v,
|
235
|
-
name
|
236
|
-
auth_value_method(:"#{name}_#{meth}", v)
|
245
|
+
define_method(meth) do |v, name=feature_name|
|
246
|
+
translatable_method(:"#{name}_#{meth}", v)
|
237
247
|
end
|
238
248
|
end
|
239
249
|
end
|
@@ -328,10 +338,8 @@ module Rodauth
|
|
328
338
|
end
|
329
339
|
|
330
340
|
def freeze
|
331
|
-
|
332
|
-
|
333
|
-
opts[:rodauths].freeze
|
334
|
-
end
|
341
|
+
opts[:rodauths].each_value(&:freeze)
|
342
|
+
opts[:rodauths].freeze
|
335
343
|
super
|
336
344
|
end
|
337
345
|
end
|