better banning, new deter mute, replay discord fixes.

This commit is contained in:
legop3
2026-07-21 22:50:12 -04:00
parent fb9565faf9
commit b26daed93f
25 changed files with 628 additions and 46 deletions
@@ -23,8 +23,34 @@ function registerAudioForwardHooks(deps) {
buildWhipUrl,
videoSessions,
startSilenceWriter,
isMuted,
verificationEvents,
} = deps;
verificationEvents.on('change', ({ socketId } = {}) => {
if (!socketId) return;
const socket = io.sockets.sockets.get(socketId);
if (!socket || !isMuted(socket)) return;
/*
Permission checks stop new muted audio, but an upload or microphone can
already be live when moderation changes. Stop only streams owned by this
socket so muting does not disturb another driver's audio or unrelated
server-generated sounds.
*/
for (const [roverId, ownerSocketId] of whipOwners.entries()) {
if (ownerSocketId === socketId) {
stopWhipForRover(roverId, 'owner_muted');
}
}
workers.forEach((worker, roverId) => {
if (worker?.contentKind === 'upload' && worker.activeOwnerSocketId === socketId) {
logger.info('Stopping uploaded audio because its owner was muted', { roverId, socketId });
startSilenceWriter(roverId);
}
});
});
roverManager.managerEvents.on('rover', ({ roverId, action } = {}) => {
if (!roverId) return;
if (action === 'removed') {
@@ -8,7 +8,7 @@ const logger = require('../../globals/logger').child('audioForwardService');
const { loadConfig } = require('../../helpers/configLoader');
const roverManager = require('../roverManager');
const turnService = require('../turnService');
const { isVerified } = require('../verificationService');
const { isMuted, isVerified, verificationEvents } = require('../verificationService');
const videoSessions = require('../videoSessions');
const { createAudioForwardPolicy } = require('./policy');
const { createAudioForwardWorkerEngine } = require('./workerEngine');
@@ -62,6 +62,7 @@ function getAudioForwardState() {
const audioForwardPolicy = createAudioForwardPolicy({
isVerified,
isMuted,
roverManager,
turnService,
streamSuffix,
@@ -141,6 +142,8 @@ registerAudioForwardHooks({
buildWhipUrl,
videoSessions,
startSilenceWriter,
isMuted,
verificationEvents,
});
registerChargeCompleteSound({
@@ -4,6 +4,7 @@
function createAudioForwardPolicy(deps) {
const {
isVerified,
isMuted,
roverManager,
turnService,
streamSuffix,
@@ -18,6 +19,9 @@ function createAudioForwardPolicy(deps) {
function ensureAudioForwardPermission(socket, roverId) {
ensureVipVerified(socket);
if (isMuted(socket)) {
throw new Error('Muted');
}
if (!roverManager.isDriver(roverId, socket)) {
throw new Error('Audio forwarding is only allowed on your own rover');
}
@@ -0,0 +1,27 @@
// Audio Forward Policy Tests
// Purpose: Verifies that mute blocks user-owned forwarding without changing ordinary driver authorization.
// Scope: Exercises the pure permission policy with small injected role, rover, and turn doubles.
const test = require('node:test');
const assert = require('node:assert/strict');
const { createAudioForwardPolicy } = require('./policy');
function createPolicy({ verified = true, muted = false, driver = true, canDrive = true } = {}) {
return createAudioForwardPolicy({
isVerified: () => verified,
isMuted: () => muted,
roverManager: { isDriver: () => driver },
turnService: { canDrive: () => canDrive },
streamSuffix: '-fwd',
mediaConfig: {},
});
}
test('rejects audio forwarding for a muted verified driver', () => {
const policy = createPolicy({ muted: true });
assert.throws(() => policy.ensureAudioForwardPermission({}, 'rover'), /Muted/);
});
test('preserves normal audio forwarding for an unmuted verified driver', () => {
const policy = createPolicy();
assert.doesNotThrow(() => policy.ensureAudioForwardPermission({}, 'rover'));
});