diff --git a/app/controllers/mfa_setup_controller.rb b/app/controllers/mfa_setup_controller.rb index 9e12a445..1065fcfb 100644 --- a/app/controllers/mfa_setup_controller.rb +++ b/app/controllers/mfa_setup_controller.rb @@ -20,7 +20,8 @@ class MfaSetupController < ApplicationController redirect_to settings_profile_index_path, notice: I18n.t('2fa_has_been_configured') else - @provision_url = current_user.otp_provisioning_uri(current_user.email, issuer: Wabosign.product_name) + @provision_url = current_user.otp_provisioning_uri(current_user.email, + issuer: Wabosign.branded_product_name(current_account)) @error_message = I18n.t('code_is_invalid') @@ -49,6 +50,7 @@ class MfaSetupController < ApplicationController current_user.save! - @provision_url = current_user.otp_provisioning_uri(current_user.email, issuer: Wabosign.product_name) + @provision_url = current_user.otp_provisioning_uri(current_user.email, + issuer: Wabosign.branded_product_name(current_account)) end end diff --git a/app/controllers/personalization_settings_controller.rb b/app/controllers/personalization_settings_controller.rb index 600e3bbb..86c97cad 100644 --- a/app/controllers/personalization_settings_controller.rb +++ b/app/controllers/personalization_settings_controller.rb @@ -2,6 +2,7 @@ class PersonalizationSettingsController < ApplicationController ALLOWED_KEYS = [ + AccountConfig::BRAND_NAME_KEY, AccountConfig::FORM_COMPLETED_BUTTON_KEY, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY, AccountConfig::SUBMITTER_INVITATION_REMINDER_EMAIL_KEY, diff --git a/app/controllers/sms_settings_controller.rb b/app/controllers/sms_settings_controller.rb index 5c6498b8..88acdf00 100644 --- a/app/controllers/sms_settings_controller.rb +++ b/app/controllers/sms_settings_controller.rb @@ -29,7 +29,7 @@ class SmsSettingsController < ApplicationController Sms.send_message(account: current_account, to: to, - text: "Test SMS from #{Wabosign.product_name}.") + text: "Test SMS from #{Wabosign.branded_product_name(current_account)}.") redirect_to settings_sms_path, notice: "Test SMS dispatched to #{to}." rescue Sms::Error => e diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index abc32e6d..658a891c 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,7 +1,12 @@ # frozen_string_literal: true class ApplicationMailer < ActionMailer::Base - default from: "#{Wabosign.product_name} <#{Wabosign::SUPPORT_EMAIL}>" + # Lambda is evaluated per-message in mailer context, so @current_account + # (set by each mailer action) is available here. + default from: lambda { + account = instance_variable_defined?(:@current_account) ? @current_account : nil + "#{Wabosign.branded_product_name(account)} <#{Wabosign::SUPPORT_EMAIL}>" + } layout 'mailer' register_interceptor ActionMailerConfigsInterceptor diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index a2402aa2..6df7c651 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -10,7 +10,8 @@ class UserMailer < ApplicationMailer I18n.with_locale(@current_account.locale) do mail(to: @user.friendly_name, - subject: I18n.t('you_are_invited_to_product_name', product_name: Wabosign.product_name)) + subject: I18n.t('you_are_invited_to_product_name', + product_name: Wabosign.branded_product_name(@current_account))) end end end diff --git a/app/models/account.rb b/app/models/account.rb index aab90683..eb3959d7 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -66,6 +66,10 @@ class Account < ApplicationRecord linked_account_account&.testing? end + def brand_name + account_configs.find_by(key: AccountConfig::BRAND_NAME_KEY)&.value.to_s.strip.presence + end + def tz_info @tz_info ||= TZInfo::Timezone.get(ActiveSupport::TimeZone::MAPPING[timezone] || timezone) end diff --git a/app/models/account_config.rb b/app/models/account_config.rb index eb4aabd7..c42bfb1e 100644 --- a/app/models/account_config.rb +++ b/app/models/account_config.rb @@ -61,6 +61,7 @@ class AccountConfig < ApplicationRecord TEMPLATE_CUSTOM_FIELDS_KEY = 'template_custom_fields' POLICY_LINKS_KEY = 'policy_links' ENABLE_MCP_KEY = 'enable_mcp' + BRAND_NAME_KEY = 'brand_name' EMAIL_VARIABLES = { SUBMITTER_INVITATION_EMAIL_KEY => %w[template.name submitter.link account.name].freeze, diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb index e6e9060c..5163b1aa 100644 --- a/app/views/devise/mailer/reset_password_instructions.html.erb +++ b/app/views/devise/mailer/reset_password_instructions.html.erb @@ -5,6 +5,6 @@
<%= t('if_you_didnt_request_this_you_can_ignore_this_email') %>
<%= t('thanks') %>,
- <%= Wabosign.product_name %>
+ <%= Wabosign.branded_product_name(@resource&.account) %>
<%= t('connect_to_wabosign_mcp') %>
+<%= t('connect_to_product_name_mcp', product_name: Wabosign.branded_product_name(current_account)) %>
<%= t('add_the_following_to_your_mcp_client_configuration') %>:
+ The <%= Wabosign::UPSTREAM_NAME %> upstream attribution required by AGPL §7(b) stays visible in the footer, post-signing screen, and email footers regardless of this setting. +
diff --git a/app/views/personalization_settings/show.html.erb b/app/views/personalization_settings/show.html.erb index f4ba1639..2618526f 100644 --- a/app/views/personalization_settings/show.html.erb +++ b/app/views/personalization_settings/show.html.erb @@ -10,6 +10,10 @@ <%= render 'submitter_completed_email_form' %> <%= render 'signature_request_sms_form' %>+ Product name +
+ <%= render 'brand_name_form' %><%= t('company_logo') %>
diff --git a/app/views/pwa/manifest.json.erb b/app/views/pwa/manifest.json.erb index 18aafb96..3211fd12 100644 --- a/app/views/pwa/manifest.json.erb +++ b/app/views/pwa/manifest.json.erb @@ -1,6 +1,7 @@ +<% brand = Wabosign.branded_product_name %> { - "name": "<%= Wabosign.product_name %>", - "short_name": "<%= Wabosign.product_name %>", + "name": "<%= brand %>", + "short_name": "<%= brand %>", "id": "/", "icons": [ { @@ -18,7 +19,7 @@ "display": "standalone", "scope": "/", "orientation": "any", - "description": "<%= Wabosign.product_name %> is an open source platform that provides secure and efficient digital document signing and processing.", + "description": "<%= brand %> is an open source platform that provides secure and efficient digital document signing and processing.", "categories": ["productivity", "utilities"], "theme_color": "#FAF7F4", "background_color": "#FAF7F4" diff --git a/app/views/shared/_attribution.html.erb b/app/views/shared/_attribution.html.erb index bc464bba..9a006d55 100644 --- a/app/views/shared/_attribution.html.erb +++ b/app/views/shared/_attribution.html.erb @@ -1 +1 @@ -<%= render 'shared/powered_by', with_counter: local_assigns[:with_counter], link_path: local_assigns[:link_path] %> +<%= render 'shared/powered_by', with_counter: local_assigns[:with_counter], link_path: local_assigns[:link_path], account: local_assigns[:account] %> diff --git a/app/views/shared/_email_attribution.html.erb b/app/views/shared/_email_attribution.html.erb index 23788a1c..401246a0 100644 --- a/app/views/shared/_email_attribution.html.erb +++ b/app/views/shared/_email_attribution.html.erb @@ -1,13 +1,15 @@---
+<% brand = Wabosign.branded_product_name(@current_account) %><% if @current_account&.testing? %> - <%= t('sent_using_product_name_in_testing_mode_html', product_url: "#{Wabosign::PRODUCT_EMAIL_URL}/start", product_name: Wabosign.product_name) %> + <%= t('sent_using_product_name_in_testing_mode_html', product_url: "#{Wabosign::PRODUCT_EMAIL_URL}/start", product_name: brand) %> <% else %> - <%= t('sent_using_product_name_free_document_signing_html', product_url: "#{Wabosign::PRODUCT_EMAIL_URL}/start", product_name: Wabosign.product_name) %> + <%= t('sent_using_product_name_free_document_signing_html', product_url: "#{Wabosign::PRODUCT_EMAIL_URL}/start", product_name: brand) %> <% end %>
+<%# AGPL §7(b) DocuSeal attribution. Do not remove or rebrand. %><%= t('based_on') %> <%= Wabosign::UPSTREAM_NAME %> diff --git a/app/views/shared/_meta.html.erb b/app/views/shared/_meta.html.erb index 00f49b18..edab477b 100644 --- a/app/views/shared/_meta.html.erb +++ b/app/views/shared/_meta.html.erb @@ -1,14 +1,15 @@ <% if Wabosign.demo? || (request.path != '/' && !devise_controller?) %> <% end %> -<% title = content_for(:html_title) || (signed_in? ? Wabosign.product_name : "#{Wabosign.product_name} | Open Source Document Signing") %> +<% brand = Wabosign.branded_product_name(signed_in? ? current_account : nil) %> +<% title = content_for(:html_title) || (signed_in? ? brand : "#{brand} | Open Source Document Signing") %> <% description = content_for(:html_description) || 'Open source, self-hosted tool to streamline document filling and signing. Create custom PDF forms to complete and sign with an easy to use online tool.' %> - + <% if content_for(:disable_image_preview) %> diff --git a/app/views/shared/_powered_by.html.erb b/app/views/shared/_powered_by.html.erb index 90b151b2..113c4030 100644 --- a/app/views/shared/_powered_by.html.erb +++ b/app/views/shared/_powered_by.html.erb @@ -9,8 +9,9 @@ <% else %> <%= t('powered_by') %> <% end %> - <%= Wabosign.product_name %> - <%= t('open_source_documents_software') %> + <%= Wabosign.branded_product_name(local_assigns[:account]) %> - <%= t('open_source_documents_software') %>
<%= @user.first_name.present? ? t('hello_name', name: @user.first_name) : t('hi_there') %>,
-<%= t('you_have_been_invited_to_account_name_product_name_please_sign_up_using_the_link_below_', account_name: @user.account.name, product_name: Wabosign.product_name) %>
+<%= t('you_have_been_invited_to_account_name_product_name_please_sign_up_using_the_link_below_', account_name: @user.account.name, product_name: Wabosign.branded_product_name(@current_account)) %>
<%= link_to t('sign_up'), invitation_url(reset_password_token: @token) %>
<%= t('please_contact_us_by_replying_to_this_email_if_you_have_any_questions') %>
diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml
index 3e3a3175..a36d497a 100644
--- a/config/locales/i18n.yml
+++ b/config/locales/i18n.yml
@@ -929,7 +929,7 @@ en: &en
mcp_token_has_been_removed: MCP token has been removed.
enable_mcp_server: Enable MCP server
all_existing_mcp_connections_will_be_stopped_immediately_when_this_setting_is_disabled: All existing MCP connections will be stopped immediately when this setting is disabled.
- connect_to_wabosign_mcp: Connect to WaboSign MCP
+ connect_to_product_name_mcp: Connect to %{product_name} MCP
add_the_following_to_your_mcp_client_configuration: Add the following to your MCP client configuration
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Works with Claude Desktop, Cursor, Windsurf, VS Code, and any MCP-compatible client.
your_email_address_has_been_changed: Your email address has been changed
@@ -1977,7 +1977,7 @@ es: &es
mcp_token_has_been_removed: El token MCP ha sido eliminado.
enable_mcp_server: Habilitar servidor MCP
all_existing_mcp_connections_will_be_stopped_immediately_when_this_setting_is_disabled: Todas las conexiones MCP existentes se detendrán inmediatamente cuando se desactive esta configuración.
- connect_to_wabosign_mcp: Conectar a WaboSign MCP
+ connect_to_product_name_mcp: Conectar a %{product_name} MCP
add_the_following_to_your_mcp_client_configuration: Agregue lo siguiente a la configuración de su cliente MCP
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funciona con Claude Desktop, Cursor, Windsurf, VS Code y cualquier cliente compatible con MCP.
your_email_address_has_been_changed: Tu dirección de correo electrónico ha sido cambiada
@@ -3025,7 +3025,7 @@ it: &it
mcp_token_has_been_removed: Il token MCP è stato rimosso.
enable_mcp_server: Abilita server MCP
all_existing_mcp_connections_will_be_stopped_immediately_when_this_setting_is_disabled: Tutte le connessioni MCP esistenti verranno interrotte immediatamente quando questa impostazione viene disattivata.
- connect_to_wabosign_mcp: Connetti a WaboSign MCP
+ connect_to_product_name_mcp: Connetti a %{product_name} MCP
add_the_following_to_your_mcp_client_configuration: Aggiungi quanto segue alla configurazione del tuo client MCP
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funziona con Claude Desktop, Cursor, Windsurf, VS Code e qualsiasi client compatibile con MCP.
your_email_address_has_been_changed: Il tuo indirizzo email è stato modificato
@@ -4070,7 +4070,7 @@ fr: &fr
mcp_token_has_been_removed: Le jeton MCP a été supprimé.
enable_mcp_server: Activer le serveur MCP
all_existing_mcp_connections_will_be_stopped_immediately_when_this_setting_is_disabled: Toutes les connexions MCP existantes seront arrêtées immédiatement lorsque ce paramètre est désactivé.
- connect_to_wabosign_mcp: Se connecter à WaboSign MCP
+ connect_to_product_name_mcp: Se connecter à %{product_name} MCP
add_the_following_to_your_mcp_client_configuration: Ajoutez ce qui suit à la configuration de votre client MCP
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Fonctionne avec Claude Desktop, Cursor, Windsurf, VS Code et tout client compatible MCP.
your_email_address_has_been_changed: Votre adresse e-mail a été modifiée
@@ -5118,7 +5118,7 @@ pt: &pt
mcp_token_has_been_removed: O token MCP foi removido.
enable_mcp_server: Ativar servidor MCP
all_existing_mcp_connections_will_be_stopped_immediately_when_this_setting_is_disabled: Todas as conexões MCP existentes serão interrompidas imediatamente quando esta configuração for desativada.
- connect_to_wabosign_mcp: Conectar ao WaboSign MCP
+ connect_to_product_name_mcp: Conectar ao %{product_name} MCP
add_the_following_to_your_mcp_client_configuration: Adicione o seguinte à configuração do seu cliente MCP
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funciona com Claude Desktop, Cursor, Windsurf, VS Code e qualquer cliente compatível com MCP.
your_email_address_has_been_changed: Seu endereço de e-mail foi alterado
@@ -6166,7 +6166,7 @@ de: &de
mcp_token_has_been_removed: Das MCP-Token wurde entfernt.
enable_mcp_server: MCP-Server aktivieren
all_existing_mcp_connections_will_be_stopped_immediately_when_this_setting_is_disabled: Alle bestehenden MCP-Verbindungen werden sofort gestoppt, wenn diese Einstellung deaktiviert wird.
- connect_to_wabosign_mcp: Mit WaboSign MCP verbinden
+ connect_to_product_name_mcp: Mit %{product_name} MCP verbinden
add_the_following_to_your_mcp_client_configuration: Fügen Sie Folgendes zu Ihrer MCP-Client-Konfiguration hinzu
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funktioniert mit Claude Desktop, Cursor, Windsurf, VS Code und jedem MCP-kompatiblen Client.
your_email_address_has_been_changed: Ihre E-Mail-Adresse wurde geändert
@@ -7623,7 +7623,7 @@ nl: &nl
mcp_token_has_been_removed: Het MCP-token is verwijderd.
enable_mcp_server: MCP-server inschakelen
all_existing_mcp_connections_will_be_stopped_immediately_when_this_setting_is_disabled: Alle bestaande MCP-verbindingen worden onmiddellijk gestopt wanneer deze instelling wordt uitgeschakeld.
- connect_to_wabosign_mcp: Verbinden met WaboSign MCP
+ connect_to_product_name_mcp: Verbinden met %{product_name} MCP
add_the_following_to_your_mcp_client_configuration: Voeg het volgende toe aan uw MCP-clientconfiguratie
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Werkt met Claude Desktop, Cursor, Windsurf, VS Code en elke MCP-compatibele client.
your_email_address_has_been_changed: Uw e-mailadres is gewijzigd
diff --git a/lib/mcp/handle_request.rb b/lib/mcp/handle_request.rb
index 70fd628c..3a7b66c9 100644
--- a/lib/mcp/handle_request.rb
+++ b/lib/mcp/handle_request.rb
@@ -26,7 +26,7 @@ module Mcp
result: {
protocolVersion: '2025-11-25',
serverInfo: {
- name: Wabosign.product_name,
+ name: Wabosign.branded_product_name(current_user&.account),
version: Wabosign.version.to_s
},
capabilities: {
diff --git a/lib/submissions/generate_audit_trail.rb b/lib/submissions/generate_audit_trail.rb
index 1671ccec..a87eafa7 100644
--- a/lib/submissions/generate_audit_trail.rb
+++ b/lib/submissions/generate_audit_trail.rb
@@ -43,11 +43,11 @@ module Submissions
io = StringIO.new
- document.trailer.info[:Creator] = "#{Wabosign.product_name} (#{Wabosign::PRODUCT_URL})"
+ document.trailer.info[:Creator] = "#{Wabosign.branded_product_name(account)} (#{Wabosign::PRODUCT_URL})"
if pkcs
sign_params = {
- reason: sign_reason,
+ reason: sign_reason(account),
**Submissions::GenerateResultAttachments.build_signing_params(last_submitter, pkcs, tsa_url)
}
@@ -510,8 +510,8 @@ module Submissions
composer.document
end
- def sign_reason
- "Signed with #{Wabosign.product_name}"
+ def sign_reason(account = nil)
+ "Signed with #{Wabosign.branded_product_name(account)}"
end
def select_attachments(submitter)
@@ -534,7 +534,7 @@ module Submissions
column.image(PdfIcons.account_logo_io(submission&.account),
width: 40, height: 40, position: :float)
- column.formatted_text([{ text: Wabosign.product_name,
+ column.formatted_text([{ text: Wabosign.branded_product_name(submission&.account),
link: Wabosign::PRODUCT_EMAIL_URL }],
font_size: 20,
font: [FONT_NAME, { variant: :bold }],
diff --git a/lib/submissions/generate_combined_attachment.rb b/lib/submissions/generate_combined_attachment.rb
index 3320e2b6..9b728211 100644
--- a/lib/submissions/generate_combined_attachment.rb
+++ b/lib/submissions/generate_combined_attachment.rb
@@ -15,7 +15,7 @@ module Submissions
io = StringIO.new
- pdf.trailer.info[:Creator] = "#{Wabosign.product_name} (#{Wabosign::PRODUCT_URL})"
+ pdf.trailer.info[:Creator] = "#{Wabosign.branded_product_name(account)} (#{Wabosign::PRODUCT_URL})"
if Wabosign.pdf_format == 'pdf/a-3b'
pdf.task(:pdfa, level: '3b')
diff --git a/lib/submissions/generate_result_attachments.rb b/lib/submissions/generate_result_attachments.rb
index c4d24a1d..9e9d3c68 100644
--- a/lib/submissions/generate_result_attachments.rb
+++ b/lib/submissions/generate_result_attachments.rb
@@ -37,7 +37,11 @@ module Submissions
bold_italic: FONT_BOLD_NAME
}.freeze
- SIGN_REASON = "Signed with #{Wabosign.product_name}".freeze
+ # PDF signature "reason" template. Per-account branded — the actual
+ # template is computed by `sign_reason_template(account)` below; this
+ # constant is the format placeholder. Historically the format kwarg
+ # `name:` was unused.
+ SIGN_REASON_FORMAT = 'Signed with %