mirror of https://github.com/docusealco/docuseal
				
				
				
			
							parent
							
								
									9e66f8412c
								
							
						
					
					
						commit
						f9d52e56a2
					
				@ -1,16 +1,37 @@
 | 
				
			|||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module Api
 | 
					module Api
 | 
				
			||||||
  class AttachmentsController < ApiBaseController
 | 
					  class AttachmentsController < ActionController::API
 | 
				
			||||||
    skip_before_action :authenticate_user!
 | 
					    include ActionController::Cookies
 | 
				
			||||||
    skip_authorization_check
 | 
					    include ActiveStorage::SetCurrent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    COOKIE_STORE_LIMIT = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create
 | 
					    def create
 | 
				
			||||||
      submitter = Submitter.find_by!(slug: params[:submitter_slug])
 | 
					      submitter = Submitter.find_by!(slug: params[:submitter_slug])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      attachment = Submitters.create_attachment!(submitter, params)
 | 
					      attachment = Submitters.create_attachment!(submitter, params)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if params[:remember_signature] == 'true' && submitter.email.present?
 | 
				
			||||||
 | 
					        cookies.encrypted[:signature_uuids] = build_new_cookie_signatures_json(submitter, attachment)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      render json: attachment.as_json(only: %i[uuid], methods: %i[url filename content_type])
 | 
					      render json: attachment.as_json(only: %i[uuid], methods: %i[url filename content_type])
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def build_new_cookie_signatures_json(submitter, attachment)
 | 
				
			||||||
 | 
					      values =
 | 
				
			||||||
 | 
					        begin
 | 
				
			||||||
 | 
					          JSON.parse(cookies.encrypted[:signature_uuids].presence || '{}')
 | 
				
			||||||
 | 
					        rescue JSON::ParserError
 | 
				
			||||||
 | 
					          {}
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      values[submitter.email] = attachment.uuid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      values = values.to_a.last(COOKIE_STORE_LIMIT).to_h if values.size > COOKIE_STORE_LIMIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      values.to_json
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
<% data_attachments = attachments_index.values.select { |e| e.record_id == submitter.id }.to_json(only: %i[uuid], methods: %i[url filename content_type]) %>
 | 
					<% data_attachments = attachments_index.values.select { |e| e.record_id == submitter.id }.to_json(only: %i[uuid], methods: %i[url filename content_type]) %>
 | 
				
			||||||
<% data_fields = (submitter.submission.template_fields || submitter.submission.template.fields).select { |f| f['submitter_uuid'] == submitter.uuid }.to_json %>
 | 
					<% data_fields = (submitter.submission.template_fields || submitter.submission.template.fields).select { |f| f['submitter_uuid'] == submitter.uuid }.to_json %>
 | 
				
			||||||
<% configs = Submitters::FormConfigs.call(submitter) %>
 | 
					<submission-form data-is-demo="<%= Docuseal.demo? %>" data-with-confetti="<%= configs[:with_confetti] %>" data-completed-redirect-url="<%= submitter.preferences['completed_redirect_url'] %>" data-completed-message="<%= configs[:completed_message].to_json %>" data-completed-button="<%= configs[:completed_button].to_json %>" data-go-to-last="<%= submitter.preferences.key?('go_to_last') ? submitter.preferences['go_to_last'] : submitter.opened_at? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Accounts.can_send_emails?(submitter.submission.account) %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-values="<%= submitter.values.to_json %>" data-with-typed-signature="<%= configs[:with_typed_signature] %>" data-previous-signature-value="<%= local_assigns[:signature_attachment]&.uuid %>" data-remember-signature="<%= configs[:prefill_signature] %>"></submission-form>
 | 
				
			||||||
<submission-form data-is-demo="<%= Docuseal.demo? %>" data-with-confetti="<%= configs[:with_confetti] %>" data-completed-redirect-url="<%= submitter.preferences['completed_redirect_url'] %>" data-completed-message="<%= configs[:completed_message].to_json %>" data-completed-button="<%= configs[:completed_button].to_json %>" data-go-to-last="<%= submitter.preferences.key?('go_to_last') ? submitter.preferences['go_to_last'] : submitter.opened_at? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Accounts.can_send_emails?(submitter.submission.account) %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-values="<%= submitter.values.to_json %>" data-with-typed-signature="<%= configs[:with_typed_signature] %>" data-previous-signature-value="<%= local_assigns[:signature_attachment]&.uuid %>"></submission-form>
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module Submitters
 | 
				
			||||||
 | 
					  module MaybeAssignDefaultBrowserSignature
 | 
				
			||||||
 | 
					    SIGNED_UUID_PURPPOSE = 'signature'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    module_function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def call(submitter, params, cookies = nil, attachments = [])
 | 
				
			||||||
 | 
					      if (value = params[:signature_src].presence || params[:signature].presence)
 | 
				
			||||||
 | 
					        find_or_create_signature_from_value(submitter, value, attachments)
 | 
				
			||||||
 | 
					      elsif params[:signed_signature_uuids].present?
 | 
				
			||||||
 | 
					        find_storage_signature(submitter, params[:signed_signature_uuids], attachments)
 | 
				
			||||||
 | 
					      elsif cookies
 | 
				
			||||||
 | 
					        find_session_signature(submitter, cookies, attachments)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_or_create_signature_from_value(submitter, value, attachments)
 | 
				
			||||||
 | 
					      _, attachment = Submitters::NormalizeValues.normalize_attachment_value(value,
 | 
				
			||||||
 | 
					                                                                             'signature',
 | 
				
			||||||
 | 
					                                                                             submitter.account,
 | 
				
			||||||
 | 
					                                                                             attachments,
 | 
				
			||||||
 | 
					                                                                             submitter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      attachment.record ||= submitter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      attachment.save!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      attachment
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def sign_signature_uuid(uuid)
 | 
				
			||||||
 | 
					      ApplicationRecord.signed_id_verifier.generate(uuid, purpose: SIGNED_UUID_PURPPOSE)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def verify_signature_uuid(signed_uuid)
 | 
				
			||||||
 | 
					      ApplicationRecord.signed_id_verifier.verified(signed_uuid, purpose: SIGNED_UUID_PURPPOSE)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_storage_signature(submitter, signed_uuids, attachments)
 | 
				
			||||||
 | 
					      signed_uuid = signed_uuids[submitter.email]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return if signed_uuid.blank?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      uuid = verify_signature_uuid(signed_uuid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return if uuid.blank?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      find_signature_from_uuid(submitter, uuid, attachments)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_session_signature(submitter, cookies, attachments)
 | 
				
			||||||
 | 
					      values =
 | 
				
			||||||
 | 
					        begin
 | 
				
			||||||
 | 
					          JSON.parse(cookies.encrypted[:signature_uuids].presence || '{}')
 | 
				
			||||||
 | 
					        rescue JSON::ParserError
 | 
				
			||||||
 | 
					          {}
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return if values.blank?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      uuid = values[submitter.email]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return if uuid.blank?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      find_signature_from_uuid(submitter, uuid, attachments)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_signature_from_uuid(submitter, uuid, attachments)
 | 
				
			||||||
 | 
					      signature_attachment = ActiveStorage::Attachment.find_by(uuid:)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return unless signature_attachment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return if signature_attachment.record.email != submitter.email
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      existing_attachment = attachments.find do |a|
 | 
				
			||||||
 | 
					        a.blob_id == signature_attachment.blob_id && submitter.id == a.record_id
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return existing_attachment if existing_attachment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      submitter.attachments_attachments.create_or_find_by!(blob_id: signature_attachment.blob_id)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue