Changeset 1a2f206 in Klonkt for src/services/ActivityPubService.js
- Timestamp:
- 07/30/2026 11:17:05 PM (6 weeks ago)
- Branches:
- main
- Children:
- ef519a3
- Parents:
- 55eca8b
- File:
-
- 1 edited
-
src/services/ActivityPubService.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
r55eca8b r1a2f206 2383 2383 const actorUri = c2sIdOf(object); 2384 2384 if (!actorUri) return { status: 400, error: 'missing_object' }; 2385 await followActor(site, actorUri); 2385 // The error REACHES the app (Robins melding, 31-7): swallowing it 2386 // made a failed follow look exactly like a successful one. 2387 const r = await followActor(site, actorUri); 2388 if (r && r.error) return { status: 502, error: 'follow_failed', detail: r.error }; 2386 2389 return { status: 202, url: actorUri }; 2387 2390 } … … 3645 3648 else actorUrl = null; 3646 3649 if (!actorUrl) return { error: 'not_found' }; 3647 const actor = await fetchActor(actorUrl).catch(() => null); 3650 // SIGNED, as this actor: an authorized-fetch instance refuses an anonymous 3651 // GET of the actor doc, which made following from a boost silently fail 3652 // (Robins melding, 31-7). Signed, the other side sees who asks. 3653 const actor = await signedGetJson(site.slug, actorUrl); 3648 3654 if (!actor || !actor.id || !actor.inbox) return { error: 'unreachable' }; 3649 3655 const ai = actorInfo(actor, actor.id); … … 3660 3666 // Follow + feature in one step → backfill their recent posts into the Cirkel right away. 3661 3667 if (autoBoost) backfillFromOutbox(site.slug, actor.id).catch(() => {}); 3668 // A ward's guardians are TOLD about a new follow (Robins verzoek, 31-7): 3669 // a follow brings new content into the child's feed, and the village 3670 // should know the door opened. A direct note per guardian, best-effort; 3671 // FEP-633c 5.3 gates inbound follows, the outbound notice is Shaer policy 3672 // for now (bead: spec-vraag). 3673 try { 3674 const guardians = Guardianship.listGuardians(site.slug); 3675 if (guardians.length) { 3676 const meRef = actorId(base, site.slug); 3677 const esc = (t) => String(t).replace(/[<>&]/g, (c) => ({ '<': '<', '>': '>', '&': '&' }[c])); 3678 const label = esc(ai.name || ai.handle || actor.id); 3679 for (const g of guardians) { 3680 const note = { 3681 id: `${meRef}/follow-notice/${Date.now().toString(36)}${rid()}`, 3682 type: 'Note', attributedTo: meRef, to: [g.other_uri], 3683 tag: [{ type: 'Mention', href: g.other_uri }], 3684 content: `<p>👀 ${esc(site.title || site.slug)} is now following ${label}.</p>`, 3685 }; 3686 deliverToActor(site, g.other_uri, { id: `${note.id}#create`, type: 'Create', actor: meRef, to: [g.other_uri], object: note }) 3687 .catch(() => { /* retried by the queue */ }); 3688 } 3689 console.log('[AP] follow notice →', guardians.length, 'guardian(s) of', site.slug); 3690 } 3691 } catch { /* geen guardians is geen fout */ } 3662 3692 return { ok: true, name: ai.name, handle: ai.handle, actor: actor.id }; 3663 3693 }
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)