Changeset 3ceaef6 in Klonkt for src/routes
- Timestamp:
- 09/30/2026 06:16:32 AM (5 hours ago)
- Branches:
- main
- Children:
- 9eb6e1b
- Parents:
- 407353e
- File:
-
- 1 edited
-
src/routes/search.js (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/search.js
r407353e r3ceaef6 9 9 * 4. Pages (Agenda / Downloads / Links / Press kit / Archive) by name — only 10 10 * the available ones. 11 * 5. Een ADRES van een andere server (shaer-utpi): plak je een link naar een 12 * fediverse-post of -profiel, dan is dat geen zoekterm maar een aanwijzing. 13 * Die halen we op en tonen we, met dezelfde knoppen als 14 * /authorize_interaction: antwoorden, waarderen, boosten, stemmen, 15 * volgen, melden. 11 16 * 12 17 * FTS5: user input is tokenised on non-letter/digit chars and each token is wrapped … … 21 26 import { premiumUnlocked } from '../services/PatreonService.js'; 22 27 import { t as i18nT, resolveLang } from '../services/i18n.js'; 28 import ActivityPubService from '../services/ActivityPubService.js'; 29 import PermissionsService from '../services/PermissionsService.js'; 23 30 24 31 const router = express.Router(); … … 45 52 if (!s || /^[…\s]*$/.test(s)) return esc((excerpt || '').slice(0, 160)); 46 53 return s; 54 } 55 56 /** 57 * Is dit een ADRES en geen zoekterm? Dan het genormaliseerde adres, anders null. 58 * 59 * HET SCHEMA IS VERPLICHT, en dat is een keuze. "soundfabrics.nl" is een 60 * geldige zoekterm -- iemand zoekt naar de naam -- en een bare domeinnaam als 61 * adres opvatten maakt van elke zoekopdracht met een punt erin een 62 * netwerkverzoek. Met https:// ervoor is er geen twijfel over de bedoeling. 63 * 64 * De fragmentverwijzing gaat eraf: die hoort bij de browser, niet bij het 65 * object, en met #comment eraan is het een andere sleutel voor hetzelfde ding. 66 */ 67 export function lookupUri(q) { 68 const s = String(q || '').trim(); 69 if (!/^https?:\/\//i.test(s) || /\s/.test(s)) return null; 70 try { 71 const u = new URL(s); 72 if (u.protocol !== 'http:' && u.protocol !== 'https:') return null; 73 // Een naam zonder punt is geen adres op het open net (localhost, een 74 // intern hostname). De SSRF-bewaking in de transportlaag houdt de rest 75 // tegen; dit scheelt het verzoek. 76 if (!u.hostname.includes('.')) return null; 77 u.hash = ''; 78 return u.toString(); 79 } catch { 80 return null; 81 } 82 } 83 84 /** 85 * Mag deze bezoeker een adres laten OPHALEN? 86 * 87 * Dezelfde grens als /authorize_interaction (requireSiteManager), en met opzet: 88 * ophalen is een uitgaand verzoek dat deze server namens iemand anders doet. 89 * Voor een willekeurige bezoeker zou de zoekbalk daarmee een haalservice zijn 90 * waarmee je andermans server kunt laten aankloppen op adressen naar keuze. 91 * 92 * Dit spiegelt requireSiteManager in plaats van hem aan te roepen: die stuurt 93 * je naar het inlogscherm, en een zoekopdracht hoort niemand weg te sturen. 94 */ 95 function mayLookUp(req, res) { 96 const u = req.session && req.session.user; 97 if (!u) return false; 98 if (u.role === 'god' || u.role === 'kijker') return true; 99 const site = res.locals.site; 100 return !!(site && PermissionsService.canAdminSite(u, site)); 47 101 } 48 102 … … 143 197 144 198 // ── Full results page ──────────────────────────────────────────────────────── 145 router.get('/', (req, res) => {199 router.get('/', async (req, res) => { 146 200 const site = res.locals.site; 147 201 if (!site) return res.status(404).send('No site'); … … 153 207 results: [], tracks: [], events: [], pages: [], total: 0, 154 208 }); 209 } 210 211 // Een adres wordt OPGEHAALD, niet doorzocht (shaer-utpi). Eerst als post, 212 // dan als profiel: een URL die geen van beide oplevert is gewoon een 213 // zoekterm die toevallig op een link lijkt, en dan blijft de rest staan. 214 const remoteUri = lookupUri(rawQ); 215 const mayLookup = remoteUri ? mayLookUp(req, res) : false; 216 let remote = null; 217 let remoteKind = null; 218 if (remoteUri && mayLookup) { 219 // Ondertekend als deze site: een post die alleen voor volgers zichtbaar is 220 // weigert een anonieme GET, en dan lijkt een bestaande post te ontbreken. 221 try { remote = await ActivityPubService.resolveRemoteNote(remoteUri, { asSlug: site.slug }); } catch { /* onbereikbaar */ } 222 if (remote) remoteKind = 'note'; 223 if (!remote) { 224 try { remote = await ActivityPubService.resolveRemoteActor(remoteUri); } catch { /* onbereikbaar */ } 225 if (remote) remoteKind = 'actor'; 226 } 155 227 } 156 228 … … 161 233 results: r.results, tracks: r.tracks, events: r.events, pages: r.pages, 162 234 total, queryError: r.queryError, 235 remoteUri, remote, remoteKind, mayLookup, 236 remoteReacted: (remoteKind === 'note') ? ActivityPubService.getReaction(site.slug, remote.object_uri || remoteUri) : { liked: false, boosted: false }, 237 siteTitle: site.title || '', 163 238 }); 164 239 });
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)