-
- <%= form.radio_button :upgrades_mode, "manual", checked: Setting.upgrades_mode == "manual", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
- <%= form.label :upgrades_mode_manual, t(".upgrades.manual.title"), class: "text-gray-900 text-sm" do %>
- <%= t(".upgrades.manual.title") %>
-
-
- <%= t(".upgrades.manual.description") %>
-
- <% end %>
-
-
- <%= form.radio_button :upgrades_mode, "release", checked: Setting.upgrades_mode == "auto" && Setting.upgrades_target == "release", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
- <%= form.label :upgrades_mode_release, t(".upgrades.latest_release.title"), class: "text-gray-900 text-sm" do %>
- <%= t(".upgrades.latest_release.title") %>
-
-
- <%= t(".upgrades.latest_release.description") %>
-
- <% end %>
-
-
- <%= form.radio_button :upgrades_mode, "commit", checked: Setting.upgrades_mode == "auto" && Setting.upgrades_target == "commit", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
- <%= form.label :upgrades_mode_commit, t(".upgrades.latest_commit.title"), class: "text-gray-900 text-sm" do %>
- <%= t(".upgrades.latest_commit.title") %>
-
-
- <%= t(".upgrades.latest_commit.description") %>
-
- <% end %>
-
+ <% if ENV["HOSTING_PLATFORM"] == "render" %>
+ <%= settings_section title: t(".general_settings_title") do %>
+ <%= styled_form_with model: Setting.new, url: settings_hosting_path, method: :patch, data: { controller: "auto-submit-form", "auto-submit-form-trigger-event-value" => "blur" } do |form| %>
+
<%= t(".upgrades.title") %>
+
<%= t(".upgrades.description") %>
+
+
+
+ <%= form.radio_button :upgrades_mode, "manual", checked: Setting.upgrades_mode == "manual", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
+ <%= form.label :upgrades_mode_manual, t(".upgrades.manual.title"), class: "text-gray-900 text-sm" do %>
+ <%= t(".upgrades.manual.title") %>
+
+
+ <%= t(".upgrades.manual.description") %>
+
+ <% end %>
+
+
+ <%= form.radio_button :upgrades_mode, "release", checked: Setting.upgrades_mode == "auto" && Setting.upgrades_target == "release", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
+ <%= form.label :upgrades_mode_release, t(".upgrades.latest_release.title"), class: "text-gray-900 text-sm" do %>
+ <%= t(".upgrades.latest_release.title") %>
+
+
+ <%= t(".upgrades.latest_release.description") %>
+
+ <% end %>
+
+
+ <%= form.radio_button :upgrades_mode, "commit", checked: Setting.upgrades_mode == "auto" && Setting.upgrades_target == "commit", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
+ <%= form.label :upgrades_mode_commit, t(".upgrades.latest_commit.title"), class: "text-gray-900 text-sm" do %>
+ <%= t(".upgrades.latest_commit.title") %>
+
+
+ <%= t(".upgrades.latest_commit.description") %>
+
+ <% end %>
@@ -51,37 +50,75 @@
<%= form.url_field :render_deploy_hook, label: t(".render_deploy_hook_label"), placeholder: t(".render_deploy_hook_placeholder"), value: Setting.render_deploy_hook, data: { "auto-submit-form-target" => "auto" } %>
-
<%= t(".smtp_settings.title") %>
-
<%= t(".smtp_settings.description") %>
-
-
- <%= form.text_field :email_sender, label: t(".email_sender"), placeholder: t(".email_sender_placeholder"), value: Setting.email_sender, data: { "auto-submit-form-target" => "auto" } %>
- <%= form.text_field :app_domain, label: t(".domain"), placeholder: t(".domain_placeholder"), value: Setting.app_domain, data: { "auto-submit-form-target" => "auto" } %>
- <%= form.text_field :smtp_host, label: t(".smtp_settings.host"), placeholder: t(".smtp_settings.host_placeholder"), value: Setting.smtp_host, data: { "auto-submit-form-target" => "auto" } %>
- <%= form.number_field :smtp_port, label: t(".smtp_settings.port"), placeholder: t(".smtp_settings.port_placeholder"), value: Setting.smtp_port, data: { "auto-submit-form-target" => "auto" } %>
- <%= form.text_field :smtp_username, label: t(".smtp_settings.username"), placeholder: t(".smtp_settings.username_placeholder"), value: Setting.smtp_username, data: { "auto-submit-form-target" => "auto" } %>
- <%= form.password_field :smtp_password, label: t(".smtp_settings.password"), placeholder: t(".smtp_settings.password_placeholder"), value: Setting.smtp_password, data: { "auto-submit-form-target" => "auto" } %>
-
-
-
-
- <%= lucide_icon "mails", class: "w-6 h-6 text-gray-500" %>
-
-
-
<%= t(".smtp_settings.send_test_email") %>
-
<%= t(".smtp_settings.send_test_email_description") %>
-
+ <%= settings_section title: t(".smtp_settings.title") do %>
+ <%= styled_form_with model: Setting.new, url: settings_hosting_path, method: :patch, data: { controller: "auto-submit-form", "auto-submit-form-trigger-event-value" => "blur" } do |form| %>
+
<%= t(".smtp_settings.description") %>
+
+
+ <%= form.text_field :email_sender, label: t(".email_sender"), placeholder: t(".email_sender_placeholder"), value: Setting.email_sender, data: { "auto-submit-form-target" => "auto" } %>
+ <%= form.text_field :app_domain, label: t(".domain"), placeholder: t(".domain_placeholder"), value: Setting.app_domain, data: { "auto-submit-form-target" => "auto" } %>
+ <%= form.text_field :smtp_host, label: t(".smtp_settings.host"), placeholder: t(".smtp_settings.host_placeholder"), value: Setting.smtp_host, data: { "auto-submit-form-target" => "auto" } %>
+ <%= form.number_field :smtp_port, label: t(".smtp_settings.port"), placeholder: t(".smtp_settings.port_placeholder"), value: Setting.smtp_port, data: { "auto-submit-form-target" => "auto" } %>
+ <%= form.text_field :smtp_username, label: t(".smtp_settings.username"), placeholder: t(".smtp_settings.username_placeholder"), value: Setting.smtp_username, data: { "auto-submit-form-target" => "auto" } %>
+ <%= form.password_field :smtp_password, label: t(".smtp_settings.password"), placeholder: t(".smtp_settings.password_placeholder"), value: Setting.smtp_password, data: { "auto-submit-form-target" => "auto" } %>
+
+
+
+
+ <%= lucide_icon "mails", class: "w-6 h-6 text-gray-500" %>
- <%= link_to t(".smtp_settings.send_test_email_button"), send_test_email_settings_hosting_path, data: { turbo_method: :post }, class: "bg-gray-50 text-gray-900 text-sm font-medium rounded-lg px-3 py-2" %>
+
<%= t(".smtp_settings.send_test_email") %>
+
<%= t(".smtp_settings.send_test_email_description") %>
+
+ <%= link_to t(".smtp_settings.send_test_email_button"), send_test_email_settings_hosting_path, data: { turbo_method: :post }, class: "bg-gray-50 text-gray-900 text-sm font-medium rounded-lg px-3 py-2" %>
+
<% end %>
<% end %>
+ <%= settings_section title: t(".invite_settings.title") do %>
+
+
+
+
<%= t(".invite_settings.require_invite_for_signup") %>
+
<%= t(".invite_settings.invite_code_description") %>
+
+
+ <%= styled_form_with model: Setting.new, url: settings_hosting_path, method: :patch, data: { controller: "auto-submit-form", "auto-submit-form-trigger-event-value" => "blur" } do |form| %>
+
+ <%= form.check_box :require_invite_for_signup, class: "sr-only peer", "data-auto-submit-form-target": "auto", "data-autosubmit-trigger-event": "input" %>
+ <%= form.label :require_invite_for_signup, " ".html_safe, class: "maybe-switch" %>
+
+ <% end %>
+
+
+ <% if Setting.require_invite_for_signup %>
+
+
+ <%= t(".invite_settings.generated_tokens") %>
+
+
+ <%= button_to invite_codes_path,
+ method: :post,
+ class: "flex gap-1 bg-gray-50 text-gray-900 text-sm rounded-lg px-3 py-2" do %>
+ <%= t(".invite_settings.generate_tokens") %>
+ <% end %>
+
+
+
+
+ <%= turbo_frame_tag :invite_codes, src: invite_codes_path %>
+
+ <% end %>
+
+ <% end %>
+
<%= settings_nav_footer %>
diff --git a/config/locales/views/invite_codes/en.yml b/config/locales/views/invite_codes/en.yml
new file mode 100644
index 00000000..8517ae82
--- /dev/null
+++ b/config/locales/views/invite_codes/en.yml
@@ -0,0 +1,7 @@
+---
+en:
+ invite_codes:
+ index:
+ invite_code_description: Generate a new code to see it displayed here. Generated
+ codes that have been used will no longer be shown.
+ no_invite_codes: No codes to show
diff --git a/config/locales/views/settings/en.yml b/config/locales/views/settings/en.yml
index 5484cf82..700ec20a 100644
--- a/config/locales/views/settings/en.yml
+++ b/config/locales/views/settings/en.yml
@@ -12,6 +12,13 @@ en:
email_sender: Email Sender
email_sender_placeholder: user@mydomain.com
general_settings_title: General Settings
+ invite_settings:
+ generate_tokens: Generate new code
+ generated_tokens: Generated codes
+ invite_code_description: Every new user that joins your instance if Maybe
+ can only do so via an invite code
+ require_invite_for_signup: Require invite code for new sign ups
+ title: Invite Codes
page_title: Self-Hosting
provider_settings:
title: Provider Settings
diff --git a/config/routes.rb b/config/routes.rb
index 63380659..9acbdbe1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -96,6 +96,7 @@ Rails.application.routes.draw do
end
resources :institutions, except: %i[index show]
+ resources :invite_codes, only: %i[index create]
resources :issues, only: :show
diff --git a/test/system/settings_test.rb b/test/system/settings_test.rb
index 3200672b..10d09663 100644
--- a/test/system/settings_test.rb
+++ b/test/system/settings_test.rb
@@ -31,6 +31,21 @@ class SettingsTest < ApplicationSystemTestCase
end
end
+ test "can update self hosting settings" do
+ Rails.application.config.app_mode.stubs(:self_hosted?).returns(true)
+ open_settings_from_sidebar
+ assert_selector "li", text: "Self hosting"
+ click_link "Self hosting"
+ assert_current_path settings_hosting_path
+ assert_selector "h1", text: "Self-Hosting"
+ check "setting_require_invite_for_signup", allow_label_click: true
+ click_button "Generate new code"
+ assert_selector 'span[data-clipboard-target="source"]', visible: true, count: 1 # invite code copy widget
+ copy_button = find('button[data-action="clipboard#copy"]', match: :first) # Find the first copy button (adjust if needed)
+ copy_button.click
+ assert_selector 'span[data-clipboard-target="iconSuccess"]', visible: true, count: 1 # text copied and icon changed to checkmark
+ end
+
private
def open_settings_from_sidebar