diff --git a/app/controllers/account_configs_controller.rb b/app/controllers/account_configs_controller.rb
index cfa46a14..87baf04c 100644
--- a/app/controllers/account_configs_controller.rb
+++ b/app/controllers/account_configs_controller.rb
@@ -6,7 +6,8 @@ class AccountConfigsController < ApplicationController
ALLOWED_KEYS = [
AccountConfig::ALLOW_TYPED_SIGNATURE,
- AccountConfig::FORCE_MFA
+ AccountConfig::FORCE_MFA,
+ AccountConfig::ESIGNING_PREFERENCE_KEY
].freeze
def create
diff --git a/app/models/account_config.rb b/app/models/account_config.rb
index 0c435e0e..2c18e6a3 100644
--- a/app/models/account_config.rb
+++ b/app/models/account_config.rb
@@ -29,6 +29,7 @@ class AccountConfig < ApplicationRecord
ALLOW_TYPED_SIGNATURE = 'allow_typed_signature'
SUBMITTER_REMAILERS = 'submitter_reminders'
FORM_COMPLETED_BUTTON_KEY = 'form_completed_button'
+ ESIGNING_PREFERENCE_KEY = 'esigning_preference'
DEFAULT_VALUES = {
SUBMITTER_INVITATION_EMAIL_KEY => {
diff --git a/app/views/esign_settings/show.html.erb b/app/views/esign_settings/show.html.erb
index 5f93bacd..1e8b5455 100644
--- a/app/views/esign_settings/show.html.erb
+++ b/app/views/esign_settings/show.html.erb
@@ -121,7 +121,28 @@
<%= f.button button_title(title: 'Save', disabled_with: 'Updating'), class: 'base-button' %>
<% end %>
+
+ <% end %>
+ <% if !Docuseal.multitenant? %>
+ <% account_config = AccountConfig.where(account: current_account, key: AccountConfig::ESIGNING_PREFERENCE_KEY).first_or_initialize(value: 'multiple') %>
+ <% if can?(:manage, account_config) %>
+
+
+
Preferences
+
+ <% if can?(:manage, account_config) %>
+ <%= form_for account_config, url: account_configs_path, method: :post do |f| %>
+ <%= f.hidden_field :key %>
+
+
+ Apply multiple PDF digital signatures in the document per each signer
+
+ <%= f.check_box :value, { class: 'toggle', checked: account_config.value == 'multiple', onchange: 'this.form.requestSubmit()' }, 'multiple', 'single' %>
+
+ <% end %>
+ <% end %>
+
<% end %>
-
+ <% end %>
diff --git a/lib/submissions/generate_audit_trail.rb b/lib/submissions/generate_audit_trail.rb
index db55f628..5bdcc317 100644
--- a/lib/submissions/generate_audit_trail.rb
+++ b/lib/submissions/generate_audit_trail.rb
@@ -257,7 +257,7 @@ module Submissions
if event.event_type.include?('sms') || event.event_type.include?('phone')
submitter.phone
else
- (submitter.name || submitter.email || submitter.phone)
+ submitter.name || submitter.email || submitter.phone
end
]
)
diff --git a/lib/submissions/generate_result_attachments.rb b/lib/submissions/generate_result_attachments.rb
index 845587a5..94a39db6 100644
--- a/lib/submissions/generate_result_attachments.rb
+++ b/lib/submissions/generate_result_attachments.rb
@@ -11,7 +11,8 @@ module Submissions
end
INFO_CREATOR = "#{Docuseal.product_name} (#{Docuseal::PRODUCT_URL})".freeze
- SIGN_REASON = 'Signed by %s with DocuSeal.co'
+ SIGN_REASON = 'Signed by %s with DocuSeal.co'
+ SIGN_SIGNLE_REASON = 'Digitally signed with DocuSeal.co'
TEXT_LEFT_MARGIN = 1
TEXT_TOP_MARGIN = 1
@@ -200,9 +201,9 @@ module Submissions
submitter.submission.template_schema.map do |item|
pdf = pdfs_index[item['attachment_uuid']]
- attachment = save_signed_pdf(pdf:, submitter:, pkcs:, tsa_url:,
- uuid: item['attachment_uuid'],
- name: item['name'])
+ attachment = save_pdf(pdf:, submitter:, pkcs:, tsa_url:,
+ uuid: item['attachment_uuid'],
+ name: item['name'])
image_pdfs << pdf if original_documents.find { |a| a.uuid == item['attachment_uuid'] }.image?
@@ -217,7 +218,7 @@ module Submissions
end
images_pdf_result =
- save_signed_pdf(
+ save_pdf(
pdf: images_pdf,
submitter:,
tsa_url:,
@@ -230,30 +231,34 @@ module Submissions
end
# rubocop:enable Metrics
- def save_signed_pdf(pdf:, submitter:, pkcs:, tsa_url:, uuid:, name:)
+ def save_pdf(pdf:, submitter:, pkcs:, tsa_url:, uuid:, name:)
io = StringIO.new
pdf.trailer.info[:Creator] = info_creator
- sign_params = {
- reason: sign_reason(submitter.email),
- certificate: pkcs.certificate,
- key: pkcs.key,
- certificate_chain: pkcs.ca_certs || []
- }
+ sign_reason = fetch_sign_reason(submitter)
- if tsa_url
- sign_params[:timestamp_handler] = Submissions::TimestampHandler.new(tsa_url:)
- sign_params[:signature_size] = 10_000
- end
+ if sign_reason
+ sign_params = {
+ reason: sign_reason,
+ certificate: pkcs.certificate,
+ key: pkcs.key,
+ certificate_chain: pkcs.ca_certs || []
+ }
+
+ if tsa_url
+ sign_params[:timestamp_handler] = Submissions::TimestampHandler.new(tsa_url:)
+ sign_params[:signature_size] = 10_000
+ end
- pdf.sign(io, **sign_params)
+ pdf.sign(io, **sign_params)
+ else
+ pdf.write(io, incremental: true)
+ end
ActiveStorage::Attachment.create!(
uuid:,
- blob: ActiveStorage::Blob.create_and_upload!(
- io: StringIO.new(io.string), filename: "#{name}.pdf"
- ),
+ blob: ActiveStorage::Blob.create_and_upload!(io: StringIO.new(io.string), filename: "#{name}.pdf"),
metadata: { sha256: Base64.urlsafe_encode64(Digest::SHA256.digest(io.string)) },
name: 'documents',
record: submitter
@@ -308,8 +313,27 @@ module Submissions
pdf
end
- def sign_reason(email)
- format(SIGN_REASON, email:)
+ def sign_reason(name)
+ format(SIGN_REASON, name:)
+ end
+
+ def single_sign_reason
+ SIGN_SIGNLE_REASON
+ end
+
+ def fetch_sign_reason(submitter)
+ reason_name = submitter.email || submitter.name || submitter.phone
+
+ return sign_reason(reason_name) if Docuseal.multitenant?
+
+ return sign_reason(reason_name) if AccountConfig.where(account: submitter.account,
+ key: AccountConfig::ESIGNING_PREFERENCE_KEY)
+ .first_or_initialize(value: 'multiple').value == 'multiple'
+
+ return single_sign_reason if !submitter.submission.submitters.exists?(completed_at: nil) &&
+ submitter.completed_at == submitter.submission.submitters.maximum(:completed_at)
+
+ nil
end
def info_creator