plutonium 0.10.1 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/app/assets/javascripts/turbo/index.js +1 -1
  4. data/app/views/application/_flash_alerts.html.erb +3 -0
  5. data/app/views/application/_flash_toasts.html.erb +2 -0
  6. data/app/views/application/_resource_header.html.erb +12 -12
  7. data/app/views/components/base.rb +1 -1
  8. data/app/views/layouts/resource.html copy.erb +2 -2
  9. data/app/views/layouts/resource.html.erb +3 -2
  10. data/app/views/layouts/rodauth.html.erb +13 -8
  11. data/app/views/resource/_nav_user.html.erb +1 -1
  12. data/app/views/resource/index.rabl +1 -1
  13. data/app/views/rodauth/add_recovery_codes.html.erb +8 -7
  14. data/app/views/rodauth/otp_auth.html.erb +1 -1
  15. data/app/views/rodauth/otp_setup.html.erb +10 -8
  16. data/brakeman.ignore +1 -1
  17. data/config/initializers/rabl.rb +2 -0
  18. data/css.manifest +1 -1
  19. data/js.manifest +2 -2
  20. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +0 -3
  21. data/lib/generators/pu/core/ruby/ruby_generator.rb +30 -0
  22. data/lib/generators/pu/core/ruby/templates/.keep +0 -0
  23. data/lib/generators/pu/docker/install/install_generator.rb +35 -0
  24. data/lib/generators/pu/docker/install/templates/.keep +0 -0
  25. data/lib/generators/pu/docker/install/templates/Dockerfile.dev.tt +30 -0
  26. data/lib/generators/pu/docker/install/templates/Dockerfile.tt +75 -0
  27. data/lib/generators/pu/docker/install/templates/bin/console +3 -0
  28. data/lib/generators/pu/docker/install/templates/bin/restart +3 -0
  29. data/lib/generators/pu/docker/install/templates/bin/shell +3 -0
  30. data/lib/generators/pu/docker/install/templates/docker-compose.yml +29 -0
  31. data/lib/generators/pu/gem/dotenv/dotenv_generator.rb +32 -0
  32. data/lib/generators/pu/gem/dotenv/templates/.env +6 -0
  33. data/lib/generators/pu/gem/dotenv/templates/.env.local +5 -0
  34. data/lib/generators/pu/gem/dotenv/templates/.env.local.template +5 -0
  35. data/lib/generators/pu/gem/dotenv/templates/.env.template +6 -0
  36. data/lib/generators/pu/gem/dotenv/templates/.keep +0 -0
  37. data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +15 -0
  38. data/lib/generators/pu/gem/redis/redis_generator.rb +22 -0
  39. data/lib/generators/pu/gem/redis/templates/.keep +0 -0
  40. data/lib/generators/pu/gen/pug/pug_generator.rb +6 -0
  41. data/lib/generators/pu/gen/pug/templates/pug.rb.tt +1 -1
  42. data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +154 -32
  43. data/lib/generators/pu/lib/plutonium_generators/generator.rb +6 -6
  44. data/lib/generators/pu/lib/plutonium_generators/installer.rb +1 -1
  45. data/lib/generators/pu/pkg/app/templates/config/routes.rb.tt +3 -3
  46. data/lib/generators/pu/rodauth/account_generator.rb +10 -10
  47. data/lib/generators/pu/rodauth/install_generator.rb +9 -2
  48. data/lib/generators/pu/rodauth/migration/sequel/audit_logging.erb +2 -2
  49. data/lib/generators/pu/rodauth/migration_generator.rb +1 -1
  50. data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/account_rodauth_plugin.rb.tt +2 -2
  51. data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/rodauth_plugin.rb.tt +0 -3
  52. data/lib/generators/pu/rodauth/templates/db/migrate/install_rodauth.rb.tt +5 -0
  53. data/lib/generators/pu/service/postgres/postgres_generator.rb +61 -0
  54. data/lib/generators/pu/service/postgres/templates/.keep +0 -0
  55. data/lib/generators/pu/service/postgres/templates/bin/initdb.d/create-multiple-postgresql-databases.sh +22 -0
  56. data/lib/generators/pu/service/postgres/templates/database.yml.tt +93 -0
  57. data/lib/generators/pu/service/sidekiq/sidekiq_generator.rb +62 -0
  58. data/lib/generators/pu/service/sidekiq/templates/.keep +0 -0
  59. data/lib/generators/pu/service/sidekiq/templates/app/sidekiq/sidekiq_job.rb +5 -0
  60. data/lib/generators/pu/service/sidekiq/templates/config/initializers/sidekiq.rb +53 -0
  61. data/lib/generators/pu/service/sidekiq/templates/config/sidekiq.yml +6 -0
  62. data/lib/plutonium/config.rb +7 -13
  63. data/lib/plutonium/core/autodiscovery/input_discoverer.rb +1 -1
  64. data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +1 -1
  65. data/lib/plutonium/core/controllers/base.rb +13 -3
  66. data/lib/plutonium/core/controllers/entity_scoping.rb +3 -3
  67. data/lib/plutonium/core/controllers/queryable.rb +3 -1
  68. data/lib/plutonium/icons.rb +1 -1
  69. data/lib/plutonium/pkg/app.rb +6 -0
  70. data/lib/plutonium/railtie.rb +19 -0
  71. data/lib/plutonium/reloader.rb +99 -0
  72. data/lib/plutonium/resource/controller.rb +62 -22
  73. data/lib/plutonium/resource/policy.rb +56 -9
  74. data/lib/plutonium/resource/presenter.rb +44 -12
  75. data/lib/plutonium/resource/query_object.rb +186 -73
  76. data/lib/plutonium/resource/record.rb +213 -119
  77. data/lib/plutonium/rodauth/controller_methods.rb +7 -0
  78. data/lib/plutonium/version.rb +1 -1
  79. data/lib/plutonium.rb +54 -12
  80. data/lib/tasks/create_rodauth_admin.rake +16 -0
  81. data/package-lock.json +174 -0
  82. data/package.json +2 -0
  83. data/public/plutonium-assets/plutonium-app-6WILQCTT.js +39 -0
  84. data/public/plutonium-assets/plutonium-app-6WILQCTT.js.map +7 -0
  85. data/public/plutonium-assets/plutonium-logo-original.png +0 -0
  86. data/public/plutonium-assets/plutonium-logo-white.png +0 -0
  87. data/public/plutonium-assets/plutonium-logo.png +0 -0
  88. data/public/plutonium-assets/plutonium.2d4f0c333cd000051d3b.css +3424 -0
  89. data/public/plutonium-assets/plutonium.8bee7a8482988b0360e3.css +3420 -0
  90. data/public/plutonium-assets/plutonium.ico +0 -0
  91. metadata +44 -7
  92. data/lib/plutonium/reactor/core.rb +0 -78
  93. data/public/plutonium-assets/logo.png +0 -0
  94. /data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/rodauth_app.rb.tt +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62776ccdb807ad168a6e61bcea935268d749a932018c1064c6df354d125e06c2
4
- data.tar.gz: 1bbce05f7591948984c31d1a662b55a098248323e93f0c4e171aac107e132bf6
3
+ metadata.gz: b388378444b597bf548ce883ad18b8cc939fec40bc15e6096ddbef26c996306a
4
+ data.tar.gz: dfc4cfdcd18770e44a9199da71a54c034bc4adcc786cfc0460ba011557f65e5f
5
5
  SHA512:
6
- metadata.gz: 66844257f2a1b0cbeb59cbdfaa211ec87c176389a2e8058cf679d133b31f7f09d3fb21b98cea25b5856b5e43ed0572d3fb8872189464d0fbeedf7c0ce5d96cd4
7
- data.tar.gz: 1220dded69fae0946c2df3120f2c89db1262a38a481d461410dbac2b6dd76139805612fe3a1e470c2e5951684e401f98a38ef6ebce0b6040a7222e0129b88d3f
6
+ metadata.gz: '09aab730fac6b3ff2e9207f2ba4ad463c831b2c44864acc32d45c3774624af1e2fa3c25439eb07de33d91712092ccf3b475b121a4e45a97ecd6162f669ed1b7c'
7
+ data.tar.gz: 798e6181fd2b8bc520fe08ad7c7f10deecc3301f83f946b384b9762791efd6cd0b3bde541caec0d2b486b2d35ebd87c5ec03f55672ed4f5d540f1712f8c447c0
data/README.md CHANGED
@@ -56,6 +56,8 @@ TODO: Write usage instructions here
56
56
 
57
57
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
58
58
 
59
+ To build assets, run `npm dev`
60
+
59
61
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
60
62
 
61
63
  ## Contributing
@@ -85,4 +87,5 @@ rails new pluton8_starter --name="Pluton8 Starter" --database=sqlite3 --skip-act
85
87
  bin/rails app:template LOCATION=/Users/stefan/code/plutonium/starters/vulcan/gems/plutonium/templates/base.rb
86
88
  ```
87
89
 
90
+ rails g pu:rodauth:account admin --no-defaults --login --logout --remember --change-password --internal-request --create-account --lockout --verify-account --audit-logging --close-account --otp --reset-password --reset-password-notify --active-sessions --recovery-codes --password-grace-period
88
91
  -->
@@ -1,4 +1,4 @@
1
- // import * as Turbo from "@hotwired/turbo"
1
+ import * as Turbo from "@hotwired/turbo"
2
2
 
3
3
  import "./turbo_debug"
4
4
  // import "./turbo_actions"
@@ -1,5 +1,8 @@
1
+
1
2
  <% flash.each do |type, msg| %>
2
3
  <%
4
+ next unless msg.present?
5
+
3
6
  color = case type.to_sym
4
7
  when :success
5
8
  # bg-green-50 text-green-800 text-green-500 text-green-400 ring-green-400
@@ -1,5 +1,7 @@
1
1
  <% flash.each do |type, msg| %>
2
2
  <%
3
+ next unless msg.present?
4
+
3
5
  color = case type.to_sym
4
6
  when :success
5
7
  # text-green-500 bg-green-100 bg-green-800 text-green-200 bg-green-50 text-green-400 ring-green-400
@@ -35,13 +35,15 @@
35
35
  </svg>
36
36
  <span class="sr-only">Toggle sidebar</span>
37
37
  </button>
38
- <a href="https://flowbite.com" class="flex items-center justify-between mr-4">
38
+ <a href="<%= root_path %>" class="flex items-center justify-between mr-4">
39
39
  <img
40
- src="https://flowbite.s3.amazonaws.com/logo.svg"
41
- class="mr-3 h-8"
42
- alt="Flowbite Logo"
40
+ src="<%= Plutonium.logo_link %>"
41
+ class="mr-3 h-10"
42
+ alt="<%= application_name %> Logo"
43
43
  />
44
- <span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white hidden xs:block">Plutonium</span>
44
+ <span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white hidden xs:block">
45
+ <%= application_name %>
46
+ </span>
45
47
  </a>
46
48
  <%# <form action="#" method="GET" class="hidden md:block md:pl-2">
47
49
  <label for="topbar-search" class="sr-only">Search</label>
@@ -704,18 +706,16 @@
704
706
  </a>
705
707
  </li>
706
708
  </ul>
709
+
710
+ <% if respond_to? :logout_url -%>
707
711
  <ul
708
712
  class="py-1 text-gray-700 dark:text-gray-300"
709
- aria-labelledby="dropdown"
710
- >
713
+ aria-labelledby="dropdown">
711
714
  <li>
712
- <a
713
- href="#"
714
- class="block py-2 px-4 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
715
- >Sign out</a
716
- >
715
+ <%= link_to "Sign out", logout_url, class: "block py-2 px-4 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white", data: { turbo: false } %>
717
716
  </li>
718
717
  </ul>
718
+ <% end -%>
719
719
  </div>
720
720
  </div>
721
721
  </div>
@@ -31,7 +31,7 @@ module Plutonium::Ui
31
31
  end
32
32
 
33
33
  def render_icon(icon)
34
- Plutonium::Icons.render(icon).html_safe
34
+ Plutonium::Icons.render(icon)
35
35
  end
36
36
 
37
37
  def attributes_to_string(attributes, prefix = nil)
@@ -15,8 +15,8 @@
15
15
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.css" integrity="sha512-GvqWM4KWH8mbgWIyvwdH8HgjUbyZTXrCq0sjGij9fDNiXz3vJoy3jCcAaWNekH2rJe4hXVWCJKN+bEW8V7AAEQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
16
16
  <script src="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.js" integrity="sha512-0E8oaoA2v32h26IycsmRDShtQ8kMgD91zWVBxdIvUCjU3xBw81PV61QBsBqNQpWkp/zYJZip8Ag3ifmzz1wCKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
17
17
 
18
- <%== Plutonium::Config.stylesheet_tag.call self %>
19
- <%== Plutonium::Config.script_tag.call self %>
18
+ <%= Plutonium::Config.stylesheet_tag.call self %>
19
+ <%= Plutonium::Config.script_tag.call self %>
20
20
  <%= yield(:head) %>
21
21
  </head>
22
22
  <body class="bg-body-tertiary">
@@ -7,6 +7,7 @@
7
7
  <meta name="turbo-cache-control" content="no-cache">
8
8
  <meta name="turbo-refresh-method" content="morph">
9
9
  <meta name="turbo-refresh-scroll" content="preserve">
10
+ <%= Plutonium::Config.favicon_tag.call self %>
10
11
  <%= csrf_meta_tags %>
11
12
  <%= csp_meta_tag %>
12
13
  <%= yield(:meta) %>
@@ -23,8 +24,8 @@
23
24
 
24
25
  <%= yield(:assets) %>
25
26
 
26
- <%== Plutonium::Config.stylesheet_tag.call self %>
27
- <%== Plutonium::Config.script_tag.call self %>
27
+ <%= Plutonium::Config.stylesheet_tag.call self %>
28
+ <%= Plutonium::Config.script_tag.call self %>
28
29
 
29
30
  <%= yield(:head) %>
30
31
  </head>
@@ -12,20 +12,25 @@
12
12
  <link rel="preconnect" href="https://fonts.googleapis.com">
13
13
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
14
  <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet">
15
- <%== Plutonium::Config.stylesheet_tag.call self %>
16
- <%== Plutonium::Config.script_tag.call self %>
15
+ <%= Plutonium::Config.stylesheet_tag.call self %>
16
+ <%= Plutonium::Config.script_tag.call self %>
17
17
  </head>
18
18
  <body class="antialiased bg-gray-50 dark:bg-gray-900">
19
19
  <main div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
20
- <a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
21
- <img class="w-8 h-8 mr-2" src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/logo.svg" alt="logo">
22
- Flowbite
23
- </a>
24
- <div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700">
25
- <div class="p-6 space-y-4 md:space-y-6 sm:p-8">
20
+ <%= render "flash" %>
21
+ <p class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
22
+ <img class="w-16 h-16 mr-2" src="<%= Plutonium.logo_link %>" alt="logo">
23
+ <%= application_name %>
24
+ </p>
25
+ <div class="w-full max-w-md bg-white rounded-lg shadow dark:border md:mt-0 xl:p-0 dark:bg-gray-800 dark:border-gray-700">
26
+ <div class="w-full p-6 space-y-4 md:space-y-6 sm:p-8">
26
27
  <%= yield %>
27
28
  </div>
28
29
  </div>
30
+ <div class="mt-4 flex items-center font-medium text-blue-600 dark:text-blue-500 hover:underline">
31
+ <%= Plutonium::Icons.render "outline/home" %>
32
+ <%= link_to "Home", root_path, class: "font-medium text-blue-600 dark:text-blue-500" %>
33
+ </div>
29
34
  </main>
30
35
  </body>
31
36
  </html>
@@ -1,4 +1,4 @@
1
1
  <%= display_name_of current_user %>
2
2
  <% if respond_to? :logout_url -%>
3
- <%= link_to "Sign out", "/", class: "btn btn-outline-primary", data: { turbo: false } %>
3
+ <%= link_to "Sign out", logout_url, class: "btn btn-outline-primary", data: { turbo: false } %>
4
4
  <% end -%>
@@ -1,3 +1,3 @@
1
1
  collection @resource_records, root: resource_class.to_s.demodulize.underscore.pluralize.to_sym, object_root: false
2
2
 
3
- extends "_resource"
3
+ extends "_resource_details"
@@ -1,16 +1,17 @@
1
1
  <div>
2
- <% if rodauth.recovery_codes.any? %>
3
- <div class="text-sm px-4 py-3 bg-white rounded-lg border shadow-lg grid grid-cols-2 gap-y-2 gap-x-4 dark:bg-gray-900 dark:text-gray-200">
2
+ <h4 class="text-2xl font-bold dark:text-white mb-4">Recovery Codes</h4>
3
+
4
+ <div class="mb-4 text-sm grid grid-cols-1 gap-y-2 gap-x-4 dark:bg-gray-900 dark:text-gray-200">
5
+ <% if rodauth.recovery_codes.any? %>
4
6
  <% rodauth.recovery_codes.each do |code| %>
5
7
  <div class="font-mono"><%= code %></div>
6
8
  <% end %>
7
- </div>
8
- <% end %>
9
+ <% else %>
10
+ <div class="font-mono">You have no recovery codes</div>
11
+ <% end %>
12
+ </div>
9
13
 
10
14
  <% if rodauth.can_add_recovery_codes? %>
11
- <div class="text-2xl font-medium mt-6 mb-4">
12
- <%== rodauth.add_recovery_codes_heading %>
13
- </div>
14
15
  <%= render template: "rodauth/recovery_codes", layout: false %>
15
16
  <% end %>
16
17
  </div>
@@ -1,7 +1,7 @@
1
1
  <%= form_with url: rodauth.otp_auth_path, method: :post, data: { turbo: false }, class: "w-full max-w-sm" do |form| %>
2
2
  <div class="mb-6">
3
3
  <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
4
- <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-1/2 px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
4
+ <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-full px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
5
5
  <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
6
6
  </div>
7
7
 
@@ -2,8 +2,10 @@
2
2
  <%= form.hidden_field rodauth.otp_setup_param, value: rodauth.otp_user_key, id: "otp-key" %>
3
3
  <%= form.hidden_field rodauth.otp_setup_raw_param, value: rodauth.otp_key, id: "otp-hmac-secret" if rodauth.otp_keys_use_hmac? %>
4
4
 
5
- <div class="mb-6 w-48">
6
- <%== rodauth.otp_qr_code %>
5
+ <div class="mb-6 flex items-center justify-center">
6
+ <div class="w-48">
7
+ <%== rodauth.otp_qr_code %>
8
+ </div>
7
9
  </div>
8
10
 
9
11
  <dl class="mb-6 text-sm">
@@ -14,6 +16,12 @@
14
16
  <dd><%= rodauth.otp_provisioning_uri %></dd>
15
17
  </dl>
16
18
 
19
+ <div class="mb-6">
20
+ <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
21
+ <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-full px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }" , aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
22
+ <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
23
+ </div>
24
+
17
25
  <% if rodauth.two_factor_modifications_require_password? %>
18
26
  <div class="mb-6">
19
27
  <%= form.label "password", rodauth.password_label, class: "block text-sm font-semibold" %>
@@ -22,11 +30,5 @@
22
30
  </div>
23
31
  <% end %>
24
32
 
25
- <div class="mb-6">
26
- <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
27
- <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-1/2 px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
28
- <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
29
- </div>
30
-
31
33
  <%= form.submit rodauth.otp_setup_button, class: "w-full px-8 py-3 cursor-pointer font-semibold text-sm rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-600 dark:bg-emerald-400 dark:hover:bg-emerald-500 dark:text-gray-900 dark:focus:ring-emerald-400 dark:focus:ring-offset-current" %>
32
34
  <% end %>
data/brakeman.ignore CHANGED
@@ -6,7 +6,7 @@
6
6
  "fingerprint": "1cb8570b8c91f38317cdf909e01e7016359846174f427e86011633c344d30fc3",
7
7
  "check_name": "ForgerySetting",
8
8
  "message": "`protect_from_forgery` should be called in `Plutonium::Resource::Controller`",
9
- "file": "lib/plutonium/reactor/resource_controller.rb",
9
+ "file": "lib/plutonium/resource/controller.rb",
10
10
  "line": 10,
11
11
  "link": "https://brakemanscanner.org/docs/warning_types/cross-site_request_forgery/",
12
12
  "code": null,
@@ -58,3 +58,5 @@ module Rabl
58
58
  end
59
59
  end
60
60
  end
61
+
62
+ Rabl.register!
data/css.manifest CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "plutonium.css": "plutonium.50232e35b5495f5ad90d.css"
2
+ "plutonium.css": "plutonium.8bee7a8482988b0360e3.css"
3
3
  }
data/js.manifest CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "plutonium-app.js.map": "plutonium-app-36KN5FVJ.js.map",
3
- "plutonium-app.js": "plutonium-app-36KN5FVJ.js"
2
+ "plutonium-app.js.map": "plutonium-app-6WILQCTT.js.map",
3
+ "plutonium-app.js": "plutonium-app-6WILQCTT.js"
4
4
  }
@@ -1,4 +1 @@
1
1
  # Configure plutonium
2
-
3
- # Spin up the reactor!
4
- Plutonium::Reactor::Core.achieve_criticality!
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Core
7
+ class RubyGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set ruby version for project"
13
+ class_option :version, type: :string, desc: "Ruby version", default: "3.3.0"
14
+
15
+ def start
16
+ set_ruby_version! version
17
+ say "Ruby version set to #{version}"
18
+ say "Run `bundle install` to update your dependencies"
19
+ rescue => e
20
+ exception "#{self.class} failed:", e
21
+ end
22
+
23
+ private
24
+
25
+ def version
26
+ options[:version]
27
+ end
28
+ end
29
+ end
30
+ end
File without changes
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Docker
7
+ class InstallGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set up docker for project"
13
+
14
+ def start
15
+ in_root do
16
+ template "Dockerfile", force: true
17
+ template "Dockerfile.dev", force: true
18
+ template "docker-compose.yml", force: true
19
+ proc_file :web, "env RUBY_DEBUG_OPEN=true bin/rails server -b '0.0.0.0'", env: :dev
20
+ bin_directory
21
+ gitignore ".volumes"
22
+ dockerignore ".volumes"
23
+ end
24
+ rescue => e
25
+ exception "#{self.class} failed:", e
26
+ end
27
+
28
+ private
29
+
30
+ def ruby_version
31
+ @ruby_version ||= File.read(".ruby-version").strip
32
+ end
33
+ end
34
+ end
35
+ end
File without changes
@@ -0,0 +1,30 @@
1
+ # syntax = docker/dockerfile:1
2
+
3
+ # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
4
+ ARG RUBY_VERSION=<%= ruby_version %>
5
+ FROM registry.docker.com/library/ruby:$RUBY_VERSION
6
+
7
+ WORKDIR /rails
8
+
9
+ # Install packages needed to build gems and node modules
10
+ RUN apt-get update -qq && \
11
+ apt-get install --no-install-recommends -y build-essential curl git libpq-dev node-gyp pkg-config python-is-python3
12
+
13
+ # Install JavaScript dependencies
14
+ ARG NODE_VERSION=22.2.0
15
+ ARG YARN_VERSION=1.22.22
16
+ ENV PATH=/usr/local/node/bin:$PATH
17
+ RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
18
+ /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
19
+ npm install -g yarn@$YARN_VERSION && \
20
+ rm -rf /tmp/node-build-master
21
+
22
+ # Additional dependencies go here
23
+
24
+ # Upgrade RubyGems and install the latest Bundler version
25
+ RUN gem update --system && gem install bundler
26
+
27
+ # Document that we're going to expose port 3000
28
+ EXPOSE 3000
29
+ # Use Bash as the default command
30
+ CMD ["/bin/bash"]
@@ -0,0 +1,75 @@
1
+ # syntax = docker/dockerfile:1
2
+
3
+ # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
4
+ ARG RUBY_VERSION=<%= ruby_version %>
5
+ FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
6
+
7
+ # Rails app lives here
8
+ WORKDIR /rails
9
+
10
+ # Set production environment
11
+ ENV RAILS_ENV="production" \
12
+ BUNDLE_DEPLOYMENT="1" \
13
+ BUNDLE_PATH="/usr/local/bundle" \
14
+ BUNDLE_WITHOUT="development"
15
+
16
+
17
+ # Throw-away build stage to reduce size of final image
18
+ FROM base as build
19
+
20
+ # Install packages needed to build gems and node modules
21
+ RUN apt-get update -qq && \
22
+ apt-get install --no-install-recommends -y build-essential curl git libpq-dev node-gyp pkg-config python-is-python3
23
+
24
+ # Install JavaScript dependencies
25
+ ARG NODE_VERSION=22.2.0
26
+ ARG YARN_VERSION=1.22.22
27
+ ENV PATH=/usr/local/node/bin:$PATH
28
+ RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
29
+ /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
30
+ npm install -g yarn@$YARN_VERSION && \
31
+ rm -rf /tmp/node-build-master
32
+
33
+ # Install application gems
34
+ COPY .ruby-version Gemfile Gemfile.lock ./
35
+ RUN bundle install && \
36
+ rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
37
+ bundle exec bootsnap precompile --gemfile
38
+
39
+ # Install node modules
40
+ COPY package.json yarn.lock ./
41
+ RUN yarn install --frozen-lockfile
42
+
43
+ # Copy application code
44
+ COPY . .
45
+
46
+ # Precompile bootsnap code for faster boot times
47
+ RUN bundle exec bootsnap precompile app/ lib/
48
+
49
+ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY
50
+ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
51
+
52
+
53
+ # Final stage for app image
54
+ FROM base
55
+
56
+ # Install packages needed for deployment
57
+ RUN apt-get update -qq && \
58
+ apt-get install --no-install-recommends -y curl postgresql-client && \
59
+ rm -rf /var/lib/apt/lists /var/cache/apt/archives
60
+
61
+ # Copy built artifacts: gems, application
62
+ COPY --from=build /usr/local/bundle /usr/local/bundle
63
+ COPY --from=build /rails /rails
64
+
65
+ # Run and own only the runtime files as a non-root user for security
66
+ RUN useradd rails --create-home --shell /bin/bash && \
67
+ chown -R rails:rails db log tmp
68
+ USER rails:rails
69
+
70
+ # Entrypoint prepares the database.
71
+ ENTRYPOINT ["/rails/bin/docker-entrypoint"]
72
+
73
+ # Start the server by default, this can be overwritten at runtime
74
+ EXPOSE 3000
75
+ CMD ["./bin/rails", "server"]
@@ -0,0 +1,3 @@
1
+ #!/bin/bash -e
2
+
3
+ docker compose run --rm web bash -c "bundle && rails c"
@@ -0,0 +1,3 @@
1
+ #!/bin/bash -e
2
+
3
+ touch tmp/restart.txt
@@ -0,0 +1,3 @@
1
+ #!/bin/bash -e
2
+
3
+ docker compose run --rm web bash
@@ -0,0 +1,29 @@
1
+ ---
2
+ x-managed-by: plutonium
3
+
4
+ x-app: &app
5
+ build: # x-app
6
+ context: . # x-app
7
+ dockerfile: Dockerfile.dev # x-app
8
+ # x-app properties
9
+ volumes: # x-app
10
+ - ".:/rails" # x-app
11
+ - "./.volumes/bundle:/usr/local/bundle" # x-app
12
+ - "./.volumes/node_modules:/rails/node_modules" # x-app
13
+ - "./.volumes/shell_history:/root/shell_history" # x-app
14
+ depends_on: [] # x-app
15
+ environment: # x-app
16
+ RUBY_DEBUG_OPEN: true # x-app
17
+ PORT: 3000 # x-app
18
+ HISTFILE: /root/shell_history/.bash_history # x-app
19
+ tty: true # for binding.pry # x-app
20
+ stdin_open: true # for binding.pry # x-app
21
+
22
+ services:
23
+ web:
24
+ <<: *app
25
+ command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle && yarn && bin/dev" # web
26
+ # web properties
27
+ ports: # web
28
+ - "3000:3000" # app
29
+ # additional services go here
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Gem
7
+ class DotenvGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set up dotenv"
13
+
14
+ def start
15
+ in_root do
16
+ [".env", ".env.local", ".env.template", ".env.local.template"].each do |file|
17
+ copy_file file
18
+ end
19
+
20
+ copy_file "config/initializers/001_ensure_required_env.rb"
21
+
22
+ gitignore "!/.env.template", "!/.env.local.template", "!/.env"
23
+
24
+ insert_into_file "Gemfile", "\ngem \"dotenv\", :groups => [:development, :test]\n", after: /^gem ["']rails["'].*\n/
25
+ bundle!
26
+ end
27
+ rescue => e
28
+ exception "#{self.class} failed:", e
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,6 @@
1
+ # Secrets should NOT be added here.
2
+ # Set them in `.env.local`
3
+
4
+ # # == S3
5
+ # S3_REGION=S3_REGION
6
+ # S3_BUCKET=S3_BUCKET
@@ -0,0 +1,5 @@
1
+ # Secrets for local testing should be added here.
2
+
3
+ # # == S3
4
+ # S3_ACCESS_KEY_ID=S3_ACCESS_KEY_ID
5
+ # S3_SECRET_ACCESS_KEY=S3_SECRET_ACCESS_KEY
@@ -0,0 +1,5 @@
1
+ # Secrets for local testing should be added here.
2
+
3
+ # # == S3
4
+ # S3_ACCESS_KEY_ID=S3_ACCESS_KEY_ID
5
+ # S3_SECRET_ACCESS_KEY=S3_SECRET_ACCESS_KEY
@@ -0,0 +1,6 @@
1
+ # Secrets should NOT be added here.
2
+ # Set them in `.env.local`
3
+
4
+ # # == S3
5
+ # S3_REGION=S3_REGION
6
+ # S3_BUCKET=S3_BUCKET
File without changes
@@ -0,0 +1,15 @@
1
+ # Add required env vars to this list
2
+ required_env_vars = %w[]
3
+
4
+ # Add additional env vars here
5
+
6
+ # Check required env vars
7
+ required_env_vars.each do |env_var|
8
+ if !ENV.has_key?(env_var) || ENV[env_var].blank?
9
+ raise <<~EOL
10
+ Missing required environment variable: #{env_var}
11
+
12
+ Ask a teammate for the appropriate value.
13
+ EOL
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Gem
7
+ class RedisGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set up redis"
13
+
14
+ def start
15
+ bundle "redis"
16
+ bundle "hiredis"
17
+ rescue => e
18
+ exception "#{self.class} failed:", e
19
+ end
20
+ end
21
+ end
22
+ end
File without changes