From ffc4024f7057e091eda6c047a841cc947e46198e Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Tue, 16 Sep 2025 13:03:02 +0300 Subject: [PATCH 01/11] rubocop --- .rubocop.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index cfcd7b3e..e40ff7c2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -68,6 +68,9 @@ RSpec/ExampleLength: RSpec/MultipleMemoizedHelpers: Max: 15 +RSpec/AnyInstance: + Enabled: false + Metrics/BlockNesting: Max: 5 From 6e16f81fc638c54508bb788c9c00e50637b30c32 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Tue, 16 Sep 2025 16:19:36 +0300 Subject: [PATCH 02/11] add folder filter --- app/controllers/submissions_filters_controller.rb | 1 + app/views/submissions_filters/_filter_button.html.erb | 6 ++++++ app/views/submissions_filters/folder.html.erb | 9 +++++++++ 3 files changed, 16 insertions(+) create mode 100644 app/views/submissions_filters/folder.html.erb diff --git a/app/controllers/submissions_filters_controller.rb b/app/controllers/submissions_filters_controller.rb index b0298d4c..8c08bb1d 100644 --- a/app/controllers/submissions_filters_controller.rb +++ b/app/controllers/submissions_filters_controller.rb @@ -3,6 +3,7 @@ class SubmissionsFiltersController < ApplicationController ALLOWED_NAMES = %w[ author + folder completed_at status created_at diff --git a/app/views/submissions_filters/_filter_button.html.erb b/app/views/submissions_filters/_filter_button.html.erb index 3f24aaf6..2e65f0ed 100644 --- a/app/views/submissions_filters/_filter_button.html.erb +++ b/app/views/submissions_filters/_filter_button.html.erb @@ -23,6 +23,12 @@ <%= t('status') %> <% end %> +
  • + <%= link_to submissions_filter_path('folder', query_params.merge(path: url_for)), data: { turbo_frame: 'modal' } do %> + <%= svg_icon('folder', class: 'w-5 h-5 flex-shrink-0 stroke-2') %> + <%= t('folder') %> + <% end %> +
  • <%= link_to submissions_filter_path('author', query_params.merge(path: url_for)), data: { turbo_frame: 'modal' } do %> <%= svg_icon('user', class: 'w-5 h-5 flex-shrink-0 stroke-2') %> diff --git a/app/views/submissions_filters/folder.html.erb b/app/views/submissions_filters/folder.html.erb new file mode 100644 index 00000000..d234e2eb --- /dev/null +++ b/app/views/submissions_filters/folder.html.erb @@ -0,0 +1,9 @@ +<%= render 'filter_modal', title: t('folder'), default_params: params.permit(*(Submissions::Filter::ALLOWED_PARAMS - ['folder'])) do %> +
    +
    + + + +
    +
    +<% end %> From 634b5c37ba530158181c34a76ce8c14a7898002b Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Wed, 17 Sep 2025 13:26:58 +0300 Subject: [PATCH 03/11] fix form fields import --- lib/templates/find_acro_fields.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/templates/find_acro_fields.rb b/lib/templates/find_acro_fields.rb index af0ee395..7940145a 100644 --- a/lib/templates/find_acro_fields.rb +++ b/lib/templates/find_acro_fields.rb @@ -225,7 +225,10 @@ module Templates is_option_number = option.is_a?(Symbol) && option.to_s.match?(/\A\d+\z/) option = option[1] if option.is_a?(Array) && option.size == 2 - option = option.encode('utf-8', invalid: :replace, undef: :replace, replace: '') if option.is_a?(String) + + if option.is_a?(String) || option.is_a?(Symbol) + option = option.to_s.encode('utf-8', invalid: :replace, undef: :replace, replace: '') + end next if type == 'select' && option.to_s.match?(SELECT_PLACEHOLDER_REGEXP) From 0fa8cf2dd005c22cb47cf4dbe0db953473af6202 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 18 Sep 2025 08:30:58 +0300 Subject: [PATCH 04/11] fix result generatrion --- lib/submissions/generate_combined_attachment.rb | 2 +- lib/submissions/generate_result_attachments.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/submissions/generate_combined_attachment.rb b/lib/submissions/generate_combined_attachment.rb index 715e7a18..faf55471 100644 --- a/lib/submissions/generate_combined_attachment.rb +++ b/lib/submissions/generate_combined_attachment.rb @@ -46,7 +46,7 @@ module Submissions def sign_pdf(io, pdf, sign_params) pdf.sign(io, **sign_params) - rescue HexaPDF::MalformedPDFError => e + rescue HexaPDF::MalformedPDFError, NoMethodError => e Rollbar.error(e) if defined?(Rollbar) pdf.sign(io, write_options: { incremental: false }, **sign_params) diff --git a/lib/submissions/generate_result_attachments.rb b/lib/submissions/generate_result_attachments.rb index e78deb2c..4e060770 100644 --- a/lib/submissions/generate_result_attachments.rb +++ b/lib/submissions/generate_result_attachments.rb @@ -661,7 +661,7 @@ module Submissions begin pdf.sign(io, write_options: { validate: false }, **sign_params) - rescue HexaPDF::MalformedPDFError => e + rescue HexaPDF::MalformedPDFError, NoMethodError => e Rollbar.error(e) if defined?(Rollbar) pdf.sign(io, write_options: { validate: false, incremental: false }, **sign_params) @@ -671,7 +671,7 @@ module Submissions else begin pdf.write(io, incremental: true, validate: false) - rescue HexaPDF::MalformedPDFError => e + rescue HexaPDF::MalformedPDFError, NoMethodError => e Rollbar.error(e) if defined?(Rollbar) pdf.write(io, incremental: false, validate: false) From aa27d9001779b4d88981d9640377fc0a700889a1 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 18 Sep 2025 08:48:48 +0300 Subject: [PATCH 05/11] update gem --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index efd18cf6..b3300f1f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -461,7 +461,7 @@ GEM actionpack (>= 5.2) railties (>= 5.2) retriable (3.1.2) - rexml (3.4.0) + rexml (3.4.4) rotp (6.3.0) rouge (4.5.2) rqrcode (2.2.0) From f3b26bf7a089626123bfc8ab9a562768dd031b2d Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Wed, 17 Sep 2025 20:48:50 +0300 Subject: [PATCH 06/11] add tooltips to account preferences --- app/views/accounts/show.html.erb | 127 +++++++++++++++++++------------ config/locales/i18n.yml | 96 +++++++++++++++++++++++ 2 files changed, 176 insertions(+), 47 deletions(-) diff --git a/app/views/accounts/show.html.erb b/app/views/accounts/show.html.erb index d5c5453f..aae5a3eb 100644 --- a/app/views/accounts/show.html.erb +++ b/app/views/accounts/show.html.erb @@ -50,10 +50,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('force_2fa_with_authenticator_app') %> - +
    +
    +
    + <%= t('force_2fa_with_authenticator_app') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -62,10 +65,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('add_signature_id_to_the_documents') %> - +
    +
    +
    + <%= t('add_signature_id_to_the_documents') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()', disabled: can?(:manage, :cfr) %>
    <% end %> @@ -74,10 +80,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('require_signing_reason') %> - +
    +
    +
    + <%= t('require_signing_reason') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()', disabled: can?(:manage, :cfr) %>
    <% end %> @@ -86,10 +95,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('allow_typed_text_signatures') %> - +
    +
    +
    + <%= t('allow_typed_text_signatures') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -98,10 +110,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('allow_to_resubmit_completed_forms') %> - +
    +
    +
    + <%= t('allow_to_resubmit_completed_forms') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -110,10 +125,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('allow_to_decline_documents') %> - +
    +
    +
    + <%= t('allow_to_decline_documents') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -122,10 +140,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('remember_and_pre_fill_signatures') %> - +
    +
    +
    + <%= t('remember_and_pre_fill_signatures') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -134,10 +155,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('expirable_file_download_links') %> - +
    +
    +
    + <%= t('expirable_file_download_links') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -146,10 +170,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('require_authentication_for_file_download_links') %> - +
    +
    +
    + <%= t('require_authentication_for_file_download_links') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -158,10 +185,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('combine_completed_documents_and_audit_log') %> - +
    +
    +
    + <%= t('combine_completed_documents_and_audit_log') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -171,10 +201,13 @@ <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %> -
    - - <%= t('always_enforce_signing_order') %> - +
    +
    +
    + <%= t('always_enforce_signing_order') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> +
    +
    <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %>
    <% end %> @@ -182,11 +215,11 @@ <% end %> <%= render 'extra_preferences' %> <% if !Docuseal.multitenant? && SearchEntry.table_exists? && (!Docuseal.fulltext_search? || params[:reindex] == 'true') && can?(:manage, EncryptedConfig) %> -
    +
    - Efficient search with search index + <%= t('efficient_search_with_search_index') %> - <%= button_to params[:reindex] == 'true' ? 'Reindex' : 'Build Search Index', settings_search_entries_reindex_index_path, method: :post, class: 'btn btn-sm btn-neutral text-white px-4' %> + <%= button_to params[:reindex] == 'true' ? t('reindex') : t('build_search_index'), settings_search_entries_reindex_index_path, method: :post, class: 'btn btn-sm btn-neutral text-white px-4' %>
    <% end %>
    diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index cb6cdf24..eaf10d7f 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -810,6 +810,22 @@ en: &en please_reply_to_this_email_if_you_dont_recognize_this_request: Please reply to this email if you don't recognize this request. your_user_account_has_been_archived_contact_your_administrator_to_restore_access_to_your_account: Your user account has been archived. Contact your administrator to restore access to your account. your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: Your email could not be reached. This may happen if there was a typo in your address or if your mailbox is not available. Please contact support@docuseal.com to log in. + efficient_search_with_search_index: Efficient search with search index + reindex: Reindex + build_search_index: Build Search Index + require_two_factor_authentication_2fa_with_an_authenticator_app_e_g_google_authenticator_authy_all_users_signing_documents_must_pass_the_second_factor_verification_using_a_secure_code_in_addition_to_their_password: Require two-factor authentication (2FA) with an authenticator app (e.g., Google Authenticator, Authy). All users signing documents must pass the second factor verification using a secure code in addition to their password. + add_a_unique_signature_id_and_timestamp_to_each_signature_for_audit_and_traceability_purposes_along_with_the_timestamp_part_of_docuseals_21_cfr_part_11_compliance_settings: "Add a unique Signature ID and timestamp to each signature for audit and traceability purposes along with the timestamp. Part of DocuSeal's 21 CFR Part 11 compliance settings." + require_signer_to_provide_a_reason_for_signing_before_completing_their_signature_e_g_approvals_certifications_part_of_docuseals_21_cfr_part_11_compliance_settings: "Require signers to provide a reason for signing before completing their signature (e.g., approvals, certifications). Part of DocuSeal's 21 CFR Part 11 compliance settings." + allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Allow signers to create signatures by typing their name instead of drawing or uploading one. + allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Allow signers to resubmit forms after completion, useful when corrections or multiple submissions are needed. + allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Allow recipients to decline signing a document. The decline reason notification will be sent to the signature requester. + save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: "Save a user's signature and automatically pre-fill it in future signing sessions." + make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Make document download links expire after 40 minutes to prevent long-term access and enhance security. + require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Require authentication with user login or API key to access the document download links. + combine_signed_documents_and_the_audit_log_into_a_single_pdf_file_for_easier_recordkeeping_and_compliance: Combine signed documents and the Audit Log into a single PDF file for easier recordkeeping and compliance. + require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Require a JWT authorization to preview embedded forms, ensuring only authorized users can view them. + make_all_newly_created_templates_private_to_their_creator_by_default: Make all newly created templates private to their creator by default. + make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Make the recipients signing order always enforced, so that the second signer can start signing their part only after the first signer has completed signing. submission_sources: api: API bulk: Bulk Send @@ -1705,6 +1721,22 @@ es: &es please_reply_to_this_email_if_you_dont_recognize_this_request: Responde a este correo si no reconoces esta solicitud. your_user_account_has_been_archived_contact_your_administrator_to_restore_access_to_your_account: Tu cuenta de usuario ha sido archivada. Contacta a tu administrador para restaurar el acceso a tu cuenta. your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: No se pudo acceder a tu correo electrónico. Esto puede ocurrir si hubo un error tipográfico en tu dirección o si tu buzón no está disponible. Por favor, contacta a support@docuseal.com para iniciar sesión. + efficient_search_with_search_index: Búsqueda eficiente con índice de búsqueda + reindex: Reindexar + build_search_index: Construir índice de búsqueda + require_two_factor_authentication_2fa_with_an_authenticator_app_e_g_google_authenticator_authy_all_users_signing_documents_must_pass_the_second_factor_verification_using_a_secure_code_in_addition_to_their_password: Requerir autenticación de dos factores (2FA) con una aplicación de autenticación (p. ej., Google Authenticator, Authy). Todos los usuarios que firman documentos deben pasar la verificación del segundo factor usando un código seguro además de su contraseña. + add_a_unique_signature_id_and_timestamp_to_each_signature_for_audit_and_traceability_purposes_along_with_the_timestamp_part_of_docuseals_21_cfr_part_11_compliance_settings: Agregar un ID de firma único y una marca de tiempo a cada firma para fines de auditoría y trazabilidad junto con la marca de tiempo. Parte de la configuración de cumplimiento 21 CFR Parte 11 de DocuSeal. + require_signer_to_provide_a_reason_for_signing_before_completing_their_signature_e_g_approvals_certifications_part_of_docuseals_21_cfr_part_11_compliance_settings: Requerir que los firmantes proporcionen un motivo para firmar antes de completar su firma (p. ej., aprobaciones, certificaciones). Parte de la configuración de cumplimiento 21 CFR Parte 11 de DocuSeal. + allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Permitir que los firmantes creen firmas escribiendo su nombre en lugar de dibujar o subir una. + allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Permitir que los firmantes vuelvan a enviar formularios después de completarlos, útil cuando se necesitan correcciones o múltiples envíos. + allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Permitir que los destinatarios rechacen firmar un documento. La notificación del motivo del rechazo se enviará al solicitante de la firma. + save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Guardar la firma de un usuario y rellenarla automáticamente en futuras sesiones de firma. + make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Hacer que los enlaces de descarga de documentos caduquen después de 40 minutos para evitar el acceso a largo plazo y mejorar la seguridad. + require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Requerir autenticación con inicio de sesión de usuario o clave API para acceder a los enlaces de descarga de documentos. + combine_signed_documents_and_the_audit_log_into_a_single_pdf_file_for_easier_recordkeeping_and_compliance: Combinar documentos firmados y el registro de auditoría en un solo archivo PDF para una gestión y cumplimiento más fáciles. + require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Requerir autorización JWT para previsualizar formularios incrustados, garantizando que solo los usuarios autorizados puedan verlos. + make_all_newly_created_templates_private_to_their_creator_by_default: Hacer que todas las plantillas creadas sean privadas para su creador por defecto. + make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Hacer que el orden de firma de los destinatarios se aplique siempre, de modo que el segundo firmante pueda comenzar a firmar solo después de que el primero haya completado la firma. submission_sources: api: API bulk: Envío masivo @@ -2601,6 +2633,22 @@ it: &it please_reply_to_this_email_if_you_dont_recognize_this_request: Rispondi a questa email se non riconosci questa richiesta. your_user_account_has_been_archived_contact_your_administrator_to_restore_access_to_your_account: Il tuo account utente è stato archiviato. Contatta il tuo amministratore per ripristinare l'accesso al tuo account. your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: Non è stato possibile raggiungere la tua email. Questo può accadere se c'è stato un errore di digitazione nell'indirizzo o se la tua casella di posta non è disponibile. Contatta support@docuseal.com per accedere. + efficient_search_with_search_index: Ricerca efficiente con indice di ricerca + reindex: Reindicizza + build_search_index: Crea indice di ricerca + require_two_factor_authentication_2fa_with_an_authenticator_app_e_g_google_authenticator_authy_all_users_signing_documents_must_pass_the_second_factor_verification_using_a_secure_code_in_addition_to_their_password: "Richiedere l'autenticazione a due fattori (2FA) con un'app di autenticazione (es. Google Authenticator, Authy). Tutti gli utenti che firmano documenti devono superare la verifica del secondo fattore utilizzando un codice sicuro oltre alla password." + add_a_unique_signature_id_and_timestamp_to_each_signature_for_audit_and_traceability_purposes_along_with_the_timestamp_part_of_docuseals_21_cfr_part_11_compliance_settings: Aggiungere un ID firma univoco e una marca temporale a ogni firma per scopi di audit e tracciabilità insieme alla marca temporale. Parte delle impostazioni di conformità 21 CFR Parte 11 di DocuSeal. + require_signer_to_provide_a_reason_for_signing_before_completing_their_signature_e_g_approvals_certifications_part_of_docuseals_21_cfr_part_11_compliance_settings: Richiedere ai firmatari di fornire una motivazione prima di completare la firma (es. approvazioni, certificazioni). Parte delle impostazioni di conformità 21 CFR Parte 11 di DocuSeal. + allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Consentire ai firmatari di creare firme digitando il proprio nome invece di disegnarle o caricarle. + allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Consentire ai firmatari di reinviare i moduli dopo il completamento, utile quando sono necessarie correzioni o più invii. + allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Consentire ai destinatari di rifiutare di firmare un documento. La notifica del motivo del rifiuto verrà inviata al richiedente della firma. + save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Salvare la firma di un utente e compilarla automaticamente nelle future sessioni di firma. + make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: "Fare in modo che i link di download dei documenti scadano dopo 40 minuti per prevenire l'accesso a lungo termine e migliorare la sicurezza." + require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: "Richiedere l'autenticazione con login utente o chiave API per accedere ai link di download dei documenti." + combine_signed_documents_and_the_audit_log_into_a_single_pdf_file_for_easier_recordkeeping_and_compliance: Combinare documenti firmati e registro di audit in un unico file PDF per una gestione e conformità più semplici. + require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: "Richiedere un'autorizzazione JWT per visualizzare in anteprima i moduli incorporati, garantendo che solo gli utenti autorizzati possano vederli." + make_all_newly_created_templates_private_to_their_creator_by_default: Rendere tutte le nuove template private per il creatore per impostazione predefinita. + make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: "Rendere sempre obbligatorio l'ordine di firma dei destinatari, in modo che il secondo firmatario possa iniziare solo dopo che il primo ha completato la firma." submission_sources: api: API bulk: Invio massivo @@ -3500,6 +3548,22 @@ fr: &fr please_reply_to_this_email_if_you_dont_recognize_this_request: Veuillez répondre à cet e-mail si vous ne reconnaissez pas cette demande. your_user_account_has_been_archived_contact_your_administrator_to_restore_access_to_your_account: Votre compte utilisateur a été archivé. Contactez votre administrateur pour rétablir l'accès à votre compte. your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: Votre e-mail n'a pas pu être atteint. Cela peut arriver s'il y a eu une faute de frappe dans votre adresse ou si votre boîte aux lettres n'est pas disponible. Veuillez contacter support@docuseal.com pour vous connecter. + efficient_search_with_search_index: Recherche efficace avec index de recherche + reindex: Réindexer + build_search_index: Construire un index de recherche + require_two_factor_authentication_2fa_with_an_authenticator_app_e_g_google_authenticator_authy_all_users_signing_documents_must_pass_the_second_factor_verification_using_a_secure_code_in_addition_to_their_password: "Exiger une authentification à deux facteurs (2FA) avec une application d'authentification (ex. Google Authenticator, Authy). Tous les utilisateurs signant des documents doivent passer la vérification du second facteur en utilisant un code sécurisé en plus de leur mot de passe." + add_a_unique_signature_id_and_timestamp_to_each_signature_for_audit_and_traceability_purposes_along_with_the_timestamp_part_of_docuseals_21_cfr_part_11_compliance_settings: "Ajouter un identifiant de signature unique et un horodatage à chaque signature à des fins d'audit et de traçabilité avec l'horodatage. Fait partie des paramètres de conformité 21 CFR Partie 11 de DocuSeal." + require_signer_to_provide_a_reason_for_signing_before_completing_their_signature_e_g_approvals_certifications_part_of_docuseals_21_cfr_part_11_compliance_settings: "Exiger des signataires qu'ils fournissent une raison avant de compléter leur signature (ex. approbations, certifications). Fait partie des paramètres de conformité 21 CFR Partie 11 de DocuSeal." + allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Permettre aux signataires de créer des signatures en tapant leur nom au lieu de les dessiner ou de les télécharger. + allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Permettre aux signataires de soumettre à nouveau des formulaires après achèvement, utile lorsque des corrections ou plusieurs envois sont nécessaires. + allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Permettre aux destinataires de refuser de signer un document. La notification de la raison du refus sera envoyée au demandeur de la signature. + save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: "Enregistrer la signature d'un utilisateur et la pré-remplir automatiquement dans les futures sessions de signature." + make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Faire expirer les liens de téléchargement de documents après 40 minutes pour éviter un accès à long terme et améliorer la sécurité. + require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Exiger une authentification avec identifiant utilisateur ou clé API pour accéder aux liens de téléchargement de documents. + combine_signed_documents_and_the_audit_log_into_a_single_pdf_file_for_easier_recordkeeping_and_compliance: "Combiner les documents signés et le journal d'audit dans un seul fichier PDF pour une gestion et une conformité plus faciles." + require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Exiger une autorisation JWT pour prévisualiser les formulaires intégrés, garantissant que seuls les utilisateurs autorisés puissent les voir. + make_all_newly_created_templates_private_to_their_creator_by_default: Rendre toutes les nouvelles modèles privées à leur créateur par défaut. + make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: "Rendre l'ordre de signature des destinataires toujours obligatoire, de sorte que le deuxième signataire ne puisse commencer qu'après que le premier a terminé." submission_sources: api: API bulk: Envoi en masse @@ -4397,6 +4461,22 @@ pt: &pt please_reply_to_this_email_if_you_dont_recognize_this_request: Responda a este e-mail se você não reconhecer esta solicitação. your_user_account_has_been_archived_contact_your_administrator_to_restore_access_to_your_account: Sua conta de usuário foi arquivada. Entre em contato com o administrador para restaurar o acesso à sua conta. your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: Seu e-mail não pôde ser acessado. Isso pode acontecer se houve um erro de digitação no endereço ou se sua caixa de correio não estiver disponível. Entre em contato com support@docuseal.com para fazer login. + efficient_search_with_search_index: Pesquisa eficiente com índice de busca + reindex: Reindexar + build_search_index: Construir índice de busca + require_two_factor_authentication_2fa_with_an_authenticator_app_e_g_google_authenticator_authy_all_users_signing_documents_must_pass_the_second_factor_verification_using_a_secure_code_in_addition_to_their_password: "Exigir autenticação de dois fatores (2FA) com um aplicativo autenticador (ex.: Google Authenticator, Authy). Todos os usuários que assinam documentos devem passar pela verificação do segundo fator usando um código seguro além da senha." + add_a_unique_signature_id_and_timestamp_to_each_signature_for_audit_and_traceability_purposes_along_with_the_timestamp_part_of_docuseals_21_cfr_part_11_compliance_settings: Adicionar um ID de assinatura exclusivo e um carimbo de data/hora a cada assinatura para fins de auditoria e rastreabilidade junto com o carimbo de data/hora. Parte das configurações de conformidade 21 CFR Parte 11 do DocuSeal. + require_signer_to_provide_a_reason_for_signing_before_completing_their_signature_e_g_approvals_certifications_part_of_docuseals_21_cfr_part_11_compliance_settings: "Exigir que os signatários forneçam uma razão antes de completar a assinatura (ex.: aprovações, certificações). Parte das configurações de conformidade 21 CFR Parte 11 do DocuSeal." + allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Permitir que os signatários criem assinaturas digitando seu nome em vez de desenhá-las ou carregá-las. + allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Permitir que os signatários reenviem formulários após o término, útil quando são necessárias correções ou múltiplos envios. + allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Permitir que os destinatários recusem assinar um documento. A notificação do motivo da recusa será enviada ao solicitante da assinatura. + save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Salvar a assinatura de um usuário e preenchê-la automaticamente em futuras sessões de assinatura. + make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Fazer os links de download de documentos expirarem após 40 minutos para evitar o acesso prolongado e aumentar a segurança. + require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Exigir autenticação com login do usuário ou chave API para acessar os links de download de documentos. + combine_signed_documents_and_the_audit_log_into_a_single_pdf_file_for_easier_recordkeeping_and_compliance: Combinar documentos assinados e o registro de auditoria em um único arquivo PDF para facilitar o arquivamento e a conformidade. + require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Exigir autorização JWT para visualizar formulários incorporados, garantindo que apenas usuários autorizados possam vê-los. + make_all_newly_created_templates_private_to_their_creator_by_default: Tornar todos os modelos recém-criados privados para seu criador por padrão. + make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Tornar a ordem de assinatura dos destinatários sempre obrigatória, para que o segundo signatário só possa assinar após o primeiro concluir. submission_sources: api: API bulk: Envio em massa @@ -5292,6 +5372,22 @@ de: &de api_key_access_code: API-Schlüssel-Zugangscode use_otp_code_to_access_the_api_key_html: Verwenden Sie den Code %{code}, um auf den API-Schlüssel zuzugreifen. please_reply_to_this_email_if_you_dont_recognize_this_request: Bitte antworten Sie auf diese E-Mail, wenn Sie diese Anfrage nicht erkennen. + efficient_search_with_search_index: Effiziente Suche mit Suchindex + reindex: Neu indexieren + build_search_index: Suchindex erstellen + require_two_factor_authentication_2fa_with_an_authenticator_app_e_g_google_authenticator_authy_all_users_signing_documents_must_pass_the_second_factor_verification_using_a_secure_code_in_addition_to_their_password: Zwei-Faktor-Authentifizierung (2FA) mit einer Authentifizierungs-App (z. B. Google Authenticator, Authy) erforderlich. Alle Benutzer, die Dokumente unterzeichnen, müssen die zweite Faktorprüfung mit einem sicheren Code zusätzlich zu ihrem Passwort bestehen. + add_a_unique_signature_id_and_timestamp_to_each_signature_for_audit_and_traceability_purposes_along_with_the_timestamp_part_of_docuseals_21_cfr_part_11_compliance_settings: Eine eindeutige Signatur-ID und einen Zeitstempel zu jeder Signatur hinzufügen, um Prüfungs- und Nachverfolgbarkeitszwecke zusammen mit dem Zeitstempel zu erfüllen. Teil der 21 CFR Teil 11-Compliance-Einstellungen von DocuSeal. + require_signer_to_provide_a_reason_for_signing_before_completing_their_signature_e_g_approvals_certifications_part_of_docuseals_21_cfr_part_11_compliance_settings: Unterzeichner müssen einen Grund für die Unterzeichnung angeben, bevor sie ihre Signatur abschließen (z. B. Genehmigungen, Zertifizierungen). Teil der 21 CFR Teil 11-Compliance-Einstellungen von DocuSeal. + allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Unterzeichner dürfen Signaturen erstellen, indem sie ihren Namen eingeben, anstatt eine zu zeichnen oder hochzuladen. + allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Unterzeichner dürfen Formulare nach Abschluss erneut einreichen, was nützlich ist, wenn Korrekturen oder mehrere Einreichungen erforderlich sind. + allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Empfänger dürfen die Unterzeichnung eines Dokuments ablehnen. Die Benachrichtigung über den Ablehnungsgrund wird an den Anforderer der Signatur gesendet. + save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Die Signatur eines Benutzers speichern und sie in zukünftigen Signatursitzungen automatisch ausfüllen. + make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Download-Links für Dokumente nach 40 Minuten ablaufen lassen, um langfristigen Zugriff zu verhindern und die Sicherheit zu erhöhen. + require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Authentifizierung mit Benutzeranmeldung oder API-Schlüssel erforderlich, um auf die Download-Links für Dokumente zuzugreifen. + combine_signed_documents_and_the_audit_log_into_a_single_pdf_file_for_easier_recordkeeping_and_compliance: Unterzeichnete Dokumente und das Prüfprotokoll in einer einzigen PDF-Datei kombinieren, um die Aufbewahrung und Compliance zu erleichtern. + require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: JWT-Autorisierung erforderlich, um eingebettete Formulare anzuzeigen, sodass nur autorisierte Benutzer sie sehen können. + make_all_newly_created_templates_private_to_their_creator_by_default: Alle neu erstellten Vorlagen standardmäßig für ihren Ersteller privat machen. + make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Die Unterzeichnungsreihenfolge der Empfänger immer erzwingen, sodass der zweite Unterzeichner erst nach Abschluss der Unterschrift durch den ersten beginnen kann. submission_sources: api: API bulk: Massenversand From 804431c44abe0bce70103cb236456ac51ef533df Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 18 Sep 2025 10:05:04 +0300 Subject: [PATCH 07/11] adjust account preferences --- app/javascript/elements/submit_form.js | 4 + app/views/accounts/show.html.erb | 132 ++++++++++++++----------- 2 files changed, 81 insertions(+), 55 deletions(-) diff --git a/app/javascript/elements/submit_form.js b/app/javascript/elements/submit_form.js index 7a27ed5f..164a069e 100644 --- a/app/javascript/elements/submit_form.js +++ b/app/javascript/elements/submit_form.js @@ -4,6 +4,10 @@ export default class extends HTMLElement { this.interval = setInterval(() => { this.querySelector('form').requestSubmit() }, parseInt(this.dataset.interval)) + } else if (this.dataset.on) { + this.lastElementChild.addEventListener(this.dataset.on, () => { + this.lastElementChild.form.requestSubmit() + }) } else { this.querySelector('form').requestSubmit() } diff --git a/app/views/accounts/show.html.erb b/app/views/accounts/show.html.erb index aae5a3eb..4152d1d0 100644 --- a/app/views/accounts/show.html.erb +++ b/app/views/accounts/show.html.erb @@ -51,13 +51,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('force_2fa_with_authenticator_app') %> +
    + <%= t('force_2fa_with_authenticator_app') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value %> +
    <% end %> <% end %> @@ -66,13 +68,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('add_signature_id_to_the_documents') %> +
    + <%= t('add_signature_id_to_the_documents') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()', disabled: can?(:manage, :cfr) %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value, disabled: can?(:manage, :cfr) %> +
    <% end %> <% end %> @@ -81,13 +85,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('require_signing_reason') %> +
    + <%= t('require_signing_reason') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()', disabled: can?(:manage, :cfr) %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value, disabled: can?(:manage, :cfr) %> +
    <% end %> <% end %> @@ -96,13 +102,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('allow_typed_text_signatures') %> +
    + <%= t('allow_typed_text_signatures') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value != false %> +
    <% end %> <% end %> @@ -111,13 +119,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('allow_to_resubmit_completed_forms') %> +
    + <%= t('allow_to_resubmit_completed_forms') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value != false %> +
    <% end %> <% end %> @@ -126,13 +136,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('allow_to_decline_documents') %> +
    + <%= t('allow_to_decline_documents') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value != false %> +
    <% end %> <% end %> @@ -141,13 +153,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('remember_and_pre_fill_signatures') %> +
    + <%= t('remember_and_pre_fill_signatures') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value != false %> +
    <% end %> <% end %> @@ -156,13 +170,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('expirable_file_download_links') %> +
    + <%= t('expirable_file_download_links') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value != false %> +
    <% end %> <% end %> @@ -171,13 +187,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('require_authentication_for_file_download_links') %> +
    + <%= t('require_authentication_for_file_download_links') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value %> +
    <% end %> <% end %> @@ -186,13 +204,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('combine_completed_documents_and_audit_log') %> +
    + <%= t('combine_completed_documents_and_audit_log') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value %> +
    <% end %> <% end %> @@ -202,13 +222,15 @@ <%= form_for account_config, url: account_configs_path, method: :post do |f| %> <%= f.hidden_field :key %>
    -
    -
    - <%= t('always_enforce_signing_order') %> +
    + <%= t('always_enforce_signing_order') %> + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> -
    +
    - <%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %> + + <%= f.check_box :value, class: 'toggle', checked: account_config.value %> +
    <% end %> <% end %> From 2a4e6435f10937d7715b32337eacf89c93c8b87c Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 18 Sep 2025 10:12:28 +0300 Subject: [PATCH 08/11] adjust api settings --- app/views/api_settings/index.html.erb | 6 +++--- config/routes.rb | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/views/api_settings/index.html.erb b/app/views/api_settings/index.html.erb index 57f6fa16..6c15c755 100644 --- a/app/views/api_settings/index.html.erb +++ b/app/views/api_settings/index.html.erb @@ -46,7 +46,7 @@
    <% text = capture do %>curl --location '<%= api_submissions_url %>' \ - --header 'X-Auth-Token: <%= current_user.access_token.token %>' \ + --header 'X-Auth-Token: API_TOKEN' \ --data-raw '{ "template_id": <%= current_account.templates.last&.id || 1 %>, "submitters": [ @@ -82,7 +82,7 @@
    <% text = capture do %>curl --location '<%= api_submissions_emails_url %>' \ - --header 'X-Auth-Token: <%= current_user.access_token.token %>' \ + --header 'X-Auth-Token: API_TOKEN' \ --data-raw '{ "template_id": <%= current_account.templates.last&.id || 1 %>, "emails": "<%= current_user.email.sub('@', '+test@') %>, <%= current_user.email.sub('@', '+test2@') %>" @@ -108,7 +108,7 @@
    <% text = capture do %>curl '<%= api_template_url(current_account.templates&.last || 1) %>' \ - --header 'X-Auth-Token: <%= current_user.access_token.token %>'<% end.to_str %> + --header 'X-Auth-Token: API_TOKEN'<% end.to_str %> <%= render 'shared/clipboard_copy', icon: 'copy', text:, class: 'btn btn-ghost text-white', icon_class: 'w-6 h-6 text-white', copy_title: t('copy'), copied_title: t('copied') %> diff --git a/config/routes.rb b/config/routes.rb index 1947b4b4..e90bd2f2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -170,6 +170,10 @@ Rails.application.routes.draw do resources :search_entries_reindex, only: %i[create] resources :sms, only: %i[index], controller: 'sms_settings' end + if Docuseal.demo? || !Docuseal.multitenant? + resources :api, only: %i[index create], controller: 'api_settings' + resource :reveal_access_token, only: %i[show create], controller: 'reveal_access_token' + end resources :email, only: %i[index create], controller: 'email_smtp_settings' resources :sso, only: %i[index], controller: 'sso_settings' resources :notifications, only: %i[index create], controller: 'notifications_settings' @@ -180,8 +184,6 @@ Rails.application.routes.draw do resources :integration_users, only: %i[index], path: 'users/:status', controller: 'users', defaults: { status: :integration } resource :personalization, only: %i[show create], controller: 'personalization_settings' - resources :api, only: %i[index create], controller: 'api_settings' - resource :reveal_access_token, only: %i[show create], controller: 'reveal_access_token' resources :webhooks, only: %i[index show new create update destroy], controller: 'webhook_settings' do post :resend From e5ab7667b9e0fa990343e95f721302e0ec186307 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 18 Sep 2025 10:48:29 +0300 Subject: [PATCH 09/11] adjust verification step --- .../submission_form/verification_step.vue | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/javascript/submission_form/verification_step.vue b/app/javascript/submission_form/verification_step.vue index 833fa68c..39da2419 100644 --- a/app/javascript/submission_form/verification_step.vue +++ b/app/javascript/submission_form/verification_step.vue @@ -156,6 +156,10 @@ export default { }).then(async (resp) => { this.eidEasyData = await resp.json() + if (this.eidEasyData.check_completed) { + this.$emit('submit') + } + if (this.eidEasyData.available_methods[0] === 'itsme-qes-signature' && this.eidEasyData.available_methods.length === 1) { const redirectUrl = new URL('https://id.eideasy.com/sign_contract_external') @@ -179,15 +183,23 @@ export default { }) }, async submit () { - return fetch(this.baseUrl + '/api/identity_verification', { + const resp = await fetch(this.baseUrl + '/api/identity_verification', { method: 'POST', body: JSON.stringify({ submitter_slug: this.submitterSlug }), headers: { 'Content-Type': 'application/json' } - }).then(async (resp) => { - return resp }) + + if (resp.status === 404) { + throw new Error('Verification not completed yet') + } + + if (resp.ok) { + return resp + } else { + throw new Error('Verification failed') + } } } } From b3dc8d55beae4848e20e030f788ea594df1c114a Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Fri, 19 Sep 2025 21:36:05 +0300 Subject: [PATCH 10/11] fix submission name --- lib/submissions/create_from_submitters.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/submissions/create_from_submitters.rb b/lib/submissions/create_from_submitters.rb index 5aaef47f..29aa37e8 100644 --- a/lib/submissions/create_from_submitters.rb +++ b/lib/submissions/create_from_submitters.rb @@ -18,13 +18,15 @@ module Submissions set_submission_preferences['send_email'] = true if params['send_completed_email'] expire_at = attrs[:expire_at] || Templates.build_default_expire_at(template) - submission = template.submissions.new(created_by_user: user, source:, - account_id: user.account_id, - preferences: set_submission_preferences, - name: with_template ? attrs[:name] : (attrs[:name] || template.name), - variables: attrs[:variables] || {}, - expire_at:, - template_submitters: [], submitters_order:) + submission = template.submissions.new( + created_by_user: user, source:, + account_id: user.account_id, + preferences: set_submission_preferences, + name: with_template ? attrs[:name] : (attrs[:name].presence || template.name), + variables: attrs[:variables] || {}, + expire_at:, + template_submitters: [], submitters_order: + ) template_submitters = template.submitters.deep_dup From 0b4754ca24c1e5d3465b2eb70a243a4d091dfcf9 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Mon, 22 Sep 2025 08:40:12 +0300 Subject: [PATCH 11/11] update email events index --- app/models/email_event.rb | 2 +- .../20250922053744_update_email_event_type_index.rb | 12 ++++++++++++ db/schema.rb | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20250922053744_update_email_event_type_index.rb diff --git a/app/models/email_event.rb b/app/models/email_event.rb index ed796226..8683a444 100644 --- a/app/models/email_event.rb +++ b/app/models/email_event.rb @@ -20,7 +20,7 @@ # # index_email_events_on_account_id_and_event_datetime (account_id,event_datetime) # index_email_events_on_email (email) -# index_email_events_on_email_event_types (email) WHERE ((event_type)::text = ANY ((ARRAY['bounce'::character varying, 'soft_bounce'::character varying, 'complaint'::character varying, 'soft_complaint'::character varying])::text[])) +# index_email_events_on_email_event_types (email) WHERE ((event_type)::text = ANY ((ARRAY['bounce'::character varying, 'soft_bounce'::character varying, 'permanent_bounce'::character varying, 'complaint'::character varying, 'soft_complaint'::character varying])::text[])) # index_email_events_on_emailable (emailable_type,emailable_id) # index_email_events_on_message_id (message_id) # diff --git a/db/migrate/20250922053744_update_email_event_type_index.rb b/db/migrate/20250922053744_update_email_event_type_index.rb new file mode 100644 index 00000000..7c33c65f --- /dev/null +++ b/db/migrate/20250922053744_update_email_event_type_index.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class UpdateEmailEventTypeIndex < ActiveRecord::Migration[8.0] + def change + remove_index :email_events, :email, where: "event_type IN ('bounce', 'soft_bounce', 'complaint', 'soft_complaint')", + name: 'index_email_events_on_email_event_types' + + add_index :email_events, :email, + where: "event_type IN ('bounce', 'soft_bounce', 'permanent_bounce', 'complaint', 'soft_complaint')", + name: 'index_email_events_on_email_event_types' + end +end diff --git a/db/schema.rb b/db/schema.rb index deff3e5a..c14f705b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_09_15_060548) do +ActiveRecord::Schema[8.0].define(version: 2025_09_22_053744) do # These are extensions that must be enabled in order to support this database enable_extension "btree_gin" enable_extension "plpgsql" @@ -178,7 +178,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_09_15_060548) do t.datetime "created_at", null: false t.index ["account_id", "event_datetime"], name: "index_email_events_on_account_id_and_event_datetime" t.index ["email"], name: "index_email_events_on_email" - t.index ["email"], name: "index_email_events_on_email_event_types", where: "((event_type)::text = ANY ((ARRAY['bounce'::character varying, 'soft_bounce'::character varying, 'complaint'::character varying, 'soft_complaint'::character varying])::text[]))" + t.index ["email"], name: "index_email_events_on_email_event_types", where: "((event_type)::text = ANY ((ARRAY['bounce'::character varying, 'soft_bounce'::character varying, 'permanent_bounce'::character varying, 'complaint'::character varying, 'soft_complaint'::character varying])::text[]))" t.index ["emailable_type", "emailable_id"], name: "index_email_events_on_emailable" t.index ["message_id"], name: "index_email_events_on_message_id" end