source: Klonkt/tools/ward-farm/offer-many.mjs@ dc0da72

main
Last change on this file since dc0da72 was dc0da72, checked in by roboburr <roboburr@…>, 4 weeks ago

Alleen claimen wat je herkent (regressie uit shaer-8ru)

Barts honderd aanbiedingen liepen meteen stuk op "400 unsupported_offer", en dat
was mijn fout van een uur eerder.

Ik zette het gate-voorstel als case 'Offer' in de outbox-switch. Die case
claimde ELKE Offer: wat geen shaer:GatedSetting was kreeg 400 -- dus ook de
adoptie-handshake, en straks elke Offer-vorm die we nog toevoegen. De
guardianship-afhandeling stond ervoor en ving het meestal op, maar zodra die iets
niet herkende viel het in mijn 400 in plaats van door te lopen.

Nu voor de switch, naast de andere Offer-afhandeling, en alleen als
parseGatedSetting iets teruggeeft. De toets die 'unsupported_offer' verwachtte is
vervangen: die legde mijn verkeerde aanname vast. Er staat nu een toets op dat een
adoptie-Offer NIET door de gate-tak wordt afgevangen.

Twee kleinere dingen die dezelfde ronde boven kwamen:

  • Het aanbod-script gebruikte een verzonnen relatie-URI en werd daarom stil geweigerd. isGuardianRelationship accepteert precies twee waarden.
  • De SSRF-toets hing af van wat er toevallig draaide: hij ging ervan uit dat er niets op [::1]:3060 luisterde, en viel om zodra de testkudde daar stond. Nu een poort waar met opzet niets luistert. Een toets die afhangt van wat er draait bewijst niets.

Suite 756/756.

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/**
2 * Deze Klonkt biedt zich aan als guardian bij een reeks wards (FEP-633c 3.1).
3 *
4 * Bedoeld voor de caseload-test: honderd kinderen, een guardian. Draait tegen de
5 * database van de instance zelf, zoals de andere scripts hier -- geen OAuth, geen
6 * tweede weg. Wat het doet is precies wat de PWA-knop doet, honderd keer.
7 *
8 * DATABASE_PATH=... PUBLIC_BASE_URL=... node offer-many.mjs \
9 * --slug dev --base https://wards.klonkt.com --from 1 --to 100
10 *
11 * ECHTE FEDERATIE, geen kortsluiting: de wards wonen op een andere origin, dus
12 * elk aanbod gaat over de lijn en wordt daar ondertekend beantwoord. Dat is het
13 * hele punt -- een test die de co-locatieroute neemt meet iets anders dan wat er
14 * in productie gebeurt.
15 *
16 * VEILIG OM OPNIEUW TE DRAAIEN: een ward die al gecommit is wordt overgeslagen,
17 * en een aanbod dat al openstaat wordt niet nog eens gestuurd. Zonder dat maakt
18 * een tweede run honderd dubbele aanbiedingen bij mensen die al ja zeiden.
19 */
20
21const args = Object.fromEntries(
22 process.argv.slice(2).join(' ').split('--').filter(Boolean)
23 .map((s) => s.trim().split(/\s+/)).map(([k, ...v]) => [k, v.join(' ') || true]),
24);
25
26const slug = args.slug || 'dev';
27const farmBase = (args.base || 'http://[::1]:3060').replace(/\/+$/, '');
28const van = Number(args.from || 1);
29const tot = Number(args.to || 100);
30const pauze = Number(args.pauze || 150);
31
32const AP = await import('../../src/services/ActivityPubService.js');
33const Guardianship = await import('../../src/services/guardianship/index.js');
34const dbMod = await import('../../src/config/database.js');
35const db = dbMod.default;
36
37const site = db.prepare('SELECT * FROM sites WHERE slug = ?').get(slug);
38if (!site) { console.error(`geen site met slug "${slug}"`); process.exit(1); }
39
40const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
41const me = AP.actorId(base, site.slug);
42console.log(`[offer] ${me} biedt zich aan bij w${String(van).padStart(3, '0')}..w${String(tot).padStart(3, '0')} op ${farmBase}`);
43
44const alBekend = new Set(Guardianship.listWards(site.slug).map((w) => w.other_uri));
45let gestuurd = 0, overgeslagen = 0, mislukt = 0;
46
47for (let i = van; i <= tot; i++) {
48 const naam = `w${String(i).padStart(3, '0')}`;
49 const ward = `${farmBase}/u/${naam}`;
50 if (alBekend.has(ward)) { overgeslagen++; continue; }
51
52 // Precies de vorm die handleOutbox verwacht: een Offer van een
53 // Relationship{subject: ward, object: ik}. Door hem via de outbox te sturen
54 // loopt dit langs dezelfde code als de knop in de PWA -- er is geen tweede pad
55 // naar hetzelfde besluit, en dat is de les van vandaag.
56 const activity = {
57 type: 'Offer',
58 to: [ward],
59 object: {
60 type: 'Relationship',
61 subject: ward,
62 object: me,
63 // De exacte waarde die isGuardianRelationship accepteert. Mijn eerste
64 // poging gebruikte een verzonnen URI en werd stil geweigerd.
65 relationship: 'shaer:Guardian',
66 },
67 };
68
69 try {
70 const uit = await AP.ingestOutboxActivity(site, { id: site.owner_id, username: slug }, activity);
71 if (uit && (uit.status === 201 || uit.status === 200)) gestuurd++;
72 else { mislukt++; console.warn(` ${naam}: ${uit && uit.status} ${uit && uit.error}`); }
73 } catch (e) {
74 mislukt++;
75 console.warn(` ${naam}: ${e.message}`);
76 }
77 // Een adempauze. Honderd handshakes tegelijk zegt meer over de bezorgwachtrij
78 // dan over het paneel, en dit script is er om het paneel te kunnen bekijken.
79 if (pauze) await new Promise((r) => setTimeout(r, pauze));
80}
81
82console.log(`[offer] verstuurd ${gestuurd}, overgeslagen ${overgeslagen}, mislukt ${mislukt}`);
83console.log('[offer] de commit valt pas als elke ward heeft geaccepteerd; kijk over een minuut met listWards.');
84process.exit(0);
Note: See TracBrowser for help on using the repository browser.