Changeset 0ca7e9a4 in Klonkt for src/services/ActivityPubService.js
- Timestamp:
- 07/31/2026 05:43:16 PM (6 weeks ago)
- Branches:
- main
- Children:
- bfa6fa1
- Parents:
- f434294
- File:
-
- 1 edited
-
src/services/ActivityPubService.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
rf434294 r0ca7e9a4 3843 3843 } 3844 3844 3845 /** 3846 * Slice 2 van shaer-0j2 (FEP-7628, DRAFT): de UITGAANDE helft — deze Klonkt 3847 * is het oude huis en kondigt het vertrek aan. Twee eisen voordat er iets 3848 * de deur uit gaat: 3849 * 1. Geen guardians: een warded account verhuizen zonder de guardianship 3850 * te hertargeten zou het vangnet van het kind stil breken; dat is 3851 * shaer-tge's gated beslissing, dus tot die er is weigert een bewaakt 3852 * account de verhuizing. 3853 * 2. De NIEUWE actor claimt ons in alsoKnownAs — dezelfde back-reference 3854 * die elke ontvangende server (onze eigen slice 1 incluis) eist. Zonder 3855 * die claim is de Move overal dood bij aankomst. 3856 * De Move gaat duurzaam naar elke volger-inbox; hun servers doen de 3857 * re-follow. `moved_to` wordt hier vastgelegd; het SERVEREN ervan op de 3858 * actor (en het beleid van de oude site) is slice 3. 3859 * Deps injecteerbaar voor tests (geen netwerk in node:test). 3860 */ 3861 export async function moveAccount(site, targetRaw, { fetchActorFn = null, deliverFn = null } = {}) { 3862 const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, ''); 3863 if (!base || !site || !site.slug) return { error: 'config' }; 3864 try { 3865 const guardians = Guardianship.listGuardians(site.slug); 3866 if (guardians.length) { 3867 console.warn('[AP] move refused: guarded account (shaer-tge):', site.slug, '→', String(targetRaw || '')); 3868 return { error: 'guarded_account' }; 3869 } 3870 } catch { /* geen guardianship-tabellen = geen guardians */ } 3871 const s = String(targetRaw || '').trim(); 3872 let targetUri = null; 3873 if (/^https?:\/\//i.test(s)) targetUri = safeUrl(s); 3874 else if (s.includes('@')) targetUri = await webfingerResolve(s); 3875 if (!targetUri) return { error: 'not_found' }; 3876 const me = actorId(base, site.slug); 3877 if (targetUri === me) return { error: 'self' }; 3878 const target = await (fetchActorFn ? fetchActorFn(targetUri) : signedGetJson(site.slug, targetUri)); 3879 if (!target || !target.id || !target.inbox) return { error: 'unreachable' }; 3880 const aka = [].concat(target.alsoKnownAs || []) 3881 .map((a) => (typeof a === 'string' ? a : (a && a.id))).filter(Boolean); 3882 if (!aka.includes(me)) return { error: 'no_backreference' }; 3883 db.prepare('UPDATE sites SET moved_to = ? WHERE slug = ?').run(target.id, site.slug); 3884 const keys = getOrCreateKeys(site.slug); 3885 const move = { 3886 '@context': AP_CONTEXT, 3887 id: `${me}#move-${Date.now()}-${rid()}`, 3888 type: 'Move', 3889 actor: me, 3890 object: me, 3891 target: target.id, 3892 to: [`${me}/followers`], 3893 }; 3894 const inboxes = [...new Set(fStmts().list.all(site.slug).map((f) => f.shared_inbox || f.inbox).filter(Boolean))]; 3895 for (const inbox of inboxes) { 3896 await (deliverFn || deliverWithRetry)(site.slug, inbox, move, `${me}#main-key`, keys.private_pem); 3897 } 3898 console.log('[AP] MOVE announced:', site.slug, '→', target.id, 'naar', inboxes.length, 'inbox(en)'); 3899 return { ok: true, target: target.id, inboxes: inboxes.length }; 3900 } 3901 3845 3902 // FEP-633c §5.3 note (authorized fetch): true when `actorUri` is a committed 3846 3903 /** … … 4359 4416 getInteractions, getInteractionById, setInteractionBoosted, setInteractionLiked, setMyReaction, getMyReactions, buildReplyNote, getOutboxNote, getSentNotes, deliverReply, resolveRemoteNote, 4360 4417 listOutbox, deliverOutboxDelete, deliverOutboxUpdate, deliverDirectNote, 4361 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, handleMoveInbox, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, getDirectMessages, isoStamp, timelineAttachments, timelineEmojis, timelineObjectLinks, timelineQuote, timelineEmbed, applyQuoteProps, deliverToActor, sendInteraction, voteOnPoll, voteOnRemotePoll,4418 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, handleMoveInbox, moveAccount, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, getDirectMessages, isoStamp, timelineAttachments, timelineEmojis, timelineObjectLinks, timelineQuote, timelineEmbed, applyQuoteProps, deliverToActor, sendInteraction, voteOnPoll, voteOnRemotePoll, 4362 4419 acceptGatedFollow, rejectGatedFollow, isWardGuardian, outboxAudience, sendFollowDecision, 4363 4420 parseOwnPoll, pollTally, ownPollView, deliverPollUpdate, maybeCrawlThread, sendReport, localMentionSlugs,
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)