Changeset 8cb1dc7 in Klonkt for src/middleware


Ignore:
Timestamp:
06/14/2026 04:17:14 PM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
640b39c
Parents:
ccbd6a6
Message:

hub: artist self-management — owner manages their own subsite (posts/appearance/comments)

A site owner (member) now gets a "My PrutFolio" dashboard and can manage their
OWN site; cross-site access is restricted.

  • auth.js: requireSiteManager (owner of res.locals.site or god) + requireSiteManagerBySlug (owner of :slug or god).
  • admin.js: /admin role-aware -> god=hub management, owner=my-site dashboard, member without site=403.
  • admin-sites.js: /:slug/edit + /save owner-or-god (was god-only); upload-photo requireAuth. list/new/create/delete remain god-only.
  • admin-comments.js: requireSiteManager + redirects/form actions via siteUrlBase so the artist context (/user/<slug>/admin/comments) is correct.
  • render.js: userOwnsSite flag; topnav + overview show "Admin" for owners; topnav "New post" uses siteUrlBase.
  • pages/my-site.ejs: artist dashboard.

Co-Authored-By: Claude <noreply@…>

Location:
src/middleware
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/middleware/auth.js

    rccbd6a6 r8cb1dc7  
    22 * Auth middleware
    33 */
     4
     5import db from '../config/database.js';
    46
    57/**
     
    4244  next();
    4345}
     46
     47// Mag de ingelogde user de HUIDIGE site (res.locals.site) beheren? god altijd;
     48// anders alleen de owner van die site. Gebruikt voor site-gescopete beheerroutes
     49// die een artiest via /user/<eigen-slug>/admin/... bereikt (res.locals.site is dan
     50// z'n eigen site; een vreemde slug levert een andere site -> 403).
     51export function requireSiteManager(req, res, next) {
     52  if (!req.session?.user) return loginRedirect(req, res);
     53  const u = req.session.user;
     54  if (u.role === 'god') return next();
     55  const site = res.locals.site;
     56  if (site && site.owner_id === u.id) return next();
     57  return res.status(403).send('Geen toegang tot deze site.');
     58}
     59
     60// Idem, maar de site wordt bepaald door de :slug-parameter (bv. site-edit).
     61export function requireSiteManagerBySlug(req, res, next) {
     62  if (!req.session?.user) return loginRedirect(req, res);
     63  const u = req.session.user;
     64  if (u.role === 'god') return next();
     65  const site = db.prepare('SELECT owner_id FROM sites WHERE slug = ?').get(req.params.slug);
     66  if (site && site.owner_id === u.id) return next();
     67  return res.status(403).send('Geen toegang tot deze site.');
     68}
  • src/middleware/render.js

    rccbd6a6 r8cb1dc7  
    1313import { fileURLToPath } from 'url';
    1414import ejs from 'ejs';
     15import db from '../config/database.js';
    1516import PermissionsService from '../services/PermissionsService.js';
    1617import { PLATFORMS as PLATFORMS_CATALOG } from '../services/PlatformIcons.js';
     
    3637  const isPartial = req.headers['hx-request'] === 'true' || req.query.partial === '1';
    3738
     39  // Bezit deze (niet-god) user een eigen site? Bepaalt of 'ie een "Beheer"-
     40  // ingang ziet (artiest-zelfbeheer). god ziet beheer sowieso (op rol).
     41  const _u = req.session?.user || null;
     42  const userOwnsSite = !!(_u && _u.role !== 'god' &&
     43    db.prepare('SELECT 1 FROM sites WHERE owner_id = ? LIMIT 1').get(_u.id));
     44
    3845  // Common locals
    3946  const locals = {
    40     user: req.session?.user || null,
     47    user: _u,
     48    userOwnsSite,
    4149    site: data.site || res.locals.site || null,
    4250    audioTracks: data.audioTracks || res.locals.audioTracks || [],
Note: See TracChangeset for help on using the changeset viewer.