diff --git a/files/mod_token_moderator_owner.lua b/files/mod_token_moderator_owner.lua new file mode 100644 index 0000000..480482d --- /dev/null +++ b/files/mod_token_moderator_owner.lua @@ -0,0 +1,24 @@ +-- Promotes to owner (real moderator) if the JWT has context.user.moderator = true +local util = module:require "util" +local is_admin = util.is_admin +local is_healthcheck_room = util.is_healthcheck_room + +-- When a participant enters the room: +module:hook('muc-occupant-joined', function (event) + local room, occupant, session = event.room, event.occupant, event.origin + + -- Ignores focus/healthcheck/etc. + if is_healthcheck_room(room.jid) or is_admin(occupant.bare_jid) then + return + end + + -- Requires moderator token and claim (accepts boolean or string "true") + local user = session and session.jitsi_meet_context_user + local has_token = session and session.auth_token + local wants_mod = user and (user.moderator == true or user.moderator == "true") + + if has_token and wants_mod then + -- Assign owner affiliation -> Jicofo will see you as moderator + room:set_affiliation(true, occupant.bare_jid, 'owner') + end +end, 1) diff --git a/mode/jwt.sh b/mode/jwt.sh index 3c6a345..20a1e98 100644 --- a/mode/jwt.sh +++ b/mode/jwt.sh @@ -64,7 +64,8 @@ sed -i "$SRP_STR,$SRP_END{s|authentication = \"jitsi-anonymous\"|authentication sed -i "s|--app_id=\"example_app_id\"|app_id=\"$APP_ID\"|" "$PROSODY_FILE" sed -i "s|--app_secret=\"example_app_secret\"|app_secret=\"$SECRET_APP\"|" "$PROSODY_FILE" sed -i "/app_secret/a \\\\" "$PROSODY_FILE" -## Only token owners can create, open the room and become moderators: allow_empty_token = false +## Only token owners can create, open the room and become moderators, +## but require jibri: `allow_empty_token = true` ## other participants are redirected authentication to guest. sed -i "/app_secret/a \ \ \ \ allow_empty_token = true" "$PROSODY_FILE" sed -i "/app_secret/a \\\\" "$PROSODY_FILE" @@ -79,12 +80,32 @@ sed -i "/token_verification/a \ \ \ \ \ \ \ \ \"muc_wait_for_host\";" "$PROSODY_ # Set JWT and Guest settings ## Harden JWT auth, preventing "free" moderator by racing into room, ## only participants with token with moderator:true. -sed -i '1ijicofo.conference.enable-auto-owner = false' "$JICOFO_CONF" +# Custom 'token_moderator_owner' module for passing JWT claim +cp files/mod_token_moderator_owner.lua /usr/share/jitsi-meet/prosody-plugins/ +sed -i '/"muc_password_whitelist"/a \ \ \ \ \ \ \ \ \"token_moderator_owner";' "$PROSODY_FILE" +envsubst < \ + patches/prosody/001-enable_wait_for_host_disable_auto_owners.patch | \ + patch --no-backup-if-mismatch -d / -p1 +hocon set jicofo.conference.enable-auto-owner false -f "$JICOFO_CONF" + ## config.js sed -i "s|// anonymousdomain: 'guest.example.com'|anonymousdomain: \'guest.$DOMAIN\'|" "$MEET_CONF" +awk ' + BEGIN{done=0} + /^[[:space:]]*var[[:space:]]+config[[:space:]]*=[[:space:]]*{\s*$/ && !done{ + print + print " enableFeaturesBasedOnToken: true," + print " enableUserRolesBasedOnToken: true," + done=1 + next + } + {print} +' "$MEET_CONF" > "${MEET_CONF}.new" && mv "${MEET_CONF}.new" "$MEET_CONF" # Setup guests and lobby cat << P_SR >> "$PROSODY_FILE" + +-- jwt setup -QJI VirtualHost "guest.$DOMAIN" authentication = "anonymous" c2s_require_encryption = false @@ -104,8 +125,9 @@ echo -e "You can test JWT authentication with the following token for the next 2 python3 tools/jwt/jitsi_token_maker_features.py \ --app-id "$APP_ID" --secret "$SECRET_APP" \ --domain "$DOMAIN" --room "$ROOM" \ + --username "Moderator Token Test User" --moderator --features-all \ --minutes 120 --nbf-offset 300 --include-iat \ - --url "https://$DOMAIN/" <<<"$APP_SECRET" + --url "https://$DOMAIN/" read -n 1 -s -r -p $'\n'"Press any key to continue..."$'\n' diff --git a/patches/prosody/001-enable_wait_for_host_disable_auto_owners.patch b/patches/prosody/001-enable_wait_for_host_disable_auto_owners.patch new file mode 100644 index 0000000..9127afe --- /dev/null +++ b/patches/prosody/001-enable_wait_for_host_disable_auto_owners.patch @@ -0,0 +1,18 @@ +# Quick Jibri Installer - *buntu (LTS) based systems. +# SwITNet Ltd © - 2025, https://switnet.net/ +# GPLv3 or later. + +Patch prosody (0.12) $DOMAIN.cfg.lua to enable wait_for_host_disable_auto_owners. + +diff --git a/etc/prosody/conf.d/${DOMAIN}.cfg.lua b/etc/prosody/conf.d/${DOMAIN}.cfg.lua +index f2b647e..031a064 100644 +--- a/etc/prosody/conf.d/${DOMAIN}.cfg.lua ++++ b/etc/prosody/conf.d/${DOMAIN}.cfg.lua +@@ -103,6 +103,7 @@ Component "conference.${DOMAIN}" "muc" + } + muc_room_locking = false + muc_room_default_public_jids = true ++ wait_for_host_disable_auto_owners = true + + Component "breakout.${DOMAIN}" "muc" + restrict_room_creation = true