From f0b88153b1ead3798ac1546500618d1411231940 Mon Sep 17 00:00:00 2001
From: James Smith
Date: Wed, 26 Nov 2025 13:06:40 +0000
Subject: [PATCH 1/5] Change CopyButton into a more complex CopyableText
component
---
app/components/copy_button.rb | 2 +-
app/components/copyable_text.rb | 27 ++++++++++++++++++++
app/views/collections/show.html.erb | 3 +--
app/views/creators/show.html.erb | 3 +--
app/views/devise/registrations/edit.html.erb | 3 +--
app/views/home/_federation.html.erb | 6 ++---
app/views/models/show.html.erb | 3 +--
7 files changed, 34 insertions(+), 13 deletions(-)
create mode 100644 app/components/copyable_text.rb
diff --git a/app/components/copy_button.rb b/app/components/copy_button.rb
index da26980ac..35b69e4bb 100644
--- a/app/components/copy_button.rb
+++ b/app/components/copy_button.rb
@@ -9,7 +9,7 @@ class Components::CopyButton < Components::Base
end
def view_template
- a href: "#", class: "link-secondary", data: {controller: "copy-text", action: "click->copy-text#copy:prevent", copy_text_text_value: @text} do
+ button class: "btn btn-secondary", data: {controller: "copy-text", action: "click->copy-text#copy:prevent", copy_text_text_value: @text} do
Icon icon: "clipboard-plus", label: @label
end
end
diff --git a/app/components/copyable_text.rb b/app/components/copyable_text.rb
new file mode 100644
index 000000000..c87d7d8ed
--- /dev/null
+++ b/app/components/copyable_text.rb
@@ -0,0 +1,27 @@
+class Components::CopyableText < Components::Base
+ def initialize(text:, label: nil, obfuscated: false)
+ @text = text
+ @label = label
+ @obfuscated = obfuscated
+ end
+
+ def before_template
+ @label ||= t("components.copy_button.copy")
+ end
+
+ def view_template
+ div do
+ span(class: @obfuscated ? "obfuscated" : nil) { @text }
+ whitespace
+ if @obfuscated
+ button class: "btn btn-sm btn-outline-secondary", title: t("components.copyable_text.reveal") do
+ Icon icon: "eye"
+ end
+ end
+ whitespace
+ button class: "btn btn-sm btn-outline-secondary", title: @label, data: {controller: "copy-text", action: "click->copy-text#copy:prevent", copy_text_text_value: @text} do
+ Icon icon: "clipboard-plus"
+ end
+ end
+ end
+end
diff --git a/app/views/collections/show.html.erb b/app/views/collections/show.html.erb
index 6e822dba7..24f11b827 100644
--- a/app/views/collections/show.html.erb
+++ b/app/views/collections/show.html.erb
@@ -19,8 +19,7 @@
<%= link_to @collection.federails_actor.at_address, @collection.federails_actor.profile_url, target: "new" %>
<% elsif SiteSettings.federation_enabled? %>
- <%= @collection.federails_actor.short_at_address %>
- <%= CopyButton(text: @collection.federails_actor.at_address, label: t("general.copy_fediverse_handle")) %>
+ <%= CopyableText(text: @collection.federails_actor.at_address, label: t("general.copy_fediverse_handle")) %>
<% end %>
diff --git a/app/views/creators/show.html.erb b/app/views/creators/show.html.erb
index d7563a082..48d8b6976 100644
--- a/app/views/creators/show.html.erb
+++ b/app/views/creators/show.html.erb
@@ -25,8 +25,7 @@
<%= link_to @creator.federails_actor.at_address, @creator.federails_actor.profile_url, target: "new" %>
<% elsif SiteSettings.federation_enabled? %>
- <%= @creator.federails_actor.short_at_address %>
- <%= CopyButton(text: @creator.federails_actor.at_address, label: t("general.copy_fediverse_handle")) %>
+ <%= CopyableText(text: @creator.federails_actor.at_address, label: t("general.copy_fediverse_handle")) %>
<% end %>
diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb
index 750f61826..1d5b8b49d 100644
--- a/app/views/devise/registrations/edit.html.erb
+++ b/app/views/devise/registrations/edit.html.erb
@@ -15,8 +15,7 @@
<% if SiteSettings.federation_enabled? %>
<%= t("settings.users.index.fediverse_address") %>
- <%= resource.federails_actor.at_address %>
- <%= CopyButton(text: resource.federails_actor.at_address, label: t("general.copy_fediverse_handle")) %>
+ <%= CopyableText(text: resource.federails_actor.at_address, label: t("general.copy_fediverse_handle")) %>
<% end %>
diff --git a/app/views/home/_federation.html.erb b/app/views/home/_federation.html.erb
index 333d6b14e..d93e51cbb 100644
--- a/app/views/home/_federation.html.erb
+++ b/app/views/home/_federation.html.erb
@@ -19,8 +19,7 @@
<%= t(".creator_handle") %>
- <%= current_user.creators.local.first.federails_actor.at_address %>
- <%= CopyButton text: current_user.creators.local.first.federails_actor.at_address, label: t("general.copy_fediverse_handle") %>
+ <%= CopyableText text: current_user.creators.local.first.federails_actor.at_address, label: t("general.copy_fediverse_handle") %>
@@ -33,8 +32,7 @@
<%= t(".account_handle") %>
- <%= current_user.federails_actor.at_address %>
- <%= CopyButton text: current_user.federails_actor.at_address, label: t("general.copy_fediverse_handle") %>
+ <%= CopyableText text: current_user.federails_actor.at_address, label: t("general.copy_fediverse_handle") %>
diff --git a/app/views/models/show.html.erb b/app/views/models/show.html.erb
index e9a140cdf..001c0ec61 100644
--- a/app/views/models/show.html.erb
+++ b/app/views/models/show.html.erb
@@ -91,8 +91,7 @@
<%= link_to @model.federails_actor.at_address, @model.federails_actor.profile_url, target: "new" %>
<% else %>
- <%= @model.federails_actor.short_at_address %>
- <%= CopyButton(text: @model.federails_actor.at_address, label: t("general.copy_fediverse_handle")) %>
+ <%= CopyableText(text: @model.federails_actor.at_address, label: t("general.copy_fediverse_handle")) %>
<% end %>
From 2b9797eb1bb6c41705ff272947313e3fc3031965 Mon Sep 17 00:00:00 2001
From: James Smith
Date: Wed, 26 Nov 2025 13:07:16 +0000
Subject: [PATCH 2/5] change oauth ID and secret into copyable text fields
---
app/views/doorkeeper_applications/show.html.erb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/doorkeeper_applications/show.html.erb b/app/views/doorkeeper_applications/show.html.erb
index aafaed751..a915f926d 100644
--- a/app/views/doorkeeper_applications/show.html.erb
+++ b/app/views/doorkeeper_applications/show.html.erb
@@ -8,11 +8,11 @@
| <%= Doorkeeper::Application.human_attribute_name :uid %> |
- <%= @application.uid %> |
+ <%= CopyableText text: @application.uid %> |
| <%= Doorkeeper::Application.human_attribute_name :secret %> |
- <%= @application.secret %> |
+ <%= CopyableText text: @application.secret, obfuscated: true %> |
| <%= Doorkeeper::Application.human_attribute_name :confidential %> |
From 96a9a771c6128ab8b5b4c95cc02af7fb43c3edd7 Mon Sep 17 00:00:00 2001
From: James Smith
Date: Wed, 26 Nov 2025 13:07:38 +0000
Subject: [PATCH 3/5] Add visual obfuscation for CopyableText components
---
app/assets/stylesheets/application.scss | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index dd3e82e02..3728223ac 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -47,3 +47,7 @@ p.notice:empty {
#navbar>ul.navbar-nav>li>a.nav-link {
color: var(--bs-navbar-hover-color) !important;
}
+
+span.obfuscated {
+ -webkit-text-security: disc;
+}
From 949d12a89e36c3cb3c06ac5655717e575b4320b3 Mon Sep 17 00:00:00 2001
From: James Smith
Date: Wed, 26 Nov 2025 14:11:43 +0000
Subject: [PATCH 4/5] add javascript to reveal hidden copyable text
---
app/assets/stylesheets/application.scss | 4 ++++
app/components/copyable_text.rb | 4 ++--
app/javascript/controllers/index.ts | 2 ++
.../controllers/obfuscated_text_controller.ts | 15 +++++++++++++++
4 files changed, 23 insertions(+), 2 deletions(-)
create mode 100644 app/javascript/controllers/obfuscated_text_controller.ts
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 3728223ac..0816b20a4 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -51,3 +51,7 @@ p.notice:empty {
span.obfuscated {
-webkit-text-security: disc;
}
+
+span.deobfuscated {
+ -webkit-text-security: none;
+}
diff --git a/app/components/copyable_text.rb b/app/components/copyable_text.rb
index c87d7d8ed..adc75d5b5 100644
--- a/app/components/copyable_text.rb
+++ b/app/components/copyable_text.rb
@@ -10,11 +10,11 @@ class Components::CopyableText < Components::Base
end
def view_template
- div do
+ div(data: {controller: "obfuscated-text"}) do
span(class: @obfuscated ? "obfuscated" : nil) { @text }
whitespace
if @obfuscated
- button class: "btn btn-sm btn-outline-secondary", title: t("components.copyable_text.reveal") do
+ button class: "btn btn-sm btn-outline-secondary", title: t("components.copyable_text.reveal"), data: {action: "click->obfuscated-text#toggle:prevent"} do
Icon icon: "eye"
end
end
diff --git a/app/javascript/controllers/index.ts b/app/javascript/controllers/index.ts
index cf8307575..d710611a7 100644
--- a/app/javascript/controllers/index.ts
+++ b/app/javascript/controllers/index.ts
@@ -11,6 +11,7 @@ import CocoonedController from './cocooned_controller'
import CopyTextController from './copy_text_controller'
import EditableController from './editable_controller'
import I18nController from './i18n_controller'
+import ObfuscatedTextController from './obfuscated_text_controller'
import RendererController from './renderer_controller'
import SearchableSelectController from './searchable_select_controller'
import StorageServiceController from './storage_service_controller'
@@ -27,6 +28,7 @@ application.register('cocooned', CocoonedController)
application.register('copy-text', CopyTextController)
application.register('editable', EditableController)
application.register('i18n', I18nController)
+application.register('obfuscated-text', ObfuscatedTextController)
application.register('renderer', RendererController)
application.register('searchable-select', SearchableSelectController)
application.register('storage-service', StorageServiceController)
diff --git a/app/javascript/controllers/obfuscated_text_controller.ts b/app/javascript/controllers/obfuscated_text_controller.ts
new file mode 100644
index 000000000..edb173554
--- /dev/null
+++ b/app/javascript/controllers/obfuscated_text_controller.ts
@@ -0,0 +1,15 @@
+import { Controller } from '@hotwired/stimulus'
+
+// Connects to data-controller="obfuscated-text"
+export default class extends Controller {
+ toggle (): void {
+ const hidden = this.element.querySelectorAll('.obfuscated')
+ const shown = this.element.querySelectorAll('.deobfuscated')
+ hidden.forEach((element: HTMLElement) => {
+ element.classList.replace('obfuscated', 'deobfuscated')
+ })
+ shown.forEach((element: HTMLElement) => {
+ element.classList.replace('deobfuscated', 'obfuscated')
+ })
+ }
+}
From 317a290b79cee03e40df665c4f9515f9f2e1021c Mon Sep 17 00:00:00 2001
From: James Smith
Date: Wed, 26 Nov 2025 14:47:45 +0000
Subject: [PATCH 5/5] Add reveal button label translation
---
config/locales/cs.yml | 2 ++
config/locales/de.yml | 2 ++
config/locales/en.yml | 2 ++
config/locales/es.yml | 2 ++
config/locales/fr.yml | 2 ++
config/locales/ja.yml | 2 ++
config/locales/nl.yml | 2 ++
config/locales/pl.yml | 2 ++
config/locales/pt.yml | 2 ++
config/locales/ru.yml | 2 ++
config/locales/zh-CN.yml | 2 ++
11 files changed, 22 insertions(+)
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index a8a197ac0..f6e578e79 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -359,6 +359,8 @@ cs:
help:
copy_button:
copy:
+ copyable_text:
+ reveal:
display_user_quota:
request_increase:
download_button:
diff --git a/config/locales/de.yml b/config/locales/de.yml
index de9658d39..93fa9aa35 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -359,6 +359,8 @@ de:
help: datenschutzfreundlicher Spamschutz durch ALTCHA
copy_button:
copy: In die Zwischenablage kopieren
+ copyable_text:
+ reveal:
display_user_quota:
request_increase: Um eine Quotenerhöhung zu beantragen, wende dich an deinen Website-Administrator.
download_button:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 3c195f4b8..113da4988 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -359,6 +359,8 @@ en:
help: privacy-friendly spam protection by ALTCHA
copy_button:
copy: Copy to Clipboard
+ copyable_text:
+ reveal: Reveal
display_user_quota:
request_increase: To request a quota increase, contact your site administrator.
download_button:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 827b0545c..bf1c84fbb 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -359,6 +359,8 @@ es:
help: protección antispam mediante ALTCHA
copy_button:
copy: Copiar al portapapeles
+ copyable_text:
+ reveal:
display_user_quota:
request_increase: Para solicitar un aumento de cuota, póngase en contacto con el administrador de su sitio.
download_button:
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 580a204df..851608d2f 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -359,6 +359,8 @@ fr:
help:
copy_button:
copy: Copier dans le presse-papiers
+ copyable_text:
+ reveal:
display_user_quota:
request_increase:
download_button:
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 18449b9e1..667d6313b 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -359,6 +359,8 @@ ja:
help:
copy_button:
copy:
+ copyable_text:
+ reveal:
display_user_quota:
request_increase:
download_button:
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index dd5a477d1..f0f3619ed 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -359,6 +359,8 @@ nl:
help:
copy_button:
copy:
+ copyable_text:
+ reveal:
display_user_quota:
request_increase:
download_button:
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index 9fe1cb818..51fa7bd7a 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -359,6 +359,8 @@ pl:
help:
copy_button:
copy: Kopiuj do schowka
+ copyable_text:
+ reveal:
display_user_quota:
request_increase:
download_button:
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index 48dc3558c..fa88c2a65 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -359,6 +359,8 @@ pt:
help:
copy_button:
copy:
+ copyable_text:
+ reveal:
display_user_quota:
request_increase:
download_button:
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 715b948e0..97ab9be78 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -359,6 +359,8 @@ ru:
help:
copy_button:
copy:
+ copyable_text:
+ reveal:
display_user_quota:
request_increase:
download_button:
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 78621bf75..7b2129f93 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -359,6 +359,8 @@ zh-CN:
help:
copy_button:
copy: 复制到剪贴板
+ copyable_text:
+ reveal:
display_user_quota:
request_increase: 如需增加配额,请联系管理员。
download_button: