81 lines
2.9 KiB
PL/PgSQL
81 lines
2.9 KiB
PL/PgSQL
-- R1 Konto und Profil: profiles, Anlage beim Registrieren.
|
|
|
|
create table public.profiles (
|
|
id uuid primary key references auth.users (id) on delete cascade,
|
|
display_name text not null check (char_length(display_name) between 1 and 30),
|
|
bio text check (char_length(bio) <= 300),
|
|
city text check (char_length(city) <= 100),
|
|
city_visible boolean not null default true,
|
|
avatar_path text,
|
|
locale text not null default 'de' check (locale in ('de', 'en')),
|
|
terms_accepted_at timestamptz not null,
|
|
age_confirmed_at timestamptz not null,
|
|
deleted_at timestamptz,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now()
|
|
);
|
|
|
|
create trigger set_updated_at before update on public.profiles
|
|
for each row execute function public.set_updated_at();
|
|
|
|
-- Profil automatisch anlegen. Die Registrierung scheitert ohne Altersbestätigung (ab 16)
|
|
-- und ohne Zustimmung zu den Nutzungsbedingungen. Die App sendet beide als user_metadata.
|
|
create or replace function public.handle_new_user()
|
|
returns trigger
|
|
language plpgsql
|
|
security definer
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
meta jsonb := coalesce(new.raw_user_meta_data, '{}'::jsonb);
|
|
name text;
|
|
begin
|
|
if coalesce(meta ->> 'age_confirmed', '') <> 'true' then
|
|
raise exception 'age_confirmation_required';
|
|
end if;
|
|
if coalesce(meta ->> 'terms_accepted', '') <> 'true' then
|
|
raise exception 'terms_acceptance_required';
|
|
end if;
|
|
|
|
name := left(btrim(coalesce(
|
|
nullif(btrim(meta ->> 'display_name'), ''),
|
|
nullif(split_part(new.email, '@', 1), ''),
|
|
'Spieler'
|
|
)), 30);
|
|
|
|
insert into public.profiles (id, display_name, locale, terms_accepted_at, age_confirmed_at)
|
|
values (
|
|
new.id,
|
|
name,
|
|
case when meta ->> 'locale' in ('de', 'en') then meta ->> 'locale' else 'de' end,
|
|
now(),
|
|
now()
|
|
);
|
|
return new;
|
|
end;
|
|
$$;
|
|
|
|
revoke all on function public.handle_new_user() from public, anon, authenticated;
|
|
|
|
create trigger on_auth_user_created
|
|
after insert on auth.users
|
|
for each row execute function public.handle_new_user();
|
|
|
|
-- Zugriff: Jeder sieht nur das eigene Profil. Fremde Profile gibt es nur über die View
|
|
-- public_profiles (siehe Migration plays), und dort nur für Mitspieler.
|
|
alter table public.profiles enable row level security;
|
|
|
|
revoke all on public.profiles from anon, authenticated;
|
|
grant select on public.profiles to authenticated;
|
|
-- Nur diese Spalten darf der Nutzer ändern; Bestätigungen und Löschmarke nie.
|
|
grant update (display_name, bio, city, city_visible, avatar_path, locale)
|
|
on public.profiles to authenticated;
|
|
|
|
create policy profiles_select_own on public.profiles
|
|
for select to authenticated
|
|
using (id = (select auth.uid()));
|
|
|
|
create policy profiles_update_own on public.profiles
|
|
for update to authenticated
|
|
using (id = (select auth.uid()))
|
|
with check (id = (select auth.uid()));
|