From 75a0779a3a593d5cfe3dd0d7e76b3a855a0c907a Mon Sep 17 00:00:00 2001 From: Hermes cc-worker Date: Mon, 8 Jun 2026 01:08:09 +0000 Subject: [PATCH] fix(files): allow GC through storage protect_delete (cherry picked from commit a6eff7ad124c94c75751c77a499433b562911b7b) --- volumes/db/cc/75-files-gc-protect-delete.sql | 51 ++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 volumes/db/cc/75-files-gc-protect-delete.sql diff --git a/volumes/db/cc/75-files-gc-protect-delete.sql b/volumes/db/cc/75-files-gc-protect-delete.sql new file mode 100644 index 0000000..302117f --- /dev/null +++ b/volumes/db/cc/75-files-gc-protect-delete.sql @@ -0,0 +1,51 @@ +-- Allow our file-GC helpers to satisfy Supabase storage.protect_delete +-- without weakening the managed storage trigger for arbitrary raw deletes. +-- +-- Supabase storage.protect_delete permits direct storage.objects deletes only +-- when the transaction-local GUC storage.allow_delete_query is 'true'. The +-- Storage API sets that GUC for its own deletes. public.files GC is our +-- trigger-side cleanup path, so scope the same GUC to these SECURITY DEFINER +-- helpers immediately before their storage.objects DELETE statements. + +create or replace function public._delete_storage_objects(p_bucket text, p_path text) +returns void +language plpgsql security definer +set search_path to 'public', 'storage' +as $$ +begin + if p_bucket is null or p_path is null then + return; + end if; + + perform set_config('storage.allow_delete_query', 'true', true); + + delete from storage.objects where bucket_id = p_bucket and name = p_path; + delete from storage.objects where bucket_id = p_bucket and name like p_path || '/%'; +end +$$; + +create or replace function public._delete_storage_prefix(p_bucket text, p_prefix text) +returns void +language plpgsql security definer +set search_path to 'public', 'storage' +as $$ +begin + if p_bucket is null or p_prefix is null then + return; + end if; + + perform set_config('storage.allow_delete_query', 'true', true); + + -- Delete any objects whose name starts with the prefix + '/' + delete from storage.objects where bucket_id = p_bucket and name like p_prefix || '/%'; + -- In case an object exists exactly at the prefix (rare but safe) + delete from storage.objects where bucket_id = p_bucket and name = p_prefix; +end +$$; + +-- These helpers are intended for our SECURITY DEFINER GC triggers/helpers, not +-- as a general SQL delete API for application roles. +revoke all on function public._delete_storage_objects(text, text) from public; +revoke all on function public._delete_storage_prefix(text, text) from public; +revoke all on function public._delete_storage_objects(text, text) from anon, authenticated; +revoke all on function public._delete_storage_prefix(text, text) from anon, authenticated;