booth 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/LICENSE.md +1 -2
- data/README.md +37 -6
- data/app/assets/images/booth/browsers/README.md +1 -2
- data/app/assets/images/booth/browsers/chrome.svg +1 -1
- data/app/assets/images/booth/browsers/edge.svg +1 -1
- data/app/assets/images/booth/browsers/firefox.svg +1 -1
- data/app/assets/images/booth/browsers/opera.svg +1 -1
- data/app/assets/images/booth/browsers/safari.svg +1 -1
- data/app/assets/images/booth/fido/passkey_mark_a.svg +10 -0
- data/app/assets/images/booth/fido/passkey_mark_a_black.svg +32 -0
- data/app/assets/images/booth/fido/passkey_mark_a_reverse.svg +33 -0
- data/app/assets/images/booth/fido/passkey_mark_a_white.svg +32 -0
- data/app/assets/images/booth/fido/passkey_mark_b_black.svg +1 -0
- data/app/assets/images/booth/platforms/android.svg +1 -6
- data/app/assets/images/booth/platforms/apple.svg +1 -6
- data/app/assets/images/booth/platforms/linux.svg +1 -6
- data/app/assets/images/booth/platforms/windows.svg +1 -6
- data/app/assets/javascripts/booth/authentication.js +29 -0
- data/app/assets/javascripts/booth/authentication.js.map +1 -0
- data/app/assets/javascripts/booth/error.js +38 -0
- data/app/assets/javascripts/booth/error.js.map +1 -0
- data/app/assets/javascripts/booth/form.js +78 -0
- data/app/assets/javascripts/booth/form.js.map +1 -0
- data/app/assets/javascripts/booth/gui.js +53 -0
- data/app/assets/javascripts/booth/gui.js.map +1 -0
- data/app/assets/javascripts/booth/registration.js +29 -0
- data/app/assets/javascripts/booth/registration.js.map +1 -0
- data/app/assets/javascripts/booth/setup.js +14 -0
- data/app/assets/javascripts/booth/verification.js +49 -0
- data/app/assets/javascripts/booth/verification.js.map +1 -0
- data/app/assets/javascripts/declarations/authentication.d.ts +6 -0
- data/app/assets/javascripts/declarations/error.d.ts +36 -0
- data/app/assets/javascripts/declarations/form.d.ts +8 -0
- data/app/assets/javascripts/declarations/gui.d.ts +4 -0
- data/app/assets/javascripts/declarations/registration.d.ts +6 -0
- data/app/assets/javascripts/declarations/setup.d.ts +3 -0
- data/app/assets/javascripts/declarations/verification.d.ts +6 -0
- data/app/assets/javascripts/src/authentication.ts +41 -0
- data/app/assets/javascripts/src/error.ts +35 -0
- data/app/assets/javascripts/src/form.ts +90 -0
- data/app/assets/javascripts/src/gui.ts +59 -0
- data/app/assets/javascripts/src/registration.ts +44 -0
- data/app/assets/javascripts/src/verification.ts +61 -0
- data/app/assets/stylesheets/booth/booth.css +3 -0
- data/config/importmap.rb +11 -0
- data/config/locales/de.yml +14 -38
- data/config/locales/en.yml +17 -36
- data/data/combined_aaguid.json +1 -0
- data/lib/booth/adminland/credentials/create.rb +10 -12
- data/lib/booth/adminland/credentials/index.rb +31 -0
- data/lib/booth/adminland/onboardings/create.rb +24 -15
- data/lib/booth/adminland/onboardings/destroy.rb +8 -4
- data/lib/booth/adminland/onboardings/find.rb +52 -45
- data/lib/booth/adminland/onboardings/find_unconsumed.rb +61 -0
- data/lib/booth/adminland/onboardings/index.rb +6 -3
- data/lib/booth/adminland/periodic_cleanup.rb +7 -2
- data/lib/booth/adminland.rb +17 -18
- data/lib/booth/coercers/domain.rb +11 -0
- data/lib/booth/coercers/request.rb +51 -0
- data/lib/booth/coercers/scope.rb +11 -0
- data/lib/booth/comparisons/domain.rb +38 -0
- data/lib/booth/comparisons/scope.rb +38 -0
- data/lib/booth/concerns/action.rb +25 -13
- data/lib/booth/concerns/transition.rb +5 -2
- data/lib/booth/configuration.rb +14 -73
- data/lib/booth/configure.rb +3 -10
- data/lib/booth/{audits/register → core/audit}/completed_onboarding.rb +8 -6
- data/lib/booth/core/audit/credential_created.rb +24 -0
- data/lib/booth/core/audit/logout.rb +24 -0
- data/lib/booth/core/authenticators/confirm.rb +30 -0
- data/lib/booth/core/authenticators/step.rb +24 -0
- data/lib/booth/core/cooldowns/distance_of_time.rb +50 -0
- data/lib/booth/core/cooldowns/strategies/exponential.rb +88 -0
- data/lib/booth/core/cooldowns/strategies/global.rb +66 -0
- data/lib/booth/core/cooldowns/strategies/result.rb +27 -0
- data/lib/booth/core/credentials/create.rb +32 -0
- data/lib/booth/core/credentials/find_by_username.rb +63 -0
- data/lib/booth/core/credentials/index.rb +15 -0
- data/lib/booth/core/credentials/webauth_challenge.rb +37 -0
- data/lib/booth/core/geolocation.rb +25 -0
- data/lib/booth/core/onboardings/find.rb +92 -0
- data/lib/booth/core/onboardings/step.rb +19 -0
- data/lib/booth/core/remotes/get.rb +45 -0
- data/lib/booth/core/remotes/respond.rb +82 -0
- data/lib/booth/core/remotes/set_for_login.rb +31 -0
- data/lib/booth/core/sessions/create_and_login.rb +63 -0
- data/lib/booth/core/sessions/historical_locations.rb +22 -0
- data/lib/booth/core/sessions/index.rb +66 -0
- data/lib/booth/core/sessions/revoke.rb +59 -0
- data/lib/booth/core/sessions/revoke_all_others.rb +49 -0
- data/lib/booth/core/sessions/to_passport.rb +35 -0
- data/lib/booth/core/webauth/authentication_verification.rb +76 -0
- data/lib/booth/core/webauth/options_for_create.rb +56 -0
- data/lib/booth/core/webauth/options_for_get.rb +30 -0
- data/lib/booth/core/webauth/provider.rb +36 -0
- data/lib/booth/core/webauth/registration_verification.rb +100 -0
- data/lib/booth/credential.rb +35 -0
- data/lib/booth/engine.rb +15 -4
- data/lib/booth/errors.rb +2 -0
- data/lib/booth/hooks/after_fetch.rb +14 -6
- data/lib/booth/hooks/before_logout.rb +5 -3
- data/lib/booth/hooks/serialize_from_session.rb +13 -5
- data/lib/booth/hooks/serialize_into_session.rb +6 -3
- data/lib/booth/logging.rb +13 -42
- data/lib/booth/models/application_record.rb +3 -0
- data/lib/booth/models/audit.rb +10 -11
- data/lib/booth/models/authenticator.rb +6 -9
- data/lib/booth/models/credential.rb +17 -20
- data/lib/booth/models/onboarding.rb +16 -39
- data/lib/booth/models/{contest.rb → remote.rb} +13 -14
- data/lib/booth/models/remotes/scopes/recently_created.rb +26 -0
- data/lib/booth/models/remotes/scopes/recently_responded.rb +35 -0
- data/lib/booth/models/session.rb +15 -10
- data/lib/booth/models/user_agent.rb +2 -0
- data/lib/booth/request.rb +43 -22
- data/lib/booth/requests/agent.rb +3 -1
- data/lib/booth/requests/authentication.rb +15 -5
- data/lib/booth/requests/ip.rb +4 -2
- data/lib/booth/requests/return_path.rb +4 -2
- data/lib/booth/requests/session.rb +6 -4
- data/lib/booth/requests/storage.rb +5 -31
- data/lib/booth/requests/storages/login.rb +35 -29
- data/lib/booth/requests/storages/registration.rb +2 -0
- data/lib/booth/requests/storages/webauth.rb +3 -0
- data/lib/booth/requests/sudo.rb +6 -50
- data/lib/booth/routes/userland.rb +13 -59
- data/lib/booth/syntaxes/domain.rb +46 -0
- data/lib/booth/syntaxes/email.rb +11 -8
- data/lib/booth/syntaxes/ip.rb +6 -4
- data/lib/booth/syntaxes/remote_code.rb +60 -0
- data/lib/booth/syntaxes/scope.rb +7 -3
- data/lib/booth/syntaxes/secret_key.rb +8 -6
- data/lib/booth/syntaxes/username.rb +23 -10
- data/lib/booth/syntaxes/uuid.rb +3 -1
- data/lib/booth/test.rb +27 -22
- data/lib/booth/testing/incorporation_test_case.rb +29 -0
- data/lib/booth/testing/shortcuts.rb +77 -0
- data/lib/booth/testing/support/assert_all_partials_were_covered.rb +69 -0
- data/lib/booth/testing/support/assert_logged_in.rb +68 -0
- data/lib/booth/{test → testing}/support/assert_logged_out.rb +7 -4
- data/lib/booth/testing/support/assert_partial.rb +56 -0
- data/lib/booth/{test → testing}/support/force_login.rb +10 -4
- data/lib/booth/{test → testing}/support/get_session_value.rb +8 -6
- data/lib/booth/testing/support/scenario.rb +23 -0
- data/lib/booth/testing/support/shortcuts/create_and_onboard.rb +56 -0
- data/lib/booth/testing/support/shortcuts/login_with_passkey.rb +55 -0
- data/lib/booth/testing/support/shortcuts/register_new_passkey.rb +51 -0
- data/lib/booth/testing/support/soft_reset_session.rb +24 -0
- data/lib/booth/testing/support/virtual_authenticators/create.rb +34 -0
- data/lib/booth/testing/support/virtual_authenticators/destroy.rb +20 -0
- data/lib/booth/testing/support/virtual_authenticators/enable.rb +24 -0
- data/lib/booth/testing/support/virtual_authenticators/load.rb +38 -0
- data/lib/booth/testing/support/virtual_authenticators/manager.rb +124 -0
- data/lib/booth/testing/support/visit.rb +62 -0
- data/lib/booth/testing/userland/login_remotely.rb +100 -0
- data/lib/booth/testing/userland/onboarding_first_time.rb +81 -0
- data/lib/booth/testing/userland/onboarding_to_reset_passkeys.rb +129 -0
- data/lib/booth/testing/userland/registration_with_passkey.rb +93 -0
- data/lib/booth/testing/userland/registration_without_passkey.rb +101 -0
- data/lib/booth/testing/userland/sessions_manage_behavior.rb +68 -0
- data/lib/booth/testing/userland/sessions_revoke_all_others.rb +17 -0
- data/lib/booth/testing/userland/sessions_revoke_one.rb +17 -0
- data/lib/booth/testing/userland.rb +36 -0
- data/lib/booth/to_struct.rb +9 -2
- data/lib/booth/userland/extract_flash_messages.rb +10 -3
- data/lib/booth/userland/logins/create.rb +8 -6
- data/lib/booth/userland/logins/destroy.rb +23 -6
- data/lib/booth/userland/logins/new.rb +23 -25
- data/lib/booth/userland/logins/transitions/create/choose_username.rb +62 -27
- data/lib/booth/userland/logins/transitions/create/skip_remotes.rb +18 -14
- data/lib/booth/userland/logins/transitions/create/webauth_authentication_initiation.rb +54 -48
- data/lib/booth/userland/logins/transitions/create/webauth_authentication_verification.rb +62 -58
- data/lib/booth/userland/logins/transitions/new/already_logged_in.rb +4 -3
- data/lib/booth/userland/logins/transitions/new/fallible.rb +4 -0
- data/lib/booth/userland/logins/transitions/new/{mode_username_and_password.rb → missing_authenticators.rb} +5 -4
- data/lib/booth/userland/logins/transitions/new/mode_username_and_webauth.rb +6 -4
- data/lib/booth/userland/logins/transitions/new/no_username_chosen.rb +3 -1
- data/lib/booth/userland/logins/transitions/new/remote_session_available.rb +20 -13
- data/lib/booth/userland/logins/transitions/new/timed_out.rb +3 -1
- data/lib/booth/userland/onboardings/show.rb +65 -39
- data/lib/booth/userland/onboardings/update.rb +46 -38
- data/lib/booth/userland/registrations/create.rb +51 -20
- data/lib/booth/userland/registrations/new.rb +6 -7
- data/lib/booth/userland/remotes/show.rb +56 -0
- data/lib/booth/userland/{personal_contests → remotes}/update.rb +5 -3
- data/lib/booth/userland/sessions/destroy_one_or_other.rb +3 -16
- data/lib/booth/userland/sessions/index.rb +4 -2
- data/lib/booth/userland/sessions/show.rb +5 -6
- data/lib/booth/userland/sessions/transitions/destroy/enter_webauth.rb +8 -6
- data/lib/booth/userland/sessions/transitions/destroy/webauth_authentication_initiation.rb +8 -6
- data/lib/booth/userland/sessions/transitions/destroy/webauth_authentication_verification.rb +7 -5
- data/lib/booth/userland/sessions/transitions/show/enter_webauth.rb +8 -6
- data/lib/booth/userland/webauths/create.rb +20 -17
- data/lib/booth/userland/webauths/destroy.rb +6 -16
- data/lib/booth/userland/webauths/guards/sudo.rb +10 -5
- data/lib/booth/userland/webauths/index.rb +4 -2
- data/lib/booth/userland/webauths/new.rb +7 -22
- data/lib/booth/userland/webauths/sudo.rb +3 -1
- data/lib/booth/userland/webauths/transitions/create/authentication_initiation.rb +8 -11
- data/lib/booth/userland/webauths/transitions/create/authentication_verification.rb +11 -13
- data/lib/booth/userland/webauths/transitions/create/choose_nickname.rb +8 -5
- data/lib/booth/userland/webauths/transitions/create/registration_initiation.rb +15 -14
- data/lib/booth/userland/webauths/transitions/create/registration_verification.rb +34 -28
- data/lib/booth/userland/webauths/transitions/create/reset.rb +2 -0
- data/lib/booth/userland/webauths/transitions/new/step.rb +3 -1
- data/lib/booth/userland/webauths/transitions/sudo/authentication_initiation.rb +5 -10
- data/lib/booth/userland/webauths/transitions/sudo/authentication_verification.rb +4 -2
- data/lib/booth/userland.rb +53 -109
- data/lib/booth/version.rb +3 -1
- data/lib/booth.rb +6 -236
- data/lib/generators/booth/migration/migration_generator.rb +2 -1
- data/lib/generators/booth/migration/templates/add_credential_to_users.erb +6 -4
- data/lib/generators/booth/migration/templates/create_booth_tables.erb +61 -72
- metadata +124 -571
- data/app/assets/config/booth_manifest.js +0 -15
- data/app/assets/images/booth/browsers/internet_explorer.svg +0 -1
- data/app/assets/javascripts/booth/all.js +0 -162
- data/app/assets/javascripts/booth/all.js.map +0 -1
- data/app/assets/javascripts/booth/booth.ts +0 -194
- data/app/assets/javascripts/booth/webauthn-json.ts +0 -99
- data/lib/booth/adminland/recoveries/consume.rb +0 -70
- data/lib/booth/audits/register/added_otp.rb +0 -22
- data/lib/booth/audits/register/changed_otp.rb +0 -22
- data/lib/booth/audits/register/correct_otp.rb +0 -42
- data/lib/booth/audits/register/correct_password.rb +0 -43
- data/lib/booth/audits/register/logout.rb +0 -22
- data/lib/booth/audits/register/requested_password_reset.rb +0 -22
- data/lib/booth/audits/register/wrong_otp.rb +0 -22
- data/lib/booth/audits/register/wrong_password.rb +0 -25
- data/lib/booth/authenticators/confirm.rb +0 -34
- data/lib/booth/authenticators/credential_mode_after_confirmation.rb +0 -25
- data/lib/booth/authenticators/step.rb +0 -19
- data/lib/booth/contests/get.rb +0 -36
- data/lib/booth/contests/respond.rb +0 -78
- data/lib/booth/contests/set_for_login.rb +0 -28
- data/lib/booth/cooldowns/distance_of_time.rb +0 -46
- data/lib/booth/cooldowns/otp.rb +0 -22
- data/lib/booth/cooldowns/password.rb +0 -44
- data/lib/booth/cooldowns/password_reset.rb +0 -24
- data/lib/booth/cooldowns/strategies/exponential.rb +0 -82
- data/lib/booth/cooldowns/strategies/global.rb +0 -62
- data/lib/booth/cooldowns/strategies/result.rb +0 -22
- data/lib/booth/credentials/create.rb +0 -28
- data/lib/booth/credentials/create_with_onboarding.rb +0 -26
- data/lib/booth/credentials/find_by_username.rb +0 -45
- data/lib/booth/credentials/mode.rb +0 -69
- data/lib/booth/credentials/modes/otp_addable.rb +0 -23
- data/lib/booth/credentials/modes/otp_changeable.rb +0 -23
- data/lib/booth/credentials/modes/otp_manageable.rb +0 -17
- data/lib/booth/credentials/modes/otp_removable.rb +0 -23
- data/lib/booth/credentials/modes/password_addable.rb +0 -29
- data/lib/booth/credentials/modes/password_changeable.rb +0 -31
- data/lib/booth/credentials/modes/password_manageable.rb +0 -17
- data/lib/booth/credentials/modes/password_removable.rb +0 -24
- data/lib/booth/credentials/modes/password_removal_requires_user_verifiable_webauth.rb +0 -16
- data/lib/booth/credentials/modes/webauth_addable.rb +0 -26
- data/lib/booth/credentials/modes/webauth_manageable.rb +0 -16
- data/lib/booth/credentials/modes/webauth_removable.rb +0 -25
- data/lib/booth/credentials/otp_authentication.rb +0 -59
- data/lib/booth/credentials/password_authentication.rb +0 -72
- data/lib/booth/credentials/webauth_challenge.rb +0 -28
- data/lib/booth/geolocation.rb +0 -20
- data/lib/booth/logger.rb +0 -41
- data/lib/booth/method_object.rb +0 -73
- data/lib/booth/mode.rb +0 -22
- data/lib/booth/models/concerns/modeable.rb +0 -50
- data/lib/booth/models/concerns/otpable.rb +0 -37
- data/lib/booth/models/concerns/passwordable.rb +0 -58
- data/lib/booth/models/contests/scopes/recently_created.rb +0 -23
- data/lib/booth/models/contests/scopes/recently_responded.rb +0 -32
- data/lib/booth/models/password_reset.rb +0 -41
- data/lib/booth/models/recovery.rb +0 -32
- data/lib/booth/models/registration.rb +0 -10
- data/lib/booth/modes/base.rb +0 -25
- data/lib/booth/modes/username_and_password.rb +0 -7
- data/lib/booth/modes/username_and_webauth.rb +0 -7
- data/lib/booth/modes/username_password_and_otp.rb +0 -7
- data/lib/booth/modes/username_password_and_webauth.rb +0 -7
- data/lib/booth/onboardings/find.rb +0 -35
- data/lib/booth/onboardings/propagate_to_credential.rb +0 -63
- data/lib/booth/onboardings/step.rb +0 -68
- data/lib/booth/password_resets/create.rb +0 -57
- data/lib/booth/password_resets/find.rb +0 -36
- data/lib/booth/password_resets/propagate_to_credential.rb +0 -36
- data/lib/booth/password_resets/step.rb +0 -18
- data/lib/booth/recoveries/create.rb +0 -45
- data/lib/booth/requests/storages/otp.rb +0 -54
- data/lib/booth/requests/storages/password.rb +0 -49
- data/lib/booth/requests/storages/password_reset.rb +0 -35
- data/lib/booth/requests/storages/recovery.rb +0 -35
- data/lib/booth/sessions/create_and_login.rb +0 -46
- data/lib/booth/sessions/historical_locations.rb +0 -18
- data/lib/booth/sessions/index.rb +0 -59
- data/lib/booth/sessions/revoke.rb +0 -51
- data/lib/booth/sessions/revoke_all_others.rb +0 -43
- data/lib/booth/sessions/to_passport.rb +0 -51
- data/lib/booth/syntaxes/contest_code.rb +0 -58
- data/lib/booth/syntaxes/otp.rb +0 -57
- data/lib/booth/syntaxes/scope_comparison.rb +0 -28
- data/lib/booth/test/helpers.rb +0 -63
- data/lib/booth/test/support/assert_all_partials_were_covered.rb +0 -63
- data/lib/booth/test/support/assert_logged_in.rb +0 -49
- data/lib/booth/test/support/assert_partial.rb +0 -29
- data/lib/booth/test/support/otp_code_from_session.rb +0 -30
- data/lib/booth/test/support/soft_reset_session.rb +0 -22
- data/lib/booth/test/userland/logins/missing_authenticators.rb +0 -72
- data/lib/booth/test/userland/logins/missing_onboarding.rb +0 -35
- data/lib/booth/test/userland/logins/username_and_password.rb +0 -40
- data/lib/booth/test/userland/logins/username_and_webauth.rb +0 -75
- data/lib/booth/test/userland/logins/username_password_and_otp.rb +0 -45
- data/lib/booth/test/userland/logins/username_password_and_webauth.rb +0 -86
- data/lib/booth/test/userland/onboardings/already_logged_in.rb +0 -64
- data/lib/booth/test/userland/onboardings/otp.rb +0 -63
- data/lib/booth/test/userland/onboardings/password.rb +0 -49
- data/lib/booth/test/userland/onboardings/timeout.rb +0 -47
- data/lib/booth/test/userland/otps/manage.rb +0 -86
- data/lib/booth/test/userland/password_resets/reset.rb +0 -102
- data/lib/booth/test/userland.rb +0 -38
- data/lib/booth/test/webauthn/disable.rb +0 -17
- data/lib/booth/test/webauthn/enable.rb +0 -19
- data/lib/booth/test/webauthn/virtual_authenticators/create.rb +0 -38
- data/lib/booth/test/webauthn/virtual_authenticators/destroy.rb +0 -20
- data/lib/booth/userland/logins/transitions/create/enter_otp.rb +0 -70
- data/lib/booth/userland/logins/transitions/create/verify_password.rb +0 -70
- data/lib/booth/userland/logins/transitions/new/mode_first_time.rb +0 -20
- data/lib/booth/userland/logins/transitions/new/mode_username_password_and_otp.rb +0 -24
- data/lib/booth/userland/logins/transitions/new/mode_username_password_and_webauth.rb +0 -24
- data/lib/booth/userland/onboardings/transitions/update/choose_mode.rb +0 -58
- data/lib/booth/userland/onboardings/transitions/update/choose_password.rb +0 -41
- data/lib/booth/userland/onboardings/transitions/update/choose_webauth_nickname.rb +0 -50
- data/lib/booth/userland/onboardings/transitions/update/confirm_otp.rb +0 -58
- data/lib/booth/userland/onboardings/transitions/update/confirm_password.rb +0 -49
- data/lib/booth/userland/onboardings/transitions/update/register_otp.rb +0 -31
- data/lib/booth/userland/onboardings/transitions/update/reset_otp.rb +0 -40
- data/lib/booth/userland/onboardings/transitions/update/reset_password.rb +0 -35
- data/lib/booth/userland/onboardings/transitions/update/reset_webauth.rb +0 -46
- data/lib/booth/userland/onboardings/transitions/update/webauth_authentication_initiation.rb +0 -40
- data/lib/booth/userland/onboardings/transitions/update/webauth_authentication_verification.rb +0 -59
- data/lib/booth/userland/onboardings/transitions/update/webauth_registration_initiation.rb +0 -46
- data/lib/booth/userland/onboardings/transitions/update/webauth_registration_verification.rb +0 -56
- data/lib/booth/userland/otps/destroy.rb +0 -42
- data/lib/booth/userland/otps/edit.rb +0 -72
- data/lib/booth/userland/otps/guards/manageable.rb +0 -21
- data/lib/booth/userland/otps/guards/sudo.rb +0 -23
- data/lib/booth/userland/otps/show.rb +0 -36
- data/lib/booth/userland/otps/sudo.rb +0 -51
- data/lib/booth/userland/otps/transitions/update/confirm.rb +0 -84
- data/lib/booth/userland/otps/transitions/update/register.rb +0 -40
- data/lib/booth/userland/otps/transitions/update/reset.rb +0 -31
- data/lib/booth/userland/otps/update.rb +0 -34
- data/lib/booth/userland/password_resets/create.rb +0 -73
- data/lib/booth/userland/password_resets/guards/logged_out.rb +0 -21
- data/lib/booth/userland/password_resets/new.rb +0 -57
- data/lib/booth/userland/password_resets/show.rb +0 -77
- data/lib/booth/userland/password_resets/transitions/update/choose_password.rb +0 -48
- data/lib/booth/userland/password_resets/transitions/update/confirm_password.rb +0 -54
- data/lib/booth/userland/password_resets/transitions/update/reset_password.rb +0 -29
- data/lib/booth/userland/password_resets/update.rb +0 -65
- data/lib/booth/userland/passwords/destroy.rb +0 -41
- data/lib/booth/userland/passwords/edit.rb +0 -54
- data/lib/booth/userland/passwords/guards/manageable.rb +0 -21
- data/lib/booth/userland/passwords/guards/removable.rb +0 -21
- data/lib/booth/userland/passwords/guards/sudo.rb +0 -21
- data/lib/booth/userland/passwords/remove.rb +0 -34
- data/lib/booth/userland/passwords/show.rb +0 -32
- data/lib/booth/userland/passwords/sudo.rb +0 -55
- data/lib/booth/userland/passwords/transitions/remove/step.rb +0 -27
- data/lib/booth/userland/passwords/transitions/update/choose_password.rb +0 -62
- data/lib/booth/userland/passwords/transitions/update/confirm_password.rb +0 -82
- data/lib/booth/userland/passwords/update.rb +0 -33
- data/lib/booth/userland/personal_contests/show.rb +0 -60
- data/lib/booth/userland/recoveries/create.rb +0 -48
- data/lib/booth/userland/recoveries/new.rb +0 -35
- data/lib/booth/userland/sessions/transitions/destroy/enter_password.rb +0 -50
- data/lib/booth/userland/sessions/transitions/destroy/verify_password.rb +0 -83
- data/lib/booth/userland/webauths/guards/manageable.rb +0 -21
- data/lib/booth/webauth/authentication_verification.rb +0 -68
- data/lib/booth/webauth/demand_user_verification.rb +0 -29
- data/lib/booth/webauth/options_for_create.rb +0 -46
- data/lib/booth/webauth/options_for_get.rb +0 -29
- data/lib/generators/booth/migration/templates/create_booth_mode_types.erb +0 -20
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// This file was generated using a rake task
|
|
2
|
-
|
|
3
|
-
//= link booth/browsers/chrome.svg
|
|
4
|
-
//= link booth/browsers/edge.svg
|
|
5
|
-
//= link booth/browsers/firefox.svg
|
|
6
|
-
//= link booth/browsers/opera.svg
|
|
7
|
-
//= link booth/browsers/safari.svg
|
|
8
|
-
//= link booth/browsers/internet_explorer.svg
|
|
9
|
-
//= link booth/browsers/unknown.svg
|
|
10
|
-
|
|
11
|
-
//= link booth/platforms/android.svg
|
|
12
|
-
//= link booth/platforms/apple.svg
|
|
13
|
-
//= link booth/platforms/linux.svg
|
|
14
|
-
//= link booth/platforms/windows.svg
|
|
15
|
-
//= link booth/platforms/unknown.svg
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 -2 313 305"><defs><radialGradient xlink:href="#a" id="e" cx="173.96" cy="149.58" r="161.64" gradientTransform="matrix(0 1 -.8 0 293.62 -24.38)"><stop offset=".55" stop-color="#99fbff"/><stop offset=".61" stop-color="#92f6fe"/><stop offset=".7" stop-color="#80e7fa"/><stop offset=".8" stop-color="#62cff3"/><stop offset=".91" stop-color="#38adea"/><stop offset="1" stop-color="#0f8ce1"/></radialGradient><radialGradient xlink:href="#a" id="o" cx="62.968" cy="220.74" r="48.326" gradientTransform="matrix(3.4175 -2.0751 1.0888 1.7931 -389.83 -12.808)"><stop offset="0" stop-color="#fcf69f" stop-opacity="0"/><stop offset=".5" stop-color="#fcf69f" stop-opacity="0"/><stop offset="1" stop-color="#fcf69f" stop-opacity=".77"/></radialGradient><radialGradient xlink:href="#a" id="k" cx="100.32" cy="148.8" r="138.81" gradientTransform="matrix(.9302 -.83744 .32785 .36414 17.035 155.03)"><stop offset="0" stop-color="#f8b633" stop-opacity="0"/><stop offset=".83" stop-color="#fabc3f" stop-opacity="0"/><stop offset=".92" stop-color="#fdf8c3" stop-opacity=".98"/><stop offset=".96" stop-color="#fdf8c3" stop-opacity=".98"/><stop offset="1" stop-color="#fdf6b0" stop-opacity=".98"/></radialGradient><radialGradient xlink:href="#a" id="p" cx="138.27" cy="245.02" r="84.078" gradientTransform="matrix(1.3738 -1.4223 .47637 .46011 -146.79 229.99)"><stop offset="0" stop-color="#3d3a04" stop-opacity="0"/><stop offset=".924" stop-color="#454205" stop-opacity="0"/><stop offset="1" stop-color="#4e4a06" stop-opacity=".27"/></radialGradient><radialGradient xlink:href="#a" id="n" cx="92.079" cy="70.362" r="64.365" gradientTransform="matrix(1.82 .03223 -.03882 2.1923 -73.94 -85.114)"><stop offset="0" stop-color="#a0f5fc"/><stop offset="1" stop-color="#a0f3fc" stop-opacity="0"/></radialGradient><radialGradient xlink:href="#a" id="b" cx="136.1" cy="93.932" r="157.94" gradientTransform="matrix(.67825 -.45732 .55906 .82913 -15.248 63.774)"><stop offset="0" stop-color="#fcfcfc"/><stop offset=".681" stop-color="#fff"/><stop offset="1"/></radialGradient><radialGradient xlink:href="#a" id="h" cx="160.08" cy="156.25" r="138.81" gradientTransform="matrix(1.0704 -1.0538 .44083 .44775 -75.068 245.37)"><stop offset="0" stop-opacity="0"/><stop offset=".82" stop-color="#fdbb36" stop-opacity=".94"/><stop offset=".89" stop-color="#fbd44d" stop-opacity=".92"/><stop offset="1" stop-color="#fbcf39" stop-opacity=".88"/></radialGradient><radialGradient xlink:href="#a" id="i" cx="180.99" cy="167.23" r="138.81" gradientTransform="matrix(1.1348 -1.1322 .52964 .53081 -114.38 274.24)"><stop offset="0" stop-color="#f7ab32" stop-opacity="0"/><stop offset=".76" stop-color="#f7b535" stop-opacity=".92"/><stop offset=".84" stop-color="#f7b33f" stop-opacity=".96"/><stop offset=".93" stop-color="#f7e232"/><stop offset="1" stop-color="#f5ec80"/></radialGradient><radialGradient xlink:href="#a" id="m" cx="-2.5" cy="136.62" r="138.81" gradientTransform="matrix(.85784 -.85837 .28831 .28814 123.22 99.466)"><stop offset="0"/><stop offset=".94" stop-color="#fee259" stop-opacity=".5"/><stop offset="1" stop-color="#fff045" stop-opacity="0"/></radialGradient><radialGradient xlink:href="#a" id="c" cx="222.81" cy="221.24" r="156.35" gradientTransform="matrix(1.1049 -.66263 .37599 .62704 -95.652 198.56)"><stop offset="0"/><stop offset=".672"/><stop offset="1" stop-color="#fff"/></radialGradient><radialGradient xlink:href="#a" id="d" cx="101.97" cy="109.66" r="158" gradientTransform="matrix(.84189 -.58292 .28064 .4054 -11.053 122.85)"><stop offset="0" stop-color="#fff"/><stop offset=".69" stop-color="#fff"/><stop offset="1"/></radialGradient><mask id="l" maskUnits="userSpaceOnUse"><path fill="url(#b)" fill-rule="evenodd" stroke="#000" d="M.5-12.389h314.89v314.89H.5z"/></mask><mask id="f" maskUnits="userSpaceOnUse"><path fill="url(#c)" fill-rule="evenodd" d="M0-.374h312.71v302.26H0z"/></mask><mask id="j" maskUnits="userSpaceOnUse"><path fill="url(#d)" fill-rule="evenodd" stroke="#000" d="M.5-12.5h315v315H.5z"/></mask><linearGradient id="a" gradientUnits="userSpaceOnUse"/><path id="g" d="M108.75 260.53c-27.7 14.08-50 17.08-61.5 5.6-25-25 7.8-94.8 74.3-161.32S257.86 5.5 282.9 30.52c10.13 10.13 9 28.72-1.14 52q2.1 3.34 4 6.82c13.47-31.15 14.25-57.5-1.46-73.2-28.75-29.12-126.4 4.2-186.67 67.3S-.16 242.8 27.74 271.4c18.14 18.14 51.2 13.87 89.56-6.43q-4.38-2.05-8.55-4.43z"/></defs><path fill="url(#e)" stroke="#1b62a2" stroke-opacity=".878" stroke-width="4.913" d="M226.06 194.2c-10.23 17.2-29.93 28.53-51.3 28.53a56.08 56.08 0 0 1-56.28-56v-2.2H298a125.85 125.85 0 0 0 .77-13.88A124.27 124.27 0 0 0 174.44 25.82c-69.08 0-125.9 55.76-125.9 124.84 0 22.48 6.47 43.56 16.7 61.75 9.15 16.27 21.16 30.23 36.5 40.8 20.22 13.92 45.5 21.58 72 21.58 27.95 0 54.67-8.54 75.7-23.84A122 122 0 0 0 292 194.19zM176.56 79c30.52 0 53.3 24.3 54.13 54.6H118.2c.97-30.3 27.8-54.6 58.37-54.6z" paint-order="stroke markers fill"/><g mask="url(#f)"><use xlink:href="#g" fill="url(#h)"/><path fill="url(#i)" d="M108.75 260.53c-27.7 14.08-50 17.08-61.5 5.6-25-25 7.8-94.8 74.3-161.32S257.86 5.5 282.9 30.52c10.13 10.13 9 28.72-1.14 52q2.1 3.34 4 6.82c13.47-31.15 14.25-57.5-1.46-73.2-28.75-29.12-126.4 4.2-186.67 67.3S-.16 242.8 27.74 271.4c18.14 18.14 51.2 13.87 89.56-6.43q-4.38-2.05-8.55-4.43z" mask="url(#j)" opacity=".93"/><path fill="url(#k)" d="M108.75 260.53c-27.7 14.08-50 17.08-61.5 5.6-25-25 7.8-94.8 74.3-161.32S257.86 5.5 282.9 30.52c10.13 10.13 9 28.72-1.14 52q2.1 3.34 4 6.82c13.47-31.15 14.25-57.5-1.46-73.2-28.75-29.12-126.4 4.2-186.67 67.3S-.16 242.8 27.74 271.4c18.14 18.14 51.2 13.87 89.56-6.43q-4.38-2.05-8.55-4.43z" mask="url(#l)" opacity=".835"/><use xlink:href="#g" fill="url(#m)"/></g><path fill="url(#n)" d="M174.44 27.82c-68.937 0-125.66 55.53-125.89 124.41 13.174-23.455 29.981-46.791 49.086-66.793 23.061-24.144 51.592-43.919 79.645-57.514l-2.836-.105z" transform="translate(0 -2)"/><path fill="url(#o)" d="M46.15 154.56c12.851-24.577 33.552-52.853 50.53-70.16-19.184 16.918-38.242 38.928-50 53.93C4.16 193.01-8.37 240.79 5.33 264.03c11.08 18.8 32.27 23.17 53 18.83-12.4-.08-22.86-3.75-30.6-11.48-18.48-18.97-8.2-67.73 18.4-116.82z" opacity=".877"/><path fill="url(#p)" d="M217.33 35.551c-28.801 13.432-62.699 38.165-95.781 71.258-29.291 29.3-52.032 59.233-66.188 85.697a131.825 131.825 0 0 0 4.354 10.953c6.442-25.294 32.58-54.181 64.28-92.234 1.748-2.1 3.675-5.125 5.817-7.215a59.603 59.603 0 0 1 14.154-13.086c29.88-18.073 54.304-40.563 79.551-52.885a124.255 124.255 0 0 0-6.187-2.488z" transform="translate(0 -2)"/></svg>
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
/// <reference path='webauthn-json.ts' />
|
|
2
|
-
//= require rails-ujs
|
|
3
|
-
//= require @github/webauthn-json/dist/browser-global/webauthn-json.browser-global
|
|
4
|
-
var Booth;
|
|
5
|
-
(function (Booth) {
|
|
6
|
-
function reloadSoon() {
|
|
7
|
-
const seconds = Math.floor(Math.random() * 3) + 5; // 4,5,6 or 7 to avoid request bursts
|
|
8
|
-
setTimeout(() => {
|
|
9
|
-
console.debug('Reloading page...');
|
|
10
|
-
window.location.reload();
|
|
11
|
-
}, 1000 * seconds);
|
|
12
|
-
}
|
|
13
|
-
Booth.reloadSoon = reloadSoon;
|
|
14
|
-
let Webauth;
|
|
15
|
-
(function (Webauth) {
|
|
16
|
-
class Registration {
|
|
17
|
-
constructor(form, challengeData) {
|
|
18
|
-
this.form = form;
|
|
19
|
-
this.challengeData = challengeData;
|
|
20
|
-
this.call();
|
|
21
|
-
}
|
|
22
|
-
call() {
|
|
23
|
-
console.debug('WebAuthn Registration Ceremony - Initiation Phase Part 2 - START');
|
|
24
|
-
webauthnJSON.create({ publicKey: this.challengeData }).then((responseData) => {
|
|
25
|
-
console.debug(`WebAuthn Registration Ceremony - Initiation Phase Part 2 - SUCCESS - ${JSON.stringify(responseData)}`);
|
|
26
|
-
new Verification(this.form, responseData);
|
|
27
|
-
}).catch((error) => {
|
|
28
|
-
console.error(`WebAuthn Registration Ceremony - Verification Phase - ERROR - ${error.name} - ${error.message}`);
|
|
29
|
-
if (error.name == 'NotAllowedError') {
|
|
30
|
-
// Every webauth registration form needs this localized error message.
|
|
31
|
-
alert(this.form.dataset.boothIncompatibleDeviceMessage);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
alert(error.message);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
Webauth.Registration = Registration;
|
|
40
|
-
class Authentication {
|
|
41
|
-
constructor(form, challengeData) {
|
|
42
|
-
this.form = form;
|
|
43
|
-
this.challengeData = challengeData;
|
|
44
|
-
this.call();
|
|
45
|
-
}
|
|
46
|
-
call() {
|
|
47
|
-
console.debug('WebAuthn Authentication Ceremony - Initiation Phase Part 2 - START');
|
|
48
|
-
webauthnJSON.get({ publicKey: this.challengeData }).then((responseData) => {
|
|
49
|
-
console.debug(`WebAuthn Authentication Ceremony - Initiation Phase Part 2 - SUCCESS - ${JSON.stringify(responseData)}`);
|
|
50
|
-
new Verification(this.form, responseData);
|
|
51
|
-
}).catch((error) => {
|
|
52
|
-
console.error(`WebAuthn Authentication Ceremony - Verification Phase - ERROR - ${error.name} - ${error.message}`);
|
|
53
|
-
if (error.name == 'NotAllowedError') {
|
|
54
|
-
// Every webauth authentication form needs this localized error message.
|
|
55
|
-
alert(this.form.dataset.boothUnknownDeviceMessage);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
alert(error.message);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
Webauth.Authentication = Authentication;
|
|
64
|
-
class Verification {
|
|
65
|
-
constructor(form, webauth) {
|
|
66
|
-
this.form = form;
|
|
67
|
-
this.webauth = webauth;
|
|
68
|
-
this.call();
|
|
69
|
-
}
|
|
70
|
-
call() {
|
|
71
|
-
console.debug(`WebAuthn Ceremony - Verification Phase - START - ${this.formMethod} ${this.formUrl}`);
|
|
72
|
-
const options = {
|
|
73
|
-
body: JSON.stringify(this.webauth),
|
|
74
|
-
method: this.formMethod,
|
|
75
|
-
credentials: 'same-origin',
|
|
76
|
-
// Rails should not redirect us anywhere when making API calls.
|
|
77
|
-
// But in order to avoid mistakes let's be sure and never follow anywhere.
|
|
78
|
-
redirect: 'manual',
|
|
79
|
-
headers: {
|
|
80
|
-
'Content-type': 'application/json',
|
|
81
|
-
'Accept': 'application/json',
|
|
82
|
-
'X-CSRF-Token': this.csrfToken
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
fetch(this.formUrl, options)
|
|
86
|
-
.then((response) => {
|
|
87
|
-
// Conventionally the server returns 201 on successful WebAuth verification.
|
|
88
|
-
// That makes it easier to detect a mistake (most other server responses will usually return 200).
|
|
89
|
-
if (response.status == 201) {
|
|
90
|
-
console.debug(`WebAuthn Ceremony - Verification Phase - SUCCESS - ${response.statusText}`);
|
|
91
|
-
console.info(`Reloading page with a GET request: ${window.location.href}`);
|
|
92
|
-
window.location.href = window.location.href;
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
// TODO: Extract error message from JSON that the server sent.
|
|
96
|
-
const message = `WebAuthn Ceremony - Verification Phase - ERROR - ${response.statusText} ${response.body}`;
|
|
97
|
-
console.debug(message);
|
|
98
|
-
alert(message);
|
|
99
|
-
}
|
|
100
|
-
}).catch((error) => {
|
|
101
|
-
const message = 'Please check your Internet connection and try again later.';
|
|
102
|
-
console.error(message);
|
|
103
|
-
alert(message);
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
get formUrl() {
|
|
107
|
-
return this.form.action;
|
|
108
|
-
}
|
|
109
|
-
get formMethod() {
|
|
110
|
-
return this.form.querySelector('input[name="_method"]')?.value?.toUpperCase() || 'POST';
|
|
111
|
-
}
|
|
112
|
-
get csrfToken() {
|
|
113
|
-
return document.querySelector('meta[name="csrf-token"]')?.content;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
Webauth.Verification = Verification;
|
|
117
|
-
})(Webauth = Booth.Webauth || (Booth.Webauth = {}));
|
|
118
|
-
})(Booth || (Booth = {}));
|
|
119
|
-
// --------------
|
|
120
|
-
// Initialization
|
|
121
|
-
// --------------
|
|
122
|
-
document.addEventListener('DOMContentLoaded', function () {
|
|
123
|
-
document.querySelectorAll('.js-booth-webauth-registration').forEach((form) => {
|
|
124
|
-
form.addEventListener('ajax:before', () => {
|
|
125
|
-
console.debug('WebAuthn Registration Ceremony - Initiation Phase Part 1 - START');
|
|
126
|
-
});
|
|
127
|
-
form.addEventListener('ajax:success', (event) => {
|
|
128
|
-
const [data, status, xhr] = event.detail;
|
|
129
|
-
console.debug(`WebAuthn Registration Ceremony - Initiation Phase Part 1 - SUCCESS - ${JSON.stringify(data)}`);
|
|
130
|
-
new Booth.Webauth.Registration(form, data);
|
|
131
|
-
});
|
|
132
|
-
form.addEventListener('ajax:error', (event) => {
|
|
133
|
-
const [data, status, xhr] = event.detail;
|
|
134
|
-
// TODO: Extract error message from JSON that the server sent.
|
|
135
|
-
// I don't think we need to reload the page on the registration page.
|
|
136
|
-
const message = `WebAuthn Registration Ceremony - Initiation Phase Part 1 - ERROR - ${xhr.responseText}`;
|
|
137
|
-
console.error(message);
|
|
138
|
-
alert(message);
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
document.querySelectorAll('.js-booth-webauth-authentication').forEach((form) => {
|
|
142
|
-
form.addEventListener('ajax:before', () => {
|
|
143
|
-
console.debug('WebAuthn Authentication Ceremony - Initiation Phase Part 1 - START');
|
|
144
|
-
});
|
|
145
|
-
form.addEventListener('ajax:success', (event) => {
|
|
146
|
-
const [data, status, xhr] = event.detail;
|
|
147
|
-
console.debug(`WebAuthn Authentication Ceremony - Initiation Phase Part 1 - SUCCESS - ${JSON.stringify(data)}`);
|
|
148
|
-
new Booth.Webauth.Authentication(form, data);
|
|
149
|
-
});
|
|
150
|
-
form.addEventListener('ajax:error', (event) => {
|
|
151
|
-
const [data, status, xhr] = event.detail;
|
|
152
|
-
// TODO: Extract error message from JSON that the server sent.
|
|
153
|
-
// On the authentication page there are timeout restrictions, it would be a good idea to reload page.
|
|
154
|
-
const message = `WebAuthn Authentication Ceremony - Initiation Phase Part 1 - ERROR - ${xhr.responseText}`;
|
|
155
|
-
console.error(message);
|
|
156
|
-
alert(message);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
if (document.querySelector('.js-booth-polling'))
|
|
160
|
-
Booth.reloadSoon();
|
|
161
|
-
});
|
|
162
|
-
//# sourceMappingURL=all.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"all.js","sourceRoot":"","sources":["webauthn-json.ts","booth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
/// <reference path='webauthn-json.ts' />
|
|
2
|
-
|
|
3
|
-
//= require rails-ujs
|
|
4
|
-
//= require @github/webauthn-json/dist/browser-global/webauthn-json.browser-global
|
|
5
|
-
|
|
6
|
-
namespace Booth {
|
|
7
|
-
export function reloadSoon() {
|
|
8
|
-
const seconds = Math.floor(Math.random() * 3) + 5 // 4,5,6 or 7 to avoid request bursts
|
|
9
|
-
|
|
10
|
-
setTimeout(() => {
|
|
11
|
-
console.debug('Reloading page...')
|
|
12
|
-
window.location.reload()
|
|
13
|
-
}, 1000 * seconds)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export namespace Webauth {
|
|
17
|
-
export class Registration {
|
|
18
|
-
private form: HTMLFormElement
|
|
19
|
-
private challengeData: any
|
|
20
|
-
|
|
21
|
-
constructor(form: HTMLFormElement, challengeData: any) {
|
|
22
|
-
this.form = form
|
|
23
|
-
this.challengeData = challengeData
|
|
24
|
-
this.call()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
private call() {
|
|
28
|
-
console.debug('WebAuthn Registration Ceremony - Initiation Phase Part 2 - START')
|
|
29
|
-
webauthnJSON.create({ publicKey: this.challengeData }).then((responseData) => {
|
|
30
|
-
console.debug(`WebAuthn Registration Ceremony - Initiation Phase Part 2 - SUCCESS - ${JSON.stringify(responseData)}`)
|
|
31
|
-
new Verification(this.form, responseData)
|
|
32
|
-
|
|
33
|
-
}).catch((error: DOMException) => {
|
|
34
|
-
console.error(`WebAuthn Registration Ceremony - Verification Phase - ERROR - ${error.name} - ${error.message}`)
|
|
35
|
-
|
|
36
|
-
if (error.name == 'NotAllowedError') {
|
|
37
|
-
// Every webauth registration form needs this localized error message.
|
|
38
|
-
alert(this.form.dataset.boothIncompatibleDeviceMessage)
|
|
39
|
-
} else {
|
|
40
|
-
alert(error.message)
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export class Authentication {
|
|
47
|
-
private form: HTMLFormElement
|
|
48
|
-
private challengeData: any
|
|
49
|
-
|
|
50
|
-
constructor(form: HTMLFormElement, challengeData: any) {
|
|
51
|
-
this.form = form
|
|
52
|
-
this.challengeData = challengeData
|
|
53
|
-
this.call()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private call() {
|
|
57
|
-
console.debug('WebAuthn Authentication Ceremony - Initiation Phase Part 2 - START')
|
|
58
|
-
webauthnJSON.get({ publicKey: this.challengeData }).then((responseData) => {
|
|
59
|
-
console.debug(`WebAuthn Authentication Ceremony - Initiation Phase Part 2 - SUCCESS - ${JSON.stringify(responseData)}`)
|
|
60
|
-
new Verification(this.form, responseData)
|
|
61
|
-
|
|
62
|
-
}).catch((error) => {
|
|
63
|
-
console.error(`WebAuthn Authentication Ceremony - Verification Phase - ERROR - ${error.name} - ${error.message}`)
|
|
64
|
-
|
|
65
|
-
if (error.name == 'NotAllowedError') {
|
|
66
|
-
// Every webauth authentication form needs this localized error message.
|
|
67
|
-
alert(this.form.dataset.boothUnknownDeviceMessage)
|
|
68
|
-
} else {
|
|
69
|
-
alert(error.message)
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export class Verification {
|
|
76
|
-
private form: HTMLFormElement
|
|
77
|
-
private webauth: any
|
|
78
|
-
|
|
79
|
-
public constructor(form: HTMLFormElement, webauth: any) {
|
|
80
|
-
this.form = form
|
|
81
|
-
this.webauth = webauth
|
|
82
|
-
this.call()
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private call() {
|
|
86
|
-
console.debug(`WebAuthn Ceremony - Verification Phase - START - ${this.formMethod} ${this.formUrl}`)
|
|
87
|
-
|
|
88
|
-
const options: RequestInit = {
|
|
89
|
-
body: JSON.stringify(this.webauth),
|
|
90
|
-
method: this.formMethod,
|
|
91
|
-
credentials: 'same-origin',
|
|
92
|
-
// Rails should not redirect us anywhere when making API calls.
|
|
93
|
-
// But in order to avoid mistakes let's be sure and never follow anywhere.
|
|
94
|
-
redirect: 'manual',
|
|
95
|
-
headers: {
|
|
96
|
-
'Content-type': 'application/json',
|
|
97
|
-
'Accept': 'application/json',
|
|
98
|
-
'X-CSRF-Token': this.csrfToken
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
fetch(this.formUrl, options)
|
|
103
|
-
.then((response) => {
|
|
104
|
-
|
|
105
|
-
// Conventionally the server returns 201 on successful WebAuth verification.
|
|
106
|
-
// That makes it easier to detect a mistake (most other server responses will usually return 200).
|
|
107
|
-
if (response.status == 201) {
|
|
108
|
-
console.debug(`WebAuthn Ceremony - Verification Phase - SUCCESS - ${response.statusText}`)
|
|
109
|
-
console.info(`Reloading page with a GET request: ${window.location.href}`)
|
|
110
|
-
window.location.href = window.location.href
|
|
111
|
-
|
|
112
|
-
} else {
|
|
113
|
-
// TODO: Extract error message from JSON that the server sent.
|
|
114
|
-
const message = `WebAuthn Ceremony - Verification Phase - ERROR - ${response.statusText} ${response.body}`
|
|
115
|
-
console.debug(message)
|
|
116
|
-
alert(message)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
}).catch((error) => {
|
|
120
|
-
const message = 'Please check your Internet connection and try again later.'
|
|
121
|
-
console.error(message)
|
|
122
|
-
alert(message)
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private get formUrl() {
|
|
127
|
-
return this.form.action
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
private get formMethod() {
|
|
131
|
-
return this.form.querySelector<HTMLInputElement>('input[name="_method"]')?.value?.toUpperCase() || 'POST'
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
private get csrfToken() {
|
|
135
|
-
return document.querySelector<HTMLMetaElement>('meta[name="csrf-token"]')?.content
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// --------------
|
|
145
|
-
// Initialization
|
|
146
|
-
// --------------
|
|
147
|
-
|
|
148
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
149
|
-
|
|
150
|
-
document.querySelectorAll('.js-booth-webauth-registration').forEach((form: HTMLFormElement) => {
|
|
151
|
-
form.addEventListener('ajax:before', () => {
|
|
152
|
-
console.debug('WebAuthn Registration Ceremony - Initiation Phase Part 1 - START')
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
form.addEventListener('ajax:success', (event: CustomEvent) => {
|
|
156
|
-
const [data, status, xhr] = event.detail
|
|
157
|
-
console.debug(`WebAuthn Registration Ceremony - Initiation Phase Part 1 - SUCCESS - ${JSON.stringify(data)}`)
|
|
158
|
-
new Booth.Webauth.Registration(form, data)
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
form.addEventListener('ajax:error', (event: CustomEvent) => {
|
|
162
|
-
const [data, status, xhr] = event.detail
|
|
163
|
-
// TODO: Extract error message from JSON that the server sent.
|
|
164
|
-
// I don't think we need to reload the page on the registration page.
|
|
165
|
-
const message = `WebAuthn Registration Ceremony - Initiation Phase Part 1 - ERROR - ${xhr.responseText}`
|
|
166
|
-
console.error(message)
|
|
167
|
-
alert(message)
|
|
168
|
-
})
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
document.querySelectorAll('.js-booth-webauth-authentication').forEach((form: HTMLFormElement) => {
|
|
172
|
-
form.addEventListener('ajax:before', () => {
|
|
173
|
-
console.debug('WebAuthn Authentication Ceremony - Initiation Phase Part 1 - START')
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
form.addEventListener('ajax:success', (event: CustomEvent) => {
|
|
177
|
-
const [data, status, xhr] = event.detail
|
|
178
|
-
console.debug(`WebAuthn Authentication Ceremony - Initiation Phase Part 1 - SUCCESS - ${JSON.stringify(data)}`)
|
|
179
|
-
new Booth.Webauth.Authentication(form, data)
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
form.addEventListener('ajax:error', (event: CustomEvent) => {
|
|
183
|
-
const [data, status, xhr] = event.detail
|
|
184
|
-
// TODO: Extract error message from JSON that the server sent.
|
|
185
|
-
// On the authentication page there are timeout restrictions, it would be a good idea to reload page.
|
|
186
|
-
const message = `WebAuthn Authentication Ceremony - Initiation Phase Part 1 - ERROR - ${xhr.responseText}`
|
|
187
|
-
console.error(message)
|
|
188
|
-
alert(message)
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
if (document.querySelector('.js-booth-polling')) Booth.reloadSoon()
|
|
193
|
-
|
|
194
|
-
})
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
type Base64urlString = string;
|
|
2
|
-
type SchemaLeaf = "copy" | "convert";
|
|
3
|
-
interface SchemaObject {
|
|
4
|
-
[property: string]: {
|
|
5
|
-
required: boolean;
|
|
6
|
-
schema: Schema;
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
type SchemaArray = [SchemaObject] | [SchemaLeaf];
|
|
10
|
-
type Schema = SchemaLeaf | SchemaArray | SchemaObject;
|
|
11
|
-
interface CredPropsAuthenticationExtensionsClientOutputsJSON {
|
|
12
|
-
rk: boolean;
|
|
13
|
-
}
|
|
14
|
-
interface PublicKeyCredentialDescriptorJSON {
|
|
15
|
-
type: PublicKeyCredentialType;
|
|
16
|
-
id: Base64urlString;
|
|
17
|
-
transports?: AuthenticatorTransport[];
|
|
18
|
-
}
|
|
19
|
-
interface SimpleWebAuthnExtensionsJSON {
|
|
20
|
-
appid?: string;
|
|
21
|
-
appidExclude?: string;
|
|
22
|
-
credProps?: boolean;
|
|
23
|
-
}
|
|
24
|
-
interface SimpleClientExtensionResultsJSON {
|
|
25
|
-
appid?: boolean;
|
|
26
|
-
appidExclude?: boolean;
|
|
27
|
-
credProps?: CredPropsAuthenticationExtensionsClientOutputsJSON;
|
|
28
|
-
}
|
|
29
|
-
interface PublicKeyCredentialUserEntityJSON extends PublicKeyCredentialEntity {
|
|
30
|
-
displayName: string;
|
|
31
|
-
id: Base64urlString;
|
|
32
|
-
}
|
|
33
|
-
declare interface AuthenticatorSelectionCriteriaJSON extends AuthenticatorSelectionCriteria {
|
|
34
|
-
residentKey?: ResidentKeyRequirement;
|
|
35
|
-
}
|
|
36
|
-
interface PublicKeyCredentialCreationOptionsJSON {
|
|
37
|
-
rp: PublicKeyCredentialRpEntity;
|
|
38
|
-
user: PublicKeyCredentialUserEntityJSON;
|
|
39
|
-
challenge: Base64urlString;
|
|
40
|
-
pubKeyCredParams: PublicKeyCredentialParameters[];
|
|
41
|
-
timeout?: number;
|
|
42
|
-
excludeCredentials?: PublicKeyCredentialDescriptorJSON[];
|
|
43
|
-
authenticatorSelection?: AuthenticatorSelectionCriteriaJSON;
|
|
44
|
-
attestation?: AttestationConveyancePreference;
|
|
45
|
-
extensions?: SimpleWebAuthnExtensionsJSON;
|
|
46
|
-
}
|
|
47
|
-
declare interface CredentialCreationOptionsJSON {
|
|
48
|
-
publicKey: PublicKeyCredentialCreationOptionsJSON;
|
|
49
|
-
signal?: AbortSignal;
|
|
50
|
-
}
|
|
51
|
-
interface AuthenticatorAttestationResponseJSON {
|
|
52
|
-
clientDataJSON: Base64urlString;
|
|
53
|
-
attestationObject: Base64urlString;
|
|
54
|
-
}
|
|
55
|
-
declare interface PublicKeyCredentialWithAttestationJSON {
|
|
56
|
-
id: string;
|
|
57
|
-
type: PublicKeyCredentialType;
|
|
58
|
-
rawId: Base64urlString;
|
|
59
|
-
response: AuthenticatorAttestationResponseJSON;
|
|
60
|
-
clientExtensionResults: SimpleClientExtensionResultsJSON;
|
|
61
|
-
}
|
|
62
|
-
interface PublicKeyCredentialRequestOptionsJSON {
|
|
63
|
-
challenge: Base64urlString;
|
|
64
|
-
timeout?: number;
|
|
65
|
-
rpId?: string;
|
|
66
|
-
allowCredentials?: PublicKeyCredentialDescriptorJSON[];
|
|
67
|
-
userVerification?: UserVerificationRequirement;
|
|
68
|
-
extensions?: SimpleWebAuthnExtensionsJSON;
|
|
69
|
-
}
|
|
70
|
-
declare interface CredentialRequestOptionsJSON {
|
|
71
|
-
mediation?: CredentialMediationRequirement;
|
|
72
|
-
publicKey?: PublicKeyCredentialRequestOptionsJSON;
|
|
73
|
-
signal?: AbortSignal;
|
|
74
|
-
}
|
|
75
|
-
interface AuthenticatorAssertionResponseJSON {
|
|
76
|
-
clientDataJSON: Base64urlString;
|
|
77
|
-
authenticatorData: Base64urlString;
|
|
78
|
-
signature: Base64urlString;
|
|
79
|
-
userHandle: Base64urlString | null;
|
|
80
|
-
}
|
|
81
|
-
declare interface PublicKeyCredentialWithAssertionJSON {
|
|
82
|
-
type: PublicKeyCredentialType;
|
|
83
|
-
id: string;
|
|
84
|
-
rawId: Base64urlString;
|
|
85
|
-
response: AuthenticatorAssertionResponseJSON;
|
|
86
|
-
clientExtensionResults: SimpleClientExtensionResultsJSON;
|
|
87
|
-
}
|
|
88
|
-
declare const schema: {
|
|
89
|
-
[s: string]: Schema;
|
|
90
|
-
};
|
|
91
|
-
// export function create(requestJSON: CredentialCreationOptionsJSON): Promise<PublicKeyCredentialWithAttestationJSON>;
|
|
92
|
-
// export function get(requestJSON: CredentialRequestOptionsJSON): Promise<PublicKeyCredentialWithAssertionJSON>;
|
|
93
|
-
// export function supported(): boolean;
|
|
94
|
-
|
|
95
|
-
declare class webauthnJSON {
|
|
96
|
-
static create(requestJSON: CredentialCreationOptionsJSON): Promise<PublicKeyCredentialWithAttestationJSON>;
|
|
97
|
-
static get(requestJSON: CredentialRequestOptionsJSON): Promise<PublicKeyCredentialWithAssertionJSON>;
|
|
98
|
-
static supported(): boolean;
|
|
99
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Adminland
|
|
3
|
-
module Recoveries
|
|
4
|
-
# When sending out username recovery emails,
|
|
5
|
-
# this class helps to keep the sending mechanism idempodent.
|
|
6
|
-
class Consume
|
|
7
|
-
include ::Booth::MethodObject
|
|
8
|
-
include ::Booth::Logging
|
|
9
|
-
|
|
10
|
-
option :recovery_id
|
|
11
|
-
option :credential_id
|
|
12
|
-
|
|
13
|
-
def call
|
|
14
|
-
do_find_recovery
|
|
15
|
-
.on_success { do_find_credential }
|
|
16
|
-
.on_success { do_check_eligibility }
|
|
17
|
-
.on_success { do_consume }
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def do_find_recovery
|
|
23
|
-
debug { "Looking for Recovery with ID #{recovery_id.inspect}" }
|
|
24
|
-
@recovery = ::Booth::Models::Recovery.find_by(id: recovery_id)
|
|
25
|
-
|
|
26
|
-
if @recovery
|
|
27
|
-
debug { 'Recovery was found' }
|
|
28
|
-
return Tron.success :recovery_exists
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
debug { 'Did not find Recovery' }
|
|
32
|
-
Tron.failure :recovery_not_found, provided_id: recovery_id.inspect
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def do_find_credential
|
|
36
|
-
debug { "Looking for Credential with ID #{credential_id.inspect}" }
|
|
37
|
-
@credential = ::Booth::Models::Credential.find_by(id: credential_id)
|
|
38
|
-
|
|
39
|
-
if @credential
|
|
40
|
-
debug { 'Credential was found' }
|
|
41
|
-
return Tron.success :credential_exists
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
debug { 'Did not find Credential' }
|
|
45
|
-
Tron.failure :credential_not_found, provided_id: credential_id.inspect
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def do_check_eligibility
|
|
49
|
-
return Tron.failure :already_consumed if @recovery.consumed?
|
|
50
|
-
|
|
51
|
-
return Tron.failure :already_revoked if @recovery.revoked?
|
|
52
|
-
|
|
53
|
-
Tron.success :can_be_consumed
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def do_consume
|
|
57
|
-
@recovery.transaction do
|
|
58
|
-
@recovery.update! consumed_at: Time.current
|
|
59
|
-
|
|
60
|
-
@recovery.other_recoveries_with_this_scope_and_email
|
|
61
|
-
.update_all revoked_at: Time.current # rubocop:disable Rails/SkipsModelValidations
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
Tron.success :recovery_consumed, email: @recovery.email,
|
|
65
|
-
username: @credential.username
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Audits
|
|
3
|
-
module Register
|
|
4
|
-
class AddedOtp
|
|
5
|
-
include ::Booth::MethodObject
|
|
6
|
-
|
|
7
|
-
option :credential
|
|
8
|
-
option :ip
|
|
9
|
-
option :agent
|
|
10
|
-
|
|
11
|
-
def call
|
|
12
|
-
::Booth::Models::Audit.create! credential: credential,
|
|
13
|
-
ip: ip,
|
|
14
|
-
agent: agent,
|
|
15
|
-
event: :added_otp
|
|
16
|
-
|
|
17
|
-
nil
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Audits
|
|
3
|
-
module Register
|
|
4
|
-
class ChangedOtp
|
|
5
|
-
include ::Booth::MethodObject
|
|
6
|
-
|
|
7
|
-
option :credential
|
|
8
|
-
option :ip
|
|
9
|
-
option :agent
|
|
10
|
-
|
|
11
|
-
def call
|
|
12
|
-
::Booth::Models::Audit.create! credential: credential,
|
|
13
|
-
ip: ip,
|
|
14
|
-
agent: agent,
|
|
15
|
-
event: :changed_otp
|
|
16
|
-
|
|
17
|
-
nil
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Audits
|
|
3
|
-
module Register
|
|
4
|
-
class CorrectOtp
|
|
5
|
-
include ::Booth::MethodObject
|
|
6
|
-
include ::Booth::Logging
|
|
7
|
-
|
|
8
|
-
option :credential
|
|
9
|
-
option :ip
|
|
10
|
-
option :agent
|
|
11
|
-
|
|
12
|
-
def call
|
|
13
|
-
::Booth::Models::Audit.transaction do
|
|
14
|
-
register_attempt!
|
|
15
|
-
clear_failed_attempts!
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
nil
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def register_attempt!
|
|
24
|
-
debug { "Auditing correct OTP for credential `#{credential.id}` and IP `#{ip}`" }
|
|
25
|
-
|
|
26
|
-
::Booth::Models::Audit.create! credential:,
|
|
27
|
-
ip:,
|
|
28
|
-
agent:,
|
|
29
|
-
event: :entered_correct_password
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def clear_failed_attempts!
|
|
33
|
-
debug { "Redeeming all failed OTP attempts for credential `#{credential.id}`" }
|
|
34
|
-
|
|
35
|
-
::Booth::Models::Audit.where(credential:)
|
|
36
|
-
.where(event: :entered_wrong_otp)
|
|
37
|
-
.update_all(deleted_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|