Index: src/middleware/auth.js
===================================================================
--- src/middleware/auth.js	(revision 7bc636b391c66ac399c33e54f7173a022c6a3cbd)
+++ src/middleware/auth.js	(revision 8cb1dc7b23142c8a8ec44f7659178b51a2da4ddf)
@@ -2,4 +2,6 @@
  * Auth middleware
  */
+
+import db from '../config/database.js';
 
 /**
@@ -42,2 +44,25 @@
   next();
 }
+
+// Mag de ingelogde user de HUIDIGE site (res.locals.site) beheren? god altijd;
+// anders alleen de owner van die site. Gebruikt voor site-gescopete beheerroutes
+// die een artiest via /user/<eigen-slug>/admin/... bereikt (res.locals.site is dan
+// z'n eigen site; een vreemde slug levert een andere site -> 403).
+export function requireSiteManager(req, res, next) {
+  if (!req.session?.user) return loginRedirect(req, res);
+  const u = req.session.user;
+  if (u.role === 'god') return next();
+  const site = res.locals.site;
+  if (site && site.owner_id === u.id) return next();
+  return res.status(403).send('Geen toegang tot deze site.');
+}
+
+// Idem, maar de site wordt bepaald door de :slug-parameter (bv. site-edit).
+export function requireSiteManagerBySlug(req, res, next) {
+  if (!req.session?.user) return loginRedirect(req, res);
+  const u = req.session.user;
+  if (u.role === 'god') return next();
+  const site = db.prepare('SELECT owner_id FROM sites WHERE slug = ?').get(req.params.slug);
+  if (site && site.owner_id === u.id) return next();
+  return res.status(403).send('Geen toegang tot deze site.');
+}
