diff options
| author | Adam Soltys <[email protected]> | 2026-10-19 11:15:11 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-19 11:15:11 -0700 |
| commit | 5bbc130102de0a3c0eff6727241d0f8029ab6572 (patch) | |
| tree | 37b14de70f498aa0173bbffa6dc5ddf515c34c90 /tools | |
| parent | 926fe1f1958396deac929013d88847f6703665b6 (diff) | |
| download | coinosv3-server-5bbc130102de0a3c0eff6727241d0f8029ab6572.tar.gz coinosv3-server-5bbc130102de0a3c0eff6727241d0f8029ab6572.zip | |
live: a streamer can delete their own recording (POST /live/<id>/delete, NIP-98), ending the stream if it's on. Its files go, and stream.json stays as 'deleted' so the address answers 410 until the trim takes it. A stream someone reported is taken aside instead (.removed/, kept for reporting), so deleting can't destroy what was reported. Removed and deleted streams no longer count as live (toward MAX_STREAMS, or as exempt from the trim).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/live-ingest-test.js | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/tools/live-ingest-test.js b/tools/live-ingest-test.js index d1b15e0..dc24ff8 100644 --- a/tools/live-ingest-test.js +++ b/tools/live-ingest-test.js @@ -4,7 +4,7 @@ // discontinuity between); the end closes the playlist; nobody else may send. // Run: bun tools/live-ingest-test.js (needs ffmpeg) import { generateSecretKey, getPublicKey, finalizeEvent } from 'nostr-tools/pure'; -import { mkdtempSync, rmSync, readFileSync, writeFileSync, existsSync } from 'node:fs'; +import { mkdtempSync, rmSync, readFileSync, writeFileSync, existsSync, readdirSync } from 'node:fs'; import { tmpdir } from 'node:os'; const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); let ok = true; @@ -122,6 +122,18 @@ try { check('once ended, the owner can go live again', !!c.hello?.id && c.hello.id !== id); c.ws.send('end'); await sleep(500); + + console.log('\n[the streamer deletes a recording]'); + const cid = c.hello.id; + check('someone else can\'t delete it', (await post(OTHER, `/live/${cid}/delete`, {})).status === 403); + const del = await (await post(SK, `/live/${cid}/delete`, {})).json(); + check('its streamer can', del.deleted === true, JSON.stringify(del)); + check('...its playlist is gone (410), said to be deleted', (await fetch(`${HTTP}/${cid}/index.m3u8`)).status === 410 && (await (await fetch(`${HTTP}/${cid}/stats`)).json()).state === 'deleted'); + check('...its files with it (only a note of it left)', readdirSync(`${dir}/data/${cid}`).join() === 'stream.json'); + check('...and the owner can still go live', (await (await fetch(`${HTTP}/allowed?name=alice`, { headers: { authorization: nip98(SK, '/live/allowed') } })).json()).ok === true); + const kept = await (await post(SK, `/live/${id}/delete`, {})).json(); + check('a reported one, deleted by its streamer, is gone from view but kept aside for reporting', kept.deleted === true + && (await fetch(`${HTTP}/${id}/index.m3u8`)).status === 410 && existsSync(`${dir}/data/.removed/${id}`) && !existsSync(`${dir}/data/${id}`)); const c0 = await connect(`auth=${auth(SK)}&name=alice`); const tid = c0.hello.id; await send(c0.ws, 0, Math.floor(webm.length * 0.3)); |
