source: Klonkt/src/middleware/site.js@ 72ec6a4

main
Last change on this file since 72ec6a4 was 72ec6a4, checked in by Robin <roboburr@…>, 6 weeks ago

Hub-modus en guardian-lite eruit

Robins besluit (31-7): een instance is een eigenaar. Twee dingen weg.

HUB-MODUS was al dood: getTenancy() gaf sinds 24-6 hardcoded 'solo'
terug, dus elke tenancy === 'hub'-tak was onbereikbaar. Nu ook echt
verwijderd: getTenancy/setTenancy zelf, de /user/:slug-routing in
resolveSite, de hub-takken in admin, zoeken, audio, posts (neighbours
en related over alle sites), download, en de push-prefix. In de views
verdwijnen de hub-tagline, de hub-navigatie, de sites- en
users-tabellen (die kwamen alleen in hub-modus gevuld en verwezen nu
naar locals die niemand meer meegeeft), de eigenaar-toewijzing bij een
site, de /user/-slugprefix, het hub-brandblok en de hub-thuisknop.

GUARDIAN-LITE was de laatste multi-user-rest: /guardian/invite gaf een
link waarmee iemand via /guardian/join een echte user plus een site met
guardian_only=1 aanmaakte. Dat zette andermans wachtwoordhash, sessie
en PRIVATE actor-sleutel in jouw database, waardoor een verhuizing of
export nooit netjes kon (shaer-qw6q). Routes, formulier, kolom en
uitnodigingstabel zijn weg. Het guardian-DASHBOARD blijft: dat is
FEP-633c en werkt voor guardians met een eigen Klonkt. Bestaande
installaties houden kolom en tabel ongebruikt; nieuwe krijgen ze niet.

Changed files:
src/services/SettingsService.js

  • getTenancy/setTenancy verwijderd; kop herschreven

src/middleware/site.js, src/middleware/render.js

  • /user/:slug-routing weg; tenancy en hubTitle uit de locals

src/routes/admin.js, admin-settings.js, audio.js, download.js,
src/routes/posts.js, search.js

  • hub-takken en hub-queries weg; postNeighbors zonder isHub

src/services/ActivityPubService.js

  • pushPrefix is nu gewoon ; getTenancy-import weg

src/routes/guardian.js

  • /invite en /join verwijderd (dashboard blijft), imports opgeschoond

src/config/database.js

  • guardian_only-kolom en ap_guardian_invites-tabel niet meer aangemaakt

src/views/pages/admin.ejs, admin-users.ejs, admin-site-edit.ejs,
src/views/pages/guardian.ejs, partials/topnav.ejs, chrome.ejs, bottom-tab.ejs

  • alle hub-takken en de uitnodigingsknop weg

remarks: 320 regels weg, 63 erbij. Suite 372 groen; alle 85 templates
compileren; en met een wegwerp-kopie van de database daadwerkelijk
gedraaid en ingelogd: /, /admin, /admin/users, /admin/sites,
/admin/settings, /admin/sites/demo/edit, /admin/media en /guardian
geven alle 200 zonder fouten in het log, en /guardian/invite en
/guardian/join geven nu 404.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/**
2 * Site middleware — resolve which site this request is for.
3 *
4 * Resolution order (hub-modus):
5 * 1. Pad /user/:slug → die site (legacy /sites/:slug → 301 naar /user/)
6 * 2. Anders (solo, of hub-landing): de primaire/hoofd-site
7 *
8 * Sets res.locals.site for all downstream handlers.
9 */
10
11import db from '../config/database.js';
12import { audioUrl } from '../services/AudioStreamService.js';
13import { audioEnabled } from '../config/features.js';
14
15/**
16 * The primary/main site — ONE source of truth (replaces the "oldest site ="
17 * main" assumption that was previously scattered across resolveSite/hub/account/admin).
18 * Reads the explicit is_primary flag; falls back to the oldest if it isn't set
19 * anywhere yet, so existing behaviour is preserved exactly.
20 */
21export function getPrimarySite() {
22 return db.prepare('SELECT * FROM sites WHERE is_primary = 1 LIMIT 1').get()
23 || db.prepare('SELECT * FROM sites ORDER BY created_at ASC LIMIT 1').get()
24 || null;
25}
26
27export function resolveSite(req, res, next) {
28 // One instance is one owner (Robins besluit, 31-7): there is one site tree,
29 // pinned to the primary site. The /user/:slug routing that hub mode needed
30 // is gone with it.
31 const defaultSite = getPrimarySite();
32 if (defaultSite) {
33 res.locals.site = defaultSite;
34 res.locals.siteUrlBase = '';
35 }
36
37 next();
38}
39
40/**
41 * Audio tracks loader — pulls site-level tracks for the persistent player widget.
42 * Per Robin: player is separate from the footer, gated by site.enable_audio_player.
43 * Returns empty array if no site or audio is disabled — shell.ejs uses the
44 * length to decide whether to mount audio-player.js.
45 */
46export function loadAudioTracks(req, res, next) {
47 if (!audioEnabled()) { res.locals.audioTracks = []; return next(); } // lite-modus
48 const site = res.locals.site;
49 if (!site || site.enable_audio_player === 0) {
50 res.locals.audioTracks = [];
51 return next();
52 }
53
54 try {
55 // m.filename = the bare filename; the playable URL is the gated stream route
56 // (audioUrl). The media table has NO url column — the old query selected
57 // m.url and always failed silently (empty player). Now we build the URL from filename.
58 const rows = db.prepare(`
59 SELECT t.id, t.title, t.artist, t.duration, t.position, m.filename
60 FROM audio_tracks t
61 LEFT JOIN media m ON m.id = t.media_id
62 WHERE t.site_id = ?
63 ORDER BY t.position ASC, t.created_at ASC
64 `).all(site.id);
65 res.locals.audioTracks = rows.map((r) => ({
66 id: r.id, title: r.title, artist: r.artist, duration: r.duration, position: r.position,
67 media_url: r.filename ? audioUrl(r.filename) : null,
68 }));
69 } catch (e) {
70 // media table might not be queryable in some test setups — fall back gracefully
71 res.locals.audioTracks = [];
72 }
73
74 next();
75}
76
77/**
78 * Theme loader — applies user/site theme preferences.
79 */
80export function loadTheme(req, res, next) {
81 const PALETTES = ['klonkt','forest','ocean','teal','lilac','sunset','candy','amber'];
82
83 const user = req.session?.user;
84 const site = res.locals.site;
85
86 // A site always renders in ITS OWN palette, regardless of who is viewing. There is
87 // no per-user palette UI (user.palette is vestigial/stale data from old migrations),
88 // and the htmx pcmsNav path (render.js) already uses the site palette only — so reading
89 // user.palette here made a full page load (owner logged in) flip to the viewer's stale
90 // palette while htmx-nav kept the site's, i.e. "palette changes on hard refresh".
91 const palette = (site && PALETTES.includes(site.palette) ? site.palette : null)
92 || 'klonkt';
93
94 res.locals.palette = palette;
95 res.locals.theme = (user && ['dark','light'].includes(user.theme)) ? user.theme : 'dark';
96
97 next();
98}
Note: See TracBrowser for help on using the repository browser.