Files
Dungeons-Ground/supabase/migrations/0004_anonymous_alpha_access.sql
pavel444-byte 438e5af0ad
Some checks failed
CI / validate (push) Failing after 9m21s
Important Fixes, New mechanics, and many more
2026-08-15 17:37:57 +05:00

101 lines
3.0 KiB
PL/PgSQL

-- Guest access still uses a real authenticated Supabase user. This keeps the
-- existing ownership checks, RLS policies, and multiplayer membership model.
-- Email accounts remain restricted to the allowlist.
create or replace function public.create_profile_for_allowlisted_user()
returns trigger
language plpgsql
security definer
set search_path = ''
as $$
declare
v_is_anonymous boolean := coalesce(new.is_anonymous, false);
v_display_name text;
begin
if not v_is_anonymous and (
new.email is null or not exists (
select 1
from public.allowlist
where email = lower(btrim(new.email))
)
) then
raise exception using
errcode = '42501',
message = 'This email is not invited to the Dungeons & Ground alpha.';
end if;
v_display_name := case
when v_is_anonymous then 'Guest ' || upper(substr(replace(new.id::text, '-', ''), 1, 6))
else coalesce(nullif(btrim(new.raw_user_meta_data ->> 'display_name'), ''), 'Adventurer')
end;
insert into public.profiles(id, display_name)
values (new.id, v_display_name)
on conflict (id) do nothing;
return new;
end;
$$;
revoke all on function public.create_profile_for_allowlisted_user() from public;
-- An anonymous account can be upgraded later. Recheck the allowlist on the
-- relevant auth.users transition so linking an email cannot bypass the alpha
-- gate. Unrelated token and metadata updates do not fire this trigger.
create or replace function public.enforce_alpha_email_allowlist()
returns trigger
language plpgsql
security definer
set search_path = ''
as $$
begin
if not coalesce(new.is_anonymous, false) and (
new.email is null or not exists (
select 1
from public.allowlist
where email = lower(btrim(new.email))
)
) then
raise exception using
errcode = '42501',
message = 'This email is not invited to the Dungeons & Ground alpha.';
end if;
return new;
end;
$$;
revoke all on function public.enforce_alpha_email_allowlist() from public;
drop trigger if exists enforce_alpha_email_allowlist on auth.users;
create trigger enforce_alpha_email_allowlist
before update of email, is_anonymous on auth.users
for each row
when (
old.email is distinct from new.email
or old.is_anonymous is distinct from new.is_anonymous
)
execute function public.enforce_alpha_email_allowlist();
-- The schema may be installed after Auth users already exist. Backfill only
-- anonymous users and explicitly allowlisted email accounts; do not silently
-- enable unrelated accounts.
insert into public.profiles(id, display_name)
select
auth_user.id,
case
when coalesce(auth_user.is_anonymous, false)
then 'Guest ' || upper(substr(replace(auth_user.id::text, '-', ''), 1, 6))
else coalesce(nullif(btrim(auth_user.raw_user_meta_data ->> 'display_name'), ''), 'Adventurer')
end
from auth.users auth_user
where coalesce(auth_user.is_anonymous, false)
or exists (
select 1
from public.allowlist
where allowlist.email = lower(btrim(auth_user.email))
)
on conflict (id) do nothing;
notify pgrst, 'reload schema';