From 01a731ab4d80ba8a4a5232ed127942cb2c66384a Mon Sep 17 00:00:00 2001 From: Robert Oanta <109954554+roanta2@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:03:26 +0200 Subject: [PATCH] feat(prosody): extend jigasi kick endpoint to work for any participant (#15387) * feat(prosody): extend jigasi kick endpoint to work for any participant * apply review * squash: Fix UI when there is no actor of the kick. --------- Co-authored-by: damencho --- lang/main.json | 1 + react/features/conference/actions.native.ts | 6 ++--- react/features/conference/middleware.web.ts | 11 ++++++--- react/features/external-api/middleware.ts | 4 ++-- ...igasi.lua => mod_muc_kick_participant.lua} | 23 +++++++++++++++---- 5 files changed, 32 insertions(+), 13 deletions(-) rename resources/prosody-plugins/{mod_muc_kick_jigasi.lua => mod_muc_kick_participant.lua} (85%) diff --git a/lang/main.json b/lang/main.json index 98ee70b5ed69..b98bd979518f 100644 --- a/lang/main.json +++ b/lang/main.json @@ -334,6 +334,7 @@ "kickParticipantButton": "Kick", "kickParticipantDialog": "Are you sure you want to kick this participant?", "kickParticipantTitle": "Kick this participant?", + "kickSystemTitle": "Ouch! You were kicked out of the meeting", "kickTitle": "Ouch! {{participantDisplayName}} kicked you out of the meeting", "linkMeeting": "Link meeting", "linkMeetingTitle": "Link meeting to Salesforce", diff --git a/react/features/conference/actions.native.ts b/react/features/conference/actions.native.ts index 49d9701a9fe9..d6cc316cdaa2 100644 --- a/react/features/conference/actions.native.ts +++ b/react/features/conference/actions.native.ts @@ -16,7 +16,7 @@ import { DISMISS_CALENDAR_NOTIFICATION } from './actionTypes'; */ export function notifyKickedOut(participant: any, submit?: Function) { return (dispatch: IStore['dispatch'], getState: IStore['getState']) => { - if (!participant || participant?.isReplaced?.()) { + if (participant?.isReplaced?.()) { submit?.(); return; @@ -24,9 +24,9 @@ export function notifyKickedOut(participant: any, submit?: Function) { dispatch(openDialog(AlertDialog, { contentKey: { - key: 'dialog.kickTitle', + key: participant ? 'dialog.kickTitle' : 'dialog.kickSystemTitle', params: { - participantDisplayName: getParticipantDisplayName(getState, participant.getId()) + participantDisplayName: participant && getParticipantDisplayName(getState, participant.getId()) } }, onSubmit: submit diff --git a/react/features/conference/middleware.web.ts b/react/features/conference/middleware.web.ts index ec517725aa86..1a6e06ce9d2a 100644 --- a/react/features/conference/middleware.web.ts +++ b/react/features/conference/middleware.web.ts @@ -27,12 +27,17 @@ MiddlewareRegistry.register(store => next => action => { const { dispatch } = store; const { participant } = action; + // we need to first finish dispatching or the notification can be cleared out + const result = next(action); + const participantDisplayName - = getParticipantDisplayName(store.getState, participant.getId()); + = participant && getParticipantDisplayName(store.getState, participant.getId()); - dispatch(hangup(true, i18next.t('dialog.kickTitle', { participantDisplayName }))); + dispatch(hangup(true, + participantDisplayName ? i18next.t('dialog.kickTitle', { participantDisplayName }) + : i18next.t('dialog.kickSystemTitle'))); - break; + return result; } } diff --git a/react/features/external-api/middleware.ts b/react/features/external-api/middleware.ts index 25c7efa8ab74..039509f96345 100644 --- a/react/features/external-api/middleware.ts +++ b/react/features/external-api/middleware.ts @@ -153,8 +153,8 @@ MiddlewareRegistry.register(store => next => action => { local: true }, { - id: actor.getId(), - name: actor.getDisplayName() + id: actor?.getId(), + name: actor?.getDisplayName() } ); break; diff --git a/resources/prosody-plugins/mod_muc_kick_jigasi.lua b/resources/prosody-plugins/mod_muc_kick_participant.lua similarity index 85% rename from resources/prosody-plugins/mod_muc_kick_jigasi.lua rename to resources/prosody-plugins/mod_muc_kick_participant.lua index 735ea0f91d7f..11b0bbbb32d3 100644 --- a/resources/prosody-plugins/mod_muc_kick_jigasi.lua +++ b/resources/prosody-plugins/mod_muc_kick_participant.lua @@ -115,9 +115,10 @@ function handle_kick_participant (event) end local number = params["number"]; + local participantId = params["participantId"]; - if not number then - module:log("warn", "Missing number param"); + if (not number and not participantId) or (number and participantId) then + module:log("warn", "Invalid parameters: exactly one of 'number' or 'participantId' must be provided."); return { status_code = 400; }; end @@ -134,10 +135,8 @@ function handle_kick_participant (event) for _, occupant in room:each_occupant() do local pr = occupant:get_presence(); - local displayName = pr:get_child_text( - 'nick', 'http://jabber.org/protocol/nick'); - if is_sip_jigasi(pr) and displayName and starts_with(displayName, number) then + if is_participant_match(pr, number, participantId) then room:set_role(true, occupant.nick, nil); module:log('info', 'Occupant kicked %s from %s', occupant.nick, room.jid); return { status_code = 200; } @@ -148,6 +147,20 @@ function handle_kick_participant (event) return { status_code = 404; }; end +function is_participant_match(pr, number, participantId) + if number then + local displayName = pr:get_child_text('nick', 'http://jabber.org/protocol/nick'); + return is_sip_jigasi(pr) and displayName and starts_with(displayName, number); + elseif participantId then + local from = pr.attr.from; + local _, _, from_resource = jid.split(from); + if from_resource then + return from_resource == participantId; + end + end + return false; +end + module:log("info","Adding http handler for /kick-participant on %s", module.host); module:depends("http"); module:provides("http", {