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
data/lib/booth/method_object.rb
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# Copyright 2018 Bukowskis https://github.com/bukowskis/method_object
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
-
# a copy of this software and associated documentation files (the
|
|
5
|
-
# "Software"), to deal in the Software without restriction, including
|
|
6
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
-
# the following conditions:
|
|
10
|
-
#
|
|
11
|
-
# The above copyright notice and this permission notice shall be
|
|
12
|
-
# included in all copies or substantial portions of the Software.
|
|
13
|
-
#
|
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
-
|
|
22
|
-
module Booth
|
|
23
|
-
module MethodObject
|
|
24
|
-
def self.included(base)
|
|
25
|
-
base.extend Dry::Initializer
|
|
26
|
-
base.extend ClassMethods
|
|
27
|
-
base.send(:private_class_method, :new)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
module ClassMethods
|
|
31
|
-
def call(*args, **kwargs, &)
|
|
32
|
-
__check_for_unknown_options(*args, **kwargs)
|
|
33
|
-
|
|
34
|
-
if kwargs.empty?
|
|
35
|
-
# Preventing `Passing the keyword argument as the last hash parameter is deprecated`
|
|
36
|
-
new(*args).call(&)
|
|
37
|
-
else
|
|
38
|
-
new(*args, **kwargs).call(&)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Overriding the implementation of `#param` in the `dry-initializer` gem.
|
|
43
|
-
# Because of the positioning of multiple params, params can never be omitted in a method object.
|
|
44
|
-
def param(name, type = nil, **opts, &)
|
|
45
|
-
raise ArgumentError, "Default value for param not allowed - #{name}" if opts.key? :default
|
|
46
|
-
raise ArgumentError, "Optional params not supported - #{name}" if opts.fetch(:optional, false)
|
|
47
|
-
|
|
48
|
-
super
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def __check_for_unknown_options(*args, **kwargs)
|
|
52
|
-
return if __defined_options.empty?
|
|
53
|
-
|
|
54
|
-
# Checking params
|
|
55
|
-
opts = args.drop(__defined_params.length).first || kwargs
|
|
56
|
-
raise ArgumentError, "Unexpected argument #{opts}" unless opts.is_a? Hash
|
|
57
|
-
|
|
58
|
-
# Checking options
|
|
59
|
-
unknown_options = opts.keys - __defined_options
|
|
60
|
-
message = "Key(s) #{unknown_options} not found in #{__defined_options}"
|
|
61
|
-
raise KeyError, message if unknown_options.any?
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def __defined_options
|
|
65
|
-
dry_initializer.options.map(&:source)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def __defined_params
|
|
69
|
-
dry_initializer.params.map(&:source)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
data/lib/booth/mode.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Mode
|
|
3
|
-
def self.find(symbol)
|
|
4
|
-
return if symbol.to_s == 'first_time'
|
|
5
|
-
|
|
6
|
-
all.detect { _1.id.to_s == symbol.to_s } || raise("Unknown Booth Mode: #{symbol.inspect}")
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def self.wrap(input)
|
|
10
|
-
Array(input).map { find(_1) }.sort
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.all
|
|
14
|
-
[
|
|
15
|
-
::Booth::Modes::UsernameAndWebauth, # Recommended for convenience
|
|
16
|
-
::Booth::Modes::UsernamePasswordAndWebauth, # Most secure
|
|
17
|
-
::Booth::Modes::UsernamePasswordAndOtp, # If you don't have a hardware key
|
|
18
|
-
::Booth::Modes::UsernameAndPassword, # Discouraged
|
|
19
|
-
]
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Models
|
|
3
|
-
module Concerns
|
|
4
|
-
module Modeable
|
|
5
|
-
extend ActiveSupport::Concern
|
|
6
|
-
|
|
7
|
-
included do
|
|
8
|
-
enum mode: { first_time: 'first_time',
|
|
9
|
-
username_and_password: 'username_and_password',
|
|
10
|
-
username_password_and_otp: 'username_password_and_otp',
|
|
11
|
-
username_password_and_webauth: 'username_password_and_webauth',
|
|
12
|
-
username_and_webauth: 'username_and_webauth' },
|
|
13
|
-
_prefix: true
|
|
14
|
-
|
|
15
|
-
validates :mode, presence: true, inclusion: { in: modes.keys }
|
|
16
|
-
validates :mode, inclusion: { in: -> { ['first_time'] + _1.allowed_modes } }
|
|
17
|
-
|
|
18
|
-
before_validation :ensure_mode
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def requires_user_verification?
|
|
22
|
-
# Passwordless login should always require user presence
|
|
23
|
-
!mode_username_password_and_webauth?
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def allows_mode_username_and_password?
|
|
27
|
-
allowed_modes.include?('username_and_password')
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def allows_mode_username_password_and_otp?
|
|
31
|
-
allowed_modes.include?('username_password_and_otp')
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def allows_mode_username_password_and_webauth?
|
|
35
|
-
allowed_modes.include?('username_password_and_webauth')
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def allows_mode_username_and_webauth?
|
|
39
|
-
allowed_modes.include?('username_and_webauth')
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
def ensure_mode
|
|
45
|
-
self.mode ||= 'first_time'
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Models
|
|
3
|
-
module Concerns
|
|
4
|
-
module Otpable
|
|
5
|
-
extend ActiveSupport::Concern
|
|
6
|
-
|
|
7
|
-
included do
|
|
8
|
-
# See https://github.com/heapsource/active_model_otp/blob/master/lib/active_model/one_time_password.rb
|
|
9
|
-
has_one_time_password length: otp_digits
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
class_methods do
|
|
13
|
-
def otp_digits
|
|
14
|
-
6
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def authenticate_otp(code)
|
|
19
|
-
super(code, drift: 30.seconds)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def otp_provisioning_url
|
|
23
|
-
raise "Expected #{self} to respond to #scope" unless respond_to?(:scope)
|
|
24
|
-
|
|
25
|
-
provisioning_uri(username, issuer: ::Booth.config.otp_issuer(scope:), digits: otp_digits)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def otp_provisioning_svg
|
|
29
|
-
qr = ::RQRCode::QRCode.new(otp_provisioning_url, level: :l)
|
|
30
|
-
# See https://whomwah.github.io/rqrcode/
|
|
31
|
-
qr.as_svg use_path: false,
|
|
32
|
-
viewbox: true, fill: 'fff', offset: 5, module_size: 8, svg_attributes: { 'data-booth' => :otpqr }
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Models
|
|
3
|
-
module Concerns
|
|
4
|
-
module Passwordable
|
|
5
|
-
extend ActiveSupport::Concern
|
|
6
|
-
|
|
7
|
-
included do
|
|
8
|
-
# See https://github.com/rails/rails/blob/master/activemodel/lib/active_model/secure_password.rb
|
|
9
|
-
has_secure_password
|
|
10
|
-
|
|
11
|
-
define_method('password=') do |unencrypted_password|
|
|
12
|
-
# We auto-assign a random password before validation.
|
|
13
|
-
# If a non-empty password was explicitly assigned, then we should not generate a random password.
|
|
14
|
-
@apparently_wants_no_password = unencrypted_password.blank?
|
|
15
|
-
|
|
16
|
-
# See https://github.com/rails/rails/issues/34348#issuecomment-615856794
|
|
17
|
-
super(unencrypted_password.presence)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
validates :password, length: { minimum: password_minlength }, allow_blank: true
|
|
21
|
-
# Don't say anything about breaches if the password was already too short to be accepted.
|
|
22
|
-
validates :password, not_pwned: {
|
|
23
|
-
on_error: :valid,
|
|
24
|
-
request_options: {
|
|
25
|
-
read_timeout: 3,
|
|
26
|
-
open_timeout: 1
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
allow_blank: true,
|
|
30
|
-
if: proc { _1.errors.empty? }
|
|
31
|
-
|
|
32
|
-
before_validation :ensure_initial_password
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
class_methods do
|
|
36
|
-
def password_minlength
|
|
37
|
-
8
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# See https://support.1password.com/compatible-website-design
|
|
41
|
-
# See https://developer.apple.com/password-rules
|
|
42
|
-
def passwordrules
|
|
43
|
-
"minlength: #{password_minlength}; maxlength: #{::ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED};"
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
|
|
49
|
-
def ensure_initial_password
|
|
50
|
-
return if password_digest.present?
|
|
51
|
-
return if @apparently_wants_no_password
|
|
52
|
-
|
|
53
|
-
self.password = ::SecureRandom.alphanumeric(::ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Models
|
|
3
|
-
module Contests
|
|
4
|
-
module Scopes
|
|
5
|
-
class RecentlyCreated
|
|
6
|
-
include ::Booth::MethodObject
|
|
7
|
-
|
|
8
|
-
param :contest
|
|
9
|
-
|
|
10
|
-
def self.scope(base)
|
|
11
|
-
base.where.not(created_at: nil)
|
|
12
|
-
.where('created_at > ?', ::Booth::Models::Contest.lifespan.ago)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def call
|
|
16
|
-
contest.created_at.present? &&
|
|
17
|
-
contest.created_at > ::Booth::Models::Contest.lifespan.ago
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Models
|
|
3
|
-
module Contests
|
|
4
|
-
module Scopes
|
|
5
|
-
class RecentlyResponded
|
|
6
|
-
include ::Booth::MethodObject
|
|
7
|
-
|
|
8
|
-
param :contest
|
|
9
|
-
|
|
10
|
-
def self.scope(base)
|
|
11
|
-
base.where.not(created_at: nil, responded_at: nil)
|
|
12
|
-
.where('created_at > ?', lifespan.ago)
|
|
13
|
-
.where('responded_at > ?', lifespan.ago)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def call
|
|
17
|
-
contest.created_at.present? &&
|
|
18
|
-
contest.responded_at.present? &&
|
|
19
|
-
contest.created_at > lifespan.ago &&
|
|
20
|
-
contest.responded_at > lifespan.ago
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
|
|
25
|
-
def lifespan
|
|
26
|
-
contest.class.lifespan
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Models
|
|
3
|
-
class PasswordReset < ::Booth::Models::ApplicationRecord
|
|
4
|
-
include ::Booth::Logging
|
|
5
|
-
include ::Booth::Models::Concerns::Passwordable
|
|
6
|
-
|
|
7
|
-
self.table_name = 'booth_password_resets'
|
|
8
|
-
|
|
9
|
-
def self.lifetime
|
|
10
|
-
::Booth.config.password_reset_window
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
belongs_to :credential, class_name: '::Booth::Models::Credential'
|
|
14
|
-
|
|
15
|
-
validates :creator_ip, presence: true
|
|
16
|
-
|
|
17
|
-
# See https://github.com/rails/rails/blob/main/activerecord/lib/active_record/secure_token.rb
|
|
18
|
-
has_secure_token :secret_key, length: 30
|
|
19
|
-
|
|
20
|
-
def step
|
|
21
|
-
::Booth::PasswordResets::Step.call(self)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def completed?
|
|
25
|
-
password_chosen_at.present? && password_confirmed_at.present?
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def revoked?
|
|
29
|
-
revoked_at.present?
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def recently_created?
|
|
33
|
-
created_at > self.class.lifetime.ago
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def other_password_resets_of_this_credential
|
|
37
|
-
credential.password_resets.where.not(id:)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Models
|
|
3
|
-
class Recovery < ::Booth::Models::ApplicationRecord
|
|
4
|
-
include ::Booth::Logging
|
|
5
|
-
|
|
6
|
-
self.table_name = 'booth_recoveries'
|
|
7
|
-
|
|
8
|
-
before_validation :normalize_email
|
|
9
|
-
|
|
10
|
-
def consumed?
|
|
11
|
-
consumed_at.present?
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def revoked?
|
|
15
|
-
revoked_at.present?
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def other_recoveries_with_this_scope_and_email
|
|
19
|
-
self.class
|
|
20
|
-
.where(scope:)
|
|
21
|
-
.where(email:)
|
|
22
|
-
.where.not(id:)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def normalize_email
|
|
28
|
-
self.email = ::Booth::Syntaxes::Email.call(email).normalized_email
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
data/lib/booth/modes/base.rb
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Modes
|
|
3
|
-
module Base
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
|
|
6
|
-
class_methods do
|
|
7
|
-
def id
|
|
8
|
-
self.to_s.demodulize.underscore
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def title
|
|
12
|
-
I18n.t "booth.mode_#{id}_title"
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def description
|
|
16
|
-
I18n.t "booth.mode_#{id}_description"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def <=>(other)
|
|
20
|
-
::Booth::Mode.all.index(self) <=> ::Booth::Mode.all.index(other)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Onboardings
|
|
3
|
-
class Find
|
|
4
|
-
include ::Booth::Logging
|
|
5
|
-
include ::Booth::MethodObject
|
|
6
|
-
|
|
7
|
-
option :secret_key
|
|
8
|
-
|
|
9
|
-
def call
|
|
10
|
-
check_secret_key_syntax_action
|
|
11
|
-
.on_success { find_onboarding_action }
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def check_secret_key_syntax_action
|
|
17
|
-
::Booth::Syntaxes::SecretKey.call(secret_key)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def find_onboarding_action
|
|
21
|
-
debug { "Looking for Onboarding with secret key #{secret_key.inspect}" }
|
|
22
|
-
onboarding = ::Booth::Models::Onboarding.find_by(secret_key:)
|
|
23
|
-
|
|
24
|
-
if onboarding
|
|
25
|
-
debug { "Found Onboarding with ID #{onboarding.id.inspect}" }
|
|
26
|
-
Tron.success(:found_onboarding, onboarding:)
|
|
27
|
-
else
|
|
28
|
-
message = "Could not find userland Onboarding with secret key #{secret_key.inspect}"
|
|
29
|
-
debug { message }
|
|
30
|
-
Tron.failure :onboarding_not_found, public_message: I18n.t('booth.unknown_secret_key')
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Onboardings
|
|
3
|
-
class PropagateToCredential
|
|
4
|
-
include ::Booth::Logging
|
|
5
|
-
include ::Booth::MethodObject
|
|
6
|
-
|
|
7
|
-
param :onboarding
|
|
8
|
-
option :ip
|
|
9
|
-
option :agent
|
|
10
|
-
|
|
11
|
-
def call
|
|
12
|
-
debug { 'Propagating Onboarding to Credential...' }
|
|
13
|
-
raise "Expected Onboarding to be valid: #{onboarding.errors.full_messages.to_sentence}" if onboarding.invalid?
|
|
14
|
-
|
|
15
|
-
onboarding.transaction do
|
|
16
|
-
update_credential!
|
|
17
|
-
remove_existing_authenticators!
|
|
18
|
-
create_authenticator!
|
|
19
|
-
register_audit!
|
|
20
|
-
finalize_onboarding!
|
|
21
|
-
end
|
|
22
|
-
debug { 'Propagation of Onboarding completed' }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def update_credential!
|
|
28
|
-
onboarding.credential.update! mode: onboarding.mode,
|
|
29
|
-
password_digest: onboarding.password_digest,
|
|
30
|
-
otp_secret_key: onboarding.otp_secret_key
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def remove_existing_authenticators!
|
|
34
|
-
onboarding.credential.authenticators.destroy_all
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def create_authenticator!
|
|
38
|
-
return unless onboarding.authenticator?
|
|
39
|
-
|
|
40
|
-
onboarding.credential.authenticators.create! webauthn_id: onboarding.webauthn_id,
|
|
41
|
-
device_id: onboarding.authenticator_id,
|
|
42
|
-
nickname: onboarding.authenticator_nickname,
|
|
43
|
-
public_key: onboarding.authenticator_public_key,
|
|
44
|
-
sign_count: onboarding.authenticator_sign_count,
|
|
45
|
-
challenge: onboarding.authenticator_challenge,
|
|
46
|
-
supports_user_verification: onboarding.requires_user_verification?,
|
|
47
|
-
confirmed_at: Time.current
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def register_audit!
|
|
51
|
-
::Booth::Audits::Register::CompletedOnboarding.call(
|
|
52
|
-
credential: onboarding.credential,
|
|
53
|
-
ip:,
|
|
54
|
-
agent:
|
|
55
|
-
)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def finalize_onboarding!
|
|
59
|
-
onboarding.update! propagated_at: Time.current
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module Onboardings
|
|
3
|
-
class Step
|
|
4
|
-
include ::Booth::MethodObject
|
|
5
|
-
|
|
6
|
-
param :onboarding
|
|
7
|
-
|
|
8
|
-
def call
|
|
9
|
-
return :timed_out unless onboarding.recently_created?
|
|
10
|
-
|
|
11
|
-
if onboarding.mode_first_time?
|
|
12
|
-
mode_first_time
|
|
13
|
-
elsif onboarding.mode_username_and_password?
|
|
14
|
-
mode_username_and_password
|
|
15
|
-
elsif onboarding.mode_username_password_and_otp?
|
|
16
|
-
mode_username_password_and_otp
|
|
17
|
-
elsif onboarding.mode_username_password_and_webauth?
|
|
18
|
-
mode_username_password_and_webauth
|
|
19
|
-
elsif onboarding.mode_username_and_webauth?
|
|
20
|
-
mode_username_and_webauth
|
|
21
|
-
else
|
|
22
|
-
raise 'Invalid Onboarding State'
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def mode_first_time
|
|
29
|
-
:choose_mode
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def mode_username_and_password
|
|
33
|
-
return :choose_password if onboarding.password_chosen_at.blank?
|
|
34
|
-
return :completed if onboarding.password_confirmed_at.present?
|
|
35
|
-
|
|
36
|
-
:confirm_password
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def mode_username_password_and_otp
|
|
40
|
-
return mode_username_and_password unless mode_username_and_password == :completed
|
|
41
|
-
return :register_otp if onboarding.otp_registered_at.blank?
|
|
42
|
-
return :confirm_otp if onboarding.otp_confirmed_at.blank?
|
|
43
|
-
|
|
44
|
-
:completed
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def mode_username_password_and_webauth
|
|
48
|
-
return mode_username_and_password unless mode_username_and_password == :completed
|
|
49
|
-
|
|
50
|
-
mode_username_and_webauth
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def mode_username_and_webauth
|
|
54
|
-
return :register_webauth if onboarding.authenticator_id.blank? ||
|
|
55
|
-
onboarding.authenticator_public_key.blank? ||
|
|
56
|
-
onboarding.authenticator_sign_count.blank?
|
|
57
|
-
return :choose_webauth_nickname if onboarding.authenticator_nickname.blank?
|
|
58
|
-
return :confirm_webauth if onboarding.authenticator_confirmed_at.blank?
|
|
59
|
-
|
|
60
|
-
:completed
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def mode_unknown
|
|
64
|
-
:unknown
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
module Booth
|
|
2
|
-
module PasswordResets
|
|
3
|
-
class Create
|
|
4
|
-
include ::Booth::Logging
|
|
5
|
-
include ::Booth::MethodObject
|
|
6
|
-
|
|
7
|
-
option :credential
|
|
8
|
-
option :email
|
|
9
|
-
option :ip
|
|
10
|
-
option :agent
|
|
11
|
-
|
|
12
|
-
def call
|
|
13
|
-
do_check_applicability
|
|
14
|
-
.on_success { do_check_email_syntax }
|
|
15
|
-
.on_success { do_check_cooldown }
|
|
16
|
-
.on_success { do_create_password_reset }
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
def do_check_applicability
|
|
22
|
-
return Tron.success :credential_has_password if credential.applicable_for_password_reset?
|
|
23
|
-
|
|
24
|
-
debug { 'This credential has no password to be reset' }
|
|
25
|
-
Tron.failure :credential_cannot_reset_password, public_message: I18n.t('booth.password_reset_not_available')
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def do_check_email_syntax
|
|
29
|
-
check = ::Booth::Syntaxes::Email.call(email)
|
|
30
|
-
|
|
31
|
-
check.on_success do
|
|
32
|
-
@email_address = check.normalized_email
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
check
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def do_check_cooldown
|
|
39
|
-
::Booth::Cooldowns::PasswordReset.call(credential:)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def do_create_password_reset
|
|
43
|
-
password_reset = nil
|
|
44
|
-
|
|
45
|
-
::Booth::Models::PasswordReset.transaction do
|
|
46
|
-
password_reset = ::Booth::Models::PasswordReset.create! credential:, creator_ip: ip
|
|
47
|
-
::Booth::Audits::Register::RequestedPasswordReset.call credential:, ip:, agent:
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
Tron.success :applicable_for_reset, username: credential.username,
|
|
51
|
-
email: @email_address,
|
|
52
|
-
credential_id: credential.id,
|
|
53
|
-
secret_key: password_reset.secret_key
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|