From f739f3da0f6c51b1f093516579b500e807fbc9cb Mon Sep 17 00:00:00 2001 From: puffo Date: Wed, 10 Jun 2026 10:57:56 -0500 Subject: [PATCH] Allow disabling CORS fetch mode in the service worker Self-hosted instances using cross-site S3-compatible storage have no load balancer to add CORS headers to Active Storage redirects, so the service worker's `mode: "cors"` fetch fails and inline images break. Setting SERVICE_WORKER_CORS_ENABLED=false omits the CORS fetch option. --- app/views/pwa/service_worker.js.erb | 4 ++-- docs/docker-deployment.md | 3 +++ test/controllers/pwa_controller_test.rb | 31 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 test/controllers/pwa_controller_test.rb diff --git a/app/views/pwa/service_worker.js.erb b/app/views/pwa/service_worker.js.erb index 41fac14463..f9234d4197 100644 --- a/app/views/pwa/service_worker.js.erb +++ b/app/views/pwa/service_worker.js.erb @@ -42,8 +42,8 @@ TurboOffline.addRule({ maxAge: 60 * 60 * 24 * 7, networkTimeout: 2, maxEntrySize: 2 * 1024 * 1024, // 2MB covers about 95% of all Fizzy blobs - maxEntries: 500, - fetchOptions: { mode: "cors" } + maxEntries: 500<% unless ENV["SERVICE_WORKER_CORS_ENABLED"] == "false" %>, + fetchOptions: { mode: "cors" }<% end %> }) }) diff --git a/docs/docker-deployment.md b/docs/docker-deployment.md index c74efe2915..219bcab1da 100644 --- a/docs/docker-deployment.md +++ b/docs/docker-deployment.md @@ -143,6 +143,9 @@ If you're using a provider other than AWS, you will also need some of the follow - `S3_REQUEST_CHECKSUM_CALCULATION` - `S3_RESPONSE_CHECKSUM_VALIDATION` +If your storage provider is on a different site than your Fizzy instance and doesn't return CORS headers on presigned URL responses, inline images may fail to load. +In that case, set `SERVICE_WORKER_CORS_ENABLED=false` so the service worker fetches uploaded files without CORS mode. + #### Multi-tenant mode By default, when you run the Fizzy Docker image you'll be limited to creating a single account (although that account can have as many users as you like). diff --git a/test/controllers/pwa_controller_test.rb b/test/controllers/pwa_controller_test.rb new file mode 100644 index 0000000000..0b391b8ce4 --- /dev/null +++ b/test/controllers/pwa_controller_test.rb @@ -0,0 +1,31 @@ +require "test_helper" + +class PwaControllerTest < ActionDispatch::IntegrationTest + setup do + sign_in_as :david + end + + test "service worker fetches storage with CORS mode by default" do + untenanted { get "/service-worker.js" } + + assert_response :success + assert_match 'fetchOptions: { mode: "cors" }', response.body + end + + test "service worker omits CORS fetch mode when disabled" do + switch_env "SERVICE_WORKER_CORS_ENABLED", "false" do + untenanted { get "/service-worker.js" } + end + + assert_response :success + assert_no_match(/mode: "cors"/, response.body) + end + + private + def switch_env(key, value) + old, ENV[key] = ENV[key], value + yield + ensure + ENV[key] = old + end +end