Changeset d7526bd in Klonkt
- Timestamp:
- 06/25/2026 05:20:29 AM (3 months ago)
- Branches:
- main
- Children:
- e951b7c
- Parents:
- 5a6a457
- Location:
- src
- Files:
-
- 2 edited
-
routes/activitypub.js (modified) (2 diffs)
-
services/ActivityPubService.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/activitypub.js
r5a6a457 rd7526bd 12 12 */ 13 13 import express from 'express'; 14 import { readFileSync } from 'fs'; 14 15 import db from '../config/database.js'; 15 16 import AP from '../services/ActivityPubService.js'; 16 17 17 18 const router = express.Router(); 19 let _ver = '1.0.0'; 20 try { _ver = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url))).version || _ver; } catch { /* keep default */ } 18 21 19 22 const baseUrl = (req) => (process.env.PUBLIC_BASE_URL || `${req.protocol}://${req.get('host')}`).replace(/\/+$/, ''); … … 85 88 }); 86 89 90 // ── Replies collection ── lets remote servers fetch a post's whole thread. 91 router.get('/ap/notes/:id/replies', (req, res) => { 92 const base = baseUrl(req); 93 const items = AP.getReplyUris(base, req.params.id); 94 AP.sendAP(res, { 95 '@context': 'https://www.w3.org/ns/activitystreams', 96 id: `${base}/ap/notes/${req.params.id}/replies`, 97 type: 'OrderedCollection', 98 totalItems: items.length, 99 orderedItems: items, 100 }); 101 }); 102 103 // ── NodeInfo ── standard instance metadata so fediverse tools recognise Klonkt. 104 router.get('/.well-known/nodeinfo', (req, res) => { 105 res.type('application/json'); 106 res.set('Cache-Control', 'public, max-age=3600'); 107 res.send(JSON.stringify({ links: [{ rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1', href: `${baseUrl(req)}/nodeinfo/2.1` }] })); 108 }); 109 router.get('/nodeinfo/2.1', (req, res) => { 110 let users = 0; let posts = 0; 111 try { users = db.prepare('SELECT COUNT(*) c FROM users').get().c; } catch { /* */ } 112 try { posts = db.prepare("SELECT COUNT(*) c FROM posts WHERE status = 'published'").get().c; } catch { /* */ } 113 res.type('application/json; charset=utf-8'); 114 res.set('Cache-Control', 'public, max-age=600'); 115 res.send(JSON.stringify({ 116 version: '2.1', 117 software: { name: 'klonkt', version: _ver, repository: 'https://github.com/roboburr/klonkt' }, 118 protocols: ['activitypub'], 119 services: { inbound: [], outbound: [] }, 120 openRegistrations: false, 121 usage: { users: { total: users }, localPosts: posts }, 122 metadata: { nodeName: 'Klonkt' }, 123 })); 124 }); 125 87 126 // ── Inbox — Follow→Accept, Undo Follow (best-effort signature verify) ── 88 127 const apJson = express.json({ -
src/services/ActivityPubService.js
r5a6a457 rd7526bd 153 153 cc: [`${aId}/followers`], 154 154 tag: Array.isArray(post.tags) ? post.tags.map((t) => ({ type: 'Hashtag', name: '#' + String(t).replace(/\s+/g, '') })) : [], 155 replies: `${id}/replies`, 155 156 }; 156 157 if (attachment.length) note.attachment = attachment; 157 158 return note; 159 } 160 161 // All reply note URIs on a local post (inbound fediverse replies + our own 162 // outbound replies) — backs the Note's `replies` Collection so remote servers 163 // can fetch the whole thread. 164 export function getReplyUris(base, postId) { 165 const out = []; 166 try { 167 for (const r of db.prepare("SELECT object_uri FROM ap_interactions WHERE kind = 'reply' AND post_id = ? AND object_uri != '' ORDER BY created_at").all(postId)) out.push(r.object_uri); 168 for (const r of db.prepare('SELECT id FROM ap_outbox WHERE post_id = ? ORDER BY rowid').all(postId)) out.push(`${base}/ap/notes/${r.id}`); 169 } catch { /* non-fatal */ } 170 return out; 158 171 } 159 172 … … 906 919 getNotifications, listBlocks, isBlockedAny, blockTarget, unblock, 907 920 deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker, 921 getReplyUris, 908 922 };
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)