Changeset e27b8db in Klonkt for src/routes/activitypub.js


Ignore:
Timestamp:
07/29/2026 10:04:36 AM (6 weeks ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
329873e
Parents:
88d7c8f
Message:

Afspelen in de app als tweede gated feature, en het gat in de gate

Bij het uitzoeken van de YouTube-vraag bleek de gate lek. De web-Krant bouwt de
speler uit de inhoud van de post via timelineEmbedHtml, en dat pad raakte
gateEmbeds nooit. Een ward wiens guardians niets hadden toegestaan kreeg dus de
volledige YouTube-speler op het web, terwijl de app niets liet zien: het zware
ding open, het lichte dicht. Precies omgekeerd.

Nu zijn het twee besluiten, want het zijn twee dingen. Zien dat er een filmpje
is, is niet hetzelfde als het scherm afstaan aan de motor van een derde partij,
compleet met eindscherm en volgende-video. shaer:externalEmbeds houdt de kaart,
shaer:externalPlayback de speler, allebei standaard uit voor een ward, en
afspelen vereist de kaart: je kunt niet spelen wat je niet mag zien.

En het antwoord op Robins vraag over de links: die vallen er ook onder. De gate
verborg tot nu toe alleen het plaatje terwijl de kale link eronder gewoon
aantikbaar bleef, dus de deur stond open met een doek eroverheen. Staat de gate
dicht, dan toont de kaart zich nog wel maar is hij geen deur meer.

De server bepaalt wat gespeeld mag worden, niet de client: hij levert
shaer:playerUrl mee, alleen bij een open gate en alleen in de privacy-variant
(youtube-nocookie met rel=0, of de eigen speler van de PeerTube-instance). De
app houdt zo geen lijst van hosts bij; hij speelt wat hij krijgt aangereikt.

Changed files:
src/config/database.js

  • kolom sites.external_playback

src/services/guardianship/notes.js

  • externalPlaybackAllowed naast externalEmbedsAllowed

src/services/guardianship/gated.js

  • shaer:externalPlayback in de feature-tabel

src/services/ActivityPubService.js

  • timelineEmbed voegt shaer:playerUrl toe als afspelen mag; playerUrlFor kent alleen privacy-varianten en weigert de rest

src/routes/activitypub.js

  • shaer:capabilities op de owner-only inbox-read: wat mag dit account
  • de embed draagt de speler-URL alleen bij een open playback-gate

src/routes/posts.js

  • het gat gedicht: de speler-iframe op de web-Krant valt nu onder de gate

src/routes/guardian.js

  • de voorstel-route is feature-bewust; het lokale pad stuurt nu ook door

src/assets/js/guardian.js

  • tweede knop in het paneel, alleen zichtbaar als de kaart al aan staat

src/services/i18n.js

  • de labels in nl, en, de

test/gated-settings.test.js

  • drie tests: de speler-URL rijdt alleen mee bij een open gate, een pagina die we niet framen blijft een thumbnail, en afspelen vereist de kaart

remarks: 280 tests groen. Niets geforceerd: beide gates staan standaard uit
voor een ward en twee van de drie guardians moeten nog steeds akkoord gaan.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/activitypub.js

    r88d7c8f re27b8db  
    154154  const isWard = (() => { try { return Guardianship.listGuardians(auth.site.slug).length > 0; } catch { return false; } })();
    155155  const embedsAllowed = Guardianship.externalEmbedsAllowed(auth.site.external_embeds, isWard);
     156  // The heavier sibling (5.6): may a third party's PLAYER run inside the app,
     157  // and may a link hand the child over to a browser? Both are the guardians'
     158  // call, both default to off for a ward, and both need the preview gate open
     159  // first: you cannot play, or follow, what you may not see. Served here so
     160  // the app knows what it may offer instead of guessing.
     161  const playbackAllowed = embedsAllowed
     162    && Guardianship.externalPlaybackAllowed(auth.site.external_playback, isWard);
    156163  const items = AP.getTimeline(auth.site.slug, 60).map((t) => ({
    157164    id: `${t.id}#create`,
     
    206213      // An external (non-fediverse) embed, thumbnail-only and never an iframe.
    207214      // Omitted entirely when the gate is closed (see above).
    208       'shaer:embed': embedsAllowed ? AP.timelineEmbed(t.embed_json) : undefined,
     215      // Carries shaer:playerUrl only when the playback gate is open too.
     216      'shaer:embed': embedsAllowed ? AP.timelineEmbed(t.embed_json, { playback: playbackAllowed }) : undefined,
    209217    },
    210218  }));
     
    213221    id: `${base}/ap/users/${auth.site.slug}/inbox`,
    214222    type: 'OrderedCollection',
     223    // What this account may do with what is in here (FEP-633c 5.6). Owner-only
     224    // by construction, and never on the public actor document: it says
     225    // something about a child, and only the child and its guardians need it.
     226    'shaer:capabilities': {
     227      'shaer:externalEmbeds': embedsAllowed,
     228      'shaer:externalPlayback': playbackAllowed,
     229      // Leaving the app is the same decision as playing inside it: with the
     230      // gate shut a link is shown but not followed, so the door is closed too
     231      // and not just the picture over it.
     232      'shaer:externalLinks': playbackAllowed,
     233    },
    215234    totalItems: items.length,
    216235    orderedItems: items,
Note: See TracChangeset for help on using the changeset viewer.