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.
Files changed (346) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.ruby-version +1 -0
  4. data/.standard.yml +4 -0
  5. data/.vscode/extensions.json +15 -0
  6. data/.vscode/launch.json +7 -0
  7. data/.vscode/settings.json +35 -0
  8. data/CHANGELOG.md +5 -0
  9. data/LICENSE.txt +21 -0
  10. data/README copy.md +84 -0
  11. data/README.md +67 -0
  12. data/Rakefile +8 -0
  13. data/app/views/layouts/resource.html.erb +43 -0
  14. data/app/views/resource/_color_modes.html.erb +55 -0
  15. data/app/views/resource/_details.html.erb +6 -0
  16. data/app/views/resource/_empty_card.html.erb +12 -0
  17. data/app/views/resource/_flash.html.erb +9 -0
  18. data/app/views/resource/_form.html.erb +32 -0
  19. data/app/views/resource/_header.html.erb +8 -0
  20. data/app/views/resource/_interactive_resource_action_form.html.erb +67 -0
  21. data/app/views/resource/_messages.html.erb +1 -0
  22. data/app/views/resource/_metric_card.html.erb +16 -0
  23. data/app/views/resource/_nav_user.html.erb +4 -0
  24. data/app/views/resource/_pagination.html.erb +6 -0
  25. data/app/views/resource/_pagy_pagination.html.erb +15 -0
  26. data/app/views/resource/_resource.html.erb +1 -0
  27. data/app/views/resource/_resource.rabl +5 -0
  28. data/app/views/resource/_sidebar.html.erb +11 -0
  29. data/app/views/resource/_sidebar_menu.html.erb +1 -0
  30. data/app/views/resource/_tab_menu.html.erb +13 -0
  31. data/app/views/resource/_table.html.erb +78 -0
  32. data/app/views/resource/_table_actions.html.erb +15 -0
  33. data/app/views/resource/_toast.html.erb +26 -0
  34. data/app/views/resource/_toolbar.html.erb +22 -0
  35. data/app/views/resource/_toolbar_actions.html.erb +16 -0
  36. data/app/views/resource/_toolbar_breadcrumbs.html.erb +32 -0
  37. data/app/views/resource/_toolbar_search_input.erb +27 -0
  38. data/app/views/resource/edit.html.erb +10 -0
  39. data/app/views/resource/errors.rabl +3 -0
  40. data/app/views/resource/index.html.erb +19 -0
  41. data/app/views/resource/index.rabl +3 -0
  42. data/app/views/resource/interactive_resource_collection_action.html.erb +11 -0
  43. data/app/views/resource/interactive_resource_record_action.html.erb +11 -0
  44. data/app/views/resource/interactive_resource_recordless_action.html.erb +11 -0
  45. data/app/views/resource/new.html.erb +11 -0
  46. data/app/views/resource/readme.md +16 -0
  47. data/app/views/resource/show.html.erb +14 -0
  48. data/app/views/resource/show.rabl +3 -0
  49. data/brakeman.ignore +51 -0
  50. data/lib/active_model/validations/array_validator.rb +74 -0
  51. data/lib/active_model/validations/attached_validator.rb +17 -0
  52. data/lib/active_model/validations/url_validator.rb +51 -0
  53. data/lib/generators/pu/core/install/install_generator.rb +43 -0
  54. data/lib/generators/pu/core/install/templates/.keep +0 -0
  55. data/lib/generators/pu/core/install/templates/app/controllers/resource_controller.rb.tt +2 -0
  56. data/lib/generators/pu/core/install/templates/app/interactions/resource_interaction.rb.tt +2 -0
  57. data/lib/generators/pu/core/install/templates/app/models/resource_record.rb.tt +5 -0
  58. data/lib/generators/pu/core/install/templates/app/policies/resource_policy.rb.tt +2 -0
  59. data/lib/generators/pu/core/install/templates/app/presenters/resource_presenter.rb.tt +2 -0
  60. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +2 -0
  61. data/lib/generators/pu/core/install/templates/config/packages.rb +3 -0
  62. data/lib/generators/pu/gem/pagy/pagy_generator.rb +25 -0
  63. data/lib/generators/pu/gem/pagy/templates/.keep +0 -0
  64. data/lib/generators/pu/gem/pagy/templates/config/initializers/pagy.rb +4 -0
  65. data/lib/generators/pu/gem/rabl/rabl_generator.rb +25 -0
  66. data/lib/generators/pu/gem/rabl/templates/.keep +0 -0
  67. data/lib/generators/pu/gem/rabl/templates/config/initializers/rabl.rb +60 -0
  68. data/lib/generators/pu/gem/simple_form/simple_form_generator.rb +25 -0
  69. data/lib/generators/pu/gem/simple_form/templates/.keep +0 -0
  70. data/lib/generators/pu/gen/pug/pug_generator.rb +43 -0
  71. data/lib/generators/pu/gen/pug/templates/pug.rb.tt +23 -0
  72. data/lib/generators/pu/pkg/app/app_generator.rb +60 -0
  73. data/lib/generators/pu/pkg/app/templates/app/controllers/resource_controller.rb.tt +26 -0
  74. data/lib/generators/pu/pkg/app/templates/app/interactions/resource_interaction.rb.tt +4 -0
  75. data/lib/generators/pu/pkg/app/templates/app/policies/resource_policy.rb.tt +4 -0
  76. data/lib/generators/pu/pkg/app/templates/app/presenters/resource_presenter.rb.tt +4 -0
  77. data/lib/generators/pu/pkg/app/templates/config/routes.rb.tt +17 -0
  78. data/lib/generators/pu/pkg/app/templates/lib/engine.rb.tt +14 -0
  79. data/lib/generators/pu/pkg/feature/feature_generator.rb +44 -0
  80. data/lib/generators/pu/pkg/feature/templates/.keep +0 -0
  81. data/lib/generators/pu/pkg/feature/templates/app/controllers/resource_controller.rb.tt +7 -0
  82. data/lib/generators/pu/pkg/feature/templates/app/interactions/resource_interaction.rb.tt +4 -0
  83. data/lib/generators/pu/pkg/feature/templates/app/models/resource_record.rb.tt +5 -0
  84. data/lib/generators/pu/pkg/feature/templates/app/policies/resource_policy.rb.tt +4 -0
  85. data/lib/generators/pu/pkg/feature/templates/app/presenters/resource_presenter.rb.tt +4 -0
  86. data/lib/generators/pu/pkg/feature/templates/lib/engine.rb.tt +8 -0
  87. data/lib/generators/pu/resource/conn/conn_generator.rb +54 -0
  88. data/lib/generators/pu/resource/conn/templates/.keep +0 -0
  89. data/lib/generators/pu/resource/conn/templates/app/controllers/resource_controller.rb.tt +3 -0
  90. data/lib/generators/pu/resource/conn/templates/app/policies/resource_policy.rb.tt +3 -0
  91. data/lib/generators/pu/resource/conn/templates/app/presenters/resource_presenter.rb.tt +3 -0
  92. data/lib/generators/pu/resource/model/USAGE +113 -0
  93. data/lib/generators/pu/resource/model/model_generator.rb +163 -0
  94. data/lib/generators/pu/resource/model/templates/controller.rb.tt +5 -0
  95. data/lib/generators/pu/resource/model/templates/create_table_migration.rb.tt +26 -0
  96. data/lib/generators/pu/resource/model/templates/model.rb.tt +53 -0
  97. data/lib/generators/pu/resource/model/templates/module.rb.tt +7 -0
  98. data/lib/generators/pu/resource/model/templates/policy.rb.tt +4 -0
  99. data/lib/generators/pu/resource/model/templates/presenter.rb.tt +4 -0
  100. data/lib/generators/pu/resource/scaffold/scaffold_generator.rb +219 -0
  101. data/lib/generators/pu/resource/scaffold/templates/app/controllers/admin_resources/resource_controller.rb.tt +7 -0
  102. data/lib/generators/pu/resource/scaffold/templates/app/controllers/entity_resources/resource_controller.rb.tt +7 -0
  103. data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/admin/resource_policy.rb.tt +22 -0
  104. data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/entity/resource_policy.rb.tt +22 -0
  105. data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/resource_policy.rb.tt +13 -0
  106. data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/admin_presenter.rb.tt +7 -0
  107. data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/entity_presenter.rb.tt +7 -0
  108. data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/presenter.rb.tt +23 -0
  109. data/lib/generators/pu/resource/scaffold/templates/app/views/resources/resource/_resource.html.erb.tt +3 -0
  110. data/lib/generators/pu/resource/scaffold/templates/app/views/resources/resource/_resource.rabl +7 -0
  111. data/lib/generators/pu/rodauth/account_generator.rb +120 -0
  112. data/lib/generators/pu/rodauth/concerns/account_selector.rb +22 -0
  113. data/lib/generators/pu/rodauth/concerns/configuration.rb +211 -0
  114. data/lib/generators/pu/rodauth/concerns/feature_selector.rb +125 -0
  115. data/lib/generators/pu/rodauth/install_generator.rb +69 -0
  116. data/lib/generators/pu/rodauth/migration/active_record/account_expiration.erb +8 -0
  117. data/lib/generators/pu/rodauth/migration/active_record/active_sessions.erb +7 -0
  118. data/lib/generators/pu/rodauth/migration/active_record/audit_logging.erb +16 -0
  119. data/lib/generators/pu/rodauth/migration/active_record/base.erb +22 -0
  120. data/lib/generators/pu/rodauth/migration/active_record/disallow_password_reuse.erb +5 -0
  121. data/lib/generators/pu/rodauth/migration/active_record/email_auth.erb +8 -0
  122. data/lib/generators/pu/rodauth/migration/active_record/jwt_refresh.erb +7 -0
  123. data/lib/generators/pu/rodauth/migration/active_record/lockout.erb +13 -0
  124. data/lib/generators/pu/rodauth/migration/active_record/otp.erb +8 -0
  125. data/lib/generators/pu/rodauth/migration/active_record/password_expiration.erb +6 -0
  126. data/lib/generators/pu/rodauth/migration/active_record/recovery_codes.erb +6 -0
  127. data/lib/generators/pu/rodauth/migration/active_record/remember.erb +7 -0
  128. data/lib/generators/pu/rodauth/migration/active_record/reset_password.erb +8 -0
  129. data/lib/generators/pu/rodauth/migration/active_record/separate_passwords.erb +5 -0
  130. data/lib/generators/pu/rodauth/migration/active_record/single_session.erb +6 -0
  131. data/lib/generators/pu/rodauth/migration/active_record/sms_codes.erb +9 -0
  132. data/lib/generators/pu/rodauth/migration/active_record/verify_account.erb +8 -0
  133. data/lib/generators/pu/rodauth/migration/active_record/verify_login_change.erb +8 -0
  134. data/lib/generators/pu/rodauth/migration/active_record/webauthn.erb +13 -0
  135. data/lib/generators/pu/rodauth/migration/sequel/account_expiration.erb +7 -0
  136. data/lib/generators/pu/rodauth/migration/sequel/active_sessions.erb +8 -0
  137. data/lib/generators/pu/rodauth/migration/sequel/audit_logging.erb +17 -0
  138. data/lib/generators/pu/rodauth/migration/sequel/base.erb +25 -0
  139. data/lib/generators/pu/rodauth/migration/sequel/disallow_password_reuse.erb +6 -0
  140. data/lib/generators/pu/rodauth/migration/sequel/email_auth.erb +7 -0
  141. data/lib/generators/pu/rodauth/migration/sequel/jwt_refresh.erb +8 -0
  142. data/lib/generators/pu/rodauth/migration/sequel/lockout.erb +11 -0
  143. data/lib/generators/pu/rodauth/migration/sequel/otp.erb +7 -0
  144. data/lib/generators/pu/rodauth/migration/sequel/password_expiration.erb +5 -0
  145. data/lib/generators/pu/rodauth/migration/sequel/recovery_codes.erb +6 -0
  146. data/lib/generators/pu/rodauth/migration/sequel/remember.erb +6 -0
  147. data/lib/generators/pu/rodauth/migration/sequel/reset_password.erb +7 -0
  148. data/lib/generators/pu/rodauth/migration/sequel/separate_passwords.erb +6 -0
  149. data/lib/generators/pu/rodauth/migration/sequel/single_session.erb +5 -0
  150. data/lib/generators/pu/rodauth/migration/sequel/sms_codes.erb +8 -0
  151. data/lib/generators/pu/rodauth/migration/sequel/verify_account.erb +7 -0
  152. data/lib/generators/pu/rodauth/migration/sequel/verify_login_change.erb +7 -0
  153. data/lib/generators/pu/rodauth/migration/sequel/webauthn.erb +13 -0
  154. data/lib/generators/pu/rodauth/migration_generator.rb +190 -0
  155. data/lib/generators/pu/rodauth/templates/INSTRUCTIONS +52 -0
  156. data/lib/generators/pu/rodauth/templates/app/controllers/plugin_controller.rb.tt +6 -0
  157. data/lib/generators/pu/rodauth/templates/app/controllers/rodauth_controller.rb.tt +3 -0
  158. data/lib/generators/pu/rodauth/templates/app/mailers/account_mailer.rb.tt +4 -0
  159. data/lib/generators/pu/rodauth/templates/app/mailers/rodauth_mailer.rb.tt +62 -0
  160. data/lib/generators/pu/rodauth/templates/app/misc/account_rodauth_plugin.rb.tt +255 -0
  161. data/lib/generators/pu/rodauth/templates/app/misc/rodauth_app.rb.tt +24 -0
  162. data/lib/generators/pu/rodauth/templates/app/misc/rodauth_plugin.rb.tt +234 -0
  163. data/lib/generators/pu/rodauth/templates/app/models/account.rb.tt +40 -0
  164. data/lib/generators/pu/rodauth/templates/app/views/rodauth/_email_auth_request_form.html.erb +7 -0
  165. data/lib/generators/pu/rodauth/templates/app/views/rodauth/_login_form.html.erb +26 -0
  166. data/lib/generators/pu/rodauth/templates/app/views/rodauth/_login_form_footer.html.erb +9 -0
  167. data/lib/generators/pu/rodauth/templates/app/views/rodauth/add_recovery_codes.html.erb +6 -0
  168. data/lib/generators/pu/rodauth/templates/app/views/rodauth/change_login.html.erb +27 -0
  169. data/lib/generators/pu/rodauth/templates/app/views/rodauth/change_password.html.erb +27 -0
  170. data/lib/generators/pu/rodauth/templates/app/views/rodauth/close_account.html.erb +13 -0
  171. data/lib/generators/pu/rodauth/templates/app/views/rodauth/confirm_password.html.erb +11 -0
  172. data/lib/generators/pu/rodauth/templates/app/views/rodauth/create_account.html.erb +35 -0
  173. data/lib/generators/pu/rodauth/templates/app/views/rodauth/email_auth.html.erb +5 -0
  174. data/lib/generators/pu/rodauth/templates/app/views/rodauth/login.html.erb +4 -0
  175. data/lib/generators/pu/rodauth/templates/app/views/rodauth/logout.html.erb +14 -0
  176. data/lib/generators/pu/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +3 -0
  177. data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_auth.html.erb +15 -0
  178. data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_disable.html.erb +13 -0
  179. data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_setup.html.erb +41 -0
  180. data/lib/generators/pu/rodauth/templates/app/views/rodauth/recovery_auth.html.erb +11 -0
  181. data/lib/generators/pu/rodauth/templates/app/views/rodauth/recovery_codes.html.erb +13 -0
  182. data/lib/generators/pu/rodauth/templates/app/views/rodauth/remember.html.erb +22 -0
  183. data/lib/generators/pu/rodauth/templates/app/views/rodauth/reset_password.html.erb +19 -0
  184. data/lib/generators/pu/rodauth/templates/app/views/rodauth/reset_password_request.html.erb +17 -0
  185. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_auth.html.erb +15 -0
  186. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_confirm.html.erb +15 -0
  187. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_disable.html.erb +13 -0
  188. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_request.html.erb +5 -0
  189. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_setup.html.erb +23 -0
  190. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_email_auth_request_form.html.erb +5 -0
  191. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_login_form.html.erb +24 -0
  192. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_login_form_footer.html.erb +7 -0
  193. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/add_recovery_codes.html.erb +16 -0
  194. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/change_login.html.erb +25 -0
  195. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/change_password.html.erb +25 -0
  196. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/close_account.html.erb +11 -0
  197. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/confirm_password.html.erb +19 -0
  198. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/create_account.html.erb +33 -0
  199. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/email_auth.html.erb +3 -0
  200. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/login.html.erb +5 -0
  201. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/logout.html.erb +10 -0
  202. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/multi_phase_login.html.erb +5 -0
  203. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_auth.html.erb +9 -0
  204. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_disable.html.erb +11 -0
  205. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_setup.html.erb +32 -0
  206. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/recovery_auth.html.erb +9 -0
  207. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/recovery_codes.html.erb +11 -0
  208. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/remember.html.erb +18 -0
  209. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/reset_password.html.erb +17 -0
  210. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/reset_password_request.html.erb +17 -0
  211. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_auth.html.erb +9 -0
  212. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_confirm.html.erb +9 -0
  213. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_disable.html.erb +11 -0
  214. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_request.html.erb +3 -0
  215. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_setup.html.erb +17 -0
  216. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_auth.html.erb +5 -0
  217. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_disable.html.erb +11 -0
  218. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_manage.html.erb +26 -0
  219. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/unlock_account.html.erb +15 -0
  220. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/unlock_account_request.html.erb +9 -0
  221. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_account.html.erb +19 -0
  222. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_account_resend.html.erb +17 -0
  223. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_login_change.html.erb +3 -0
  224. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_auth.html.erb +13 -0
  225. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_autofill.html.erb +10 -0
  226. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_remove.html.erb +21 -0
  227. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_setup.html.erb +21 -0
  228. data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_auth.html.erb +5 -0
  229. data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_disable.html.erb +13 -0
  230. data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_manage.html.erb +22 -0
  231. data/lib/generators/pu/rodauth/templates/app/views/rodauth/unlock_account.html.erb +15 -0
  232. data/lib/generators/pu/rodauth/templates/app/views/rodauth/unlock_account_request.html.erb +9 -0
  233. data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_account.html.erb +21 -0
  234. data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_account_resend.html.erb +17 -0
  235. data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_login_change.html.erb +5 -0
  236. data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_auth.html.erb +15 -0
  237. data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_autofill.html.erb +10 -0
  238. data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_remove.html.erb +23 -0
  239. data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_setup.html.erb +23 -0
  240. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/email_auth.text.erb +5 -0
  241. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/password_changed.text.erb +2 -0
  242. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/reset_password.text.erb +5 -0
  243. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/reset_password_notify.text.erb +2 -0
  244. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb +5 -0
  245. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/verify_account.text.erb +4 -0
  246. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/verify_login_change.text.erb +10 -0
  247. data/lib/generators/pu/rodauth/templates/config/initializers/rodauth.rb.tt +3 -0
  248. data/lib/generators/pu/rodauth/templates/db/migrate/create_rodauth.rb.tt +13 -0
  249. data/lib/generators/pu/rodauth/views_generator.rb +125 -0
  250. data/lib/plutonium/auth/public_access.rb +17 -0
  251. data/lib/plutonium/auth/rodauth.rb +35 -0
  252. data/lib/plutonium/auth.rb +12 -0
  253. data/lib/plutonium/config.rb +11 -0
  254. data/lib/plutonium/core/.DS_Store +0 -0
  255. data/lib/plutonium/core/action.rb +46 -0
  256. data/lib/plutonium/core/actions/basic_action.rb +16 -0
  257. data/lib/plutonium/core/actions/collection.rb +33 -0
  258. data/lib/plutonium/core/actions/destroy_action.rb +21 -0
  259. data/lib/plutonium/core/actions/edit_action.rb +19 -0
  260. data/lib/plutonium/core/actions/interactive_action.rb +64 -0
  261. data/lib/plutonium/core/actions/new_action.rb +18 -0
  262. data/lib/plutonium/core/actions/show_action.rb +17 -0
  263. data/lib/plutonium/core/actions.rb +17 -0
  264. data/lib/plutonium/core/app_controller.rb +121 -0
  265. data/lib/plutonium/core/autodiscovery/discoverer.rb +15 -0
  266. data/lib/plutonium/core/autodiscovery/input_discoverer.rb +33 -0
  267. data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +33 -0
  268. data/lib/plutonium/core/autodiscovery.rb +13 -0
  269. data/lib/plutonium/core/controllers/authorizable.rb +56 -0
  270. data/lib/plutonium/core/controllers/bootable.rb +44 -0
  271. data/lib/plutonium/core/controllers/crud_actions.rb +128 -0
  272. data/lib/plutonium/core/controllers/entity_scoping.rb +69 -0
  273. data/lib/plutonium/core/controllers/interactive_actions.rb +210 -0
  274. data/lib/plutonium/core/controllers/presentable.rb +59 -0
  275. data/lib/plutonium/core/controllers.rb +16 -0
  276. data/lib/plutonium/core/definers/action_definer.rb +25 -0
  277. data/lib/plutonium/core/definers/field_definer.rb +19 -0
  278. data/lib/plutonium/core/definers/input_definer.rb +37 -0
  279. data/lib/plutonium/core/definers/renderer_definer.rb +35 -0
  280. data/lib/plutonium/core/definers.rb +14 -0
  281. data/lib/plutonium/core/fields/inputs/association_input.rb +26 -0
  282. data/lib/plutonium/core/fields/inputs/basic_input.rb +42 -0
  283. data/lib/plutonium/core/fields/inputs/belongs_to_input.rb +15 -0
  284. data/lib/plutonium/core/fields/inputs/factory.rb +58 -0
  285. data/lib/plutonium/core/fields/inputs/has_many_input.rb +15 -0
  286. data/lib/plutonium/core/fields/inputs/noop_input.rb +19 -0
  287. data/lib/plutonium/core/fields/inputs.rb +18 -0
  288. data/lib/plutonium/core/fields/renderers/association_renderer.rb +25 -0
  289. data/lib/plutonium/core/fields/renderers/basic_renderer.rb +27 -0
  290. data/lib/plutonium/core/fields/renderers/factory.rb +52 -0
  291. data/lib/plutonium/core/fields/renderers.rb +15 -0
  292. data/lib/plutonium/core/fields.rb +12 -0
  293. data/lib/plutonium/core/ui/collection.rb +14 -0
  294. data/lib/plutonium/core/ui/detail.rb +11 -0
  295. data/lib/plutonium/core/ui/form.rb +11 -0
  296. data/lib/plutonium/core/ui.rb +13 -0
  297. data/lib/plutonium/core.rb +16 -0
  298. data/lib/plutonium/helpers/action_buttons_helper.rb +32 -0
  299. data/lib/plutonium/helpers/application_helper.rb +22 -0
  300. data/lib/plutonium/helpers/attachment_helper.rb +62 -0
  301. data/lib/plutonium/helpers/content_helper.rb +66 -0
  302. data/lib/plutonium/helpers/display_helper.rb +83 -0
  303. data/lib/plutonium/helpers/form_helper.rb +24 -0
  304. data/lib/plutonium/helpers/menu_helper.rb +69 -0
  305. data/lib/plutonium/helpers/pagination_helper.rb +9 -0
  306. data/lib/plutonium/helpers/turbo_helper.rb +13 -0
  307. data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +9 -0
  308. data/lib/plutonium/helpers.rb +31 -0
  309. data/lib/plutonium/initializers/TODO +2 -0
  310. data/lib/plutonium/initializers/pagy.rb +5 -0
  311. data/lib/plutonium/initializers/patches.rb +2 -0
  312. data/lib/plutonium/initializers/rabl.rb +60 -0
  313. data/lib/plutonium/initializers/simple_form.rb +405 -0
  314. data/lib/plutonium/lib/after_commit.rb +34 -0
  315. data/lib/plutonium/lib/bit_flags.rb +36 -0
  316. data/lib/plutonium/packaging/app.rb +125 -0
  317. data/lib/plutonium/packaging/feature.rb +18 -0
  318. data/lib/plutonium/packaging/package.rb +22 -0
  319. data/lib/plutonium/packaging.rb +9 -0
  320. data/lib/plutonium/policy/initializer.rb +22 -0
  321. data/lib/plutonium/policy/scope.rb +19 -0
  322. data/lib/plutonium/policy.rb +8 -0
  323. data/lib/plutonium/preserved__/field.rb +65 -0
  324. data/lib/plutonium/preserved__/input.rb +93 -0
  325. data/lib/plutonium/reactor/core.rb +61 -0
  326. data/lib/plutonium/reactor/resource_context.rb +15 -0
  327. data/lib/plutonium/reactor/resource_controller.rb +108 -0
  328. data/lib/plutonium/reactor/resource_interaction.rb +8 -0
  329. data/lib/plutonium/reactor/resource_policy.rb +105 -0
  330. data/lib/plutonium/reactor/resource_presenter.rb +42 -0
  331. data/lib/plutonium/reactor/resource_record.rb +123 -0
  332. data/lib/plutonium/reactor.rb +13 -0
  333. data/lib/plutonium/refinements/parameter_refinements.rb +26 -0
  334. data/lib/plutonium/simple_form_components/attachment_component.rb +77 -0
  335. data/lib/plutonium/simple_form_components/input_group_component.rb +14 -0
  336. data/lib/plutonium/version.rb +3 -0
  337. data/lib/plutonium.rb +31 -0
  338. data/plutonium.gemspec +47 -0
  339. data/public/.keep +0 -0
  340. data/public/plutonium-assets/application.css +24280 -0
  341. data/public/plutonium-assets/application.js +31420 -0
  342. data/public/plutonium-assets/fonts/bootstrap-icons.woff +0 -0
  343. data/public/plutonium-assets/fonts/bootstrap-icons.woff2 +0 -0
  344. data/public/plutonium-assets/logo.png +0 -0
  345. data/sig/plutonium.rbs +4 -0
  346. metadata +519 -0
@@ -0,0 +1,120 @@
1
+ return unless defined?(Rodauth::Rails)
2
+
3
+ require "rails/generators/base"
4
+ require "securerandom"
5
+
6
+ require "#{__dir__}/concerns/configuration"
7
+ require "#{__dir__}/concerns/account_selector"
8
+ require "#{__dir__}/concerns/feature_selector"
9
+
10
+ module Pu
11
+ module Rodauth
12
+ class AccountGenerator < ::Rails::Generators::Base
13
+ include Concerns::AccountSelector
14
+ include Concerns::FeatureSelector
15
+
16
+ source_root "#{__dir__}/templates"
17
+
18
+ desc "Generate a rodauth-rails account.\n\n" \
19
+ "Configures a basic set of features as well as migrations, a model, mailer and views."
20
+
21
+ def install_dependencies
22
+ Bundler.with_unbundled_env do
23
+ run "bundle add jwt" if jwt? || jwt_refresh?
24
+ run "bundle add rotp" if otp?
25
+ run "bundle add rqrcode" if otp?
26
+ run "bundle add webauthn" if webauthn? || webauthn_autofill?
27
+ end
28
+ end
29
+
30
+ def create_rodauth_app
31
+ template "app/misc/account_rodauth_plugin.rb", "app/misc/#{table_prefix}_rodauth_plugin.rb"
32
+ end
33
+
34
+ def configure_rodauth_plugin
35
+ in_root do
36
+ plugin_name = indent(
37
+ "configure ::#{table_prefix.classify}RodauthPlugin#{", :#{table_prefix}" unless primary?}\n", 2
38
+ )
39
+ gsub_file "app/misc/rodauth_app.rb", /.*# configure RodauthMain\n/, ""
40
+ insert_into_file "app/misc/rodauth_app.rb", plugin_name, after: "# auth configuration\n"
41
+ end
42
+ end
43
+
44
+ def configure_rodauth_plugin_load_route
45
+ in_root do
46
+ route_config = indent("r.rodauth#{"(:#{table_prefix})" unless primary?}\n", 4)
47
+ gsub_file "app/misc/rodauth_app.rb", /.*# r\.rodauth\n/, ""
48
+ insert_into_file "app/misc/rodauth_app.rb", route_config, after: "# auth route configuration\n"
49
+ end
50
+ end
51
+
52
+ def configure_rodauth_plugin_load_memory
53
+ in_root do
54
+ plugin_config = indent(
55
+ "rodauth#{"(:#{table_prefix})" unless primary?}.load_memory # autologin remembered #{table}\n", 4
56
+ )
57
+ gsub_file "app/misc/rodauth_app.rb", /.*# rodauth\.load_memory.*\n/, ""
58
+
59
+ if remember?
60
+ insert_into_file "app/misc/rodauth_app.rb", plugin_config, after: "# plugin route configuration\n"
61
+ else
62
+ gsub_file "app/misc/rodauth_app.rb", plugin_config, ""
63
+ in_root do
64
+ unless File.read("app/misc/rodauth_app.rb").match?(/.*\.load_memory # autologin/)
65
+ insert_into_file "app/misc/rodauth_app.rb", indent("# rodauth.load_memory # autologin remembered users\n", 4),
66
+ after: "# plugin route configuration\n"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ def create_rodauth_controller
74
+ dest = "app/controllers/rodauth/#{table_prefix}_controller.rb"
75
+ template "app/controllers/plugin_controller.rb", dest
76
+ end
77
+
78
+ def generate_rodauth_migration
79
+ return if selected_migration_features.empty?
80
+
81
+ invoke "pu:rodauth:migration", [table], features: selected_migration_features,
82
+ name: kitchen_sink? ? "rodauth_kitchen_sink" : nil,
83
+ migration_name: options[:migration_name],
84
+ force: options[:force],
85
+ skip: options[:skip]
86
+ end
87
+
88
+ def create_account_model
89
+ return unless base?
90
+
91
+ template "app/models/account.rb", "app/models/#{table_prefix}.rb"
92
+ end
93
+
94
+ def create_mailer
95
+ return unless mails?
96
+
97
+ template "app/mailers/rodauth_mailer.rb", "app/mailers/rodauth_mailer.rb"
98
+ template "app/mailers/account_mailer.rb", "app/mailers/rodauth/#{table_prefix}_mailer.rb"
99
+ directory "app/views/rodauth_mailer", "app/views/rodauth/#{table_prefix}_mailer"
100
+ end
101
+
102
+ def create_views
103
+ return if only_json? || selected_view_features.empty?
104
+
105
+ account_name = primary? ? nil : table_prefix
106
+ # Use generate here because invoke spawns in the same process
107
+ # Unfortunately, during the generation process, some new files are created which are not currently loaded,
108
+ # causing an error when it attempts to load the rodauth config.
109
+ # Generate spawns a separate process which loads the new files and ensures it works correctly
110
+ generate "pu:rodauth:views", account_name, "--features", *selected_view_features
111
+ end
112
+
113
+ private
114
+
115
+ def only_json?
116
+ ::Rails.application.config.api_only || !::Rails.application.config.session_store || options[:api_only]
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,22 @@
1
+ module Pu
2
+ module Rodauth
3
+ module Concerns
4
+ module AccountSelector
5
+ def self.included(base)
6
+ base.send :argument, :account_name, type: :string, desc: "name of the account model. "
7
+ base.send :class_option, :migration_name, type: :string, desc: "[CONFIG] name of the generated migration file"
8
+ end
9
+
10
+ private
11
+
12
+ def table
13
+ @table ||= account_name.underscore.pluralize
14
+ end
15
+
16
+ def table_prefix
17
+ @table_prefix ||= account_name.underscore.singularize
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,211 @@
1
+ module Pu
2
+ module Rodauth
3
+ module Concerns
4
+ module Configuration
5
+ # Configuration map for the supported plugins
6
+ # key: plugin name
7
+ # value: hash that can contain the following keys
8
+ # feature(bool) => enabled in the account plugin when selected. default: true.
9
+ # default(bool) => enable this plugin by default
10
+ # desc(string) => description for this plugin to be displayed in the cli help notes
11
+ # migrations(Hash) => map of table override setter to table name.
12
+ # table name can contain the format strings: %{plural} and %{singluar}
13
+ # views(array) => a list of views to generate
14
+ CONFIGURATION = {
15
+ base: {
16
+ default: true,
17
+ feature: false,
18
+ desc: "[CONFIG] create account table and model",
19
+ migrations: {
20
+ accounts_table: "%<plural>s"
21
+ }
22
+ },
23
+ two_factor_base: {
24
+ default: true,
25
+ feature: false,
26
+ desc: "[CONFIG] setup dependencies for 2fa",
27
+ views: %w[two_factor_manage two_factor_auth two_factor_disable]
28
+ },
29
+ separate_passwords: {
30
+ feature: false,
31
+ desc: "[CONFIG] use a separate table for password hashes",
32
+ migrations: {
33
+ password_hash_table: "%<singular>s_password_hashes"
34
+ }
35
+ },
36
+ login: {
37
+ default: true,
38
+ views: %w[_login_form _login_form_footer login multi_phase_login]
39
+ },
40
+ remember: {
41
+ default: true,
42
+ views: %w[remember],
43
+ migrations: {
44
+ remember_table: "%<singular>s_remember_keys"
45
+ }
46
+ },
47
+ logout: {
48
+ default: true,
49
+ views: %w[logout]
50
+ },
51
+ create_account: {
52
+ default: true,
53
+ views: %w[create_account]
54
+ },
55
+ verify_account: {
56
+ default: true,
57
+ views: %w[verify_account_resend verify_account],
58
+ migrations: {
59
+ verify_account_table: "%<singular>s_verification_keys"
60
+ }
61
+ },
62
+ verify_account_grace_period: {default: true},
63
+ close_account: {
64
+ views: %w[close_account]
65
+ },
66
+ reset_password: {
67
+ default: true,
68
+ views: %w[reset_password_request reset_password],
69
+ migrations: {
70
+ reset_password_table: "%<singular>s_password_reset_keys"
71
+ }
72
+ },
73
+ reset_password_notify: {default: true},
74
+ change_login: {
75
+ default: true,
76
+ views: %w[change_login]
77
+ },
78
+ verify_login_change: {
79
+ default: true,
80
+ views: %w[verify_login_change],
81
+ migrations: {
82
+ verify_login_change_table: "%<singular>s_login_change_keys"
83
+ }
84
+ },
85
+ change_password: {
86
+ default: true,
87
+ views: %w[change_password]
88
+ },
89
+ change_password_notify: {
90
+ default: true
91
+ },
92
+ email_auth: {
93
+ views: %w[_email_auth_request_form email_auth],
94
+ migrations: {
95
+ email_auth_table: "%<singular>s_email_auth_keys"
96
+ }
97
+ },
98
+ otp: {
99
+ views: %w[otp_setup otp_auth otp_disable],
100
+ migrations: {
101
+ otp_keys_table: "%<singular>s_otp_keys"
102
+ }
103
+ },
104
+ sms_codes: {
105
+ views: %w[sms_setup sms_confirm sms_auth sms_request sms_disable],
106
+ migrations: {
107
+ sms_codes_table: "%<singular>s_sms_codes"
108
+ }
109
+ },
110
+ recovery_codes: {
111
+ views: %w[recovery_codes add_recovery_codes recovery_auth],
112
+ migrations: {
113
+ recovery_codes_table: "%<singular>s_recovery_codes"
114
+ }
115
+ },
116
+ webauthn: {
117
+ views: %w[webauthn_setup webauthn_auth webauthn_remove],
118
+ migrations: {
119
+ webauthn_keys_table: "%<singular>s_webauthn_keys",
120
+ webauthn_user_ids_table: "%<singular>s_webauthn_user_ids",
121
+ webauthn_keys_account_id_column: "%<singular>s_id"
122
+ }
123
+ },
124
+ webauthn_autofill: {
125
+ views: %w[webauthn_autofill]
126
+ },
127
+ lockout: {
128
+ views: %w[unlock_account_request unlock_account],
129
+ migrations: {
130
+ account_login_failures_table: "%<singular>s_login_failures",
131
+ account_lockouts_table: "%<singular>s_lockouts"
132
+ }
133
+ },
134
+ active_sessions: {
135
+ migrations: {
136
+ active_sessions_table: "%<singular>s_active_session_keys",
137
+ active_sessions_account_id_column: "%<singular>s_id"
138
+ }
139
+ },
140
+ account_expiration: {
141
+ migrations: {
142
+ account_activity_table: "%<singular>s_activity_times"
143
+ }
144
+ },
145
+ password_expiration: {
146
+ migrations: {
147
+ password_expiration_table: "%<singular>s_password_change_times"
148
+ }
149
+ },
150
+ single_session: {
151
+ migrations: {
152
+ single_session_table: "%<singular>s_session_keys"
153
+ }
154
+ },
155
+ audit_logging: {
156
+ migrations: {
157
+ audit_logging_table: "%<singular>s_authentication_audit_logs",
158
+ audit_logging_account_id_column: "%<singular>s_id"
159
+ }
160
+ },
161
+ disallow_password_reuse: {
162
+ migrations: {
163
+ previous_password_hash_table: "%<singular>s_previous_password_hashes",
164
+ previous_password_account_id_column: "%<singular>s_id"
165
+ }
166
+ },
167
+ jwt_refresh: {
168
+ migrations: {
169
+ jwt_refresh_token_table: "%<singular>s_jwt_refresh_keys",
170
+ jwt_refresh_token_account_id_column: "%<singular>s_id"
171
+ }
172
+ },
173
+ jwt: {},
174
+ json: {},
175
+ internal_request: {default: true}
176
+ }.freeze
177
+
178
+ FEATURE_CONFIG = CONFIGURATION.select { |_k, v| v[:feature] != false }
179
+ .freeze
180
+
181
+ MIGRATION_CONFIG = CONFIGURATION.select { |_k, v| v[:migrations] }
182
+ .map { |k, v| [k, v[:migrations]] }
183
+ .to_h
184
+ .freeze
185
+
186
+ VIEW_CONFIG = CONFIGURATION.select { |_k, v| v[:views] }
187
+ .map { |k, v| [k, v[:views]] }
188
+ .to_h
189
+ .freeze
190
+
191
+ private
192
+
193
+ def configuration
194
+ CONFIGURATION
195
+ end
196
+
197
+ def feature_config
198
+ FEATURE_CONFIG
199
+ end
200
+
201
+ def migration_config
202
+ MIGRATION_CONFIG
203
+ end
204
+
205
+ def view_config
206
+ VIEW_CONFIG
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,125 @@
1
+ module Pu
2
+ module Rodauth
3
+ module Concerns
4
+ module FeatureSelector
5
+ def self.included(base)
6
+ base.send :include, Configuration
7
+
8
+ base.send :class_option, :primary, type: :boolean,
9
+ desc: "[CONFIG] generated account is primary"
10
+ base.send :class_option, :argon2, type: :boolean, default: false,
11
+ desc: "[CONFIG] use Argon2 for password hashing"
12
+ base.send :class_option, :mails, type: :boolean, default: true, desc: "[CONFIG] setup mails"
13
+ base.send :class_option, :api_only, type: :boolean, default: false,
14
+ desc: "[CONFIG] configure only json api support"
15
+
16
+ config_features = {}
17
+ base::CONFIGURATION.sort.each do |feature, opts|
18
+ feature = feature.to_sym
19
+ modifier = "[*]" if opts[:default]
20
+ default_description = "[FEATURE]#{modifier} #{feature}"
21
+ description = opts[:desc] || default_description
22
+
23
+ base.define_method :"#{feature}?" do
24
+ feature_selected?(feature)
25
+ end
26
+
27
+ if opts[:feature] != false
28
+ base.send :class_option, feature, type: :boolean, desc: description
29
+ else
30
+ config_features[feature] = description
31
+ end
32
+ end
33
+
34
+ config_features.each do |feature, description|
35
+ base.send :class_option, feature, type: :boolean, desc: description
36
+ end
37
+
38
+ base.send :class_option, :kitchen_sink, type: :boolean, default: false,
39
+ desc: "[CONFIG] enable all supported features"
40
+ base.send :class_option, :defaults, type: :boolean, default: true,
41
+ desc: "[CONFIG] enable default features (indicated with [*])"
42
+ end
43
+
44
+ private
45
+
46
+ def feature_selected?(feature)
47
+ return true if kitchen_sink?
48
+
49
+ # base is special. so long as it is not explicitly disabled, always allow it through
50
+ return true if feature == :base && options[:base] != false
51
+
52
+ feature_options = configuration[feature]
53
+ case feature
54
+ when :json, :jwt
55
+ return true if only_json?
56
+ when :remember
57
+ return false if only_json?
58
+ end
59
+
60
+ return feature_options[:default] if defaults? && options[feature].nil?
61
+
62
+ options[feature]
63
+ end
64
+
65
+ # Creates a hash of options to pass down options to an invoked sub generator
66
+ def invoke_options
67
+ # These are custom options we want to track.
68
+ extra_options = %i[primary argon2 mails kitchen_sink defaults]
69
+ # Append them to all the available options from our configuration
70
+ valid_options = configuration.keys.map(&:to_sym).concat extra_options
71
+ # Index map the list with the selection value
72
+ opts = valid_options.map { |opt| [opt, send(:"#{opt}?")] }.to_h.compact
73
+ # True only options. We don't care if they are false.
74
+ %i[api_only force skip pretend quiet].each do |key|
75
+ next unless options[key]
76
+
77
+ opts[key] = options[key]
78
+ end
79
+
80
+ opts
81
+ end
82
+
83
+ def all_selected
84
+ @all_selected ||= configuration.keys.select { |feature| send(:"#{feature}?") }
85
+ end
86
+
87
+ def selected_features
88
+ @selected_features ||= (all_selected & feature_config.keys)
89
+ end
90
+
91
+ def selected_migration_features
92
+ @selected_migration_features ||= (all_selected & migration_config.keys).map(&:to_s)
93
+ end
94
+
95
+ def selected_view_features
96
+ @selected_view_features ||= (all_selected & view_config.keys).map(&:to_s)
97
+ end
98
+
99
+ def primary?
100
+ options[:primary]
101
+ end
102
+
103
+ def argon2?
104
+ options[:argon2]
105
+ end
106
+
107
+ def mails?
108
+ defined?(ActionMailer) && options[:mails]
109
+ end
110
+
111
+ def only_json?
112
+ ::Rails.application.config.api_only || !::Rails.application.config.session_store || options[:api_only]
113
+ end
114
+
115
+ def kitchen_sink?
116
+ options[:kitchen_sink]
117
+ end
118
+
119
+ def defaults?
120
+ options[:defaults]
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,69 @@
1
+ require "rails/generators/base"
2
+ require "securerandom"
3
+
4
+ module Pu
5
+ module Rodauth
6
+ class InstallGenerator < ::Rails::Generators::Base
7
+ SEQUEL_ADAPTERS = {
8
+ "postgresql" => (RUBY_ENGINE == "jruby") ? "postgresql" : "postgres",
9
+ "mysql2" => (RUBY_ENGINE == "jruby") ? "mysql" : "mysql2",
10
+ "sqlite3" => "sqlite",
11
+ "oracle_enhanced" => "oracle",
12
+ "sqlserver" => (RUBY_ENGINE == "jruby") ? "mssql" : "tinytds"
13
+ }
14
+
15
+ source_root "#{__dir__}/templates"
16
+
17
+ desc "Install rodauth-rails"
18
+
19
+ def add_rodauth
20
+ Bundler.with_unbundled_env do
21
+ run "bundle add bcrypt"
22
+ run "bundle add rodauth-rails"
23
+ end
24
+ end
25
+
26
+ def create_rodauth_initializer
27
+ template "config/initializers/rodauth.rb"
28
+ end
29
+
30
+ def create_rodauth_controller
31
+ template "app/controllers/rodauth_controller.rb"
32
+ end
33
+
34
+ def create_rodauth_app
35
+ template "app/misc/rodauth_app.rb"
36
+ template "app/misc/rodauth_plugin.rb"
37
+ end
38
+
39
+ def add_dev_config
40
+ insert_into_file "config/environments/development.rb",
41
+ "\n config.action_mailer.default_url_options = { host: '127.0.0.1', port: ENV.fetch('PORT', 3000) }\n",
42
+ before: /^end/
43
+ end
44
+
45
+ def show_instructions
46
+ readme "INSTRUCTIONS" if behavior == :invoke
47
+ end
48
+
49
+ private
50
+
51
+ def sequel_activerecord_integration?
52
+ defined?(ActiveRecord::Railtie) &&
53
+ (!defined?(Sequel) || Sequel::DATABASES.empty?)
54
+ end
55
+
56
+ def sequel_adapter
57
+ SEQUEL_ADAPTERS[activerecord_adapter] || activerecord_adapter
58
+ end
59
+
60
+ def activerecord_adapter
61
+ if ActiveRecord::Base.respond_to?(:connection_db_config)
62
+ ActiveRecord::Base.connection_db_config.adapter
63
+ else
64
+ ActiveRecord::Base.connection_config.fetch(:adapter)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,8 @@
1
+ # Used by the account expiration feature
2
+ create_table :<%= table_prefix %>_activity_times, id: false do |t|
3
+ t.<%= primary_key_type(nil) %> :id, primary_key: true
4
+ t.foreign_key :<%= table_prefix.pluralize %>, column: :id
5
+ t.datetime :last_activity_at, null: false
6
+ t.datetime :last_login_at, null: false
7
+ t.datetime :expired_at
8
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the active sessions feature
2
+ create_table :<%= table_prefix %>_active_session_keys, primary_key: [:<%= table_prefix %>_id, :session_id] do |t|
3
+ t.references :<%= table_prefix %>, foreign_key: true<%= primary_key_type(:type) %>
4
+ t.string :session_id
5
+ t.datetime :created_at, null: false, default: -> { "<%= current_timestamp %>" }
6
+ t.datetime :last_use, null: false, default: -> { "<%= current_timestamp %>" }
7
+ end
@@ -0,0 +1,16 @@
1
+ # Used by the audit logging feature
2
+ create_table :<%= table_prefix %>_authentication_audit_logs<%= primary_key_type %> do |t|
3
+ t.references :<%= table_prefix %>, foreign_key: true, null: false<%= primary_key_type(:type) %>
4
+ t.datetime :at, null: false, default: -> { "<%= current_timestamp %>" }
5
+ t.text :message, null: false
6
+ <% case activerecord_adapter -%>
7
+ <% when "postgresql" -%>
8
+ t.jsonb :metadata
9
+ <% when "sqlite3", "mysql2", "trilogy" -%>
10
+ t.json :metadata
11
+ <% else -%>
12
+ t.string :metadata
13
+ <% end -%>
14
+ t.index [:<%= table_prefix %>_id, :at], name: "audit_<%= table_prefix %>_at_idx"
15
+ t.index :at, name: "audit_at_idx"
16
+ end
@@ -0,0 +1,22 @@
1
+ <% if activerecord_adapter == "postgresql" -%>
2
+ enable_extension "citext"
3
+
4
+ <% end -%>
5
+ create_table :<%= table_prefix.pluralize %><%= primary_key_type %> do |t|
6
+ t.integer :status, null: false, default: 1
7
+ <% case activerecord_adapter -%>
8
+ <% when "postgresql" -%>
9
+ t.citext :email, null: false
10
+ <% else -%>
11
+ t.string :email, null: false
12
+ <% end -%>
13
+ <% case activerecord_adapter -%>
14
+ <% when "postgresql", "sqlite3" -%>
15
+ t.index :email, unique: true, where: "status IN (1, 2)"
16
+ <% else -%>
17
+ t.index :email, unique: true
18
+ <% end -%>
19
+ <% unless separate_passwords? -%>
20
+ t.string :password_hash
21
+ <% end -%>
22
+ end
@@ -0,0 +1,5 @@
1
+ # Used by the disallow password reuse feature
2
+ create_table :<%= table_prefix %>_previous_password_hashes do |t|
3
+ t.references :<%= table_prefix %>, foreign_key: true<%= primary_key_type(:type) %>
4
+ t.string :password_hash, null: false
5
+ end
@@ -0,0 +1,8 @@
1
+ # Used by the email auth feature
2
+ create_table :<%= table_prefix %>_email_auth_keys, id: false do |t|
3
+ t.<%= primary_key_type(nil) %> :id, primary_key: true
4
+ t.foreign_key :<%= table_prefix.pluralize %>, column: :id
5
+ t.string :key, null: false
6
+ t.datetime :deadline, null: false
7
+ t.datetime :email_last_sent, null: false, default: -> { "<%= current_timestamp %>" }
8
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the jwt refresh feature
2
+ create_table :<%= table_prefix %>_jwt_refresh_keys<%= primary_key_type %> do |t|
3
+ t.references :<%= table_prefix %>, foreign_key: true, null: false<%= primary_key_type(:type) %>
4
+ t.string :key, null: false
5
+ t.datetime :deadline, null: false
6
+ t.index :<%= table_prefix %>_id, name: "<%= table_prefix %>_jwt_rk_<%= table_prefix %>_id_idx"
7
+ end
@@ -0,0 +1,13 @@
1
+ # Used by the lockout feature
2
+ create_table :<%= table_prefix %>_login_failures, id: false do |t|
3
+ t.<%= primary_key_type(nil) %> :id, primary_key: true
4
+ t.foreign_key :<%= table_prefix.pluralize %>, column: :id
5
+ t.integer :number, null: false, default: 1
6
+ end
7
+ create_table :<%= table_prefix %>_lockouts, id: false do |t|
8
+ t.<%= primary_key_type(nil) %> :id, primary_key: true
9
+ t.foreign_key :<%= table_prefix.pluralize %>, column: :id
10
+ t.string :key, null: false
11
+ t.datetime :deadline, null: false
12
+ t.datetime :email_last_sent
13
+ end
@@ -0,0 +1,8 @@
1
+ # Used by the otp feature
2
+ create_table :<%= table_prefix %>_otp_keys, id: false do |t|
3
+ t.<%= primary_key_type(nil) %> :id, primary_key: true
4
+ t.foreign_key :<%= table_prefix.pluralize %>, column: :id
5
+ t.string :key, null: false
6
+ t.integer :num_failures, null: false, default: 0
7
+ t.datetime :last_use, null: false, default: -> { "<%= current_timestamp %>" }
8
+ end
@@ -0,0 +1,6 @@
1
+ # Used by the password expiration feature
2
+ create_table :<%= table_prefix %>_password_change_times, id: false do |t|
3
+ t.<%= primary_key_type(nil) %> :id, primary_key: true
4
+ t.foreign_key :<%= table_prefix.pluralize %>, column: :id
5
+ t.datetime :changed_at, null: false, default: -> { "<%= current_timestamp %>" }
6
+ end
@@ -0,0 +1,6 @@
1
+ # Used by the recovery codes feature
2
+ create_table :<%= table_prefix %>_recovery_codes, primary_key: [:id, :code] do |t|
3
+ t.<%= primary_key_type(nil) %> :id
4
+ t.foreign_key :<%= table_prefix.pluralize %>, column: :id
5
+ t.string :code
6
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the remember me feature
2
+ create_table :<%= table_prefix %>_remember_keys, id: false do |t|
3
+ t.<%= primary_key_type(nil) %> :id, primary_key: true
4
+ t.foreign_key :<%= table_prefix.pluralize %>, column: :id
5
+ t.string :key, null: false
6
+ t.datetime :deadline, null: false
7
+ end