Changeset 2bfe26c in Klonkt for src/routes/guardian.js
- Timestamp:
- 08/08/2026 07:00:17 AM (5 weeks ago)
- Branches:
- main
- Children:
- 0b0cd54
- Parents:
- f3a2556
- git-author:
- Robin <roboburr@…> (08/08/2026 07:00:15 AM)
- git-committer:
- roboburr <roboburr@…> (08/08/2026 07:00:17 AM)
- File:
-
- 1 edited
-
src/routes/guardian.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/guardian.js
rf3a2556 r2bfe26c 620 620 const site = siteForUser(req); 621 621 if (!site) return res.status(404).json({ error: 'no_site' }); 622 const uri = String(req.body?.uri || '').trim(); 623 const allow = req.body?.allow === true; 624 if (!uri) return res.status(400).json({ error: 'empty_uri' }); 625 // Only a guardian of this ward, and only for a ward we host: a setting on a 626 // remote ward belongs to that ward's own server (federating it is Fase 4). 627 const isMyWard = Guardianship.listWards(site.slug).some((w) => w.other_uri === uri); 628 if (!isMyWard) return res.status(403).json({ error: 'not_your_ward' }); 629 // §5.6: propose it to the WARD'S server, wherever that is. The ward's server 630 // tallies (a majority of its guardians, §3.5) and enforces. Co-location is 631 // just the case where that server happens to be this one, so it takes the 632 // same road: propose, then let the tally decide. Anything else would make a 633 // guardian on the ward's own instance more powerful than one elsewhere. 634 const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, ''); 635 const me = AP.actorId(base, site.slug); 636 const feature = req.body.feature; // normalised by the route above 637 const offerId = `${me}/gated/${Date.now().toString(36)}${Math.floor(Math.random() * 1e4).toString(36)}`; 638 const offer = Guardianship.gated.buildGatedOffer(offerId, me, uri, feature, allow); 639 // ONE path, whether the ward lives here or on the other side of the world 640 // (Robins regel, 29-7): propose over the wire and let the ward's server do 641 // what it does for everyone. deliverToActor loops a local recipient back 642 // into the same inbox handler, so co-location changes the transport and 643 // nothing else. The old shortcut recorded the vote here directly, which is 644 // how the remote path stayed broken for a month without anyone noticing. 645 // Our own record of what we sent (5.6): the ward's server answers this Offer 646 // once the decision settles, and that answer needs a row to land in. It is 647 // also the only way the proposer's screen can say more than a button caption. 648 Guardianship.gated.recordSent(offerId, site.slug, uri, feature, allow); 649 AP.deliverToActor(site, uri, offer).catch(() => { /* queued, best-effort */ }); 650 const localSlug = (base && uri.startsWith(`${base}/`)) ? uri.replace(/\/+$/, '').split('/').pop() : null; 651 const progress = localSlug ? Guardianship.gated.gatedProgress(localSlug, feature) : null; 652 res.json({ ok: true, allow, state: 'open', ...(progress || { federated: true }) }); 622 // De hele afweging staat in AP.proposeGate, zodat de apps langs dezelfde weg 623 // kunnen voorstellen (shaer-8ru). Deze route is nog maar de PWA-deur ernaartoe. 624 const uit = AP.proposeGate(site, req.body?.uri, req.body?.feature, req.body?.allow === true); 625 const { status, ...rest } = uit; 626 return res.status(status === 200 ? 200 : status).json(rest); 653 627 } 654 628
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)