Changeset fe97cc3 in Klonkt for src/services/ActivityPubService.js
- Timestamp:
- 07/01/2026 10:13:40 PM (2 months ago)
- Branches:
- main
- Children:
- 2abd3d2
- Parents:
- 254939c
- File:
-
- 1 edited
-
src/services/ActivityPubService.js (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
r254939c rfe97cc3 660 660 // ── HTTP Signatures + delivery ──────────────────────────────────── 661 661 const slugFromActorUrl = (url) => { const m = String(url || '').match(/\/ap\/users\/([^/?#]+)/); return m ? decodeURIComponent(m[1]) : null; }; 662 // Which of OUR sites are named in a note's Mention tags? Only hrefs on our own base count 663 // (an /ap/users/<slug> path on a remote host is someone else's actor), and the slug must be 664 // an existing site. Deduped. 665 export function localMentionSlugs(tags, base) { 666 if (!base) return []; 667 const out = [], seen = new Set(); 668 for (const t of (Array.isArray(tags) ? tags : (tags ? [tags] : []))) { 669 if (!t || t.type !== 'Mention' || typeof t.href !== 'string') continue; 670 if (!t.href.startsWith(base + '/ap/users/')) continue; 671 const slug = slugFromActorUrl(t.href); 672 if (!slug || seen.has(slug)) continue; seen.add(slug); 673 try { if (db.prepare('SELECT 1 FROM sites WHERE slug = ?').get(slug)) out.push(slug); } catch { /* ignore */ } 674 } 675 return out; 676 } 662 677 663 678 // Sign + POST an activity to a remote inbox (draft-cavage HTTP Signatures, RSA-SHA256). … … 1073 1088 } 1074 1089 console.log('[AP] timeline +', actorUri, 'x' + subs.length); 1090 } 1091 } 1092 // Mentioned in a post that is NOT a reply to our content (a reply to us already returned 1093 // above): store a mention notification for each of our actors named in the Mention tags. 1094 // Requires our own base prefix on the tag href — /ap/users/<slug> on a REMOTE host is 1095 // someone else's actor, not ours. 1096 if (actorUri && !isLocalActor && o.id) { 1097 const slugs = localMentionSlugs(o.tag, base); 1098 if (slugs.length) { 1099 const ai = actorInfo(await resolveActor(actorUri), actorUri); 1100 const html = HtmlSanitizerService.sanitize(o.content || ''); 1101 for (const slug of slugs) { 1102 try { 1103 const r = db.prepare('INSERT OR IGNORE INTO ap_mentions (slug, object_uri, note_url, actor_uri, actor_name, actor_handle, actor_icon, actor_url, content, published, created_at) VALUES (?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP)') 1104 .run(slug, o.id, safeUrl(o.url) || null, actorUri, ai.name, ai.handle, ai.icon, ai.url, html, o.published || null); 1105 if (r.changes) console.log('[AP] mention', actorUri, '→', slug); 1106 } catch { /* ignore */ } 1107 } 1075 1108 } 1076 1109 } … … 2161 2194 } 2162 2195 } catch { /* ignore */ } 2196 try { 2197 for (const r of db.prepare('SELECT object_uri, note_url, actor_uri, actor_name, actor_handle, actor_icon, actor_url, content, created_at FROM ap_mentions WHERE slug = ? ORDER BY created_at DESC LIMIT 50').all(slug)) { 2198 out.push({ type: 'mention', name: r.actor_name, handle: r.actor_handle, url: r.actor_url || r.actor_uri, icon: r.actor_icon, content: stripLeadingMentions(r.content), note_url: r.note_url || r.object_uri, created_at: r.created_at }); 2199 } 2200 } catch { /* ignore */ } 2163 2201 out.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); 2164 2202 return out.slice(0, limit || 60); … … 2335 2373 listOutbox, deliverOutboxDelete, deliverOutboxUpdate, 2336 2374 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, sendInteraction, voteOnPoll, voteOnRemotePoll, 2337 parseOwnPoll, pollTally, ownPollView, deliverPollUpdate, maybeCrawlThread, sendReport, 2375 parseOwnPoll, pollTally, ownPollView, deliverPollUpdate, maybeCrawlThread, sendReport, localMentionSlugs, 2338 2376 autoBoostCount, boostedCount, markBoosted, unmarkBoosted, markLiked, unmarkLiked, getTimelineReaction, upsertBoostedNote, getCirkelPosts, getCirkelMembers, selfHealTimeline, 2339 2377 getNotifications, listBlocks, isBlockedAny, blockTarget, unblock,
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)