Changeset b4af6f3 in Klonkt for src/routes/posts.js


Ignore:
Timestamp:
08/24/2026 07:22:58 AM (2 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
27cb1e3
Parents:
fbacddc
Message:

Open audio travels with a paid post, and plays on the site itself

A paid post federated a bare teaser and dropped every attachment. But its
fedi_open tracks federate on their own anyway, as public Audio objects with
their context pointing back at that post. So the early return kept no secret:
it withheld only the ORDER and the fact that this is one tape. In the hub a
mixtape fell apart into loose tracks under an empty teaser card
(boiert.eu/introducing-this-machine).

The wall belongs around the TEXT. fedi_open is a separate, one-way, per-track
choice by the owner, and buildMixtapeObject already builds from
playlistOpenTracks — the tape object can only ever carry open tracks. So the
paid branch now carries them, and the redaction of the body is untouched.

The same rule on the site itself: the paid gate now shows the player when the
post's audio is open. Without it the music was available everywhere except on
the site releasing it. Only when ALL of it is open — a shortcode renders its
whole list, and /audio/stream lets a same-origin fetch through, so half open
has to count as closed. The gate gets a post that is nothing but the audio
shortcodes, so the body cannot leak through it.

Extracted openAudioAttachments() and mixtapeAttachment() out of buildNote so
both branches use one implementation.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    rfbacddc rb4af6f3  
    822822}
    823823
     824// De muziek van een betaalde post op de poortpagina zelf.
     825//
     826// WAAROM DIE DAAR HOORT. Zodra een nummer `fedi_open` is, federeert het als
     827// eigen Audio-object en speelt het bij iedereen die de post in een hub of in
     828// Mastodon tegenkomt. Toonde de poort het dan NIET, dan was de muziek overal
     829// beschikbaar behalve op de site die hem uitbrengt -- en dat is de verkeerde
     830// kant op (Robin, 24-8). De muur staat om de tekst.
     831//
     832// ALLES OF NIETS. Alleen als ELK nummer waar de post naar wijst open staat.
     833// Een shortcode rendert zijn hele lijst, dus bij een half-open bandje zou de
     834// speler ook de gesloten nummers krijgen -- en /audio/stream laat een
     835// gelijke-oorsprong-fetch door, dus dat is geen theoretisch lek maar een echt.
     836// Half open is hier dus dicht.
     837//
     838// De TEKST komt hier niet langs: we geven renderPostBodyHtml een post mee die
     839// alleen uit de audio-shortcodes bestaat. Wat niet meegegeven wordt kan ook
     840// niet lekken -- dezelfde regel als bij readerItems.
     841export function paidOpenAudioHtml(site, post, req) {
     842  if (!postAudioFediOpen(site.id, post.content)) return '';
     843  const codes = String(post.content || '').match(/\[\[(?:track|album|playlist):[^\]]+\]\]/gi) || [];
     844  if (!codes.length) return '';
     845  const alleenMuziek = codes.join('\n');
     846  try {
     847    return renderPostBodyHtml(site, { ...post, content: alleenMuziek, content_rendered: alleenMuziek }, req);
     848  } catch { return ''; /* geen speler is geen kapotte poort */ }
     849}
     850
    824851function postNeighbors(site, post) {
    825852  const ordered = db.prepare(`
     
    15731600  if (post.paid && !canEditThis && !_unlocked) {
    15741601    const { newerPost, olderPost } = postNeighbors(site, post);
     1602    const pgAudio = paidOpenAudioHtml(site, post, req);
    15751603    return renderPage(req, res, 'pages/paid-gate', {
    1576     pageJs: 'paid-gate',
     1604    pageJs: 'paid-gate' + (pgAudio ? ' tape' : ''),
    15771605      pageTitle: post.title || 'Voor supporters',
    15781606      bodyClass: 'on-special',
    15791607      pgTitle: post.title || '',
    15801608      pgTeaser: paidTeaser(post),
     1609      pgAudio,
    15811610      pgCents: post.paid_min_cents || paidDefaultMinCents(site.id),
    15821611      pgSlug: post.slug,
Note: See TracChangeset for help on using the changeset viewer.