From 609eb6c35e57117f529d44e2c6e695f8eb3ae906 Mon Sep 17 00:00:00 2001 From: legop3 Date: Tue, 15 Sep 2026 16:35:55 -0400 Subject: [PATCH] always let through audio forwarding --- docs/server-admin-container-migration.md | 2 +- server/src/services/videoAuthService/httpRoute.js | 10 +++++++--- server/src/services/videoAuthService/httpRoute.test.js | 5 +++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/server-admin-container-migration.md b/docs/server-admin-container-migration.md index 54bebc78..db3636c4 100644 --- a/docs/server-admin-container-migration.md +++ b/docs/server-admin-container-migration.md @@ -476,7 +476,7 @@ Implemented on 2026-09-14: - Discord command authorization and lockdown moderation recipients now read the live administrator registry, so setup imports and later Discord-ID or role edits take effect without restarting the server. - Full-data restore now leaves `runtime/` untouched, matching its existing exclusion from backup archives and preventing the non-root application from trying to remove lifecycle-controller state owned by the root controller container. - The Users and administrators tab now requests at most 100 lightweight identity summaries through one bounded SQLite query. Search and moderation filters run on the server, while complete signals, permissions, and feature state load only after selecting a user, preventing large identity databases from blocking Socket.IO heartbeats or freezing the browser. -- Removed the remaining server-local SRT hops after Fedora's newer libSRT rejected the zero-payload ACKACK packets emitted by MediaMTX's GoSRT implementation on every acknowledgement cycle. PTZ publishing, replay capture, and snapshot capture now share the existing RTSP/TCP listener, SRT is disabled, and only loopback RTSP readers bypass browser-session authorization. +- Removed the remaining server-local SRT hops after Fedora's newer libSRT rejected the zero-payload ACKACK packets emitted by MediaMTX's GoSRT implementation on every acknowledgement cycle. PTZ publishing, replay capture, and snapshot capture now share the existing RTSP/TCP listener, SRT is disabled, and browser-session authorization is bypassed only for loopback readers and rover `-fwd` speaker feeds. - Fixed inter-instance public payload generation to read feature flags and social links from the same live configuration revision. Social links enabled through the new configuration system no longer trigger an undefined legacy-config reference and an HTTP 500 response. Local verification completed: diff --git a/server/src/services/videoAuthService/httpRoute.js b/server/src/services/videoAuthService/httpRoute.js index 3edeb647..a2e2bd93 100644 --- a/server/src/services/videoAuthService/httpRoute.js +++ b/server/src/services/videoAuthService/httpRoute.js @@ -34,10 +34,14 @@ function registerVideoAuthRoute(deps) { const isRtspProtocol = protocol === 'rtsp' || protocol.startsWith('rtsp'); const isLoopback = ip === '127.0.0.1' || ip === '::1'; + const isRoverForwardAudioRead = action === 'read' + && isRtspProtocol + && streamInfo?.id?.endsWith('-fwd'); // Replay and snapshot workers read MediaMTX through loopback RTSP. They do - // not represent a browser session, while non-loopback RTSP readers remain - // subject to the normal session authorization below. - if (action === 'read' && isRtspProtocol && isLoopback) { + // not represent a browser session. Rovers likewise read their dedicated + // -fwd speaker feed without browser credentials; every other non-loopback + // RTSP read remains subject to normal session authorization below. + if ((action === 'read' && isRtspProtocol && isLoopback) || isRoverForwardAudioRead) { return res.status(200).end(); } /* diff --git a/server/src/services/videoAuthService/httpRoute.test.js b/server/src/services/videoAuthService/httpRoute.test.js index 6ba00752..d5b50ba5 100644 --- a/server/src/services/videoAuthService/httpRoute.test.js +++ b/server/src/services/videoAuthService/httpRoute.test.js @@ -52,6 +52,11 @@ test('continues rejecting an unauthenticated remote RTSP reader', () => { assert.equal(request({ protocol: 'rtsp', action: 'read', path: 'rover-one' }), 401); }); +test('allows a rover to read its RTSP speaker-forward stream without a browser session', () => { + const { request } = createHarness({ requestIp: '192.0.2.10' }); + assert.equal(request({ protocol: 'rtsp', action: 'read', path: 'rover-one-fwd' }), 200); +}); + test('continues rejecting an unauthenticated WebRTC read', () => { const { request } = createHarness(); assert.equal(request({ protocol: 'webrtc', action: 'read', path: 'rover-one' }), 401);