plutonium 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.standard.yml +4 -0
- data/.vscode/extensions.json +15 -0
- data/.vscode/launch.json +7 -0
- data/.vscode/settings.json +35 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README copy.md +84 -0
- data/README.md +67 -0
- data/Rakefile +8 -0
- data/app/views/layouts/resource.html.erb +43 -0
- data/app/views/resource/_color_modes.html.erb +55 -0
- data/app/views/resource/_details.html.erb +6 -0
- data/app/views/resource/_empty_card.html.erb +12 -0
- data/app/views/resource/_flash.html.erb +9 -0
- data/app/views/resource/_form.html.erb +32 -0
- data/app/views/resource/_header.html.erb +8 -0
- data/app/views/resource/_interactive_resource_action_form.html.erb +67 -0
- data/app/views/resource/_messages.html.erb +1 -0
- data/app/views/resource/_metric_card.html.erb +16 -0
- data/app/views/resource/_nav_user.html.erb +4 -0
- data/app/views/resource/_pagination.html.erb +6 -0
- data/app/views/resource/_pagy_pagination.html.erb +15 -0
- data/app/views/resource/_resource.html.erb +1 -0
- data/app/views/resource/_resource.rabl +5 -0
- data/app/views/resource/_sidebar.html.erb +11 -0
- data/app/views/resource/_sidebar_menu.html.erb +1 -0
- data/app/views/resource/_tab_menu.html.erb +13 -0
- data/app/views/resource/_table.html.erb +78 -0
- data/app/views/resource/_table_actions.html.erb +15 -0
- data/app/views/resource/_toast.html.erb +26 -0
- data/app/views/resource/_toolbar.html.erb +22 -0
- data/app/views/resource/_toolbar_actions.html.erb +16 -0
- data/app/views/resource/_toolbar_breadcrumbs.html.erb +32 -0
- data/app/views/resource/_toolbar_search_input.erb +27 -0
- data/app/views/resource/edit.html.erb +10 -0
- data/app/views/resource/errors.rabl +3 -0
- data/app/views/resource/index.html.erb +19 -0
- data/app/views/resource/index.rabl +3 -0
- data/app/views/resource/interactive_resource_collection_action.html.erb +11 -0
- data/app/views/resource/interactive_resource_record_action.html.erb +11 -0
- data/app/views/resource/interactive_resource_recordless_action.html.erb +11 -0
- data/app/views/resource/new.html.erb +11 -0
- data/app/views/resource/readme.md +16 -0
- data/app/views/resource/show.html.erb +14 -0
- data/app/views/resource/show.rabl +3 -0
- data/brakeman.ignore +51 -0
- data/lib/active_model/validations/array_validator.rb +74 -0
- data/lib/active_model/validations/attached_validator.rb +17 -0
- data/lib/active_model/validations/url_validator.rb +51 -0
- data/lib/generators/pu/core/install/install_generator.rb +43 -0
- data/lib/generators/pu/core/install/templates/.keep +0 -0
- data/lib/generators/pu/core/install/templates/app/controllers/resource_controller.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/app/interactions/resource_interaction.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/app/models/resource_record.rb.tt +5 -0
- data/lib/generators/pu/core/install/templates/app/policies/resource_policy.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/app/presenters/resource_presenter.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +2 -0
- data/lib/generators/pu/core/install/templates/config/packages.rb +3 -0
- data/lib/generators/pu/gem/pagy/pagy_generator.rb +25 -0
- data/lib/generators/pu/gem/pagy/templates/.keep +0 -0
- data/lib/generators/pu/gem/pagy/templates/config/initializers/pagy.rb +4 -0
- data/lib/generators/pu/gem/rabl/rabl_generator.rb +25 -0
- data/lib/generators/pu/gem/rabl/templates/.keep +0 -0
- data/lib/generators/pu/gem/rabl/templates/config/initializers/rabl.rb +60 -0
- data/lib/generators/pu/gem/simple_form/simple_form_generator.rb +25 -0
- data/lib/generators/pu/gem/simple_form/templates/.keep +0 -0
- data/lib/generators/pu/gen/pug/pug_generator.rb +43 -0
- data/lib/generators/pu/gen/pug/templates/pug.rb.tt +23 -0
- data/lib/generators/pu/pkg/app/app_generator.rb +60 -0
- data/lib/generators/pu/pkg/app/templates/app/controllers/resource_controller.rb.tt +26 -0
- data/lib/generators/pu/pkg/app/templates/app/interactions/resource_interaction.rb.tt +4 -0
- data/lib/generators/pu/pkg/app/templates/app/policies/resource_policy.rb.tt +4 -0
- data/lib/generators/pu/pkg/app/templates/app/presenters/resource_presenter.rb.tt +4 -0
- data/lib/generators/pu/pkg/app/templates/config/routes.rb.tt +17 -0
- data/lib/generators/pu/pkg/app/templates/lib/engine.rb.tt +14 -0
- data/lib/generators/pu/pkg/feature/feature_generator.rb +44 -0
- data/lib/generators/pu/pkg/feature/templates/.keep +0 -0
- data/lib/generators/pu/pkg/feature/templates/app/controllers/resource_controller.rb.tt +7 -0
- data/lib/generators/pu/pkg/feature/templates/app/interactions/resource_interaction.rb.tt +4 -0
- data/lib/generators/pu/pkg/feature/templates/app/models/resource_record.rb.tt +5 -0
- data/lib/generators/pu/pkg/feature/templates/app/policies/resource_policy.rb.tt +4 -0
- data/lib/generators/pu/pkg/feature/templates/app/presenters/resource_presenter.rb.tt +4 -0
- data/lib/generators/pu/pkg/feature/templates/lib/engine.rb.tt +8 -0
- data/lib/generators/pu/resource/conn/conn_generator.rb +54 -0
- data/lib/generators/pu/resource/conn/templates/.keep +0 -0
- data/lib/generators/pu/resource/conn/templates/app/controllers/resource_controller.rb.tt +3 -0
- data/lib/generators/pu/resource/conn/templates/app/policies/resource_policy.rb.tt +3 -0
- data/lib/generators/pu/resource/conn/templates/app/presenters/resource_presenter.rb.tt +3 -0
- data/lib/generators/pu/resource/model/USAGE +113 -0
- data/lib/generators/pu/resource/model/model_generator.rb +163 -0
- data/lib/generators/pu/resource/model/templates/controller.rb.tt +5 -0
- data/lib/generators/pu/resource/model/templates/create_table_migration.rb.tt +26 -0
- data/lib/generators/pu/resource/model/templates/model.rb.tt +53 -0
- data/lib/generators/pu/resource/model/templates/module.rb.tt +7 -0
- data/lib/generators/pu/resource/model/templates/policy.rb.tt +4 -0
- data/lib/generators/pu/resource/model/templates/presenter.rb.tt +4 -0
- data/lib/generators/pu/resource/scaffold/scaffold_generator.rb +219 -0
- data/lib/generators/pu/resource/scaffold/templates/app/controllers/admin_resources/resource_controller.rb.tt +7 -0
- data/lib/generators/pu/resource/scaffold/templates/app/controllers/entity_resources/resource_controller.rb.tt +7 -0
- data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/admin/resource_policy.rb.tt +22 -0
- data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/entity/resource_policy.rb.tt +22 -0
- data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/resource_policy.rb.tt +13 -0
- data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/admin_presenter.rb.tt +7 -0
- data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/entity_presenter.rb.tt +7 -0
- data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/presenter.rb.tt +23 -0
- data/lib/generators/pu/resource/scaffold/templates/app/views/resources/resource/_resource.html.erb.tt +3 -0
- data/lib/generators/pu/resource/scaffold/templates/app/views/resources/resource/_resource.rabl +7 -0
- data/lib/generators/pu/rodauth/account_generator.rb +120 -0
- data/lib/generators/pu/rodauth/concerns/account_selector.rb +22 -0
- data/lib/generators/pu/rodauth/concerns/configuration.rb +211 -0
- data/lib/generators/pu/rodauth/concerns/feature_selector.rb +125 -0
- data/lib/generators/pu/rodauth/install_generator.rb +69 -0
- data/lib/generators/pu/rodauth/migration/active_record/account_expiration.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/active_sessions.erb +7 -0
- data/lib/generators/pu/rodauth/migration/active_record/audit_logging.erb +16 -0
- data/lib/generators/pu/rodauth/migration/active_record/base.erb +22 -0
- data/lib/generators/pu/rodauth/migration/active_record/disallow_password_reuse.erb +5 -0
- data/lib/generators/pu/rodauth/migration/active_record/email_auth.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/jwt_refresh.erb +7 -0
- data/lib/generators/pu/rodauth/migration/active_record/lockout.erb +13 -0
- data/lib/generators/pu/rodauth/migration/active_record/otp.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/password_expiration.erb +6 -0
- data/lib/generators/pu/rodauth/migration/active_record/recovery_codes.erb +6 -0
- data/lib/generators/pu/rodauth/migration/active_record/remember.erb +7 -0
- data/lib/generators/pu/rodauth/migration/active_record/reset_password.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/separate_passwords.erb +5 -0
- data/lib/generators/pu/rodauth/migration/active_record/single_session.erb +6 -0
- data/lib/generators/pu/rodauth/migration/active_record/sms_codes.erb +9 -0
- data/lib/generators/pu/rodauth/migration/active_record/verify_account.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/verify_login_change.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/webauthn.erb +13 -0
- data/lib/generators/pu/rodauth/migration/sequel/account_expiration.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/active_sessions.erb +8 -0
- data/lib/generators/pu/rodauth/migration/sequel/audit_logging.erb +17 -0
- data/lib/generators/pu/rodauth/migration/sequel/base.erb +25 -0
- data/lib/generators/pu/rodauth/migration/sequel/disallow_password_reuse.erb +6 -0
- data/lib/generators/pu/rodauth/migration/sequel/email_auth.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/jwt_refresh.erb +8 -0
- data/lib/generators/pu/rodauth/migration/sequel/lockout.erb +11 -0
- data/lib/generators/pu/rodauth/migration/sequel/otp.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/password_expiration.erb +5 -0
- data/lib/generators/pu/rodauth/migration/sequel/recovery_codes.erb +6 -0
- data/lib/generators/pu/rodauth/migration/sequel/remember.erb +6 -0
- data/lib/generators/pu/rodauth/migration/sequel/reset_password.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/separate_passwords.erb +6 -0
- data/lib/generators/pu/rodauth/migration/sequel/single_session.erb +5 -0
- data/lib/generators/pu/rodauth/migration/sequel/sms_codes.erb +8 -0
- data/lib/generators/pu/rodauth/migration/sequel/verify_account.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/verify_login_change.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/webauthn.erb +13 -0
- data/lib/generators/pu/rodauth/migration_generator.rb +190 -0
- data/lib/generators/pu/rodauth/templates/INSTRUCTIONS +52 -0
- data/lib/generators/pu/rodauth/templates/app/controllers/plugin_controller.rb.tt +6 -0
- data/lib/generators/pu/rodauth/templates/app/controllers/rodauth_controller.rb.tt +3 -0
- data/lib/generators/pu/rodauth/templates/app/mailers/account_mailer.rb.tt +4 -0
- data/lib/generators/pu/rodauth/templates/app/mailers/rodauth_mailer.rb.tt +62 -0
- data/lib/generators/pu/rodauth/templates/app/misc/account_rodauth_plugin.rb.tt +255 -0
- data/lib/generators/pu/rodauth/templates/app/misc/rodauth_app.rb.tt +24 -0
- data/lib/generators/pu/rodauth/templates/app/misc/rodauth_plugin.rb.tt +234 -0
- data/lib/generators/pu/rodauth/templates/app/models/account.rb.tt +40 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/_email_auth_request_form.html.erb +7 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/_login_form.html.erb +26 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/_login_form_footer.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/add_recovery_codes.html.erb +6 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/change_login.html.erb +27 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/change_password.html.erb +27 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/close_account.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/confirm_password.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/create_account.html.erb +35 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/email_auth.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/login.html.erb +4 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/logout.html.erb +14 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +3 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_auth.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_disable.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_setup.html.erb +41 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/recovery_auth.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/recovery_codes.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/remember.html.erb +22 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/reset_password.html.erb +19 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/reset_password_request.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_auth.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_confirm.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_disable.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_request.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_setup.html.erb +23 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_email_auth_request_form.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_login_form.html.erb +24 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_login_form_footer.html.erb +7 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/add_recovery_codes.html.erb +16 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/change_login.html.erb +25 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/change_password.html.erb +25 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/close_account.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/confirm_password.html.erb +19 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/create_account.html.erb +33 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/email_auth.html.erb +3 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/login.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/logout.html.erb +10 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/multi_phase_login.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_auth.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_disable.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_setup.html.erb +32 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/recovery_auth.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/recovery_codes.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/remember.html.erb +18 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/reset_password.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/reset_password_request.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_auth.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_confirm.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_disable.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_request.html.erb +3 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_setup.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_auth.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_disable.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_manage.html.erb +26 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/unlock_account.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/unlock_account_request.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_account.html.erb +19 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_account_resend.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_login_change.html.erb +3 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_auth.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_autofill.html.erb +10 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_remove.html.erb +21 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_setup.html.erb +21 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_auth.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_disable.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_manage.html.erb +22 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/unlock_account.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/unlock_account_request.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_account.html.erb +21 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_account_resend.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_login_change.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_auth.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_autofill.html.erb +10 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_remove.html.erb +23 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_setup.html.erb +23 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/email_auth.text.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/password_changed.text.erb +2 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/reset_password.text.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/reset_password_notify.text.erb +2 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/verify_account.text.erb +4 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/verify_login_change.text.erb +10 -0
- data/lib/generators/pu/rodauth/templates/config/initializers/rodauth.rb.tt +3 -0
- data/lib/generators/pu/rodauth/templates/db/migrate/create_rodauth.rb.tt +13 -0
- data/lib/generators/pu/rodauth/views_generator.rb +125 -0
- data/lib/plutonium/auth/public_access.rb +17 -0
- data/lib/plutonium/auth/rodauth.rb +35 -0
- data/lib/plutonium/auth.rb +12 -0
- data/lib/plutonium/config.rb +11 -0
- data/lib/plutonium/core/.DS_Store +0 -0
- data/lib/plutonium/core/action.rb +46 -0
- data/lib/plutonium/core/actions/basic_action.rb +16 -0
- data/lib/plutonium/core/actions/collection.rb +33 -0
- data/lib/plutonium/core/actions/destroy_action.rb +21 -0
- data/lib/plutonium/core/actions/edit_action.rb +19 -0
- data/lib/plutonium/core/actions/interactive_action.rb +64 -0
- data/lib/plutonium/core/actions/new_action.rb +18 -0
- data/lib/plutonium/core/actions/show_action.rb +17 -0
- data/lib/plutonium/core/actions.rb +17 -0
- data/lib/plutonium/core/app_controller.rb +121 -0
- data/lib/plutonium/core/autodiscovery/discoverer.rb +15 -0
- data/lib/plutonium/core/autodiscovery/input_discoverer.rb +33 -0
- data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +33 -0
- data/lib/plutonium/core/autodiscovery.rb +13 -0
- data/lib/plutonium/core/controllers/authorizable.rb +56 -0
- data/lib/plutonium/core/controllers/bootable.rb +44 -0
- data/lib/plutonium/core/controllers/crud_actions.rb +128 -0
- data/lib/plutonium/core/controllers/entity_scoping.rb +69 -0
- data/lib/plutonium/core/controllers/interactive_actions.rb +210 -0
- data/lib/plutonium/core/controllers/presentable.rb +59 -0
- data/lib/plutonium/core/controllers.rb +16 -0
- data/lib/plutonium/core/definers/action_definer.rb +25 -0
- data/lib/plutonium/core/definers/field_definer.rb +19 -0
- data/lib/plutonium/core/definers/input_definer.rb +37 -0
- data/lib/plutonium/core/definers/renderer_definer.rb +35 -0
- data/lib/plutonium/core/definers.rb +14 -0
- data/lib/plutonium/core/fields/inputs/association_input.rb +26 -0
- data/lib/plutonium/core/fields/inputs/basic_input.rb +42 -0
- data/lib/plutonium/core/fields/inputs/belongs_to_input.rb +15 -0
- data/lib/plutonium/core/fields/inputs/factory.rb +58 -0
- data/lib/plutonium/core/fields/inputs/has_many_input.rb +15 -0
- data/lib/plutonium/core/fields/inputs/noop_input.rb +19 -0
- data/lib/plutonium/core/fields/inputs.rb +18 -0
- data/lib/plutonium/core/fields/renderers/association_renderer.rb +25 -0
- data/lib/plutonium/core/fields/renderers/basic_renderer.rb +27 -0
- data/lib/plutonium/core/fields/renderers/factory.rb +52 -0
- data/lib/plutonium/core/fields/renderers.rb +15 -0
- data/lib/plutonium/core/fields.rb +12 -0
- data/lib/plutonium/core/ui/collection.rb +14 -0
- data/lib/plutonium/core/ui/detail.rb +11 -0
- data/lib/plutonium/core/ui/form.rb +11 -0
- data/lib/plutonium/core/ui.rb +13 -0
- data/lib/plutonium/core.rb +16 -0
- data/lib/plutonium/helpers/action_buttons_helper.rb +32 -0
- data/lib/plutonium/helpers/application_helper.rb +22 -0
- data/lib/plutonium/helpers/attachment_helper.rb +62 -0
- data/lib/plutonium/helpers/content_helper.rb +66 -0
- data/lib/plutonium/helpers/display_helper.rb +83 -0
- data/lib/plutonium/helpers/form_helper.rb +24 -0
- data/lib/plutonium/helpers/menu_helper.rb +69 -0
- data/lib/plutonium/helpers/pagination_helper.rb +9 -0
- data/lib/plutonium/helpers/turbo_helper.rb +13 -0
- data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +9 -0
- data/lib/plutonium/helpers.rb +31 -0
- data/lib/plutonium/initializers/TODO +2 -0
- data/lib/plutonium/initializers/pagy.rb +5 -0
- data/lib/plutonium/initializers/patches.rb +2 -0
- data/lib/plutonium/initializers/rabl.rb +60 -0
- data/lib/plutonium/initializers/simple_form.rb +405 -0
- data/lib/plutonium/lib/after_commit.rb +34 -0
- data/lib/plutonium/lib/bit_flags.rb +36 -0
- data/lib/plutonium/packaging/app.rb +125 -0
- data/lib/plutonium/packaging/feature.rb +18 -0
- data/lib/plutonium/packaging/package.rb +22 -0
- data/lib/plutonium/packaging.rb +9 -0
- data/lib/plutonium/policy/initializer.rb +22 -0
- data/lib/plutonium/policy/scope.rb +19 -0
- data/lib/plutonium/policy.rb +8 -0
- data/lib/plutonium/preserved__/field.rb +65 -0
- data/lib/plutonium/preserved__/input.rb +93 -0
- data/lib/plutonium/reactor/core.rb +61 -0
- data/lib/plutonium/reactor/resource_context.rb +15 -0
- data/lib/plutonium/reactor/resource_controller.rb +108 -0
- data/lib/plutonium/reactor/resource_interaction.rb +8 -0
- data/lib/plutonium/reactor/resource_policy.rb +105 -0
- data/lib/plutonium/reactor/resource_presenter.rb +42 -0
- data/lib/plutonium/reactor/resource_record.rb +123 -0
- data/lib/plutonium/reactor.rb +13 -0
- data/lib/plutonium/refinements/parameter_refinements.rb +26 -0
- data/lib/plutonium/simple_form_components/attachment_component.rb +77 -0
- data/lib/plutonium/simple_form_components/input_group_component.rb +14 -0
- data/lib/plutonium/version.rb +3 -0
- data/lib/plutonium.rb +31 -0
- data/plutonium.gemspec +47 -0
- data/public/.keep +0 -0
- data/public/plutonium-assets/application.css +24280 -0
- data/public/plutonium-assets/application.js +31420 -0
- data/public/plutonium-assets/fonts/bootstrap-icons.woff +0 -0
- data/public/plutonium-assets/fonts/bootstrap-icons.woff2 +0 -0
- data/public/plutonium-assets/logo.png +0 -0
- data/sig/plutonium.rbs +4 -0
- metadata +519 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
require "sequel/core"
|
|
2
|
+
|
|
3
|
+
class <%= table_prefix.classify %>RodauthPlugin < RodauthPlugin
|
|
4
|
+
configure do
|
|
5
|
+
# This block is running inside of
|
|
6
|
+
# plugin :rodauth do
|
|
7
|
+
# ...
|
|
8
|
+
# end
|
|
9
|
+
|
|
10
|
+
# ==> Features
|
|
11
|
+
# See the Rodauth documentation for the list of available config options:
|
|
12
|
+
# http://rodauth.jeremyevans.net/documentation.html
|
|
13
|
+
|
|
14
|
+
# List of authentication features that are loaded.
|
|
15
|
+
enable <%= selected_features.map(&:inspect).join ', ' %>
|
|
16
|
+
|
|
17
|
+
# ==> General
|
|
18
|
+
|
|
19
|
+
# Change prefix of table and foreign key column names from default "account"
|
|
20
|
+
# accounts_table: 'players'
|
|
21
|
+
|
|
22
|
+
# The secret key used for hashing public-facing tokens for various features.
|
|
23
|
+
# Defaults to Rails `secret_key_base`, but you can use your own secret key.
|
|
24
|
+
# hmac_secret "<SECRET_KEY>"
|
|
25
|
+
|
|
26
|
+
# Use path prefix for all routes.
|
|
27
|
+
<%= '# ' if primary? %>prefix "/<%= table_prefix.pluralize %>"
|
|
28
|
+
<% unless separate_passwords? -%>
|
|
29
|
+
|
|
30
|
+
# Store password hash in a column instead of a separate table.
|
|
31
|
+
account_password_hash_column :password_hash
|
|
32
|
+
<% end -%>
|
|
33
|
+
|
|
34
|
+
# Specify the controller used for view rendering, CSRF, and callbacks.
|
|
35
|
+
rails_controller { Rodauth::<%= "#{table_prefix.classify}" %>Controller }
|
|
36
|
+
<% if verify_account? -%>
|
|
37
|
+
|
|
38
|
+
# Set password when verifying account.
|
|
39
|
+
verify_account_set_password? false
|
|
40
|
+
<% end -%>
|
|
41
|
+
|
|
42
|
+
# Change some default param keys.
|
|
43
|
+
# login_param "email"
|
|
44
|
+
# password_confirm_param "confirm_password"
|
|
45
|
+
|
|
46
|
+
# Redirect back to originally requested location after authentication.
|
|
47
|
+
# login_return_to_requested_location? true
|
|
48
|
+
# two_factor_auth_return_to_requested_location? true # if using MFA
|
|
49
|
+
|
|
50
|
+
# Autologin the user after they have reset their password.
|
|
51
|
+
# reset_password_autologin? true
|
|
52
|
+
|
|
53
|
+
# Delete the account record when the user has closed their account.
|
|
54
|
+
# delete_account_on_close? true
|
|
55
|
+
|
|
56
|
+
# Redirect to the app from login and registration pages if already logged in.
|
|
57
|
+
# already_logged_in { redirect login_redirect }
|
|
58
|
+
<% if jwt? -%>
|
|
59
|
+
|
|
60
|
+
# ==> JWT
|
|
61
|
+
|
|
62
|
+
# Set JWT secret, which is used to cryptographically protect the token.
|
|
63
|
+
jwt_secret Rails.application.credentials.secret_key_base
|
|
64
|
+
<% end -%>
|
|
65
|
+
<% if only_json? -%>
|
|
66
|
+
|
|
67
|
+
# ==> Api only
|
|
68
|
+
|
|
69
|
+
# Accept only JSON requests.
|
|
70
|
+
only_json? true
|
|
71
|
+
|
|
72
|
+
# Handle login and password confirmation fields on the client side.
|
|
73
|
+
require_password_confirmation? false
|
|
74
|
+
require_login_confirmation? false
|
|
75
|
+
<% else -%>
|
|
76
|
+
|
|
77
|
+
# Accept both api and form requests
|
|
78
|
+
# Requires the JSON feature
|
|
79
|
+
<%= '# ' unless json? %>only_json? false
|
|
80
|
+
<% end -%>
|
|
81
|
+
<% if mails? -%>
|
|
82
|
+
|
|
83
|
+
# ==> Emails
|
|
84
|
+
# Use a custom mailer for delivering authentication emails.
|
|
85
|
+
<% if reset_password? -%>
|
|
86
|
+
|
|
87
|
+
create_reset_password_email do
|
|
88
|
+
Rodauth::<%= table_prefix.classify %>Mailer.reset_password(self.class.configuration_name, account_id, reset_password_key_value)
|
|
89
|
+
end
|
|
90
|
+
<% end -%>
|
|
91
|
+
<% if verify_account? -%>
|
|
92
|
+
|
|
93
|
+
create_verify_account_email do
|
|
94
|
+
Rodauth::<%= table_prefix.classify %>Mailer.verify_account(self.class.configuration_name, account_id, verify_account_key_value)
|
|
95
|
+
end
|
|
96
|
+
<% end -%>
|
|
97
|
+
<% if verify_login_change? -%>
|
|
98
|
+
|
|
99
|
+
create_verify_login_change_email do |_login|
|
|
100
|
+
Rodauth::<%= table_prefix.classify %>Mailer.verify_login_change(self.class.configuration_name, account_id, verify_login_change_key_value)
|
|
101
|
+
end
|
|
102
|
+
<% end -%>
|
|
103
|
+
<% if change_password_notify? -%>
|
|
104
|
+
|
|
105
|
+
create_password_changed_email do
|
|
106
|
+
Rodauth::<%= table_prefix.classify %>Mailer.change_password_notify(self.class.configuration_name, account_id)
|
|
107
|
+
end
|
|
108
|
+
<% end -%>
|
|
109
|
+
<% if reset_password_notify? -%>
|
|
110
|
+
|
|
111
|
+
create_reset_password_notify_email do
|
|
112
|
+
Rodauth::<%= table_prefix.classify %>Mailer.reset_password_notify(self.class.configuration_name, account_id)
|
|
113
|
+
end
|
|
114
|
+
<% end -%>
|
|
115
|
+
<% if email_auth? -%>
|
|
116
|
+
|
|
117
|
+
create_email_auth_email do
|
|
118
|
+
Rodauth::<%= table_prefix.classify %>Mailer.email_auth(self.class.configuration_name, account_id, email_auth_key_value)
|
|
119
|
+
end
|
|
120
|
+
<% end -%>
|
|
121
|
+
<% if lockout? -%>
|
|
122
|
+
|
|
123
|
+
create_unlock_account_email do
|
|
124
|
+
Rodauth::<%= table_prefix.classify %>Mailer.unlock_account(self.class.configuration_name, account_id, unlock_account_key_value)
|
|
125
|
+
end
|
|
126
|
+
<% end -%>
|
|
127
|
+
|
|
128
|
+
send_email do |email|
|
|
129
|
+
# queue email delivery on the mailer after the transaction commits
|
|
130
|
+
db.after_commit { email.deliver_later }
|
|
131
|
+
end
|
|
132
|
+
<% end -%>
|
|
133
|
+
<% unless only_json? -%>
|
|
134
|
+
|
|
135
|
+
# ==> Flash
|
|
136
|
+
# Does not work with only_json?
|
|
137
|
+
|
|
138
|
+
# Match flash keys with ones already used in the Rails app.
|
|
139
|
+
# flash_notice_key :success # default is :notice
|
|
140
|
+
# flash_error_key :error # default is :alert
|
|
141
|
+
|
|
142
|
+
# Override default flash messages.
|
|
143
|
+
# create_account_notice_flash "Your account has been created. Please verify your account by visiting the confirmation link sent to your email address."
|
|
144
|
+
# require_login_error_flash "Login is required for accessing this page"
|
|
145
|
+
# login_notice_flash nil
|
|
146
|
+
<% end -%>
|
|
147
|
+
|
|
148
|
+
# ==> Validation
|
|
149
|
+
# Override default validation error messages.
|
|
150
|
+
# no_matching_login_message "user with this email address doesn't exist"
|
|
151
|
+
# already_an_account_with_this_login_message "user with this email address already exists"
|
|
152
|
+
# password_too_short_message { "needs to have at least #{password_minimum_length} characters" }
|
|
153
|
+
# login_does_not_meet_requirements_message { "invalid email#{", #{login_requirement_message}" if login_requirement_message}" }
|
|
154
|
+
|
|
155
|
+
# ==> Passwords
|
|
156
|
+
|
|
157
|
+
# Passwords shorter than 8 characters are considered weak according to OWASP.
|
|
158
|
+
<%= '# ' unless login? %>password_minimum_length 8
|
|
159
|
+
|
|
160
|
+
# Custom password complexity requirements (alternative to password_complexity feature).
|
|
161
|
+
# password_meets_requirements? do |password|
|
|
162
|
+
# super(password) && password_complex_enough?(password)
|
|
163
|
+
# end
|
|
164
|
+
# auth_class_eval do
|
|
165
|
+
# def password_complex_enough?(password)
|
|
166
|
+
# return true if password.match?(/\d/) && password.match?(/[^a-zA-Z\d]/)
|
|
167
|
+
# set_password_requirement_error_message(:password_simple, "requires one number and one special character")
|
|
168
|
+
# false
|
|
169
|
+
# end
|
|
170
|
+
# end
|
|
171
|
+
<% unless argon2? -%>
|
|
172
|
+
|
|
173
|
+
# = bcrypt
|
|
174
|
+
|
|
175
|
+
# bcrypt has a maximum input length of 72 bytes, truncating any extra bytes.
|
|
176
|
+
password_maximum_bytes 72 if respond_to?(:password_maximum_bytes)
|
|
177
|
+
<% else -%>
|
|
178
|
+
|
|
179
|
+
# = argon2
|
|
180
|
+
|
|
181
|
+
# Use a rotatable password pepper when hashing passwords with Argon2.
|
|
182
|
+
argon2_secret "TODO: <SECRET_KEY>"
|
|
183
|
+
|
|
184
|
+
# Since we're using argon2, prevent loading the bcrypt gem to save memory.
|
|
185
|
+
require_bcrypt? false
|
|
186
|
+
|
|
187
|
+
# Having a maximum password length set prevents long password DoS attacks.
|
|
188
|
+
password_maximum_length 64 if respond_to?(:password_maximum_length)
|
|
189
|
+
<% end -%>
|
|
190
|
+
<% if remember? -%>
|
|
191
|
+
|
|
192
|
+
# ==> Remember Feature
|
|
193
|
+
|
|
194
|
+
# Remember all logged in users.
|
|
195
|
+
after_login { remember_login }
|
|
196
|
+
|
|
197
|
+
# Or only remember users that have ticked a "Remember Me" checkbox on login.
|
|
198
|
+
# after_login { remember_login if param_or_nil("remember") }
|
|
199
|
+
|
|
200
|
+
# Extend user's remember period when remembered via a cookie
|
|
201
|
+
extend_remember_deadline? true
|
|
202
|
+
|
|
203
|
+
# Store the user's remember cookie under a namespace
|
|
204
|
+
remember_cookie_key "_<%= table_prefix %>_remember"
|
|
205
|
+
<% end -%>
|
|
206
|
+
|
|
207
|
+
# ==> Hooks
|
|
208
|
+
|
|
209
|
+
# Validate custom fields in the create account form.
|
|
210
|
+
# before_create_account do
|
|
211
|
+
# throw_error_status(422, "name", "must be present") if param("name").empty?
|
|
212
|
+
# end
|
|
213
|
+
|
|
214
|
+
# Perform additional actions after the account is created.
|
|
215
|
+
# after_create_account do
|
|
216
|
+
# Profile.create!(account_id: account_id, name: param("name"))
|
|
217
|
+
# end
|
|
218
|
+
|
|
219
|
+
# Do additional cleanup after the account is closed.
|
|
220
|
+
# after_close_account do
|
|
221
|
+
# Profile.find_by!(account_id: account_id).destroy
|
|
222
|
+
# end
|
|
223
|
+
<% unless only_json? -%>
|
|
224
|
+
|
|
225
|
+
# ==> Redirects
|
|
226
|
+
<% if logout? -%>
|
|
227
|
+
|
|
228
|
+
# Redirect to home page after logout.
|
|
229
|
+
logout_redirect "/"
|
|
230
|
+
<% end -%>
|
|
231
|
+
<% if verify_account? -%>
|
|
232
|
+
|
|
233
|
+
# Redirect to wherever login redirects to after account verification.
|
|
234
|
+
verify_account_redirect { login_redirect }
|
|
235
|
+
<% end -%>
|
|
236
|
+
<% if reset_password? -%>
|
|
237
|
+
|
|
238
|
+
# Redirect to login page after password reset.
|
|
239
|
+
reset_password_redirect { login_path }
|
|
240
|
+
<% end -%>
|
|
241
|
+
|
|
242
|
+
# Ensure requiring login follows login route changes.
|
|
243
|
+
require_login_redirect { login_path }
|
|
244
|
+
<% end -%>
|
|
245
|
+
|
|
246
|
+
# ==> Deadlines
|
|
247
|
+
# Change default deadlines for some actions.
|
|
248
|
+
# verify_account_grace_period 3.days.to_i
|
|
249
|
+
# reset_password_deadline_interval Hash[hours: 6]
|
|
250
|
+
# verify_login_change_deadline_interval Hash[days: 2]
|
|
251
|
+
<% unless only_json? -%>
|
|
252
|
+
# remember_deadline_interval Hash[days: 30]
|
|
253
|
+
<% end -%>
|
|
254
|
+
end
|
|
255
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class RodauthApp < Rodauth::Rails::App
|
|
2
|
+
# auth configuration
|
|
3
|
+
# configure RodauthMain
|
|
4
|
+
|
|
5
|
+
route do |r|
|
|
6
|
+
# this block is running inside of a roda route
|
|
7
|
+
# see https://github.com/jeremyevans/roda#usage-
|
|
8
|
+
|
|
9
|
+
# auth route configuration
|
|
10
|
+
# r.rodauth
|
|
11
|
+
|
|
12
|
+
# plugin route configuration
|
|
13
|
+
# rodauth.load_memory # autologin remembered users
|
|
14
|
+
|
|
15
|
+
# ==> Authenticating requests
|
|
16
|
+
# Call `rodauth.require_account` for requests that you want to
|
|
17
|
+
# require authentication for. For example:
|
|
18
|
+
#
|
|
19
|
+
# # authenticate /dashboard/* and /account/* requests
|
|
20
|
+
# if r.path.start_with?("/dashboard") || r.path.start_with?("/account")
|
|
21
|
+
# rodauth.require_account
|
|
22
|
+
# end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
require "sequel/core"
|
|
2
|
+
|
|
3
|
+
class RodauthPlugin < Rodauth::Rails::Auth
|
|
4
|
+
configure do
|
|
5
|
+
# ==> Features
|
|
6
|
+
# See the Rodauth documentation for the list of available config options:
|
|
7
|
+
# http://rodauth.jeremyevans.net/documentation.html
|
|
8
|
+
|
|
9
|
+
# List of authentication features that are loaded.
|
|
10
|
+
# enable :create_account, :verify_account, :verify_account_grace_period,
|
|
11
|
+
# :reset_password, :change_password, :change_password_notify,
|
|
12
|
+
# :login, :logout, :remember, :change_login, :verify_login_change, :close_account,
|
|
13
|
+
# :json, :jwt
|
|
14
|
+
|
|
15
|
+
# ==> General
|
|
16
|
+
|
|
17
|
+
<% if sequel_activerecord_integration? -%>
|
|
18
|
+
# Initialize Sequel and have it reuse Active Record's database connection.
|
|
19
|
+
<% if RUBY_ENGINE == "jruby" -%>
|
|
20
|
+
db Sequel.connect("jdbc:<%= sequel_adapter %>://", extensions: :activerecord_connection, keep_reference: false)
|
|
21
|
+
<% else -%>
|
|
22
|
+
db Sequel.<%= sequel_adapter %>(extensions: :activerecord_connection, keep_reference: false)
|
|
23
|
+
<% end -%>
|
|
24
|
+
|
|
25
|
+
# Prevent rodauth from introspecting the database if we are not using UUIDs
|
|
26
|
+
# https://github.com/janko/rodauth-rails/issues/244
|
|
27
|
+
convert_token_id_to_integer? true
|
|
28
|
+
|
|
29
|
+
<% end -%>
|
|
30
|
+
# Change prefix of table and foreign key column names from default "account"
|
|
31
|
+
# accounts_table :users
|
|
32
|
+
# verify_account_table :user_verification_keys
|
|
33
|
+
# verify_login_change_table :user_login_change_keys
|
|
34
|
+
# reset_password_table :user_password_reset_keys
|
|
35
|
+
# remember_table :user_remember_keys
|
|
36
|
+
|
|
37
|
+
# The secret key used for hashing public-facing tokens for various features.
|
|
38
|
+
# Defaults to Rails `secret_key_base`, but you can use your own secret key.
|
|
39
|
+
# hmac_secret "<SECRET_KEY>"
|
|
40
|
+
|
|
41
|
+
# Use path prefix for all routes.
|
|
42
|
+
# prefix "/accounts"
|
|
43
|
+
|
|
44
|
+
# Specify the controller used for view rendering, CSRF, and callbacks.
|
|
45
|
+
# rails_controller { RodauthController }
|
|
46
|
+
|
|
47
|
+
# Set in Rodauth controller instance with the title of the current page.
|
|
48
|
+
title_instance_variable :@page_title
|
|
49
|
+
|
|
50
|
+
# Store account status in an integer column without foreign key constraint.
|
|
51
|
+
account_status_column :status
|
|
52
|
+
|
|
53
|
+
# Set password when verifying account.
|
|
54
|
+
# verify_account_set_password? false
|
|
55
|
+
|
|
56
|
+
# Change some default param keys/labels.
|
|
57
|
+
login_label "Email"
|
|
58
|
+
login_param "email"
|
|
59
|
+
# password_confirm_param "confirm_password"
|
|
60
|
+
|
|
61
|
+
# Redirect back to originally requested location after authentication.
|
|
62
|
+
# login_return_to_requested_location? true
|
|
63
|
+
# two_factor_auth_return_to_requested_location? true # if using MFA
|
|
64
|
+
|
|
65
|
+
# Autologin the user after they have reset their password.
|
|
66
|
+
# reset_password_autologin? true
|
|
67
|
+
|
|
68
|
+
# Delete the account record when the user has closed their account.
|
|
69
|
+
# delete_account_on_close? true
|
|
70
|
+
|
|
71
|
+
# Redirect to the app from login and registration pages if already logged in.
|
|
72
|
+
# already_logged_in { redirect login_redirect }
|
|
73
|
+
|
|
74
|
+
# ==> JWT
|
|
75
|
+
|
|
76
|
+
# Set JWT secret, which is used to cryptographically protect the token.
|
|
77
|
+
# jwt_secret Rails.application.credentials.secret_key_base
|
|
78
|
+
|
|
79
|
+
# ==> Api only
|
|
80
|
+
|
|
81
|
+
# Accept only JSON requests.
|
|
82
|
+
# Requires the JSON feature
|
|
83
|
+
# only_json? true
|
|
84
|
+
|
|
85
|
+
# Handle login and password confirmation fields on the client side.
|
|
86
|
+
# require_password_confirmation? false
|
|
87
|
+
# require_login_confirmation? false
|
|
88
|
+
|
|
89
|
+
# ==> Emails
|
|
90
|
+
# Use a custom mailer for delivering authentication emails.
|
|
91
|
+
# Requires ActionMailer
|
|
92
|
+
|
|
93
|
+
# create_reset_password_email do
|
|
94
|
+
# RodauthMailer.reset_password(self.class.configuration_name, account_id, reset_password_key_value)
|
|
95
|
+
# end
|
|
96
|
+
|
|
97
|
+
# create_verify_account_email do
|
|
98
|
+
# RodauthMailer.verify_account(self.class.configuration_name, account_id, verify_account_key_value)
|
|
99
|
+
# end
|
|
100
|
+
|
|
101
|
+
# create_verify_login_change_email do |_login|
|
|
102
|
+
# RodauthMailer.verify_login_change(self.class.configuration_name, account_id, verify_login_change_key_value)
|
|
103
|
+
# end
|
|
104
|
+
|
|
105
|
+
# create_password_changed_email do
|
|
106
|
+
# RodauthMailer.change_password_notify(self.class.configuration_name, account_id)
|
|
107
|
+
# end
|
|
108
|
+
|
|
109
|
+
# create_reset_password_notify_email do
|
|
110
|
+
# RodauthMailer.reset_password_notify(self.class.configuration_name, account_id)
|
|
111
|
+
# end
|
|
112
|
+
|
|
113
|
+
# create_email_auth_email do
|
|
114
|
+
# RodauthMailer.email_auth(self.class.configuration_name, account_id, email_auth_key_value)
|
|
115
|
+
# end
|
|
116
|
+
|
|
117
|
+
# create_unlock_account_email do
|
|
118
|
+
# RodauthMailer.unlock_account(self.class.configuration_name, account_id, unlock_account_key_value)
|
|
119
|
+
# end
|
|
120
|
+
|
|
121
|
+
# send_email do |email|
|
|
122
|
+
# # queue email delivery on the mailer after the transaction commits
|
|
123
|
+
# db.after_commit { email.deliver_later }
|
|
124
|
+
# end
|
|
125
|
+
|
|
126
|
+
# ==> Flash
|
|
127
|
+
# Does not work with only_json?
|
|
128
|
+
|
|
129
|
+
# Match flash keys with ones already used in the Rails app.
|
|
130
|
+
# flash_notice_key :success # default is :notice
|
|
131
|
+
# flash_error_key :error # default is :alert
|
|
132
|
+
|
|
133
|
+
# Override default flash messages.
|
|
134
|
+
# create_account_notice_flash "Your account has been created. Please verify your account by visiting the confirmation link sent to your email address."
|
|
135
|
+
# require_login_error_flash "Login is required for accessing this page"
|
|
136
|
+
# login_notice_flash nil
|
|
137
|
+
|
|
138
|
+
# ==> Validation
|
|
139
|
+
# Override default validation error messages.
|
|
140
|
+
# no_matching_login_message "user with this email address doesn't exist"
|
|
141
|
+
# already_an_account_with_this_login_message "user with this email address already exists"
|
|
142
|
+
# password_too_short_message { "needs to have at least #{password_minimum_length} characters" }
|
|
143
|
+
# login_does_not_meet_requirements_message { "invalid email#{", #{login_requirement_message}" if login_requirement_message}" }
|
|
144
|
+
|
|
145
|
+
# ==> Passwords
|
|
146
|
+
|
|
147
|
+
# Passwords shorter than 8 characters are considered weak according to OWASP.
|
|
148
|
+
# password_minimum_length 8
|
|
149
|
+
|
|
150
|
+
# Custom password complexity requirements (alternative to password_complexity feature).
|
|
151
|
+
# password_meets_requirements? do |password|
|
|
152
|
+
# super(password) && password_complex_enough?(password)
|
|
153
|
+
# end
|
|
154
|
+
# auth_class_eval do
|
|
155
|
+
# def password_complex_enough?(password)
|
|
156
|
+
# return true if password.match?(/\d/) && password.match?(/[^a-zA-Z\d]/)
|
|
157
|
+
# set_password_requirement_error_message(:password_simple, "requires one number and one special character")
|
|
158
|
+
# false
|
|
159
|
+
# end
|
|
160
|
+
# end
|
|
161
|
+
|
|
162
|
+
# = bcrypt
|
|
163
|
+
|
|
164
|
+
# bcrypt has a maximum input length of 72 bytes, truncating any extra bytes.
|
|
165
|
+
# password_maximum_bytes 72
|
|
166
|
+
|
|
167
|
+
# = argon2
|
|
168
|
+
|
|
169
|
+
# Use a rotatable password pepper when hashing passwords with Argon2.
|
|
170
|
+
# argon2_secret "<SECRET_KEY>"
|
|
171
|
+
|
|
172
|
+
# Since we're using argon2, prevent loading the bcrypt gem to save memory.
|
|
173
|
+
# require_bcrypt? false
|
|
174
|
+
|
|
175
|
+
# Having a maximum password length set prevents long password DoS attacks.
|
|
176
|
+
# password_maximum_length 64
|
|
177
|
+
|
|
178
|
+
# ==> Remember Feature
|
|
179
|
+
# Does not work with only_json?
|
|
180
|
+
|
|
181
|
+
# Remember all logged in users.
|
|
182
|
+
# after_login { remember_login }
|
|
183
|
+
|
|
184
|
+
# Or only remember users that have ticked a "Remember Me" checkbox on login.
|
|
185
|
+
# after_login { remember_login if param_or_nil("remember") }
|
|
186
|
+
|
|
187
|
+
# Extend user's remember period when remembered via a cookie
|
|
188
|
+
# extend_remember_deadline? true
|
|
189
|
+
|
|
190
|
+
# ==> Hooks
|
|
191
|
+
|
|
192
|
+
# Validate custom fields in the create account form.
|
|
193
|
+
# before_create_account do
|
|
194
|
+
# throw_error_status(422, "name", "must be present") if param("name").empty?
|
|
195
|
+
# end
|
|
196
|
+
|
|
197
|
+
# Perform additional actions after the account is created.
|
|
198
|
+
# after_create_account do
|
|
199
|
+
# Profile.create!(account_id: account_id, name: param("name"))
|
|
200
|
+
# end
|
|
201
|
+
|
|
202
|
+
# Do additional cleanup after the account is closed.
|
|
203
|
+
# after_close_account do
|
|
204
|
+
# Profile.find_by!(account_id: account_id).destroy
|
|
205
|
+
# end
|
|
206
|
+
|
|
207
|
+
# ==> Redirects
|
|
208
|
+
# Does not work with only_json?
|
|
209
|
+
|
|
210
|
+
# Redirect to home after login.
|
|
211
|
+
# login_redirect "/"
|
|
212
|
+
|
|
213
|
+
# Redirect to home page after logout.
|
|
214
|
+
# logout_redirect "/"
|
|
215
|
+
|
|
216
|
+
# Redirect to wherever login redirects to after account verification.
|
|
217
|
+
# verify_account_redirect { login_redirect }
|
|
218
|
+
|
|
219
|
+
# Redirect to login page after password reset.
|
|
220
|
+
# reset_password_redirect { login_path }
|
|
221
|
+
|
|
222
|
+
# Ensure requiring login follows login route changes.
|
|
223
|
+
# require_login_redirect { login_path }
|
|
224
|
+
|
|
225
|
+
# ==> Deadlines
|
|
226
|
+
# Change default deadlines for some actions.
|
|
227
|
+
# verify_account_grace_period 3.days.to_i
|
|
228
|
+
# reset_password_deadline_interval Hash[hours: 6]
|
|
229
|
+
# verify_login_change_deadline_interval Hash[days: 2]
|
|
230
|
+
|
|
231
|
+
# Does not work with only_json?
|
|
232
|
+
# remember_deadline_interval Hash[days: 30]
|
|
233
|
+
end
|
|
234
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<% if defined?(ActiveRecord::Railtie) -%>
|
|
2
|
+
class <%= table_prefix.camelize %> < ApplicationRecord
|
|
3
|
+
include Rodauth::Rails.model<%= "(:#{table_prefix})" unless primary? %>
|
|
4
|
+
# add concerns above.
|
|
5
|
+
|
|
6
|
+
# add model configurations above.
|
|
7
|
+
|
|
8
|
+
# add belongs_to associations above.
|
|
9
|
+
|
|
10
|
+
# add has_one associations above.
|
|
11
|
+
|
|
12
|
+
# add has_many associations above.
|
|
13
|
+
|
|
14
|
+
# add attachments above.
|
|
15
|
+
|
|
16
|
+
<% if ActiveRecord.version >= Gem::Version.new("7.0") -%>
|
|
17
|
+
enum :status, unverified: 1, verified: 2, closed: 3
|
|
18
|
+
<% else -%>
|
|
19
|
+
enum status: { unverified: 1, verified: 2, closed: 3 }
|
|
20
|
+
<% end -%>
|
|
21
|
+
# add misc attribute macros above.
|
|
22
|
+
|
|
23
|
+
# add scopes above.
|
|
24
|
+
|
|
25
|
+
validates :email, presence: true
|
|
26
|
+
# add validations above.
|
|
27
|
+
|
|
28
|
+
# add callbacks above.
|
|
29
|
+
|
|
30
|
+
# add delegations above.
|
|
31
|
+
|
|
32
|
+
# add methods above.
|
|
33
|
+
end
|
|
34
|
+
<% else -%>
|
|
35
|
+
class <%= table_prefix.camelize %> < Sequel::Model
|
|
36
|
+
include Rodauth::Rails.model
|
|
37
|
+
plugin :enum
|
|
38
|
+
enum :status, unverified: 1, verified: 2, closed: 3
|
|
39
|
+
end
|
|
40
|
+
<% end -%>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%= form_with url: rodauth.email_auth_request_path, method: :post, data: { turbo: false } do |form| %>
|
|
2
|
+
<%= form.hidden_field rodauth.login_param, value: params[rodauth.login_param] %>
|
|
3
|
+
|
|
4
|
+
<div class="form-group mb-3">
|
|
5
|
+
<%= form.submit rodauth.email_auth_request_button, class: "btn btn-primary" %>
|
|
6
|
+
</div>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<%= form_with url: rodauth.login_path, method: :post, data: { turbo: false } do |form| %>
|
|
2
|
+
<% if rodauth.skip_login_field_on_login? %>
|
|
3
|
+
<div class="form-group mb-3">
|
|
4
|
+
<%= form.label "login", rodauth.login_label, class: "form-label" %>
|
|
5
|
+
<%= form.email_field rodauth.login_param, value: params[rodauth.login_param], id: "login", readonly: true, class: "form-control-plaintext" %>
|
|
6
|
+
</div>
|
|
7
|
+
<% else %>
|
|
8
|
+
<div class="form-group mb-3">
|
|
9
|
+
<%= form.label "login", rodauth.login_label, class: "form-label" %>
|
|
10
|
+
<%= form.email_field rodauth.login_param, value: params[rodauth.login_param], id: "login", autocomplete: rodauth.login_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.login_param)}", aria: ({ invalid: true, describedby: "login_error_message" } if rodauth.field_error(rodauth.login_param)) %>
|
|
11
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.login_param), class: "invalid-feedback", id: "login_error_message") if rodauth.field_error(rodauth.login_param) %>
|
|
12
|
+
</div>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
<% unless rodauth.skip_password_field_on_login? %>
|
|
16
|
+
<div class="form-group mb-3">
|
|
17
|
+
<%= form.label "password", rodauth.password_label, class: "form-label" %>
|
|
18
|
+
<%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
|
|
19
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
|
|
20
|
+
</div>
|
|
21
|
+
<% end %>
|
|
22
|
+
|
|
23
|
+
<div class="form-group mb-3">
|
|
24
|
+
<%= form.submit rodauth.login_button, class: "btn btn-primary" %>
|
|
25
|
+
</div>
|
|
26
|
+
<% end %>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<%= form_with url: rodauth.change_login_path, method: :post, data: { turbo: false } do |form| %>
|
|
2
|
+
<div class="form-group mb-3">
|
|
3
|
+
<%= form.label "login", rodauth.login_label, class: "form-label" %>
|
|
4
|
+
<%= form.email_field rodauth.login_param, value: params[rodauth.login_param], id: "login", autocomplete: "email", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.login_param)}", aria: ({ invalid: true, describedby: "login_error_message" } if rodauth.field_error(rodauth.login_param)) %>
|
|
5
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.login_param), class: "invalid-feedback", id: "login_error_message") if rodauth.field_error(rodauth.login_param) %>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<% if rodauth.require_login_confirmation? %>
|
|
9
|
+
<div class="form-group mb-3">
|
|
10
|
+
<%= form.label "login-confirm", rodauth.login_confirm_label, class: "form-label" %>
|
|
11
|
+
<%= form.email_field rodauth.login_confirm_param, value: params[rodauth.login_confirm_param], id: "login-confirm", autocomplete: "email", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.login_confirm_param)}", aria: ({ invalid: true, describedby: "login-confirm_error_message" } if rodauth.field_error(rodauth.login_confirm_param)) %>
|
|
12
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.login_confirm_param), class: "invalid-feedback", id: "login-confirm_error_message") if rodauth.field_error(rodauth.login_confirm_param) %>
|
|
13
|
+
</div>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
<% if rodauth.change_login_requires_password? %>
|
|
17
|
+
<div class="form-group mb-3">
|
|
18
|
+
<%= form.label "password", rodauth.password_label, class: "form-label" %>
|
|
19
|
+
<%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
|
|
20
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
|
|
21
|
+
</div>
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
24
|
+
<div class="form-group mb-3">
|
|
25
|
+
<%= form.submit rodauth.change_login_button, class: "btn btn-primary" %>
|
|
26
|
+
</div>
|
|
27
|
+
<% end %>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<%= form_with url: rodauth.change_password_path, method: :post, data: { turbo: false } do |form| %>
|
|
2
|
+
<% if rodauth.change_password_requires_password? %>
|
|
3
|
+
<div class="form-group mb-3">
|
|
4
|
+
<%= form.label "password", rodauth.password_label, class: "form-label" %>
|
|
5
|
+
<%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
|
|
6
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
|
|
7
|
+
</div>
|
|
8
|
+
<% end %>
|
|
9
|
+
|
|
10
|
+
<div class="form-group mb-3">
|
|
11
|
+
<%= form.label "new-password", rodauth.new_password_label, class: "form-label" %>
|
|
12
|
+
<%= form.password_field rodauth.new_password_param, value: "", id: "new-password", autocomplete: "new-password", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.new_password_param)}", aria: ({ invalid: true, describedby: "new-password_error_message" } if rodauth.field_error(rodauth.new_password_param)) %>
|
|
13
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.new_password_param), class: "invalid-feedback", id: "new-password_error_message") if rodauth.field_error(rodauth.new_password_param) %>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<% if rodauth.require_password_confirmation? %>
|
|
17
|
+
<div class="form-group mb-3">
|
|
18
|
+
<%= form.label "password-confirm", rodauth.password_confirm_label, class: "form-label" %>
|
|
19
|
+
<%= form.password_field rodauth.password_confirm_param, value: "", id: "password-confirm", autocomplete: "new-password", required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_confirm_param)}", aria: ({ invalid: true, describedby: "password-confirm_error_message" } if rodauth.field_error(rodauth.password_confirm_param)) %>
|
|
20
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.password_confirm_param), class: "invalid-feedback", id: "password-confirm_error_message") if rodauth.field_error(rodauth.password_confirm_param) %>
|
|
21
|
+
</div>
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
24
|
+
<div class="form-group mb-3">
|
|
25
|
+
<%= form.submit rodauth.change_password_button, class: "btn btn-primary" %>
|
|
26
|
+
</div>
|
|
27
|
+
<% end %>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<%= form_with url: rodauth.close_account_path, method: :post, data: { turbo: false } do |form| %>
|
|
2
|
+
<% if rodauth.close_account_requires_password? %>
|
|
3
|
+
<div class="form-group mb-3">
|
|
4
|
+
<%= form.label "password", rodauth.password_label, class: "form-label" %>
|
|
5
|
+
<%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "form-control #{"is-invalid" if rodauth.field_error(rodauth.password_param)}", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
|
|
6
|
+
<%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "invalid-feedback", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
|
|
7
|
+
</div>
|
|
8
|
+
<% end %>
|
|
9
|
+
|
|
10
|
+
<div class="form-group mb-3">
|
|
11
|
+
<%= form.submit rodauth.close_account_button, class: "btn btn-danger" %>
|
|
12
|
+
</div>
|
|
13
|
+
<% end %>
|