55 lines
1.7 KiB
SQL
55 lines
1.7 KiB
SQL
-- Profile-Avatar storage bucket.
|
|
--
|
|
-- Layout: <user_id>/<filename>.webp
|
|
-- Public read so peers can see each other's avatar without auth roundtrip
|
|
-- (avatars are non-sensitive). Write/update/delete restricted to the owning
|
|
-- user via path prefix matching their auth.uid().
|
|
|
|
insert into storage.buckets (id, name, public)
|
|
values ('profile-avatars', 'profile-avatars', true)
|
|
on conflict (id) do nothing;
|
|
|
|
-- Read: anyone authenticated can view any avatar (public bucket also lets
|
|
-- unauth fetch by URL but our RLS keeps the table-level policy explicit).
|
|
drop policy if exists profile_avatars_select on storage.objects;
|
|
create policy profile_avatars_select
|
|
on storage.objects
|
|
for select
|
|
to authenticated, anon
|
|
using (bucket_id = 'profile-avatars');
|
|
|
|
-- Write only into your own folder (first path segment must equal auth.uid()).
|
|
drop policy if exists profile_avatars_insert_own on storage.objects;
|
|
create policy profile_avatars_insert_own
|
|
on storage.objects
|
|
for insert
|
|
to authenticated
|
|
with check (
|
|
bucket_id = 'profile-avatars'
|
|
and (storage.foldername(name))[1] = auth.uid()::text
|
|
);
|
|
|
|
drop policy if exists profile_avatars_update_own on storage.objects;
|
|
create policy profile_avatars_update_own
|
|
on storage.objects
|
|
for update
|
|
to authenticated
|
|
using (
|
|
bucket_id = 'profile-avatars'
|
|
and (storage.foldername(name))[1] = auth.uid()::text
|
|
)
|
|
with check (
|
|
bucket_id = 'profile-avatars'
|
|
and (storage.foldername(name))[1] = auth.uid()::text
|
|
);
|
|
|
|
drop policy if exists profile_avatars_delete_own on storage.objects;
|
|
create policy profile_avatars_delete_own
|
|
on storage.objects
|
|
for delete
|
|
to authenticated
|
|
using (
|
|
bucket_id = 'profile-avatars'
|
|
and (storage.foldername(name))[1] = auth.uid()::text
|
|
);
|