Changeset ccaa530 in Klonkt for src/routes
- Timestamp:
- 07/31/2026 01:34:46 PM (6 weeks ago)
- Branches:
- main
- Children:
- 5462bab
- Parents:
- 2dd1dc4
- File:
-
- 1 edited
-
src/routes/admin-sites.js (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/admin-sites.js
r2dd1dc4 rccaa530 26 26 import { toWebp } from '../services/ImageWebpService.js'; 27 27 import { mediaDir } from '../config/paths.js'; 28 import AP from '../services/ActivityPubService.js'; 28 29 29 30 … … 71 72 } 72 73 return arr.length ? JSON.stringify(arr) : null; 74 } 75 76 /** 77 * FEP-7628 aliases (alsoKnownAs): one former identity per line, as an actor 78 * URL or an @user@host handle. Handles resolve via WebFinger AT SAVE TIME on 79 * purpose — a typo'd alias that silently lands on the actor would make a later 80 * Move fail at the old server with no hint why. Throws the offending line. 81 */ 82 async function parseApAliases(raw, ownActorUri) { 83 const lines = String(raw || '').split(/\r?\n/).map((s) => s.trim()).filter(Boolean); 84 if (lines.length > 5) throw new Error(lines[5] + ' (max 5)'); 85 const out = []; 86 for (const line of lines) { 87 let uri = null; 88 if (/^https?:\/\//i.test(line)) uri = line; 89 else if (line.includes('@')) uri = await AP.webfingerResolve(line).catch(() => null); 90 if (!uri) throw new Error(line); 91 if (uri === ownActorUri) continue; // claiming yourself adds nothing 92 if (!out.includes(uri)) out.push(uri); 93 } 94 return out; 73 95 } 74 96 … … 256 278 } 257 279 280 let apAliases = ''; 281 try { apAliases = (JSON.parse(site.ap_aliases || '[]') || []).join('\n'); } catch { /* show empty on malformed */ } 282 258 283 renderPage(req, res, 'pages/admin-site-edit', { 259 284 pageTitleKey: 'admin.t_editsite', pageTitleVars: { title: site.title }, … … 266 291 platforms: listPlatforms(), 267 292 parsedLinks, 293 apAliases, 268 294 success: req.query.success || null, 269 295 error: req.query.error || null, … … 272 298 273 299 // ==================== SAVE ==================== 274 router.post('/:slug/save', requireSiteManagerBySlug, (req, res) => {275 const site = db.prepare('SELECT id FROM sites WHERE slug = ?').get(req.params.slug);300 router.post('/:slug/save', requireSiteManagerBySlug, async (req, res) => { 301 const site = db.prepare('SELECT id, ap_aliases FROM sites WHERE slug = ?').get(req.params.slug); 276 302 if (!site) return res.redirect('/admin/sites?error=Not+found'); 277 303 … … 279 305 const feedViewDef = f.feed_view_default === 'grid' ? 'grid' : 'timeline'; 280 306 const profileLinksJson = buildProfileLinks(f); 307 308 // FEP-7628 aliases — validated/resolved before anything is written. 309 const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, ''); 310 let apAliasesJson = null; 311 try { 312 const arr = await parseApAliases(f.ap_aliases, AP.actorId(base, req.params.slug)); 313 apAliasesJson = arr.length ? JSON.stringify(arr) : null; 314 } catch (e) { 315 return res.redirect(`/admin/sites/${req.params.slug}/edit?error=` + encodeURIComponent(`Alias niet herkend of niet vindbaar: ${e.message}`)); 316 } 281 317 282 318 // theme_override: only accept the three legal values. Empty string means … … 294 330 profile_enabled = ?, 295 331 profile_links = ?, 332 ap_aliases = ?, 296 333 is_public = ?, robots_index = ?, require_login_to_comment = ?, 297 334 enable_audio_player = ?, … … 312 349 f.profile_enabled ? 1 : 0, 313 350 profileLinksJson, 351 apAliasesJson, 314 352 f.is_public ? 1 : 0, 315 353 f.robots_index ? 1 : 0, … … 336 374 } 337 375 376 // Alias change → broadcast an actor Update so remote caches refresh. The old 377 // server re-fetches the actor live during a Move anyway; this is freshness, 378 // not correctness, hence best-effort. 379 if ((site.ap_aliases || null) !== apAliasesJson) { 380 try { 381 const fresh = db.prepare('SELECT * FROM sites WHERE id = ?').get(site.id); 382 AP.deliverActorUpdate(fresh).catch(() => {}); 383 } catch { /* never blocks the save */ } 384 } 385 338 386 res.redirect(`/admin/sites/${req.params.slug}/edit?success=` + encodeURIComponent('Opgeslagen')); 339 387 });
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)