aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-19 11:15:11 -0700
committerAdam Soltys <[email protected]>2026-10-19 11:15:11 -0700
commit5bbc130102de0a3c0eff6727241d0f8029ab6572 (patch)
tree37b14de70f498aa0173bbffa6dc5ddf515c34c90 /tools
parent926fe1f1958396deac929013d88847f6703665b6 (diff)
downloadcoinosv3-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.js14
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));