Changeset 5296349 in Klonkt for src/services/ActivityPubService.js
- Timestamp:
- 08/06/2026 10:30:50 AM (5 weeks ago)
- Branches:
- main
- Children:
- 57aee3b
- Parents:
- 25f2e64
- git-author:
- Robin <roboburr@…> (08/06/2026 10:30:49 AM)
- git-committer:
- Claude (agent) <aiclaude@…> (08/06/2026 10:30:50 AM)
- File:
-
- 1 edited
-
src/services/ActivityPubService.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
r25f2e64 r5296349 1621 1621 } 1622 1622 1623 /** 1624 * Een DOORGESTUURDE activiteit alsnog verifiëren (shaer-s8k). 1625 * 1626 * Reageert iemand in een thread, dan stuurt de server van de oorspronkelijke 1627 * poster die reactie door naar de deelnemers -- en ondertekent met zijn EIGEN 1628 * sleutel. De handtekening klopt dan, maar de ondertekenaar is niet de auteur, 1629 * dus de gate hieronder wees hem af. Gevolg: reacties van derden kwamen niet 1630 * binnen, zonder dat iemand een fout zag. 1631 * 1632 * Mastodon lost dit op met een LD-Signature over de payload. Dat vraagt 1633 * JSON-LD-canonicalisatie; wij doen het lichter en strenger: we geloven de 1634 * bezorgde inhoud NIET en halen het object op bij de bron. 1635 * 1636 * Vier voorwaarden, en geen ervan is optioneel: 1637 * 1638 * 1. Alleen Create en Update. Een doorgestuurde Delete is per definitie niet te 1639 * dereferencen -- het object is weg -- dus die blijft geweigerd. 1640 * 2. De host van de object-id MOET die van de geclaimde actor zijn. Zonder dit 1641 * anker wijst een doorsturer je naar een host die hij zelf beheert, waar 1642 * attributedTo alles kan beweren. 1643 * 3. Het OPGEHAALDE object wordt gebruikt, niet de bezorgde payload. Anders 1644 * levert een doorsturer een echt id met verdraaide inhoud. 1645 * 4. Mislukt het ophalen, of wijst het object zichzelf niet toe aan de 1646 * geclaimde actor, dan blijft het een weigering. Geen twijfelgeval opslaan. 1647 */ 1648 async function dereferenceForwarded(act, claimedActor, type, slugParam) { 1649 if (type !== 'Create' && type !== 'Update') return null; 1650 const o = act && act.object; 1651 const objId = typeof o === 'string' ? o : (o && o.id); 1652 if (!objId || typeof objId !== 'string' || !/^https:\/\//i.test(objId)) return null; 1653 try { 1654 if (new URL(objId).host !== new URL(claimedActor).host) return null; // ankereis 1655 } catch { return null; } 1656 // Ondertekend als de ontvangende site wanneer we die kennen; anders anoniem, 1657 // wat voor een publieke note volstaat. Beide gaan door safeFetch. 1658 const fetched = await signedGetJson(slugParam, objId).catch(() => null); 1659 if (!fetched || fetched.id !== objId) return null; // ook: geen omleiding naar iets anders 1660 const attributed = typeof fetched.attributedTo === 'string' 1661 ? fetched.attributedTo 1662 : (fetched.attributedTo && fetched.attributedTo.id); 1663 if (attributed !== claimedActor) return null; 1664 return fetched; 1665 } 1666 1623 1667 // Handle an incoming inbox POST. slugParam = null for the shared /ap/inbox. 1624 1668 export async function handleInbox(req, slugParam, preVerified = null) { … … 1644 1688 const GATED = ['Create', 'Like', 'Announce', 'Follow', 'Delete', 'Undo', 'Accept', 'Reject', 'Add', 'Remove', 'Update', 'Flag', 'Offer', 'Move']; 1645 1689 if (GATED.includes(type)) { 1646 if (!verified || !claimedActor || verified.id !== claimedActor) { 1647 console.warn('[AP] inbox REJECTED (signature)', type, claimedActor || '?', 'from', ip, verified ? '(signer mismatch)' : '(unsigned/invalid)'); 1690 // Een geldige handtekening van iemand anders dan de auteur is doorsturen, 1691 // geen vervalsing. Haal het object dan bij de bron op in plaats van het af 1692 // te wijzen; lukt dat niet, dan valt het door naar de weigering hieronder. 1693 let forwarded = null; 1694 if (verified && claimedActor && verified.id !== claimedActor) { 1695 forwarded = await dereferenceForwarded(act, claimedActor, type, slugParam).catch(() => null); 1696 if (forwarded) { 1697 act.object = forwarded; // de OPGEHAALDE inhoud, niet de bezorgde 1698 console.log('[AP] inbox forwarded, geverifieerd bij de bron:', type, claimedActor, 'via', verified.id); 1699 } 1700 } 1701 if (!forwarded && (!verified || !claimedActor || verified.id !== claimedActor)) { 1702 // Drie verschillende oorzaken, die eerder allemaal "unsigned/invalid" 1703 // heetten: geen handtekening meegestuurd, wel een handtekening maar niet 1704 // te verifiëren (meestal een opgeheven account waarvan de sleutel weg is), 1705 // of geldig ondertekend door iemand anders. 1706 const reden = verified ? '(signer mismatch)' 1707 : (req.headers && req.headers.signature) ? '(signature present, unverifiable)' 1708 : '(no signature)'; 1709 console.warn('[AP] inbox REJECTED (signature)', type, claimedActor || '?', 'from', ip, reden); 1648 1710 return 401; 1649 1711 }
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)