48 lines
2.0 KiB
SQL
48 lines
2.0 KiB
SQL
-- Admin-Self-Service-Onboarding.
|
|
-- ====================================================================
|
|
-- Aktuell muessen neue Admins manuell per SQL in admin_users eingefuegt
|
|
-- werden. Dieser Workflow stellt einen Magic-Link-basierten Onboarding-
|
|
-- Pfad bereit:
|
|
--
|
|
-- 1. Bestehender Admin gibt eine E-Mail-Adresse ein → Eintrag in
|
|
-- `admin_invites` mit Token (Hash) + Ablauf (48h).
|
|
-- 2. System schickt Mail mit Aktivierungs-URL `/admin/aktivieren/<token>`.
|
|
-- 3. Empfaenger oeffnet URL, setzt Passwort, ggf. Anzeigename.
|
|
-- → Eintrag in `admin_users` wird angelegt, Invite `used_at` gestempelt.
|
|
--
|
|
-- Zusatz: `admin_users.role` macht Berechtigungs-Differenzierung
|
|
-- moeglich. Default = 'admin' (Vollzugriff). Spaeter ist `viewer` denkbar
|
|
-- (lesen-only), aktuell nicht implementiert.
|
|
|
|
alter table public.admin_users
|
|
add column if not exists name text,
|
|
add column if not exists role text not null default 'admin'
|
|
check (role in ('admin', 'viewer')),
|
|
add column if not exists invited_by uuid references public.admin_users(id) on delete set null,
|
|
add column if not exists last_login_at timestamptz;
|
|
|
|
create table if not exists public.admin_invites (
|
|
id uuid primary key default gen_random_uuid(),
|
|
email text not null,
|
|
-- SHA256(token); Klartext-Token nur einmal in der Mail-URL.
|
|
token_hash text not null,
|
|
role text not null default 'admin'
|
|
check (role in ('admin', 'viewer')),
|
|
invited_by uuid references public.admin_users(id) on delete set null,
|
|
created_at timestamptz not null default now(),
|
|
expires_at timestamptz not null,
|
|
used_at timestamptz,
|
|
revoked_at timestamptz
|
|
);
|
|
|
|
create index if not exists admin_invites_token_idx
|
|
on public.admin_invites (token_hash)
|
|
where used_at is null and revoked_at is null;
|
|
|
|
create index if not exists admin_invites_email_idx
|
|
on public.admin_invites (email)
|
|
where used_at is null and revoked_at is null;
|
|
|
|
alter table public.admin_invites enable row level security;
|
|
-- Default deny — Zugriff nur ueber Service-Role (Admin-Pfade).
|