88 lines
4.1 KiB
PL/PgSQL
88 lines
4.1 KiB
PL/PgSQL
create table public.profiles (
|
|
id uuid primary key references auth.users(id) on delete cascade,
|
|
username text unique not null,
|
|
created_at timestamp with time zone default timezone('utc'::text, now()) not null
|
|
|
|
-- username should be 3 to 24 characters long containing alphabets, numbers and underscores
|
|
constraint username_validation check (username ~* '^[A-Za-z0-9_]{3,24}$')
|
|
);
|
|
|
|
-- Function to create a new row in profiles table upon signup
|
|
-- Also copies the username value from metadata
|
|
create or replace function handle_new_user() returns trigger as $$
|
|
begin
|
|
insert into public.profiles(id, username)
|
|
values(new.id, new.raw_user_meta_data->>'username');
|
|
|
|
return new;
|
|
end;
|
|
$$ language plpgsql security definer;
|
|
|
|
-- Trigger to call `handle_new_user` when new user signs up
|
|
create trigger on_auth_user_created
|
|
after insert on auth.users
|
|
for each row
|
|
execute function handle_new_user();
|
|
|
|
create table if not exists public.projects (
|
|
id uuid primary key default gen_random_uuid(),
|
|
name text not null default 'new project',
|
|
created_at timestamp with time zone default timezone('utc'::text, now()) not null
|
|
);
|
|
|
|
create table if not exists public.project_members (
|
|
profile_id uuid references public.profiles(id) on delete cascade not null,
|
|
project_id uuid references public.projects(id) on delete cascade not null,
|
|
created_at timestamp with time zone default timezone('utc' :: text, now()) not null,
|
|
primary key (profile_id, project_id)
|
|
);
|
|
|
|
alter table public.canvas_objects
|
|
add column project_id uuid references public.projects(id) on delete cascade not null;
|
|
|
|
-- Returns true if the signed in user is a member of the project
|
|
create or replace function is_project_member(project_id uuid)
|
|
returns boolean as $$
|
|
select exists(
|
|
select 1
|
|
from project_members
|
|
where project_id = is_project_member.project_id and profile_id = auth.uid()
|
|
);
|
|
$$ language sql security definer;
|
|
|
|
alter table public.profiles enable row level security;
|
|
create policy "Public profiles are viewable by everyone." on public.profiles for select using (true);
|
|
|
|
alter table public.projects enable row level security;
|
|
create policy "Users can view projects that they have joined" on public.projects for select using (is_project_member(id));
|
|
|
|
alter table public.project_members enable row level security;
|
|
create policy "Participants of the project can view other participants." on public.project_members for select using (is_project_member(project_id));
|
|
create policy "Participants of the project can insert new users." on public.project_members for insert with check (is_project_member(project_id));
|
|
|
|
alter table public.canvas_objects enable row level security;
|
|
create policy "Users can view canvas_objects of projects they are in." on public.canvas_objects for select using (is_project_member(project_id));
|
|
create policy "Users can insert canvas_objects of projects they are in." on public.canvas_objects for insert with check (is_project_member(project_id));
|
|
create policy "Users can update canvas_objects of projects they are in." on public.canvas_objects for update using (is_project_member(project_id)) with check (is_project_member(project_id));
|
|
create policy "Users can delete canvas_objects of projects they are in." on public.canvas_objects for delete using (is_project_member(project_id));
|
|
|
|
-- Creates a new project and inserts the caller as a participant
|
|
create or replace function create_new_project() returns uuid as $$
|
|
declare
|
|
new_project_id uuid;
|
|
begin
|
|
-- Create a new project
|
|
insert into public.projects default values
|
|
returning id into new_project_id;
|
|
|
|
-- Insert the caller user into the new project
|
|
insert into public.project_members (profile_id, project_id)
|
|
values (auth.uid(), new_project_id);
|
|
|
|
return new_project_id;
|
|
end
|
|
$$ language plpgsql security definer;
|
|
|
|
create policy "Project members can receive presence and broadcast messages." on realtime.messages for select using (is_project_member(realtime.topic()::uuid));
|
|
create policy "Project members can send presence and broadcast messages." on realtime.messages for insert with check (is_project_member(realtime.topic()::uuid));
|