diff --git a/app/assets/javascripts/room.js b/app/assets/javascripts/room.js index d5861d8f..d953f613 100644 --- a/app/assets/javascripts/room.js +++ b/app/assets/javascripts/room.js @@ -184,17 +184,19 @@ function copyInvite() { } } -function copyAccess() { - $('#copy-code').attr("type", "text") - $('#copy-code').select() +function copyAccess(target) { + input = target ? $("#copy-" + target + "-code") : $("#copy-code") + input.attr("type", "text") + input.select() if (document.execCommand("copy")) { - $('#copy-code').attr("type", "hidden") - copy = $("#copy-access") + input.attr("type", "hidden") + copy = target ? $("#copy-" + target + "-access") : $("#copy-access") copy.addClass('btn-success'); copy.html("" + getLocalizedString("copied")) setTimeout(function(){ copy.removeClass('btn-success'); - copy.html("" + getLocalizedString("room.copy_access")) + originalString = target ? getLocalizedString("room.copy_" + target + "_access") : getLocalizedString("room.copy_access") + copy.html("" + originalString) }, 1000) } } @@ -202,7 +204,9 @@ function copyAccess() { function showCreateRoom(target) { $("#create-room-name").val("") $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder")) + $("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code_placeholder")) $("#room_access_code").val(null) + $("#room_moderator_access_code").val(null) $("#createRoomModal form").attr("action", $("body").data('relative-root')) $("#room_mute_on_join").prop("checked", $("#room_mute_on_join").data("default")) @@ -254,6 +258,16 @@ function showUpdateRoom(target) { $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder")) $("#room_access_code").val(null) } + + var moderatorAccessCode = modal.closest(".room-block").data("room-moderator-access-code") + + if(moderatorAccessCode){ + $("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code") + ": " + moderatorAccessCode) + $("#room_moderator_access_code").val(moderatorAccessCode) + } else { + $("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code_placeholder")) + $("#room_moderator_access_code").val(null) + } } function showDeleteRoom(target) { @@ -291,6 +305,24 @@ function ResetAccessCode(){ $("#room_access_code").val(null) } +function generateModeratorAccessCode(){ + const accessCodeLength = 6 + var validCharacters = "abcdefghijklmopqrstuvwxyz" + var accessCode = "" + + for( var i = 0; i < accessCodeLength; i++){ + accessCode += validCharacters.charAt(Math.floor(Math.random() * validCharacters.length)); + } + + $("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code") + ": " + accessCode) + $("#room_moderator_access_code").val(accessCode) +} + +function ResetModeratorAccessCode(){ + $("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code_placeholder")) + $("#room_moderator_access_code").val(null) +} + function saveAccessChanges() { let listItemsToAdd = $("#user-list li:not(.remove-shared)").toArray().map(user => $(user).data("uid")) diff --git a/app/assets/stylesheets/rooms.scss b/app/assets/stylesheets/rooms.scss index 26709952..573ec5c4 100644 --- a/app/assets/stylesheets/rooms.scss +++ b/app/assets/stylesheets/rooms.scss @@ -32,8 +32,8 @@ font-size: 20px !important; } -.join-input { - height: 48px; +.moderator-code-label { + margin-top: 150px !important; } .home-indicator { diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d58f5d8d..75ac36f0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -186,6 +186,12 @@ class ApplicationController < ActionController::Base end helper_method :recording_consent_required? + # Indicates whether users are allowed to add moderator access codes to rooms + def moderator_code_allowed? + @settings.get_value("Moderator Access Codes") == "true" + end + helper_method :moderator_code_allowed? + # Returns a list of allowed file types def allowed_file_types Rails.configuration.allowed_file_types diff --git a/app/controllers/concerns/joiner.rb b/app/controllers/concerns/joiner.rb index 96958c05..6c6b016e 100644 --- a/app/controllers/concerns/joiner.rb +++ b/app/controllers/concerns/joiner.rb @@ -50,10 +50,11 @@ module Joiner def join_room(opts) @room_settings = JSON.parse(@room[:room_settings]) - if room_running?(@room.bbb_id) || @room.owned_by?(current_user) || room_setting_with_config("anyoneCanStart") + moderator_privileges = @room.owned_by?(current_user) || valid_moderator_access_code(session[:moderator_access_code]) + if room_running?(@room.bbb_id) || room_setting_with_config("anyoneCanStart") || moderator_privileges # Determine if the user needs to join as a moderator. - opts[:user_is_moderator] = @room.owned_by?(current_user) || room_setting_with_config("joinModerator") || @shared_room + opts[:user_is_moderator] = room_setting_with_config("joinModerator") || @shared_room || moderator_privileges opts[:record] = record_meeting opts[:require_moderator_approval] = room_setting_with_config("requireModeratorApproval") opts[:mute_on_start] = room_setting_with_config("muteOnStart") diff --git a/app/controllers/rooms_controller.rb b/app/controllers/rooms_controller.rb index cc06e4a5..2de6aac6 100644 --- a/app/controllers/rooms_controller.rb +++ b/app/controllers/rooms_controller.rb @@ -44,7 +44,9 @@ class RoomsController < ApplicationController return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded # Create room - @room = Room.new(name: room_params[:name], access_code: room_params[:access_code]) + @room = Room.new(name: room_params[:name], + access_code: room_params[:access_code], + moderator_access_code: room_params[:moderator_access_code]) @room.owner = current_user @room.room_settings = create_room_settings_string(room_params) @@ -109,8 +111,9 @@ class RoomsController < ApplicationController @shared_room = room_shared_with_user unless @room.owned_by?(current_user) || @shared_room - # Don't allow users to join unless they have a valid access code or the room doesn't have an access code - if @room.access_code && !@room.access_code.empty? && @room.access_code != session[:access_code] + # Don't allow users to join unless they have a valid access code or the room doesn't have an access codes + valid_access_code = !@room.access_code.present? || @room.access_code == session[:access_code] + if !valid_access_code && !valid_moderator_access_code(session[:moderator_access_code]) return redirect_to room_path(room_uid: params[:room_uid]), flash: { alert: I18n.t("room.access_code_required") } end @@ -203,7 +206,8 @@ class RoomsController < ApplicationController @room.update_attributes( name: options[:name], room_settings: room_settings_string, - access_code: options[:access_code] + access_code: options[:access_code], + moderator_access_code: options[:moderator_access_code] ) flash[:success] = I18n.t("room.update_settings_success") @@ -321,9 +325,16 @@ class RoomsController < ApplicationController # POST /:room_uid/login def login - session[:access_code] = room_params[:access_code] + # use same form for access_code and moderator_access_code + if valid_moderator_access_code(room_params[:access_code]) + session[:moderator_access_code] = room_params[:access_code] + else + session[:access_code] = room_params[:access_code] + end - flash[:alert] = I18n.t("room.access_code_required") if session[:access_code] != @room.access_code + if session[:access_code] != @room.access_code && !valid_moderator_access_code(session[:moderator_access_code]) + flash[:alert] = I18n.t("room.access_code_required") + end redirect_to room_path(@room.uid) end @@ -345,7 +356,7 @@ class RoomsController < ApplicationController def room_params params.require(:room).permit(:name, :auto_join, :mute_on_join, :access_code, :require_moderator_approval, :anyone_can_start, :all_join_moderator, - :recording, :presentation) + :recording, :presentation, :moderator_access_code) end # Find the room from the uid. @@ -412,6 +423,11 @@ class RoomsController < ApplicationController end helper_method :room_limit_exceeded + def valid_moderator_access_code(code) + code == @room.moderator_access_code && !@room.moderator_access_code.blank? && moderator_code_allowed? + end + helper_method :valid_moderator_access_code + def record_meeting # If the require consent setting is checked, then check the room setting, else, set to true if recording_consent_required? diff --git a/app/helpers/admins_helper.rb b/app/helpers/admins_helper.rb index 91f3a2e7..f21f877b 100644 --- a/app/helpers/admins_helper.rb +++ b/app/helpers/admins_helper.rb @@ -89,6 +89,14 @@ module AdminsHelper end end + def moderator_codes_string + if @settings.get_value("Moderator Access Codes") == "true" + I18n.t("administrator.site_settings.moderator_codes.enabled") + else + I18n.t("administrator.site_settings.moderator_codes.disabled") + end + end + def log_level_string case Rails.logger.level when 0 diff --git a/app/models/setting.rb b/app/models/setting.rb index 1ee18192..27cff084 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -66,6 +66,8 @@ class Setting < ApplicationRecord Rails.configuration.shared_access_default when "Preupload Presentation" Rails.configuration.preupload_presentation_default + when "Moderator Access Codes" + Rails.configuration.moderator_codes_default when "Room Configuration Mute On Join" room_config_setting("mute-on-join") when "Room Configuration Require Moderator" diff --git a/app/views/admins/components/site_settings/_settings.html.erb b/app/views/admins/components/site_settings/_settings.html.erb index 464d3088..fa4cf6eb 100644 --- a/app/views/admins/components/site_settings/_settings.html.erb +++ b/app/views/admins/components/site_settings/_settings.html.erb @@ -143,6 +143,27 @@ +