Changeset 3a0ca0f in Klonkt for src/services
- Timestamp:
- 08/08/2026 08:27:03 PM (4 weeks ago)
- Branches:
- main
- Children:
- ea211b9
- Parents:
- d1075a1
- git-author:
- Robin <roboburr@…> (08/08/2026 08:27:01 PM)
- git-committer:
- roboburr <roboburr@…> (08/08/2026 08:27:03 PM)
- Location:
- src/services
- Files:
-
- 3 edited
-
ActivityPubService.js (modified) (3 diffs)
-
guardianship/follows.js (modified) (2 diffs)
-
guardianship/outgoing.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
rd1075a1 r3a0ca0f 5422 5422 5423 5423 // Follow a fediverse account by @handle (WebFinger → actor → signed Follow). 5424 export async function followActor(site, handle, autoBoost = false ) {5424 export async function followActor(site, handle, autoBoost = false, { approved = false } = {}) { 5425 5425 const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, ''); 5426 5426 if (!base || !site || !site.slug) return { error: 'config' }; 5427 // DE POORT STAAT HIER, en niet alleen in de C2S-outbox (shaer-p729, Barts 5428 // melding 8-8: de volgverzoeken van Esmee kwamen nooit bij haar guardians 5429 // aan). Hij stond in `case 'Follow'` van de outbox -- dus alleen als je via 5430 // Shaer volgt. Volgde het kind vanuit Klonkts eigen webinterface, dan werd er 5431 // geen verzoek aangemaakt, ging er niets naar de guardians, en was er dus ook 5432 // niets om te beantwoorden. Precies dezelfde deur-naast-de-poort als bij de 5433 // antwoordpoort vanmiddag (shaer-r4c). 5434 // 5435 // Merk op wat het NIET was: niet dat een guardian elders het niet kon 5436 // beantwoorden. Die weg werkt en levert een Offer af bij de externe guardian. 5437 // Er kwam alleen nooit iets aan om af te leveren. 5438 // 5439 // `approved` is de enige doorlaat, voor performApprovedFollow: zonder dat zou 5440 // een goedgekeurd verzoek opnieuw op de poort stuiten en voor eeuwig wachten. 5441 5427 5442 // Accept any of: a profile/actor URL, an @user@host handle (WebFinger), or a 5428 5443 // bare site domain (site.com) — for a single-actor site (Klonkt etc.) the root … … 5435 5450 else actorUrl = null; 5436 5451 if (!actorUrl) return { error: 'not_found' }; 5452 // NA het oplossen, want een kind volgt net zo goed met @naam@server of een 5453 // kaal domein. Zou de poort alleen naar de ruwe invoer kijken, dan is elke 5454 // handle een sluiproute -- en dat is precies de fout die we hier repareren, 5455 // een maat kleiner. 5456 if (!approved) { 5457 const held = await gateOutgoingFollow(site, actorUrl); 5458 if (held) return { held: true, id: held.id, status: held.status || 'pending' }; 5459 } 5437 5460 // SIGNED, as this actor: an authorized-fetch instance refuses an anonymous 5438 5461 // GET of the actor doc, which made following from a boost silently fail … … 5759 5782 const site = db.prepare('SELECT * FROM sites WHERE slug = ?').get(pending.ward_slug); 5760 5783 if (!site) return { error: 'no_such_ward' }; 5761 const r = await followActor(site, pending.target_uri );5784 const r = await followActor(site, pending.target_uri, false, { approved: true }); 5762 5785 if (r && r.error) return { error: r.error }; 5763 5786 console.log('[AP] outgoing Follow approved', pending.ward_slug, '→', pending.target_uri); -
src/services/guardianship/follows.js
rd1075a1 r3a0ca0f 50 50 * send the Accept/Reject. A single reject denies; approvals meet the quorum. 51 51 */ 52 /** 53 * Hoeveel guardians moeten ja zeggen voor een volgverzoek (Barts besluit, 8-8). 54 * 55 * EENVOUDIGE MEERDERHEID: 1 van 1, 1 van 2, 2 van 3, 2 van 4. Bart: "1/2 is 56 * voldoende." 57 * 58 * BEWUST SOEPELER DAN DE POORTDREMPEL, en dat verschil hoort uitgelegd. Een gate 59 * opent een deur voor alles wat daarna komt; die vraagt om een STRIKTE 60 * meerderheid (thresholdFor in gated.js: 2 van 2, 3 van 4). Een volgverzoek gaat 61 * over een persoon, is met ontvolgen terug te draaien, en stond hier tot vandaag 62 * op 'any' -- een enkele ja, hoeveel guardians er ook waren. Dit is dus geen 63 * versoepeling maar een AANSCHERPING voor iedereen met drie of meer guardians. 64 * 65 * De 'all'-stand die hier stond is weg. Hij werd nergens gezet -- elke schrijver 66 * gaf 'any' mee -- dus het was een keuze die niemand kon maken en die alleen in 67 * de weg stond bij het lezen van deze regel. 68 */ 69 export function followThreshold(setSize) { 70 return Math.max(1, Math.ceil(setSize / 2)); 71 } 72 73 /** 74 * Een race naar de drempel, net als de poorttelling: zodra het aantal gehaald 75 * is, is het besluit gevallen. 76 * 77 * TODO (shaer-8vt): wie antwoordt weet niet dat hij de doorslag geeft. Bij 1 van 78 * 2 is de eerste ja meteen de beslissing, en het scherm zegt dat nergens. Dat is 79 * hetzelfde gat als bij de gate-voorstellen en het hoort daar samen opgelost. 80 */ 52 81 export function decide(id, guardianUri, decision, guardiansOfWard) { 53 82 const follow = stmts().get.get(id); … … 61 90 const approvers = new Set(rows.filter((r) => r.decision === 'approve').map((r) => r.guardian_uri)); 62 91 const guardians = (guardiansOfWard || []).filter(Boolean); 63 const enough = follow.quorum === 'all' 64 ? guardians.length > 0 && guardians.every((g) => approvers.has(g)) 65 : approvers.size >= 1; // 'any' (default) 92 const enough = approvers.size >= followThreshold(guardians.length); 66 93 if (enough) { 67 94 stmts().setStatus.run('accepted', id); -
src/services/guardianship/outgoing.js
rd1075a1 r3a0ca0f 15 15 */ 16 16 import db from '../../config/database.js'; 17 import { followThreshold } from './follows.js'; 17 18 18 19 let _s = null; … … 80 81 const approvers = new Set(rows.filter((r) => r.decision === 'approve').map((r) => r.guardian_uri)); 81 82 const guardians = (guardiansOfWard || []).filter(Boolean); 82 const enough = follow.quorum === 'all' 83 ? guardians.length > 0 && guardians.every((g) => approvers.has(g)) 84 : approvers.size >= 1; // 'any' (default) 83 // Dezelfde eenvoudige meerderheid als bij een inkomend volgverzoek 84 // (followThreshold): het is dezelfde vraag, alleen omgedraaid. Twee 85 // verschillende drempels voor "mag dit kind met deze persoon te maken hebben" 86 // zou een guardian nooit kunnen uitleggen. 87 const enough = approvers.size >= followThreshold(guardians.length); 85 88 if (enough) { 86 89 stmts().setStatus.run('approved', id);
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)