diff --git a/app/admin/layout.tsx b/app/admin/layout.tsx index b4ca7c5..b7f1bff 100644 --- a/app/admin/layout.tsx +++ b/app/admin/layout.tsx @@ -40,9 +40,9 @@ export default async function AdminLayout({
- + {profile.full_name || user.email} - +
+
+ + +
+

E-Mail-Adresse

+
+
+ + setEmail(e.target.value)} + required + /> +
+ {emailError && ( +

+ {emailError} +

+ )} + {emailInfo &&

{emailInfo}

} + +
+
+ +
+

Passwort ändern

+
+
+ + setCurrentPassword(e.target.value)} + autoComplete="current-password" + required + /> +
+
+ + setNewPassword(e.target.value)} + autoComplete="new-password" + minLength={8} + required + /> +
+
+ + setNewPasswordRepeat(e.target.value)} + autoComplete="new-password" + minLength={8} + required + /> +
+ {pwError && ( +

+ {pwError} +

+ )} + {pwInfo &&

{pwInfo}

} + +
+
+ + +
+ ); +} diff --git a/components/PasskeyManager.tsx b/components/PasskeyManager.tsx index 2ec75e4..103c7b7 100644 --- a/components/PasskeyManager.tsx +++ b/components/PasskeyManager.tsx @@ -57,11 +57,9 @@ export default function PasskeyManager() { } return ( -
-

- Passkeys -

-

+

+

Passkeys

+

Mit einem Passkey (Fingerabdruck, Gesichtserkennung oder Sicherheitsschlüssel) kannst du dich künftig ohne Passwort anmelden. Passkeys gelten pro Domain – für den Live-Betrieb muss die Domain in @@ -69,24 +67,24 @@ export default function PasskeyManager() {

{error && ( -

+

{error}

)} - {info &&

{info}

} + {info &&

{info}

} -
+ ); } diff --git a/proxy.ts b/proxy.ts index db7aaff..cb5e67a 100644 --- a/proxy.ts +++ b/proxy.ts @@ -41,5 +41,5 @@ export async function proxy(request: NextRequest) { } export const config = { - matcher: ["/intern/:path*", "/admin/:path*"], + matcher: ["/intern/:path*", "/admin/:path*", "/konto/:path*"], }; diff --git a/supabase/migrations/0003_account_self_service.sql b/supabase/migrations/0003_account_self_service.sql new file mode 100644 index 0000000..dd03647 --- /dev/null +++ b/supabase/migrations/0003_account_self_service.sql @@ -0,0 +1,36 @@ +-- ============================================================= +-- Selbstverwaltung des eigenen Kontos (Name, E-Mail-Abgleich) +-- ============================================================= + +-- Jeder Benutzer darf seinen eigenen Anzeigenamen ändern. Die Spalte +-- "role" bleibt geschützt: Rechte werden nicht per RLS eingeschränkt, +-- sondern per Spalten-Grant – selbst ein manuell gebauter Request mit +-- {"role": "admin"} im Payload scheitert an fehlenden Rechten auf die +-- Spalte. Rollenänderungen laufen weiterhin ausschließlich über die +-- Admin-API mit dem Service-Role-Key. +revoke update on public.profiles from authenticated; +grant update (full_name) on public.profiles to authenticated; + +create policy "profiles_update_own_name" + on public.profiles for update + to authenticated + using (id = (select auth.uid())) + with check (id = (select auth.uid())); + +-- Hält profiles.email synchron, sobald eine E-Mail-Änderung in +-- auth.users bestätigt wurde (supabase.auth.updateUser({ email })). +create or replace function public.handle_user_email_change() +returns trigger +language plpgsql +security definer +set search_path = public +as $$ +begin + update public.profiles set email = new.email where id = new.id; + return new; +end; +$$; + +create trigger on_auth_user_email_updated + after update of email on auth.users + for each row execute function public.handle_user_email_change();