# frozen_string_literal: true module Submitters module MaybeAssignDefaultBrowserSignature SIGNED_UUID_PURPPOSE = 'signature' module_function def call(submitter, params, cookies = nil, attachments = []) attachments = attachments.select { |e| e.record_id == submitter.id && e.record_type == 'Submitter' } 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, { 'type' => '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