From 388b7d172d55cca034b968b0097d288c103bcd2d Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Tue, 24 Mar 2026 19:07:55 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20allow=20unauthenticated?= =?UTF-8?q?=20participants=20to=20mute=20via=20LiveKit=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the LiveKit token when calling the mute-participant endpoint to authenticate the request. This enables non-authenticated participants to mute others through the API while preserving proper authorization checks. --- .../src/features/rooms/api/muteParticipant.ts | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/frontend/src/features/rooms/api/muteParticipant.ts b/src/frontend/src/features/rooms/api/muteParticipant.ts index fac79584..3b8418d4 100644 --- a/src/frontend/src/features/rooms/api/muteParticipant.ts +++ b/src/frontend/src/features/rooms/api/muteParticipant.ts @@ -6,14 +6,15 @@ import { NotificationType, } from '@/features/notifications' import { fetchApi } from '@/api/fetchApi' +import { useIsAdminOrOwner } from '../livekit/hooks/useIsAdminOrOwner' export const useMuteParticipant = () => { - const data = useRoomData() - + const apiRoomData = useRoomData() const { notifyParticipants } = useNotifyParticipants() + const isAdminOrOwner = useIsAdminOrOwner() const muteParticipant = async (participant: Participant) => { - if (!data?.id) { + if (!apiRoomData?.livekit?.room) { throw new Error('Room id is not available') } const trackSid = participant.getTrackPublication( @@ -24,25 +25,41 @@ export const useMuteParticipant = () => { return } + const headers = !isAdminOrOwner + ? { + Authorization: `Bearer ${apiRoomData?.livekit?.token}`, + } + : undefined + try { - const response = await fetchApi(`rooms/${data.id}/mute-participant/`, { - method: 'POST', - body: JSON.stringify({ - participant_identity: participant.identity, - track_sid: trackSid, - }), - }) - - await notifyParticipants({ - type: NotificationType.ParticipantMuted, - destinationIdentities: [participant.identity], - }) - + const response = fetchApi( + `rooms/${apiRoomData?.livekit?.room}/mute-participant/`, + { + method: 'POST', + headers, + body: JSON.stringify({ + participant_identity: participant.identity, + track_sid: trackSid, + }), + } + ) return response } catch (error) { console.error( `Failed to mute participant ${participant.identity}: ${error instanceof Error ? error.message : 'Unknown error'}` ) + return + } + + try { + await notifyParticipants({ + type: NotificationType.ParticipantMuted, + destinationIdentities: [participant.identity], + }) + } catch (e) { + console.error( + `Failed to notify muted participant ${participant.identity}: ${e}` + ) } } return { muteParticipant }