Files
docuseal/lib/templates/create_attachments.rb
T

86 lines
2.6 KiB
Ruby
Raw Normal View History

2023-09-01 01:27:13 +03:00
# frozen_string_literal: true
module Templates
module CreateAttachments
PDF_CONTENT_TYPE = 'application/pdf'
2023-10-22 01:54:20 +03:00
ANNOTATIONS_SIZE_LIMIT = 6.megabytes
2023-09-05 20:33:40 +03:00
InvalidFileType = Class.new(StandardError)
2024-01-14 23:22:41 +02:00
PdfEncrypted = Class.new(StandardError)
2023-09-01 01:27:13 +03:00
module_function
def call(template, params)
find_or_create_blobs(params).map do |blob|
document_data = blob.download
2023-09-05 20:33:40 +03:00
if !blob.image? && blob.content_type != PDF_CONTENT_TYPE
blob, document_data = handle_file_types(blob, document_data)
end
document = template.documents.create!(blob:)
2023-09-01 01:27:13 +03:00
if blob.content_type == PDF_CONTENT_TYPE && blob.metadata['pdf'].nil?
2024-01-14 23:22:41 +02:00
data = maybe_decrypt_pdf_or_raise(document_data, params)
if data != document_data
blob = ActiveStorage::Blob.create_and_upload!(
io: StringIO.new(new_data), filename: blob.filename
)
document_data = data
end
2023-10-22 01:54:20 +03:00
annotations =
document_data.size > ANNOTATIONS_SIZE_LIMIT ? [] : Templates::BuildAnnotations.call(document_data)
blob.metadata['pdf'] = { 'annotations' => annotations }
2023-09-10 19:25:57 +03:00
blob.metadata['sha256'] = Base64.urlsafe_encode64(Digest::SHA256.digest(document_data))
2023-09-01 01:27:13 +03:00
end
blob.save!
Templates::ProcessDocument.call(document, document_data)
end
end
def find_or_create_blobs(params)
blobs = params[:blobs]&.map do |attrs|
ActiveStorage::Blob.find_signed(attrs[:signed_id])
end
blobs || params[:files].map do |file|
data = file.read
if file.content_type == PDF_CONTENT_TYPE
2024-01-14 23:22:41 +02:00
data = maybe_decrypt_pdf_or_raise(data, params)
2023-10-22 01:54:20 +03:00
annotations = data.size > ANNOTATIONS_SIZE_LIMIT ? [] : Templates::BuildAnnotations.call(data)
2023-09-01 01:27:13 +03:00
metadata = { 'identified' => true, 'analyzed' => true,
2023-09-10 19:25:57 +03:00
'sha256' => Base64.urlsafe_encode64(Digest::SHA256.digest(data)),
2023-10-22 01:54:20 +03:00
'pdf' => { 'annotations' => annotations } }
2023-09-01 01:27:13 +03:00
end
ActiveStorage::Blob.create_and_upload!(
io: StringIO.new(data),
filename: file.original_filename,
metadata:,
content_type: file.content_type
)
end
end
2023-09-05 20:33:40 +03:00
2024-01-14 23:22:41 +02:00
def maybe_decrypt_pdf_or_raise(data, params)
if data.size < ANNOTATIONS_SIZE_LIMIT && PdfUtils.encrypted?(data)
PdfUtils.decrypt(data, params[:password])
else
data
end
rescue HexaPDF::EncryptionError
raise PdfEncrypted
end
2023-09-05 20:33:40 +03:00
def handle_file_types(_document_data, blob)
raise InvalidFileType, blob.content_type
end
2023-09-01 01:27:13 +03:00
end
end