plutonium 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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