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 @@ +
+
+
+ + + +
+
+
diff --git a/app/views/rooms/components/_enter_access_code_form.html.erb b/app/views/rooms/components/_enter_access_code_form.html.erb new file mode 100644 index 00000000..4f1beddd --- /dev/null +++ b/app/views/rooms/components/_enter_access_code_form.html.erb @@ -0,0 +1,29 @@ +<% +# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/. +# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). +# This program is free software; you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free Software +# Foundation; either version 3.0 of the License, or (at your option) any later +# version. +# +# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public License along +# with BigBlueButton; if not, see . +%> + +<%= form_for :room, url: login_room_path(@room.uid) do |f| %> +
+ <%= f.text_field :access_code, + required: true, + class: "form-control join-form", + placeholder: access_code_type == 'moderator' ? t("room.enter_the_moderator_access_code") : t("room.enter_the_access_code"), + value: "" , + autofocus: true, + maxlength: 26 %> + + <%= f.button t("room.login"), type: :submit, class: "btn btn-primary btn-sm px-7 form-control join-form" %> + +
+<% end %> diff --git a/app/views/rooms/components/_room_block.html.erb b/app/views/rooms/components/_room_block.html.erb index 4b57db74..d2a9baf2 100644 --- a/app/views/rooms/components/_room_block.html.erb +++ b/app/views/rooms/components/_room_block.html.erb @@ -13,7 +13,7 @@ # with BigBlueButton; if not, see . %> -
+
diff --git a/app/views/rooms/join.html.erb b/app/views/rooms/join.html.erb index cac7a022..f38f9e4d 100644 --- a/app/views/rooms/join.html.erb +++ b/app/views/rooms/join.html.erb @@ -15,23 +15,15 @@ <% content_for(:page_desc) { t("room.invitation_description", name: @room.name) } %> -<% valid_access_code = @room.access_code.nil? || @room.access_code.empty? || @room.access_code == session[:access_code] %> -<%= render 'rooms/components/room_event', render_recordings: valid_access_code do %> +<% access_code_set = @room.access_code.present? %> +<% valid_access_code = access_code_set && @room.access_code == session[:access_code] %> +<% moderator_access_code_set = @room.moderator_access_code.present? && moderator_code_allowed? %> +<% valid_moderator_access_code = valid_moderator_access_code(session[:moderator_access_code]) %> + +<%= render 'rooms/components/room_event', render_recordings: valid_access_code || valid_moderator_access_code do %> <% if room_authentication_required %>

<%= t("administrator.site_settings.authentication.user-info") %>

- <% elsif !valid_access_code %> - <%= form_for :room, url: login_room_path(@room.uid) do |f| %> -
- <%= f.text_field :access_code, - required: true, - class: "form-control join-form", - placeholder: t("room.enter_the_access_code"), - value: "" , - autofocus: true %> - <%= f.submit t("room.login"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %> -
- <% end %> - <% else %> + <% elsif valid_moderator_access_code || valid_access_code || !access_code_set %> <%= form_for room_path(@room), method: :post do |f| %>
<%= f.hidden_field(:search, :value => params[:search])%> @@ -59,5 +51,12 @@ <% end %> <% end %> + <% if moderator_access_code_set && !valid_moderator_access_code %> + + + <%= render "rooms/components/enter_access_code_form", access_code_type: 'moderator' %> + <% end %> + <% else %> + <%= render "rooms/components/enter_access_code_form", access_code_type: 'standard_access' %> <% end %> <% end %> diff --git a/app/views/rooms/show.html.erb b/app/views/rooms/show.html.erb index 3feb5219..ab190452 100644 --- a/app/views/rooms/show.html.erb +++ b/app/views/rooms/show.html.erb @@ -1,140 +1,147 @@ -<% -# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/. -# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). -# This program is free software; you can redistribute it and/or modify it under the -# terms of the GNU Lesser General Public License as published by the Free Software -# Foundation; either version 3.0 of the License, or (at your option) any later -# version. -# -# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -# You should have received a copy of the GNU Lesser General Public License along -# with BigBlueButton; if not, see . -%> - -<% exceeds_limit = current_room_exceeds_limit(@room)%> -<% if exceeds_limit%> -
- <%= t("room.room_limit_exceeded", difference: @diff) %> -
-<% end %> -
-
-
-
-
-

<%= title(@room.name) %>

- <% if current_user.main_room == @room %> - - <% else %> - - <% end %> -
-

<%= @room.sessions %> <%= t("room.sessions") %><% unless hide_recording_tables %> | <%= @recordings.length %> <%= t("room.recordings") %><% end %>

- <% unless exceeds_limit %> - -
-
- -
-
-
-
- -
-
- <% if @room.access_code.present? %> - - - <% end %> - <% if Rails.configuration.enable_google_calendar_button %> - - - <%= t("add_to_google_calendar") %> - - <% end %> -
-
-
-
- <% end %> -
-
- <% if @room_running %> - <%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right", "data-disable": "" %> - <% else %> - <% unless exceeds_limit %> - <%= button_to t("room.start"), start_room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right", "data-disable": "" %> - <% end %> - <% end %> -
-
- - <% if total_room_count(current_user) > 5 %> - - <% end %> - -
- <% if current_user.role.get_permission("can_create_rooms") %> - <% current_user.ordered_rooms.each do |room| %> -
- <%= link_to room do %> - <%= render "rooms/components/room_block", room: room %> - <% end %> -
- <% end %> - <% end %> - - <% if shared_access_allowed %> - <% current_user.shared_rooms.each do |room| %> -
- <%= link_to room do %> - <%= render "rooms/components/shared_room_block", room: room %> - <% end %> -
- <% end %> - <% end %> - - <% if current_user.role.get_permission("can_create_rooms") && !room_limit_exceeded %> - <%= render "rooms/components/create_room_block"%> - <% end %> -
-
-
- -<% unless hide_recording_tables %> - <%= render "shared/sessions", recordings: @recordings, pagy: @pagy, only_public: false, shared_room: @shared_room, user_recordings: false, title: t("room.recordings")%> -<% end %> - -<%= render "shared/modals/delete_room_modal" %> - -<%= render "shared/modals/create_room_modal" %> - -<% if preupload_allowed? %> - <%= render "shared/modals/preupload_presentation_modal" %> -<% end %> - -<% if shared_access_allowed %> - <%= render "shared/modals/share_room_modal" %> - <%= render "shared/modals/remove_access_modal" %> -<% end %> +<% +# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/. +# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). +# This program is free software; you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free Software +# Foundation; either version 3.0 of the License, or (at your option) any later +# version. +# +# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public License along +# with BigBlueButton; if not, see . +%> + +<% exceeds_limit = current_room_exceeds_limit(@room)%> +<% if exceeds_limit%> +
+ <%= t("room.room_limit_exceeded", difference: @diff) %> +
+<% end %> +
+
+
+
+
+

<%= title(@room.name) %>

+ <% if current_user.main_room == @room %> + + <% else %> + + <% end %> +
+

<%= @room.sessions %> <%= t("room.sessions") %><% unless hide_recording_tables %> | <%= @recordings.length %> <%= t("room.recordings") %><% end %>

+ <% unless exceeds_limit %> + +
+
+ +
+
+
+
+ +
+
+ <% if @room.access_code.present? %> + + + <% end %> + <% if moderator_code_allowed? && @room.moderator_access_code.present? %> + + + <% end %> + <% if Rails.configuration.enable_google_calendar_button %> + + + <%= t("add_to_google_calendar") %> + + <% end %> +
+
+
+
+ <% end %> +
+
+ <% if @room_running %> + <%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right", "data-disable": "" %> + <% else %> + <% unless exceeds_limit %> + <%= button_to t("room.start"), start_room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right", "data-disable": "" %> + <% end %> + <% end %> +
+
+ + <% if total_room_count(current_user) > 5 %> + + <% end %> + +
+ <% if current_user.role.get_permission("can_create_rooms") %> + <% current_user.ordered_rooms.each do |room| %> +
+ <%= link_to room do %> + <%= render "rooms/components/room_block", room: room %> + <% end %> +
+ <% end %> + <% end %> + + <% if shared_access_allowed %> + <% current_user.shared_rooms.each do |room| %> +
+ <%= link_to room do %> + <%= render "rooms/components/shared_room_block", room: room %> + <% end %> +
+ <% end %> + <% end %> + + <% if current_user.role.get_permission("can_create_rooms") && !room_limit_exceeded %> + <%= render "rooms/components/create_room_block"%> + <% end %> +
+
+
+ +<% unless hide_recording_tables %> + <%= render "shared/sessions", recordings: @recordings, pagy: @pagy, only_public: false, shared_room: @shared_room, user_recordings: false, title: t("room.recordings")%> +<% end %> + +<%= render "shared/modals/delete_room_modal" %> + +<%= render "shared/modals/create_room_modal" %> + +<% if preupload_allowed? %> + <%= render "shared/modals/preupload_presentation_modal" %> +<% end %> + +<% if shared_access_allowed %> + <%= render "shared/modals/share_room_modal" %> + <%= render "shared/modals/remove_access_modal" %> +<% end %> diff --git a/app/views/shared/modals/_create_room_modal.html.erb b/app/views/shared/modals/_create_room_modal.html.erb index cab6f6b4..e85d9ecb 100644 --- a/app/views/shared/modals/_create_room_modal.html.erb +++ b/app/views/shared/modals/_create_room_modal.html.erb @@ -43,6 +43,19 @@
+ <% if moderator_code_allowed? %> +
+ + + + <%= f.label :moderator_access_code, t("modal.create_room.moderator_access_code_placeholder"), id: "create-room-moderator-access-code", class: "form-control" %> + <%= f.hidden_field :moderator_access_code %> + + + +
+ <% end %> + <% mute = room_configuration("Room Configuration Mute On Join") %> <% if mute != "disabled" %>