diff --git a/app/controllers/api/active_storage_blobs_proxy_controller.rb b/app/controllers/api/active_storage_blobs_proxy_controller.rb new file mode 100644 index 00000000..af634a5e --- /dev/null +++ b/app/controllers/api/active_storage_blobs_proxy_controller.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Api + class ActiveStorageBlobsProxyController < ApiBaseController + include ActiveStorage::Streaming + + skip_before_action :authenticate_user! + skip_authorization_check + + def show + blob_uuid = ApplicationRecord.signed_id_verifier.verified(params[:signed_uuid]) + + return head :not_found unless blob_uuid + + blob = ActiveStorage::Blob.find_by!(uuid: blob_uuid) + + if request.headers['Range'].present? + send_blob_byte_range_data blob, request.headers['Range'] + else + http_cache_forever public: true do + response.headers['Accept-Ranges'] = 'bytes' + response.headers['Content-Length'] = blob.byte_size.to_s + + send_blob_stream blob, disposition: params[:disposition] + end + end + end + end +end diff --git a/app/controllers/submissions_download_controller.rb b/app/controllers/submissions_download_controller.rb index 96a6cd18..87526281 100644 --- a/app/controllers/submissions_download_controller.rb +++ b/app/controllers/submissions_download_controller.rb @@ -15,7 +15,7 @@ class SubmissionsDownloadController < ApplicationController urls = Submitters.select_attachments_for_download(last_submitter).map do |attachment| - helpers.rails_blob_url(attachment) + ActiveStorage::Blob.proxy_url(attachment.blob) end render json: urls diff --git a/app/models/submission.rb b/app/models/submission.rb index 42d1ae0b..8567c742 100644 --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -76,7 +76,7 @@ class Submission < ApplicationRecord def audit_trail_url return if audit_trail.blank? - Rails.application.routes.url_helpers.rails_storage_proxy_url(audit_trail, **Docuseal.default_url_options) + ActiveStorage::Blob.proxy_url(audit_trail.blob) end alias audit_log_url audit_trail_url end diff --git a/config/initializers/active_storage.rb b/config/initializers/active_storage.rb index a8606ec5..0396624b 100644 --- a/config/initializers/active_storage.rb +++ b/config/initializers/active_storage.rb @@ -14,13 +14,20 @@ ActiveSupport.on_load(:active_storage_attachment) do return unless first_page - Rails.application.routes.url_helpers.rails_storage_proxy_url(first_page, **Docuseal.default_url_options) + ActiveStorage::Blob.proxy_url(first_page.blob) end end ActiveSupport.on_load(:active_storage_blob) do attribute :uuid, :string, default: -> { SecureRandom.uuid } + def self.proxy_url(blob, expires_in: nil) + Rails.application.routes.url_helpers.blobs_proxy_url( + signed_uuid: blob.signed_uuid(expires_in:), filename: blob.filename, + **Docuseal.default_url_options + ) + end + def uuid super || begin new_uuid = SecureRandom.uuid @@ -29,6 +36,10 @@ ActiveSupport.on_load(:active_storage_blob) do end end + def signed_uuid(expires_in: nil) + ApplicationRecord.signed_id_verifier.generate(uuid, expires_in:) + end + def delete service.delete(key) end diff --git a/config/routes.rb b/config/routes.rb index b0c4b882..f75c7a9c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -82,6 +82,8 @@ Rails.application.routes.draw do resources :submissions_export, only: %i[index new] end resources :preview_document_page, only: %i[show], path: '/preview/:signed_uuid' + resource :blobs_proxy, only: %i[show], path: '/blobs_proxy/:signed_uuid/*filename(.:format)', + controller: 'api/active_storage_blobs_proxy' resources :start_form, only: %i[show update], path: 'd', param: 'slug' do get :completed diff --git a/lib/submissions/generate_audit_trail.rb b/lib/submissions/generate_audit_trail.rb index 770e1d43..af59b72e 100644 --- a/lib/submissions/generate_audit_trail.rb +++ b/lib/submissions/generate_audit_trail.rb @@ -98,7 +98,7 @@ module Submissions end link = - Rails.application.routes.url_helpers.rails_blob_url(document, **Docuseal.default_url_options) + ActiveStorage::Blob.proxy_url(document.blob) [ composer.document.layout.formatted_text_box( @@ -228,7 +228,7 @@ module Submissions Array.wrap(value).map do |uuid| attachment = submitter.attachments.find { |a| a.uuid == uuid } link = - Rails.application.routes.url_helpers.rails_blob_url(attachment, **Docuseal.default_url_options) + ActiveStorage::Blob.proxy_url(attachment.blob) { link:, text: "#{attachment.filename}\n", style: :link } end, diff --git a/lib/submissions/generate_result_attachments.rb b/lib/submissions/generate_result_attachments.rb index d8308c83..0052efb4 100644 --- a/lib/submissions/generate_result_attachments.rb +++ b/lib/submissions/generate_result_attachments.rb @@ -131,7 +131,7 @@ module Submissions height - (area['y'] * height) - lines[..next_index].sum(&:height) + height_diff ], A: { Type: :Action, S: :URI, - URI: h.rails_blob_url(attachment, **Docuseal.default_url_options) } + URI: ActiveStorage::Blob.proxy_url(attachment.blob) } } ) diff --git a/lib/submitters/serialize_for_webhook.rb b/lib/submitters/serialize_for_webhook.rb index 5699651a..5c44a910 100644 --- a/lib/submitters/serialize_for_webhook.rb +++ b/lib/submitters/serialize_for_webhook.rb @@ -76,7 +76,7 @@ module Submitters def rails_storage_proxy_url(attachment) return if attachment.blank? - r.rails_storage_proxy_url(attachment, **Docuseal.default_url_options) + ActiveStorage::Blob.proxy_url(attachment.blob) end def r