Changeset 6c152a5 in Klonkt for src/assets/js


Ignore:
Timestamp:
07/28/2026 08:15:31 PM (6 weeks ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
6eab7e9
Parents:
742ba7e
Message:

De Undo bij het loslaten van een ward reist nu echt mee

Loslaten was een lokale delete. De guardian vergat het kind, terwijl de server
van het kind hem gewoon in shaer:guardians bleef noemen. De vorige commit zette
dat als waarschuwing in beeld; Robin noemt het terecht een bug, want FEP-633c
3.2 zegt gewoon dat een Undo van de Relationship de guardian eruit haalt.

Nu gaat er een Undo naar het kind en naar de andere guardians, met dezelfde
adressering als de Offer waarmee het begon (3.1.1), zodat geen kopie achterblijft
die denkt dat de band er nog is. De ontvangende kant haalt de guardian eruit,
maar alleen als de guardian zelf tekent: de variant waarbij het kind opzegt met
een mede-ondertekenende guardian heeft een tweede handtekening nodig en is niet
gebouwd, dus die wordt geweigerd in plaats van half uitgevoerd.

De laatste guardian kan niet meer alleen weglopen. 3.3 geldt zolang er meer dan
een over is; de set leegmaken is emancipatie (3.4) en daar gaat geen enkele
partij alleen over. Dat wordt geweigerd aan beide kanten, en de knop biedt in
dat geval alleen nog een nee aan in plaats van een ja die toch een fout geeft.

Een kind op DEZELFDE instance kreeg de Undo niet: een inbox op deze machine is
van deze machine niet over HTTP bereikbaar, en dat hoort ook niet. De commit-kant
lost dat al zo op dat elke instance schrijft wat hij host; het loslaten doet dat
nu ook. In de browser gevonden nadat de guardian-kant leeg was en de kant van het
kind nog niet.

Een guardian-app kan hetzelfde over C2S: een Undo naar de eigen outbox loopt
langs precies dezelfde functie als de knop in de PWA, zodat die twee niet uit
elkaar kunnen groeien.

Changed files:
src/services/guardianship/handshake.js

  • endGuardianship: bouwt en verstuurt de Undo, weigert emancipatie, en schrijft de kant van een lokaal gehost kind zelf
  • applyInboundUndo + dropGuardianFromWard: de ontvangende kant
  • handleOutbox accepteert Undo; handleInbox routeert hem

src/services/guardianship/index.js

  • endGuardianship en parseUndoRelationship geexporteerd

src/services/ActivityPubService.js

  • de guardianship-dispatch ziet Undo nu voordat de generieke Undo-tak hem opslokt met een 202
  • push voor een vertrokken guardian en een vertrokken mede-guardian

src/routes/guardian.js

  • /wards/remove loopt langs endGuardianship in plaats van een lokale delete
  • release-check meldt niet langer dat de Undo blijft liggen

src/assets/js/guardian.js

  • geen ja-knop meer als jij de laatste bent; een 409 wordt getoond in plaats van stil hertekend

src/services/i18n.js

  • de waarschuwing klopt weer, plus push-teksten in nl, en, de

test/guardianship.test.js

  • zes tests: de Undo werkt aan beide kanten, de laatste guardian wordt geweigerd, hij is idempotent, C2S loopt hetzelfde pad, een vreemde Undo verandert niets, en een kind op dezelfde instance wordt ook bijgewerkt terwijl er niets bezorgd is

remarks: end-to-end nagekeken in de browser: na het loslaten staat guard niet
meer in shaer:guardians van het actor-document van het kind, en een POST die de
knop omzeilt krijgt 409 would_emancipate.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/assets/js/guardian.js

    r742ba7e r6c152a5  
    203203    else if (check.last === false) box.appendChild(el('p', null, T.release_step_down || ''));
    204204    else box.appendChild(el('p', 'grave', T.release_unknown || ''));
    205     if (check.federates === false) box.appendChild(el('p', null, T.release_local || ''));
     205    box.appendChild(el('p', null, T.release_local || ''));
    206206
    207207    var row = el('div', 'row');
    208     var yes = el('button', 'danger small', T.release_yes || 'Yes');
    209     yes.addEventListener('click', function () { yes.disabled = true; remove(uri, yes); });
    210208    var no = el('button', 'small', T.release_no || 'No');
    211209    no.addEventListener('click', function () {
     
    214212    });
    215213    // No first: the way out should be the easy one to hit.
    216     row.appendChild(no); row.appendChild(yes);
     214    row.appendChild(no);
     215    // Being the last guardian is not a warning but a wall: the server refuses
     216    // it (§3.4), so offering a yes here would only produce an error. The text
     217    // above already says what has to happen instead.
     218    if (check.last !== true) {
     219      var yes = el('button', 'danger small', T.release_yes || 'Yes');
     220      yes.addEventListener('click', function () {
     221        yes.disabled = true;
     222        remove(uri, yes, function (err) {
     223          // The guardian set can change between the check and the click.
     224          yes.disabled = false;
     225          box.appendChild(el('p', 'grave', err === 'would_emancipate' ? (T.release_last || '') : (T.failed || '')));
     226          if (err === 'would_emancipate') yes.remove();
     227        });
     228      });
     229      row.appendChild(yes);
     230    }
    217231    box.appendChild(row);
    218232    return box;
     
    312326  }
    313327
    314   function remove(uri, btn) {
     328  function remove(uri, btn, onError) {
    315329    btn.disabled = true;
    316330    fetch('/guardian/wards/remove', {
    317331      method: 'POST', headers: { 'Content-Type': 'application/json' },
    318332      body: JSON.stringify({ uri: uri, site: S.site }),
    319     }).then(refresh);
     333    }).then(function (r) { return r.json().then(function (j) { return { ok: r.ok, j: j }; }); })
     334      .then(function (res) {
     335        // The server can refuse: emptying shaer:guardians is emancipation and
     336        // not one guardian's call (§3.4). Say so instead of silently redrawing.
     337        if (!res.ok) { if (onError) onError(res.j && res.j.error); return; }
     338        refresh();
     339      })
     340      .catch(function () { if (onError) onError('network'); else btn.disabled = false; });
    320341  }
    321342
Note: See TracChangeset for help on using the changeset viewer.