From ee658b478818feed3d8f97ba64d5e3dd0a357afd Mon Sep 17 00:00:00 2001 From: neodk2004 Date: Sun, 21 Jun 2026 15:56:32 +0200 Subject: [PATCH] fix(middleware): migrate to proxy.ts for Next.js 16, enable Supabase RLS on all tables --- prisma/enable_rls.sql | 29 +++++++++++++++++++++++++++++ src/proxy.ts | 19 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 prisma/enable_rls.sql diff --git a/prisma/enable_rls.sql b/prisma/enable_rls.sql new file mode 100644 index 0000000..c8bb329 --- /dev/null +++ b/prisma/enable_rls.sql @@ -0,0 +1,29 @@ +-- Enable Row Level Security on all public tables. +-- Our app accesses Supabase exclusively via Prisma with the service_role key, +-- which bypasses RLS automatically. No permissive policies are needed. +-- This prevents direct PostgREST API access to table data. + +ALTER TABLE public."Owner" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Pet" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Post" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."VideoPost" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."PostImage" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."PostHashtag" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Hashtag" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Comment" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Reaction" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Repost" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Follow" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Report" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Notification" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Message" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Conversation" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."HealthCard" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."EmergencyVet" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."VetVisit" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Vaccine" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."WeightLog" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."Advertisement" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."ModerationLog" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."AdminRole" ENABLE ROW LEVEL SECURITY; +ALTER TABLE public."UserBan" ENABLE ROW LEVEL SECURITY; diff --git a/src/proxy.ts b/src/proxy.ts index ee8a0ba..565d36e 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -1,4 +1,5 @@ import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server"; +import { NextResponse } from "next/server"; const isPublicRoute = createRouteMatcher([ "/sign-up(.*)", @@ -6,9 +7,27 @@ const isPublicRoute = createRouteMatcher([ "/forgot-password(.*)", "/reset-password(.*)", "/verify-email(.*)", + "/health-card/(.*)", + "/impressum", + "/datenschutz", + "/api/webhooks/(.*)", ]); export default clerkMiddleware(async (auth, request) => { + const { pathname } = request.nextUrl; + + // Admin panel: validate secret path segment before anything else. + // Returns 404 (not 403) — the panel's existence must not be revealed. + if (pathname.startsWith("/p/")) { + const segments = pathname.split("/"); + const providedSecret = segments[2] ?? ""; + const adminSecret = process.env.ADMIN_SECRET ?? ""; + + if (!adminSecret || providedSecret !== adminSecret) { + return new NextResponse(null, { status: 404 }); + } + } + if (!isPublicRoute(request)) { await auth.protect(); }