Changeset d97c58c in Klonkt for test


Ignore:
Timestamp:
08/16/2026 06:15:52 PM (3 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
995b100
Parents:
1019a90
Message:

Betaalde posts lekten hun inhoud via de outbox en de volger-backfill

Bart zag de inhoud van een betaalde post op boiert.eu binnenkomen via
@actor@…. De redactie in buildNote werkte, maar kreeg de
gegevens niet: beide paden halen een KOLOMMENLIJST op, en paid stond
daar niet in. Dan is post.paid undefined, valt de vroege return weg, en
gaat de volledige tekst de deur uit -- zonder foutmelding.

  • outboxSlice miste paid en excerpt. Dit is het pad dat Bart zag.
  • backfillNewFollower miste paid, excerpt EN ap_visibility, en filterde alleen op fan_only. Die duwt bij ELKE nieuwe volger twintig posts naar hun inbox: een push, dus niet terug te nemen. Nu filtert hij ook op ap_visibility, want een friends- of direct-post hoort daar niet in.

De bestaande test was groen omdat hij buildOutbox een rij uit SELECT *
gaf -- de echte weg deed hij niet. Vervangen door een test via
outboxSlice, plus een klasse-wacht die de bron nakijkt: elke SELECT die
post.content oplevert moet ook paid ophalen.

Co-Authored-By: Claude Opus 5 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/paid-post-lekt-niet.test.js

    r1019a90 rd97c58c  
    7979  assert.ok(alleTekst(note).includes(GEHEIM), 'een gewone post draagt zijn inhoud wel');
    8080});
     81
     82
     83// ── De reparatie van 15 augustus 2026 ──────────────────────────────
     84// De test hierboven ('ook niet via de OUTBOX') gaf buildOutbox een rij uit
     85// `SELECT *` en was dus groen TERWIJL DE OUTBOX LEKTE. De echte route haalt een
     86// kolommenlijst op, en `paid` stond daar niet in -- dus post.paid was undefined
     87// en de redactie viel stil weg. Een test die de echte weg niet neemt, bewijst
     88// de echte weg niet.
     89test('via outboxSlice, de echte weg, komt paid mee', () => {
     90  maak({ id: 'p9', slug: 'betaald-slice', paid: 1 });
     91  const rij = AP.outboxSlice('s1', { offset: 0, limit: 50 }).posts.find((x) => x.id === 'p9');
     92  assert.ok(rij, 'de post hoort in de slice te zitten');
     93  assert.equal(rij.paid, 1, 'paid MOET uit de query komen; undefined IS de lek');
     94  const note = AP.buildNote('https://ons.test', site(), rij);
     95  assert.ok(!alleTekst(note).includes(GEHEIM), 'de volledige tekst mag de outbox niet uit');
     96  assert.match(note.content, /Een teaser/);
     97});
     98
     99// Klasse-wacht. Het lekte op twee plekken met dezelfde fout (outboxSlice en
     100// backfillNewFollower), en zo'n kolommenlijst faalt STIL: een vergeten veld is
     101// `undefined`, niet een fout. Deze test kijkt daarom naar de bron, zodat een
     102// derde plek niet opnieuw ongemerkt gaat lekken.
     103test('elke kolommenlijst die post-tekst ophaalt, haalt ook paid op', async () => {
     104  const { readFile } = await import('node:fs/promises');
     105  const bron = await readFile(new URL('../src/services/ActivityPubService.js', import.meta.url), 'utf8');
     106  const fout = [];
     107  for (const m of bron.matchAll(/SELECT\s+([^;`']*?)\s+FROM\s+posts\b/gis)) {
     108    const kol = m[1].replace(/\s+/g, ' ').trim();
     109    if (kol === '*' || kol.includes('(')) continue;   // SELECT * is veilig
     110    if (!/\bcontent\b/.test(kol)) continue;           // levert geen post-tekst
     111    if (!/\bpaid\b/.test(kol)) fout.push(`regel ${bron.slice(0, m.index).split('\n').length}: ${kol.slice(0, 80)}`);
     112  }
     113  assert.deepEqual(fout, [], 'deze SELECTs leveren post.content zonder post.paid:\n  ' + fout.join('\n  '));
     114});
Note: See TracChangeset for help on using the changeset viewer.