forked from External/greenlight
		
	Merge branch 'v2.2.1-alpha' into master
This commit is contained in:
		
							
								
								
									
										15
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,7 +1,14 @@
 | 
				
			|||||||
FROM ruby:2.5
 | 
					FROM ruby:2.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Install app dependencies.
 | 
					# Install app dependencies.
 | 
				
			||||||
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
 | 
					RUN apt-get update -qq && apt-get install -y build-essential libpq-dev curl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ADD https://dl.yarnpkg.com/debian/pubkey.gpg /tmp/yarn-pubkey.gpg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-key add /tmp/yarn-pubkey.gpg && rm /tmp/yarn-pubkey.gpg && \
 | 
				
			||||||
 | 
					echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list &&  \
 | 
				
			||||||
 | 
					curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
 | 
				
			||||||
 | 
					apt-get update && apt-get install -y nodejs yarn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Set an environment variable for the install location.
 | 
					# Set an environment variable for the install location.
 | 
				
			||||||
ENV RAILS_ROOT /usr/src/app
 | 
					ENV RAILS_ROOT /usr/src/app
 | 
				
			||||||
@@ -23,9 +30,9 @@ RUN bundle install --without development test --deployment --clean
 | 
				
			|||||||
# Adding project files.
 | 
					# Adding project files.
 | 
				
			||||||
COPY . .
 | 
					COPY . .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Precompile assets.
 | 
					# Precompile assets
 | 
				
			||||||
RUN bundle exec rake assets:clean
 | 
					RUN SECRET_KEY_BASE="$(bundle exec rake secret)" bundle exec rake assets:clean
 | 
				
			||||||
RUN bundle exec rake assets:precompile
 | 
					RUN SECRET_KEY_BASE="$(bundle exec rake secret)" bundle exec rake assets:precompile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Expose port 80.
 | 
					# Expose port 80.
 | 
				
			||||||
EXPOSE 80
 | 
					EXPOSE 80
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Gemfile
									
									
									
									
									
								
							@@ -8,13 +8,13 @@ git_source(:github) do |repo_name|
 | 
				
			|||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
 | 
					# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
 | 
				
			||||||
gem 'rails', '~> 5.0.7'
 | 
					gem 'rails', '~> 5.2.3'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Use Puma as the app server
 | 
					# Use Puma as the app server
 | 
				
			||||||
gem 'puma', '~> 3.0'
 | 
					gem 'puma', '~> 3.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Use SCSS for stylesheets
 | 
					# Use SCSS for stylesheets
 | 
				
			||||||
gem 'sass-rails', '~> 5.0'
 | 
					gem 'sassc-rails'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Use Uglifier as compressor for JavaScript assets
 | 
					# Use Uglifier as compressor for JavaScript assets
 | 
				
			||||||
gem 'uglifier', '>= 1.3.0'
 | 
					gem 'uglifier', '>= 1.3.0'
 | 
				
			||||||
@@ -35,11 +35,14 @@ gem 'turbolinks', '~> 5'
 | 
				
			|||||||
gem 'jbuilder', '~> 2.5'
 | 
					gem 'jbuilder', '~> 2.5'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Use Redis adapter to run Action Cable in production
 | 
					# Use Redis adapter to run Action Cable in production
 | 
				
			||||||
gem 'redis', '~> 3.0'
 | 
					# gem 'redis', '~> 3.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Use ActiveModel has_secure_password
 | 
					# Use ActiveModel has_secure_password
 | 
				
			||||||
gem 'bcrypt', '~> 3.1.7'
 | 
					gem 'bcrypt', '~> 3.1.7'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Reduces boot times through caching; required in config/boot.rb
 | 
				
			||||||
 | 
					gem 'bootsnap', '>= 1.1.0', require: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Authentication.
 | 
					# Authentication.
 | 
				
			||||||
gem 'omniauth'
 | 
					gem 'omniauth'
 | 
				
			||||||
gem 'omniauth-twitter'
 | 
					gem 'omniauth-twitter'
 | 
				
			||||||
@@ -54,7 +57,7 @@ gem 'bigbluebutton-api-ruby'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Front-end.
 | 
					# Front-end.
 | 
				
			||||||
gem 'bootstrap', '~> 4.3.1'
 | 
					gem 'bootstrap', '~> 4.3.1'
 | 
				
			||||||
gem 'tabler-rubygem'
 | 
					gem 'tabler-rubygem', git: 'https://github.com/vbalazs/tabler-rubygem.git', branch: 'fix-sass'
 | 
				
			||||||
gem 'pagy'
 | 
					gem 'pagy'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# For detecting the users preferred language.
 | 
					# For detecting the users preferred language.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										190
									
								
								Gemfile.lock
									
									
									
									
									
								
							
							
						
						
									
										190
									
								
								Gemfile.lock
									
									
									
									
									
								
							@@ -23,58 +23,73 @@ GIT
 | 
				
			|||||||
      omniauth (>= 1.3.2)
 | 
					      omniauth (>= 1.3.2)
 | 
				
			||||||
      omniauth-oauth2 (>= 1.5.0)
 | 
					      omniauth-oauth2 (>= 1.5.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GIT
 | 
				
			||||||
 | 
					  remote: https://github.com/vbalazs/tabler-rubygem.git
 | 
				
			||||||
 | 
					  revision: 1360795a174f6e6317eb6c81461597ddc965c2ce
 | 
				
			||||||
 | 
					  branch: fix-sass
 | 
				
			||||||
 | 
					  specs:
 | 
				
			||||||
 | 
					    tabler-rubygem (0.1.4)
 | 
				
			||||||
 | 
					      autoprefixer-rails (>= 6.0.3)
 | 
				
			||||||
 | 
					      bootstrap (~> 4.3.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEM
 | 
					GEM
 | 
				
			||||||
  remote: https://rubygems.org/
 | 
					  remote: https://rubygems.org/
 | 
				
			||||||
  specs:
 | 
					  specs:
 | 
				
			||||||
    action-cable-testing (0.5.0)
 | 
					    action-cable-testing (0.5.0)
 | 
				
			||||||
      actioncable (>= 5.0)
 | 
					      actioncable (>= 5.0)
 | 
				
			||||||
    actioncable (5.0.7.2)
 | 
					    actioncable (5.2.3)
 | 
				
			||||||
      actionpack (= 5.0.7.2)
 | 
					      actionpack (= 5.2.3)
 | 
				
			||||||
      nio4r (>= 1.2, < 3.0)
 | 
					      nio4r (~> 2.0)
 | 
				
			||||||
      websocket-driver (~> 0.6.1)
 | 
					      websocket-driver (>= 0.6.1)
 | 
				
			||||||
    actionmailer (5.0.7.2)
 | 
					    actionmailer (5.2.3)
 | 
				
			||||||
      actionpack (= 5.0.7.2)
 | 
					      actionpack (= 5.2.3)
 | 
				
			||||||
      actionview (= 5.0.7.2)
 | 
					      actionview (= 5.2.3)
 | 
				
			||||||
      activejob (= 5.0.7.2)
 | 
					      activejob (= 5.2.3)
 | 
				
			||||||
      mail (~> 2.5, >= 2.5.4)
 | 
					      mail (~> 2.5, >= 2.5.4)
 | 
				
			||||||
      rails-dom-testing (~> 2.0)
 | 
					      rails-dom-testing (~> 2.0)
 | 
				
			||||||
    actionpack (5.0.7.2)
 | 
					    actionpack (5.2.3)
 | 
				
			||||||
      actionview (= 5.0.7.2)
 | 
					      actionview (= 5.2.3)
 | 
				
			||||||
      activesupport (= 5.0.7.2)
 | 
					      activesupport (= 5.2.3)
 | 
				
			||||||
      rack (~> 2.0)
 | 
					      rack (~> 2.0)
 | 
				
			||||||
      rack-test (~> 0.6.3)
 | 
					      rack-test (>= 0.6.3)
 | 
				
			||||||
      rails-dom-testing (~> 2.0)
 | 
					      rails-dom-testing (~> 2.0)
 | 
				
			||||||
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
 | 
					      rails-html-sanitizer (~> 1.0, >= 1.0.2)
 | 
				
			||||||
    actionview (5.0.7.2)
 | 
					    actionview (5.2.3)
 | 
				
			||||||
      activesupport (= 5.0.7.2)
 | 
					      activesupport (= 5.2.3)
 | 
				
			||||||
      builder (~> 3.1)
 | 
					      builder (~> 3.1)
 | 
				
			||||||
      erubis (~> 2.7.0)
 | 
					      erubi (~> 1.4)
 | 
				
			||||||
      rails-dom-testing (~> 2.0)
 | 
					      rails-dom-testing (~> 2.0)
 | 
				
			||||||
      rails-html-sanitizer (~> 1.0, >= 1.0.3)
 | 
					      rails-html-sanitizer (~> 1.0, >= 1.0.3)
 | 
				
			||||||
    activejob (5.0.7.2)
 | 
					    activejob (5.2.3)
 | 
				
			||||||
      activesupport (= 5.0.7.2)
 | 
					      activesupport (= 5.2.3)
 | 
				
			||||||
      globalid (>= 0.3.6)
 | 
					      globalid (>= 0.3.6)
 | 
				
			||||||
    activemodel (5.0.7.2)
 | 
					    activemodel (5.2.3)
 | 
				
			||||||
      activesupport (= 5.0.7.2)
 | 
					      activesupport (= 5.2.3)
 | 
				
			||||||
    activerecord (5.0.7.2)
 | 
					    activerecord (5.2.3)
 | 
				
			||||||
      activemodel (= 5.0.7.2)
 | 
					      activemodel (= 5.2.3)
 | 
				
			||||||
      activesupport (= 5.0.7.2)
 | 
					      activesupport (= 5.2.3)
 | 
				
			||||||
      arel (~> 7.0)
 | 
					      arel (>= 9.0)
 | 
				
			||||||
    activesupport (5.0.7.2)
 | 
					    activestorage (5.2.3)
 | 
				
			||||||
 | 
					      actionpack (= 5.2.3)
 | 
				
			||||||
 | 
					      activerecord (= 5.2.3)
 | 
				
			||||||
 | 
					      marcel (~> 0.3.1)
 | 
				
			||||||
 | 
					    activesupport (5.2.3)
 | 
				
			||||||
      concurrent-ruby (~> 1.0, >= 1.0.2)
 | 
					      concurrent-ruby (~> 1.0, >= 1.0.2)
 | 
				
			||||||
      i18n (>= 0.7, < 2)
 | 
					      i18n (>= 0.7, < 2)
 | 
				
			||||||
      minitest (~> 5.1)
 | 
					      minitest (~> 5.1)
 | 
				
			||||||
      tzinfo (~> 1.1)
 | 
					      tzinfo (~> 1.1)
 | 
				
			||||||
    addressable (2.6.0)
 | 
					    addressable (2.6.0)
 | 
				
			||||||
      public_suffix (>= 2.0.2, < 4.0)
 | 
					      public_suffix (>= 2.0.2, < 4.0)
 | 
				
			||||||
    arel (7.1.4)
 | 
					    arel (9.0.0)
 | 
				
			||||||
    ast (2.4.0)
 | 
					    ast (2.4.0)
 | 
				
			||||||
    autoprefixer-rails (9.5.1.1)
 | 
					    autoprefixer-rails (9.6.1)
 | 
				
			||||||
      execjs
 | 
					      execjs
 | 
				
			||||||
    bcrypt (3.1.12)
 | 
					    bcrypt (3.1.13)
 | 
				
			||||||
    bigbluebutton-api-ruby (1.7.0)
 | 
					    bigbluebutton-api-ruby (1.7.0)
 | 
				
			||||||
      xml-simple (~> 1.1)
 | 
					      xml-simple (~> 1.1)
 | 
				
			||||||
    bindex (0.7.0)
 | 
					    bindex (0.8.1)
 | 
				
			||||||
 | 
					    bootsnap (1.4.4)
 | 
				
			||||||
 | 
					      msgpack (~> 1.0)
 | 
				
			||||||
    bootstrap (4.3.1)
 | 
					    bootstrap (4.3.1)
 | 
				
			||||||
      autoprefixer-rails (>= 9.1.0)
 | 
					      autoprefixer-rails (>= 9.1.0)
 | 
				
			||||||
      popper_js (>= 1.14.3, < 2)
 | 
					      popper_js (>= 1.14.3, < 2)
 | 
				
			||||||
@@ -100,26 +115,26 @@ GEM
 | 
				
			|||||||
      safe_yaml (~> 1.0.0)
 | 
					      safe_yaml (~> 1.0.0)
 | 
				
			||||||
    crass (1.0.4)
 | 
					    crass (1.0.4)
 | 
				
			||||||
    diff-lcs (1.3)
 | 
					    diff-lcs (1.3)
 | 
				
			||||||
    docile (1.3.1)
 | 
					    docile (1.3.2)
 | 
				
			||||||
    dotenv (2.7.2)
 | 
					    dotenv (2.7.4)
 | 
				
			||||||
    dotenv-rails (2.7.2)
 | 
					    dotenv-rails (2.7.4)
 | 
				
			||||||
      dotenv (= 2.7.2)
 | 
					      dotenv (= 2.7.4)
 | 
				
			||||||
      railties (>= 3.2, < 6.1)
 | 
					      railties (>= 3.2, < 6.1)
 | 
				
			||||||
    erubis (2.7.0)
 | 
					    erubi (1.8.0)
 | 
				
			||||||
    execjs (2.7.0)
 | 
					    execjs (2.7.0)
 | 
				
			||||||
    factory_bot (5.0.2)
 | 
					    factory_bot (5.0.2)
 | 
				
			||||||
      activesupport (>= 4.2.0)
 | 
					      activesupport (>= 4.2.0)
 | 
				
			||||||
    factory_bot_rails (5.0.2)
 | 
					    factory_bot_rails (5.0.2)
 | 
				
			||||||
      factory_bot (~> 5.0.2)
 | 
					      factory_bot (~> 5.0.2)
 | 
				
			||||||
      railties (>= 4.2.0)
 | 
					      railties (>= 4.2.0)
 | 
				
			||||||
    faker (1.9.3)
 | 
					    faker (1.9.6)
 | 
				
			||||||
      i18n (>= 0.7)
 | 
					      i18n (>= 0.7)
 | 
				
			||||||
    faraday (0.15.4)
 | 
					    faraday (0.15.4)
 | 
				
			||||||
      multipart-post (>= 1.2, < 3)
 | 
					      multipart-post (>= 1.2, < 3)
 | 
				
			||||||
    ffi (1.11.1)
 | 
					    ffi (1.11.1)
 | 
				
			||||||
    globalid (0.4.2)
 | 
					    globalid (0.4.2)
 | 
				
			||||||
      activesupport (>= 4.2.0)
 | 
					      activesupport (>= 4.2.0)
 | 
				
			||||||
    hashdiff (0.3.9)
 | 
					    hashdiff (0.4.0)
 | 
				
			||||||
    hashie (3.6.0)
 | 
					    hashie (3.6.0)
 | 
				
			||||||
    health_check (3.0.0)
 | 
					    health_check (3.0.0)
 | 
				
			||||||
      railties (>= 5.0)
 | 
					      railties (>= 5.0)
 | 
				
			||||||
@@ -127,15 +142,15 @@ GEM
 | 
				
			|||||||
    i18n (1.6.0)
 | 
					    i18n (1.6.0)
 | 
				
			||||||
      concurrent-ruby (~> 1.0)
 | 
					      concurrent-ruby (~> 1.0)
 | 
				
			||||||
    i18n-language-mapping (0.1.0)
 | 
					    i18n-language-mapping (0.1.0)
 | 
				
			||||||
    jaro_winkler (1.5.2)
 | 
					    jaro_winkler (1.5.3)
 | 
				
			||||||
    jbuilder (2.9.1)
 | 
					    jbuilder (2.9.1)
 | 
				
			||||||
      activesupport (>= 4.2.0)
 | 
					      activesupport (>= 4.2.0)
 | 
				
			||||||
    jquery-rails (4.3.3)
 | 
					    jquery-rails (4.3.5)
 | 
				
			||||||
      rails-dom-testing (>= 1, < 3)
 | 
					      rails-dom-testing (>= 1, < 3)
 | 
				
			||||||
      railties (>= 4.2.0)
 | 
					      railties (>= 4.2.0)
 | 
				
			||||||
      thor (>= 0.14, < 2.0)
 | 
					      thor (>= 0.14, < 2.0)
 | 
				
			||||||
    json (2.2.0)
 | 
					    json (2.2.0)
 | 
				
			||||||
    jwt (2.1.0)
 | 
					    jwt (2.2.1)
 | 
				
			||||||
    libv8 (7.3.492.27.1)
 | 
					    libv8 (7.3.492.27.1)
 | 
				
			||||||
    listen (3.0.8)
 | 
					    listen (3.0.8)
 | 
				
			||||||
      rb-fsevent (~> 0.9, >= 0.9.4)
 | 
					      rb-fsevent (~> 0.9, >= 0.9.4)
 | 
				
			||||||
@@ -145,17 +160,21 @@ GEM
 | 
				
			|||||||
      nokogiri (>= 1.5.9)
 | 
					      nokogiri (>= 1.5.9)
 | 
				
			||||||
    mail (2.7.1)
 | 
					    mail (2.7.1)
 | 
				
			||||||
      mini_mime (>= 0.1.1)
 | 
					      mini_mime (>= 0.1.1)
 | 
				
			||||||
 | 
					    marcel (0.3.3)
 | 
				
			||||||
 | 
					      mimemagic (~> 0.3.2)
 | 
				
			||||||
    method_source (0.9.2)
 | 
					    method_source (0.9.2)
 | 
				
			||||||
    mini_mime (1.0.1)
 | 
					    mimemagic (0.3.3)
 | 
				
			||||||
 | 
					    mini_mime (1.0.2)
 | 
				
			||||||
    mini_portile2 (2.4.0)
 | 
					    mini_portile2 (2.4.0)
 | 
				
			||||||
    mini_racer (0.2.6)
 | 
					    mini_racer (0.2.6)
 | 
				
			||||||
      libv8 (>= 6.9.411)
 | 
					      libv8 (>= 6.9.411)
 | 
				
			||||||
    minitest (5.11.3)
 | 
					    minitest (5.11.3)
 | 
				
			||||||
 | 
					    msgpack (1.3.0)
 | 
				
			||||||
    multi_json (1.13.1)
 | 
					    multi_json (1.13.1)
 | 
				
			||||||
    multi_xml (0.6.0)
 | 
					    multi_xml (0.6.0)
 | 
				
			||||||
    multipart-post (2.1.1)
 | 
					    multipart-post (2.1.1)
 | 
				
			||||||
    net-ldap (0.16.1)
 | 
					    net-ldap (0.16.1)
 | 
				
			||||||
    nio4r (2.3.1)
 | 
					    nio4r (2.4.0)
 | 
				
			||||||
    nokogiri (1.10.3)
 | 
					    nokogiri (1.10.3)
 | 
				
			||||||
      mini_portile2 (~> 2.4.0)
 | 
					      mini_portile2 (~> 2.4.0)
 | 
				
			||||||
    oauth (0.5.4)
 | 
					    oauth (0.5.4)
 | 
				
			||||||
@@ -168,7 +187,7 @@ GEM
 | 
				
			|||||||
    omniauth (1.9.0)
 | 
					    omniauth (1.9.0)
 | 
				
			||||||
      hashie (>= 3.4.6, < 3.7.0)
 | 
					      hashie (>= 3.4.6, < 3.7.0)
 | 
				
			||||||
      rack (>= 1.6.2, < 3)
 | 
					      rack (>= 1.6.2, < 3)
 | 
				
			||||||
    omniauth-google-oauth2 (0.6.1)
 | 
					    omniauth-google-oauth2 (0.7.0)
 | 
				
			||||||
      jwt (>= 2.0)
 | 
					      jwt (>= 2.0)
 | 
				
			||||||
      omniauth (>= 1.1.1)
 | 
					      omniauth (>= 1.1.1)
 | 
				
			||||||
      omniauth-oauth2 (>= 1.5)
 | 
					      omniauth-oauth2 (>= 1.5)
 | 
				
			||||||
@@ -181,28 +200,29 @@ GEM
 | 
				
			|||||||
    omniauth-twitter (1.4.0)
 | 
					    omniauth-twitter (1.4.0)
 | 
				
			||||||
      omniauth-oauth (~> 1.1)
 | 
					      omniauth-oauth (~> 1.1)
 | 
				
			||||||
      rack
 | 
					      rack
 | 
				
			||||||
    pagy (3.2.0)
 | 
					    pagy (3.3.2)
 | 
				
			||||||
    parallel (1.17.0)
 | 
					    parallel (1.17.0)
 | 
				
			||||||
    parser (2.6.3.0)
 | 
					    parser (2.6.3.0)
 | 
				
			||||||
      ast (~> 2.4.0)
 | 
					      ast (~> 2.4.0)
 | 
				
			||||||
    pg (0.21.0)
 | 
					    pg (0.21.0)
 | 
				
			||||||
    popper_js (1.14.5)
 | 
					    popper_js (1.14.5)
 | 
				
			||||||
    public_suffix (3.0.3)
 | 
					    public_suffix (3.1.1)
 | 
				
			||||||
    puma (3.12.1)
 | 
					    puma (3.12.1)
 | 
				
			||||||
    rack (2.0.7)
 | 
					    rack (2.0.7)
 | 
				
			||||||
    rack-test (0.6.3)
 | 
					    rack-test (1.1.0)
 | 
				
			||||||
      rack (>= 1.0)
 | 
					      rack (>= 1.0, < 3)
 | 
				
			||||||
    rails (5.0.7.2)
 | 
					    rails (5.2.3)
 | 
				
			||||||
      actioncable (= 5.0.7.2)
 | 
					      actioncable (= 5.2.3)
 | 
				
			||||||
      actionmailer (= 5.0.7.2)
 | 
					      actionmailer (= 5.2.3)
 | 
				
			||||||
      actionpack (= 5.0.7.2)
 | 
					      actionpack (= 5.2.3)
 | 
				
			||||||
      actionview (= 5.0.7.2)
 | 
					      actionview (= 5.2.3)
 | 
				
			||||||
      activejob (= 5.0.7.2)
 | 
					      activejob (= 5.2.3)
 | 
				
			||||||
      activemodel (= 5.0.7.2)
 | 
					      activemodel (= 5.2.3)
 | 
				
			||||||
      activerecord (= 5.0.7.2)
 | 
					      activerecord (= 5.2.3)
 | 
				
			||||||
      activesupport (= 5.0.7.2)
 | 
					      activestorage (= 5.2.3)
 | 
				
			||||||
 | 
					      activesupport (= 5.2.3)
 | 
				
			||||||
      bundler (>= 1.3.0)
 | 
					      bundler (>= 1.3.0)
 | 
				
			||||||
      railties (= 5.0.7.2)
 | 
					      railties (= 5.2.3)
 | 
				
			||||||
      sprockets-rails (>= 2.0.0)
 | 
					      sprockets-rails (>= 2.0.0)
 | 
				
			||||||
    rails-controller-testing (1.0.4)
 | 
					    rails-controller-testing (1.0.4)
 | 
				
			||||||
      actionpack (>= 5.0.1.x)
 | 
					      actionpack (>= 5.0.1.x)
 | 
				
			||||||
@@ -213,31 +233,30 @@ GEM
 | 
				
			|||||||
      nokogiri (>= 1.6)
 | 
					      nokogiri (>= 1.6)
 | 
				
			||||||
    rails-html-sanitizer (1.0.4)
 | 
					    rails-html-sanitizer (1.0.4)
 | 
				
			||||||
      loofah (~> 2.2, >= 2.2.2)
 | 
					      loofah (~> 2.2, >= 2.2.2)
 | 
				
			||||||
    railties (5.0.7.2)
 | 
					    railties (5.2.3)
 | 
				
			||||||
      actionpack (= 5.0.7.2)
 | 
					      actionpack (= 5.2.3)
 | 
				
			||||||
      activesupport (= 5.0.7.2)
 | 
					      activesupport (= 5.2.3)
 | 
				
			||||||
      method_source
 | 
					      method_source
 | 
				
			||||||
      rake (>= 0.8.7)
 | 
					      rake (>= 0.8.7)
 | 
				
			||||||
      thor (>= 0.18.1, < 2.0)
 | 
					      thor (>= 0.19.0, < 2.0)
 | 
				
			||||||
    rainbow (3.0.0)
 | 
					    rainbow (3.0.0)
 | 
				
			||||||
    rake (12.3.2)
 | 
					    rake (12.3.2)
 | 
				
			||||||
    random_password (0.1.1)
 | 
					    random_password (0.1.1)
 | 
				
			||||||
    rb-fsevent (0.10.3)
 | 
					    rb-fsevent (0.10.3)
 | 
				
			||||||
    rb-inotify (0.10.0)
 | 
					    rb-inotify (0.10.0)
 | 
				
			||||||
      ffi (~> 1.0)
 | 
					      ffi (~> 1.0)
 | 
				
			||||||
    recaptcha (4.14.0)
 | 
					    recaptcha (5.0.0)
 | 
				
			||||||
      json
 | 
					      json
 | 
				
			||||||
    redcarpet (3.4.0)
 | 
					    redcarpet (3.4.0)
 | 
				
			||||||
    redis (3.3.5)
 | 
					 | 
				
			||||||
    remote_syslog_logger (1.0.4)
 | 
					    remote_syslog_logger (1.0.4)
 | 
				
			||||||
      syslog_protocol
 | 
					      syslog_protocol
 | 
				
			||||||
    rolify (5.2.0)
 | 
					    rolify (5.2.0)
 | 
				
			||||||
    rspec-core (3.8.0)
 | 
					    rspec-core (3.8.2)
 | 
				
			||||||
      rspec-support (~> 3.8.0)
 | 
					      rspec-support (~> 3.8.0)
 | 
				
			||||||
    rspec-expectations (3.8.3)
 | 
					    rspec-expectations (3.8.4)
 | 
				
			||||||
      diff-lcs (>= 1.2.0, < 2.0)
 | 
					      diff-lcs (>= 1.2.0, < 2.0)
 | 
				
			||||||
      rspec-support (~> 3.8.0)
 | 
					      rspec-support (~> 3.8.0)
 | 
				
			||||||
    rspec-mocks (3.8.0)
 | 
					    rspec-mocks (3.8.1)
 | 
				
			||||||
      diff-lcs (>= 1.2.0, < 2.0)
 | 
					      diff-lcs (>= 1.2.0, < 2.0)
 | 
				
			||||||
      rspec-support (~> 3.8.0)
 | 
					      rspec-support (~> 3.8.0)
 | 
				
			||||||
    rspec-rails (3.8.2)
 | 
					    rspec-rails (3.8.2)
 | 
				
			||||||
@@ -248,31 +267,20 @@ GEM
 | 
				
			|||||||
      rspec-expectations (~> 3.8.0)
 | 
					      rspec-expectations (~> 3.8.0)
 | 
				
			||||||
      rspec-mocks (~> 3.8.0)
 | 
					      rspec-mocks (~> 3.8.0)
 | 
				
			||||||
      rspec-support (~> 3.8.0)
 | 
					      rspec-support (~> 3.8.0)
 | 
				
			||||||
    rspec-support (3.8.0)
 | 
					    rspec-support (3.8.2)
 | 
				
			||||||
    rubocop (0.70.0)
 | 
					    rubocop (0.72.0)
 | 
				
			||||||
      jaro_winkler (~> 1.5.1)
 | 
					      jaro_winkler (~> 1.5.1)
 | 
				
			||||||
      parallel (~> 1.10)
 | 
					      parallel (~> 1.10)
 | 
				
			||||||
      parser (>= 2.6)
 | 
					      parser (>= 2.6)
 | 
				
			||||||
      rainbow (>= 2.2.2, < 4.0)
 | 
					      rainbow (>= 2.2.2, < 4.0)
 | 
				
			||||||
      ruby-progressbar (~> 1.7)
 | 
					      ruby-progressbar (~> 1.7)
 | 
				
			||||||
      unicode-display_width (>= 1.4.0, < 1.7)
 | 
					      unicode-display_width (>= 1.4.0, < 1.7)
 | 
				
			||||||
    ruby-progressbar (1.10.0)
 | 
					    ruby-progressbar (1.10.1)
 | 
				
			||||||
    safe_yaml (1.0.5)
 | 
					    safe_yaml (1.0.5)
 | 
				
			||||||
    sass (3.7.4)
 | 
					 | 
				
			||||||
      sass-listen (~> 4.0.0)
 | 
					 | 
				
			||||||
    sass-listen (4.0.0)
 | 
					 | 
				
			||||||
      rb-fsevent (~> 0.9, >= 0.9.4)
 | 
					 | 
				
			||||||
      rb-inotify (~> 0.9, >= 0.9.7)
 | 
					 | 
				
			||||||
    sass-rails (5.0.7)
 | 
					 | 
				
			||||||
      railties (>= 4.0.0, < 6)
 | 
					 | 
				
			||||||
      sass (~> 3.1)
 | 
					 | 
				
			||||||
      sprockets (>= 2.8, < 4.0)
 | 
					 | 
				
			||||||
      sprockets-rails (>= 2.0, < 4.0)
 | 
					 | 
				
			||||||
      tilt (>= 1.1, < 3)
 | 
					 | 
				
			||||||
    sassc (2.0.1)
 | 
					    sassc (2.0.1)
 | 
				
			||||||
      ffi (~> 1.9)
 | 
					      ffi (~> 1.9)
 | 
				
			||||||
      rake
 | 
					      rake
 | 
				
			||||||
    sassc-rails (2.1.1)
 | 
					    sassc-rails (2.1.2)
 | 
				
			||||||
      railties (>= 4.0.0)
 | 
					      railties (>= 4.0.0)
 | 
				
			||||||
      sassc (>= 2.0)
 | 
					      sassc (>= 2.0)
 | 
				
			||||||
      sprockets (> 3.0)
 | 
					      sprockets (> 3.0)
 | 
				
			||||||
@@ -285,8 +293,7 @@ GEM
 | 
				
			|||||||
      json (>= 1.8, < 3)
 | 
					      json (>= 1.8, < 3)
 | 
				
			||||||
      simplecov-html (~> 0.10.0)
 | 
					      simplecov-html (~> 0.10.0)
 | 
				
			||||||
    simplecov-html (0.10.2)
 | 
					    simplecov-html (0.10.2)
 | 
				
			||||||
    spring (2.0.2)
 | 
					    spring (2.1.0)
 | 
				
			||||||
      activesupport (>= 4.2)
 | 
					 | 
				
			||||||
    spring-watcher-listen (2.0.1)
 | 
					    spring-watcher-listen (2.0.1)
 | 
				
			||||||
      listen (>= 2.7, < 4.0)
 | 
					      listen (>= 2.7, < 4.0)
 | 
				
			||||||
      spring (>= 1.2, < 3.0)
 | 
					      spring (>= 1.2, < 3.0)
 | 
				
			||||||
@@ -299,14 +306,12 @@ GEM
 | 
				
			|||||||
      sprockets (>= 3.0.0)
 | 
					      sprockets (>= 3.0.0)
 | 
				
			||||||
    sqlite3 (1.3.13)
 | 
					    sqlite3 (1.3.13)
 | 
				
			||||||
    syslog_protocol (0.9.2)
 | 
					    syslog_protocol (0.9.2)
 | 
				
			||||||
    tabler-rubygem (0.1.4)
 | 
					 | 
				
			||||||
      autoprefixer-rails (>= 6.0.3)
 | 
					 | 
				
			||||||
    term-ansicolor (1.7.1)
 | 
					    term-ansicolor (1.7.1)
 | 
				
			||||||
      tins (~> 1.0)
 | 
					      tins (~> 1.0)
 | 
				
			||||||
    thor (0.20.3)
 | 
					    thor (0.20.3)
 | 
				
			||||||
    thread_safe (0.3.6)
 | 
					    thread_safe (0.3.6)
 | 
				
			||||||
    tilt (2.0.9)
 | 
					    tilt (2.0.9)
 | 
				
			||||||
    tins (1.20.2)
 | 
					    tins (1.21.0)
 | 
				
			||||||
    turbolinks (5.2.0)
 | 
					    turbolinks (5.2.0)
 | 
				
			||||||
      turbolinks-source (~> 5.2)
 | 
					      turbolinks-source (~> 5.2)
 | 
				
			||||||
    turbolinks-source (5.2.0)
 | 
					    turbolinks-source (5.2.0)
 | 
				
			||||||
@@ -320,13 +325,13 @@ GEM
 | 
				
			|||||||
      activemodel (>= 5.0)
 | 
					      activemodel (>= 5.0)
 | 
				
			||||||
      bindex (>= 0.4.0)
 | 
					      bindex (>= 0.4.0)
 | 
				
			||||||
      railties (>= 5.0)
 | 
					      railties (>= 5.0)
 | 
				
			||||||
    webmock (3.5.1)
 | 
					    webmock (3.6.0)
 | 
				
			||||||
      addressable (>= 2.3.6)
 | 
					      addressable (>= 2.3.6)
 | 
				
			||||||
      crack (>= 0.3.2)
 | 
					      crack (>= 0.3.2)
 | 
				
			||||||
      hashdiff
 | 
					      hashdiff (>= 0.4.0, < 2.0.0)
 | 
				
			||||||
    websocket-driver (0.6.5)
 | 
					    websocket-driver (0.7.1)
 | 
				
			||||||
      websocket-extensions (>= 0.1.0)
 | 
					      websocket-extensions (>= 0.1.0)
 | 
				
			||||||
    websocket-extensions (0.1.3)
 | 
					    websocket-extensions (0.1.4)
 | 
				
			||||||
    xml-simple (1.1.5)
 | 
					    xml-simple (1.1.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PLATFORMS
 | 
					PLATFORMS
 | 
				
			||||||
@@ -337,6 +342,7 @@ DEPENDENCIES
 | 
				
			|||||||
  bcrypt (~> 3.1.7)
 | 
					  bcrypt (~> 3.1.7)
 | 
				
			||||||
  bigbluebutton-api-ruby
 | 
					  bigbluebutton-api-ruby
 | 
				
			||||||
  bn-ldap-authentication!
 | 
					  bn-ldap-authentication!
 | 
				
			||||||
 | 
					  bootsnap (>= 1.1.0)
 | 
				
			||||||
  bootstrap (~> 4.3.1)
 | 
					  bootstrap (~> 4.3.1)
 | 
				
			||||||
  byebug
 | 
					  byebug
 | 
				
			||||||
  cancancan (~> 2.0)
 | 
					  cancancan (~> 2.0)
 | 
				
			||||||
@@ -361,24 +367,24 @@ DEPENDENCIES
 | 
				
			|||||||
  pagy
 | 
					  pagy
 | 
				
			||||||
  pg (~> 0.18)
 | 
					  pg (~> 0.18)
 | 
				
			||||||
  puma (~> 3.0)
 | 
					  puma (~> 3.0)
 | 
				
			||||||
  rails (~> 5.0.7)
 | 
					  rails (~> 5.2.3)
 | 
				
			||||||
  rails-controller-testing
 | 
					  rails-controller-testing
 | 
				
			||||||
  random_password
 | 
					  random_password
 | 
				
			||||||
  recaptcha
 | 
					  recaptcha
 | 
				
			||||||
  redcarpet
 | 
					  redcarpet
 | 
				
			||||||
  redis (~> 3.0)
 | 
					 | 
				
			||||||
  remote_syslog_logger
 | 
					  remote_syslog_logger
 | 
				
			||||||
  rolify
 | 
					  rolify
 | 
				
			||||||
  rspec-rails (~> 3.7)
 | 
					  rspec-rails (~> 3.7)
 | 
				
			||||||
  rubocop
 | 
					  rubocop
 | 
				
			||||||
  sass-rails (~> 5.0)
 | 
					  sassc-rails
 | 
				
			||||||
  shoulda-matchers (~> 3.1)
 | 
					  shoulda-matchers (~> 3.1)
 | 
				
			||||||
  spring
 | 
					  spring
 | 
				
			||||||
  spring-watcher-listen (~> 2.0.0)
 | 
					  spring-watcher-listen (~> 2.0.0)
 | 
				
			||||||
  sqlite3 (~> 1.3.6)
 | 
					  sqlite3 (~> 1.3.6)
 | 
				
			||||||
  tabler-rubygem
 | 
					  tabler-rubygem!
 | 
				
			||||||
  turbolinks (~> 5)
 | 
					  turbolinks (~> 5)
 | 
				
			||||||
  tzinfo-data
 | 
					  tzinfo-data
 | 
				
			||||||
  uglifier (>= 1.3.0)
 | 
					  uglifier (>= 1.3.0)
 | 
				
			||||||
  web-console (>= 3.3.0)
 | 
					  web-console (>= 3.3.0)
 | 
				
			||||||
  webmock
 | 
					  webmock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,9 +43,9 @@ $(document).on('turbolinks:load', function(){
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
      window.location.replace(url);
 | 
					      window.location.replace(url);
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* COLOR SELECTORS */
 | 
					  if (controller == "admins" && action == "site_settings") {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    loadColourSelectors()
 | 
					    loadColourSelectors()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										41
									
								
								app/assets/javascripts/recording.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/assets/javascripts/recording.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					// 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Handle changing of settings tabs.
 | 
				
			||||||
 | 
					$(document).on('turbolinks:load', function(){
 | 
				
			||||||
 | 
					  var controller = $("body").data('controller');
 | 
				
			||||||
 | 
					  var action = $("body").data('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (controller == "rooms" && action == "show" 
 | 
				
			||||||
 | 
					      || controller == "rooms" && action == "update" 
 | 
				
			||||||
 | 
					      || controller == "users" && action == "recordings" 
 | 
				
			||||||
 | 
					      || controller == "admins" && action == "server_recordings"){
 | 
				
			||||||
 | 
					    // Handle recording emails.
 | 
				
			||||||
 | 
					    $('.email-link').each(function(){
 | 
				
			||||||
 | 
					      $(this).click(function(){
 | 
				
			||||||
 | 
					        var subject = $(".username").text() + " " + t('room.mailer.subject');
 | 
				
			||||||
 | 
					        var body =  t('room.mailer.body') + "\n\n" + $(this).attr("data-pres-link");
 | 
				
			||||||
 | 
					        var autogenerated = "\n\n" + t('room.mailer.autogenerated') + "\n";
 | 
				
			||||||
 | 
					        var footer = t('room.mailer.footer');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var url = "mailto:?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body) + encodeURIComponent(autogenerated) + encodeURIComponent(footer);
 | 
				
			||||||
 | 
					        var win = window.open(url, '_blank');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        win.focus();
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -18,7 +18,10 @@ $(document).on('turbolinks:load', function(){
 | 
				
			|||||||
  var controller = $("body").data('controller');
 | 
					  var controller = $("body").data('controller');
 | 
				
			||||||
  var action = $("body").data('action');
 | 
					  var action = $("body").data('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(controller == "rooms" && action == "show" || controller == "rooms" && action == "update" || controller == "users" && action == "recordings"){
 | 
					  if(controller == "rooms" && action == "show" 
 | 
				
			||||||
 | 
					    || controller == "rooms" && action == "update" 
 | 
				
			||||||
 | 
					    || controller == "users" && action == "recordings" 
 | 
				
			||||||
 | 
					    || controller == "admins" && action == "server_recordings"){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Set a room header rename event
 | 
					    // Set a room header rename event
 | 
				
			||||||
    var configure_room_header = function(room_title){
 | 
					    var configure_room_header = function(room_title){
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,29 +39,18 @@ $(document).on('turbolinks:load', function(){
 | 
				
			|||||||
        }, 2000)
 | 
					        }, 2000)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Handle recording emails.
 | 
					 | 
				
			||||||
    $('.email-link').each(function(){
 | 
					 | 
				
			||||||
      $(this).click(function(){
 | 
					 | 
				
			||||||
        var subject = $(".username").text() + " " + t('room.mailer.subject');
 | 
					 | 
				
			||||||
        var body =  t('room.mailer.body') + "\n\n" + $(this).attr("data-pres-link");
 | 
					 | 
				
			||||||
        var autogenerated = "\n\n" + t('room.mailer.autogenerated') + "\n";
 | 
					 | 
				
			||||||
        var footer = t('room.mailer.footer');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var url = "mailto:?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body) + encodeURIComponent(autogenerated) + encodeURIComponent(footer);
 | 
					 | 
				
			||||||
        var win = window.open(url, '_blank');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        win.focus();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Display and update all fields related to creating a room in the createRoomModal
 | 
					  // Display and update all fields related to creating a room in the createRoomModal
 | 
				
			||||||
  $("#create-room-block").click(function(){
 | 
					  $("#create-room-block").click(function(){
 | 
				
			||||||
    $("#create-room-name").val("")
 | 
					    $("#create-room-name").val("")
 | 
				
			||||||
 | 
					    $("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code_placeholder") %>")
 | 
				
			||||||
 | 
					    $("#room_access_code").val(null)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $("#createRoomModal form").attr("action", $("body").data('relative-root'))
 | 
					    $("#createRoomModal form").attr("action", $("body").data('relative-root'))
 | 
				
			||||||
    updateDropdown($(".dropdown-item[value='default']"))
 | 
					    updateDropdown($(".dropdown-item[value='default']"))
 | 
				
			||||||
    $("#room_mute_on_join").prop("checked", false)
 | 
					    $("#room_mute_on_join").prop("checked", false)
 | 
				
			||||||
 | 
					    $("#room_anyone_can_start").prop("checked", false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //show all elements & their children with a create-only class
 | 
					    //show all elements & their children with a create-only class
 | 
				
			||||||
    $(".create-only").each(function() {
 | 
					    $(".create-only").each(function() {
 | 
				
			||||||
@@ -95,6 +84,16 @@ $(document).on('turbolinks:load', function(){
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    updateCurrentSettings($(this).closest("#room-block").data("room-settings"))
 | 
					    updateCurrentSettings($(this).closest("#room-block").data("room-settings"))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    accessCode = $(this).closest("#room-block").data("room-access-code")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(accessCode){
 | 
				
			||||||
 | 
					      $("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code") %>: " + accessCode)
 | 
				
			||||||
 | 
					      $("#room_access_code").val(accessCode)
 | 
				
			||||||
 | 
					    } else{
 | 
				
			||||||
 | 
					      $("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code_placeholder") %>")
 | 
				
			||||||
 | 
					      $("#room_access_code").val(null)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //Update the createRoomModal to show the correct current settings
 | 
					  //Update the createRoomModal to show the correct current settings
 | 
				
			||||||
@@ -106,6 +105,12 @@ $(document).on('turbolinks:load', function(){
 | 
				
			|||||||
      $("#room_mute_on_join").prop("checked", false)
 | 
					      $("#room_mute_on_join").prop("checked", false)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(settings.anyoneCanStart){
 | 
				
			||||||
 | 
					      $("#room_anyone_can_start").prop("checked", true)
 | 
				
			||||||
 | 
					    } else { //default option
 | 
				
			||||||
 | 
					      $("#room_anyone_can_start").prop("checked", false)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //set dropdown value
 | 
					    //set dropdown value
 | 
				
			||||||
    if (settings.joinViaHtml5) {
 | 
					    if (settings.joinViaHtml5) {
 | 
				
			||||||
      updateDropdown($(".dropdown-item[value='html5']"))
 | 
					      updateDropdown($(".dropdown-item[value='html5']"))
 | 
				
			||||||
@@ -122,3 +127,21 @@ function updateDropdown(element) {
 | 
				
			|||||||
  $("#dropdown-trigger").text(element.text())
 | 
					  $("#dropdown-trigger").text(element.text())
 | 
				
			||||||
  $("#room_client").val(element.val())
 | 
					  $("#room_client").val(element.val())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function generateAccessCode(){
 | 
				
			||||||
 | 
					  const accessCodeLength = 6
 | 
				
			||||||
 | 
					  var validCharacters = "0123456789"
 | 
				
			||||||
 | 
					  var accessCode = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for( var i = 0; i < accessCodeLength; i++){
 | 
				
			||||||
 | 
					    accessCode += validCharacters.charAt(Math.floor(Math.random() * validCharacters.length));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  $("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code") %>: " + accessCode)
 | 
				
			||||||
 | 
					  $("#room_access_code").val(accessCode)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function ResetAccessCode(){
 | 
				
			||||||
 | 
					  $("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code_placeholder") %>")
 | 
				
			||||||
 | 
					  $("#room_access_code").val(null)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,8 @@ $(document).on('turbolinks:load', function(){
 | 
				
			|||||||
      (controller == "rooms" && action == "show") || 
 | 
					      (controller == "rooms" && action == "show") || 
 | 
				
			||||||
      (controller == "rooms" && action == "update") ||
 | 
					      (controller == "rooms" && action == "update") ||
 | 
				
			||||||
      (controller == "rooms" && action == "join") || 
 | 
					      (controller == "rooms" && action == "join") || 
 | 
				
			||||||
      (controller == "users" && action == "recordings")) {
 | 
					      (controller == "users" && action == "recordings") ||
 | 
				
			||||||
 | 
					      (controller == "admins" && action == "server_recordings")) {
 | 
				
			||||||
    // Submit search if the user hits enter
 | 
					    // Submit search if the user hits enter
 | 
				
			||||||
    $("#search-input").keypress(function(key) {
 | 
					    $("#search-input").keypress(function(key) {
 | 
				
			||||||
      var keyPressed = key.which
 | 
					      var keyPressed = key.which
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ $(document).on('turbolinks:load', function(){
 | 
				
			|||||||
  var action = $("body").data('action');
 | 
					  var action = $("body").data('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Only run on the settings page.
 | 
					  // Only run on the settings page.
 | 
				
			||||||
  if ((controller == "users" && action == "edit") || (controller == "users" && action == "update") || (controller == "admins" && action == "index")){
 | 
					  if ((controller == "users" && action == "edit") || (controller == "users" && action == "update")){
 | 
				
			||||||
    var settingsButtons = $('.setting-btn');
 | 
					    var settingsButtons = $('.setting-btn');
 | 
				
			||||||
    var settingsViews = $('.setting-view');
 | 
					    var settingsViews = $('.setting-view');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,10 @@ $(document).on('turbolinks:load', function(){
 | 
				
			|||||||
  var controller = $("body").data('controller');
 | 
					  var controller = $("body").data('controller');
 | 
				
			||||||
  var action = $("body").data('action');
 | 
					  var action = $("body").data('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(controller == "rooms" && action == "show" || controller == "rooms" && action == "update" || controller == "users" && action == "recordings"){
 | 
					  if(controller == "rooms" && action == "show" 
 | 
				
			||||||
 | 
					    || controller == "rooms" && action == "update" 
 | 
				
			||||||
 | 
					    || controller == "users" && action == "recordings" 
 | 
				
			||||||
 | 
					    || controller == "admins" && action == "server_recordings"){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Choose active header
 | 
					    // Choose active header
 | 
				
			||||||
    // (Name, Length or Users)
 | 
					    // (Name, Length or Users)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,3 +65,7 @@
 | 
				
			|||||||
    background-color: rgba(0, 0, 0, 0.04);
 | 
					    background-color: rgba(0, 0, 0, 0.04);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.allow-icon-click{
 | 
				
			||||||
 | 
					  pointer-events: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,6 +84,7 @@ a {
 | 
				
			|||||||
  color: #6e7687 !important;
 | 
					  color: #6e7687 !important;
 | 
				
			||||||
  &:hover {
 | 
					  &:hover {
 | 
				
			||||||
    color: $primary-color !important;
 | 
					    color: $primary-color !important;
 | 
				
			||||||
 | 
					    background-color: $primary-color-lighten !important;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  &:active {
 | 
					  &:active {
 | 
				
			||||||
    background-color: $primary-color-lighten !important;
 | 
					    background-color: $primary-color-lighten !important;
 | 
				
			||||||
@@ -130,6 +131,7 @@ input:focus, select:focus {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    & a {
 | 
					    & a {
 | 
				
			||||||
 | 
					      color: $primary-color !important;
 | 
				
			||||||
      border-color: $primary-color !important;
 | 
					      border-color: $primary-color !important;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,10 +20,11 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
  include Pagy::Backend
 | 
					  include Pagy::Backend
 | 
				
			||||||
  include Themer
 | 
					  include Themer
 | 
				
			||||||
  include Emailer
 | 
					  include Emailer
 | 
				
			||||||
 | 
					  include Recorder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve]
 | 
					  manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve]
 | 
				
			||||||
  site_settings = [:branding, :coloring, :coloring_lighten, :coloring_darken,
 | 
					  site_settings = [:branding, :coloring, :coloring_lighten, :coloring_darken,
 | 
				
			||||||
                   :registration_method, :room_authentication, :room_limit]
 | 
					                   :registration_method, :room_authentication, :room_limit, :default_recording_visibility]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  authorize_resource class: false
 | 
					  authorize_resource class: false
 | 
				
			||||||
  before_action :find_user, only: manage_users
 | 
					  before_action :find_user, only: manage_users
 | 
				
			||||||
@@ -40,11 +41,27 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
    @pagy, @users = pagy(user_list)
 | 
					    @pagy, @users = pagy(user_list)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # GET /admins/site_settings
 | 
				
			||||||
 | 
					  def site_settings
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # GET /admins/server_recordings
 | 
				
			||||||
 | 
					  def server_recordings
 | 
				
			||||||
 | 
					    server_rooms = if Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
 | 
					      Room.includes(:owner).where(users: { provider: user_settings_provider }).pluck(:bbb_id)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      Room.pluck(:bbb_id)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @search, @order_column, @order_direction, recs =
 | 
				
			||||||
 | 
					      all_recordings(server_rooms, @user_domain, params.permit(:search, :column, :direction), true, true)
 | 
				
			||||||
 | 
					    @pagy, @recordings = pagy_array(recs)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # MANAGE USERS
 | 
					  # MANAGE USERS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # GET /admins/edit/:user_uid
 | 
					  # GET /admins/edit/:user_uid
 | 
				
			||||||
  def edit_user
 | 
					  def edit_user
 | 
				
			||||||
    render "admins/index", locals: { setting_id: "account" }
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # POST /admins/promote/:user_uid
 | 
					  # POST /admins/promote/:user_uid
 | 
				
			||||||
@@ -111,7 +128,7 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
  # POST /admins/branding
 | 
					  # POST /admins/branding
 | 
				
			||||||
  def branding
 | 
					  def branding
 | 
				
			||||||
    @settings.update_value("Branding Image", params[:url])
 | 
					    @settings.update_value("Branding Image", params[:url])
 | 
				
			||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
					    redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # POST /admins/color
 | 
					  # POST /admins/color
 | 
				
			||||||
@@ -119,23 +136,23 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
    @settings.update_value("Primary Color", params[:color])
 | 
					    @settings.update_value("Primary Color", params[:color])
 | 
				
			||||||
    @settings.update_value("Primary Color Lighten", color_lighten(params[:color]))
 | 
					    @settings.update_value("Primary Color Lighten", color_lighten(params[:color]))
 | 
				
			||||||
    @settings.update_value("Primary Color Darken", color_darken(params[:color]))
 | 
					    @settings.update_value("Primary Color Darken", color_darken(params[:color]))
 | 
				
			||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
					    redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def coloring_lighten
 | 
					  def coloring_lighten
 | 
				
			||||||
    @settings.update_value("Primary Color Lighten", params[:color])
 | 
					    @settings.update_value("Primary Color Lighten", params[:color])
 | 
				
			||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
					    redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def coloring_darken
 | 
					  def coloring_darken
 | 
				
			||||||
    @settings.update_value("Primary Color Darken", params[:color])
 | 
					    @settings.update_value("Primary Color Darken", params[:color])
 | 
				
			||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
					    redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # POST /admins/room_authentication
 | 
					  # POST /admins/room_authentication
 | 
				
			||||||
  def room_authentication
 | 
					  def room_authentication
 | 
				
			||||||
    @settings.update_value("Room Authentication", params[:value])
 | 
					    @settings.update_value("Room Authentication", params[:value])
 | 
				
			||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
					    redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # POST /admins/registration_method/:method
 | 
					  # POST /admins/registration_method/:method
 | 
				
			||||||
@@ -144,11 +161,11 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Only allow change to Join by Invitation if user has emails enabled
 | 
					    # Only allow change to Join by Invitation if user has emails enabled
 | 
				
			||||||
    if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite]
 | 
					    if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite]
 | 
				
			||||||
      redirect_to admins_path,
 | 
					      redirect_to admin_site_settings_path,
 | 
				
			||||||
        flash: { alert: I18n.t("administrator.flash.invite_email_verification") }
 | 
					        flash: { alert: I18n.t("administrator.flash.invite_email_verification") }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      @settings.update_value("Registration Method", new_method)
 | 
					      @settings.update_value("Registration Method", new_method)
 | 
				
			||||||
      redirect_to admins_path,
 | 
					      redirect_to admin_site_settings_path,
 | 
				
			||||||
        flash: { success: I18n.t("administrator.flash.registration_method_updated") }
 | 
					        flash: { success: I18n.t("administrator.flash.registration_method_updated") }
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
@@ -156,13 +173,20 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
  # POST /admins/room_limit
 | 
					  # POST /admins/room_limit
 | 
				
			||||||
  def room_limit
 | 
					  def room_limit
 | 
				
			||||||
    @settings.update_value("Room Limit", params[:limit])
 | 
					    @settings.update_value("Room Limit", params[:limit])
 | 
				
			||||||
    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
					    redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # POST /admins/default_recording_visibility
 | 
				
			||||||
 | 
					  def default_recording_visibility
 | 
				
			||||||
 | 
					    @settings.update_value("Default Recording Visibility", params[:visibility])
 | 
				
			||||||
 | 
					    redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") + ". " +
 | 
				
			||||||
 | 
					                                               I18n.t("administrator.site_settings.recording_visibility.warning") }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def find_user
 | 
					  def find_user
 | 
				
			||||||
    @user = User.find_by!(uid: params[:user_uid])
 | 
					    @user = User.where(uid: params[:user_uid]).includes(:roles).first
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def find_setting
 | 
					  def find_setting
 | 
				
			||||||
@@ -176,20 +200,18 @@ class AdminsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Gets the list of users based on your configuration
 | 
					  # Gets the list of users based on your configuration
 | 
				
			||||||
  def user_list
 | 
					  def user_list
 | 
				
			||||||
    initial_list = if current_user.has_role? :super_admin
 | 
					    initial_list = if current_user.has_cached_role? :super_admin
 | 
				
			||||||
      User.where.not(id: current_user.id)
 | 
					      User.where.not(id: current_user.id).includes(:roles)
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      User.without_role(:super_admin).where.not(id: current_user.id)
 | 
					      User.without_role(:super_admin).where.not(id: current_user.id).includes(:roles)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list = @role.present? ? initial_list.with_role(@role.to_sym) : initial_list
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if Rails.configuration.loadbalanced_configuration
 | 
					    if Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
      list.where(provider: user_settings_provider)
 | 
					      initial_list.where(provider: user_settings_provider)
 | 
				
			||||||
          .admins_search(@search)
 | 
					                  .admins_search(@search, @role)
 | 
				
			||||||
                  .admins_order(@order_column, @order_direction)
 | 
					                  .admins_order(@order_column, @order_direction)
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      list.admins_search(@search)
 | 
					      initial_list.admins_search(@search, @role)
 | 
				
			||||||
                  .admins_order(@order_column, @order_direction)
 | 
					                  .admins_order(@order_column, @order_direction)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -121,6 +121,9 @@ class ApplicationController < ActionController::Base
 | 
				
			|||||||
      meeting_logout_url: request.base_url + logout_room_path(@room),
 | 
					      meeting_logout_url: request.base_url + logout_room_path(@room),
 | 
				
			||||||
      meeting_recorded: true,
 | 
					      meeting_recorded: true,
 | 
				
			||||||
      moderator_message: "#{invite_msg}\n\n#{request.base_url + room_path(@room)}",
 | 
					      moderator_message: "#{invite_msg}\n\n#{request.base_url + room_path(@room)}",
 | 
				
			||||||
 | 
					      host: request.host,
 | 
				
			||||||
 | 
					      recording_default_visibility: Setting.find_or_create_by!(provider: user_settings_provider)
 | 
				
			||||||
 | 
					                                           .get_value("Default Recording Visibility") == "public"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -131,7 +134,7 @@ class ApplicationController < ActionController::Base
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Checks to make sure that the admin has changed his password from the default
 | 
					  # Checks to make sure that the admin has changed his password from the default
 | 
				
			||||||
  def check_admin_password
 | 
					  def check_admin_password
 | 
				
			||||||
    if current_user&.has_role?(:admin) && current_user&.greenlight_account? &&
 | 
					    if current_user&.has_cached_role?(:admin) && current_user&.greenlight_account? &&
 | 
				
			||||||
       current_user&.authenticate(Rails.configuration.admin_password_default)
 | 
					       current_user&.authenticate(Rails.configuration.admin_password_default)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      flash.now[:alert] = I18n.t("default_admin",
 | 
					      flash.now[:alert] = I18n.t("default_admin",
 | 
				
			||||||
@@ -179,10 +182,10 @@ class ApplicationController < ActionController::Base
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Checks if the user is banned and logs him out if he is
 | 
					  # Checks if the user is banned and logs him out if he is
 | 
				
			||||||
  def check_user_role
 | 
					  def check_user_role
 | 
				
			||||||
    if current_user&.has_role? :denied
 | 
					    if current_user&.has_cached_role? :denied
 | 
				
			||||||
      session.delete(:user_id)
 | 
					      session.delete(:user_id)
 | 
				
			||||||
      redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") }
 | 
					      redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") }
 | 
				
			||||||
    elsif current_user&.has_role? :pending
 | 
					    elsif current_user&.has_cached_role? :pending
 | 
				
			||||||
      session.delete(:user_id)
 | 
					      session.delete(:user_id)
 | 
				
			||||||
      redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") }
 | 
					      redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") }
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,14 +64,20 @@ module Emailer
 | 
				
			|||||||
  def send_approval_user_signup_email(user)
 | 
					  def send_approval_user_signup_email(user)
 | 
				
			||||||
    return unless Rails.configuration.enable_email_verification
 | 
					    return unless Rails.configuration.enable_email_verification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    admin_emails = admin_emails()
 | 
				
			||||||
 | 
					    unless admin_emails.empty?
 | 
				
			||||||
      UserMailer.approval_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
 | 
					      UserMailer.approval_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def send_invite_user_signup_email(user)
 | 
					  def send_invite_user_signup_email(user)
 | 
				
			||||||
    return unless Rails.configuration.enable_email_verification
 | 
					    return unless Rails.configuration.enable_email_verification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    admin_emails = admin_emails()
 | 
				
			||||||
 | 
					    unless admin_emails.empty?
 | 
				
			||||||
      UserMailer.invite_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
 | 
					      UserMailer.invite_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,14 +16,53 @@
 | 
				
			|||||||
# You should have received a copy of the GNU Lesser General Public License along
 | 
					# You should have received a copy of the GNU Lesser General Public License along
 | 
				
			||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module APIConcern
 | 
					module Recorder
 | 
				
			||||||
  extend ActiveSupport::Concern
 | 
					  extend ActiveSupport::Concern
 | 
				
			||||||
 | 
					  include ::BbbApi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Fetches all recordings for a room.
 | 
				
			||||||
 | 
					  def recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false)
 | 
				
			||||||
 | 
					    res = bbb(provider).get_recordings(meetingID: room_bbb_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    format_recordings(res, search_params, ret_search_params)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Fetches a rooms public recordings.
 | 
				
			||||||
 | 
					  def public_recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false)
 | 
				
			||||||
 | 
					    search, order_col, order_dir, recs = recordings(room_bbb_id, provider, search_params, ret_search_params)
 | 
				
			||||||
 | 
					    [search, order_col, order_dir, recs.select { |r| r[:metadata][:"gl-listed"] == "true" }]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Makes paginated API calls to get recordings
 | 
				
			||||||
 | 
					  def all_recordings(room_bbb_ids, provider, search_params = {}, ret_search_params = false, search_name = false)
 | 
				
			||||||
 | 
					    pag_num = Rails.configuration.pagination_number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pag_loops = room_bbb_ids.length / pag_num - 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    res = { recordings: [] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (0..pag_loops).each do |i|
 | 
				
			||||||
 | 
					      pag_rooms = room_bbb_ids[pag_num * i, pag_num]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # bbb.get_recordings returns an object
 | 
				
			||||||
 | 
					      # take only the array portion of the object that is returned
 | 
				
			||||||
 | 
					      full_res = bbb(provider).get_recordings(meetingID: pag_rooms)
 | 
				
			||||||
 | 
					      res[:recordings].push(*full_res[:recordings])
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    last_pag_room = room_bbb_ids[pag_num * (pag_loops + 1), room_bbb_ids.length % pag_num]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    full_res = bbb(provider).get_recordings(meetingID: last_pag_room)
 | 
				
			||||||
 | 
					    res[:recordings].push(*full_res[:recordings])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    format_recordings(res, search_params, ret_search_params, search_name)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Format, filter, and sort recordings to match their current use in the app
 | 
					  # Format, filter, and sort recordings to match their current use in the app
 | 
				
			||||||
  def format_recordings(api_res, search_params, ret_search_params)
 | 
					  def format_recordings(api_res, search_params, ret_search_params, search_name = false)
 | 
				
			||||||
    search = search_params[:search] || ""
 | 
					    search = search_params[:search] || ""
 | 
				
			||||||
    order_col = search_params[:column] && search_params[:direction] != "none" ? search_params[:column] : "end_time"
 | 
					    order_col = search_params[:column] && search_params[:direction] != "none" ? search_params[:column] : "end_time"
 | 
				
			||||||
    order_dir = search_params[:column] && search_params[:direction] != "none" ? search_params[:direction] : "asc"
 | 
					    order_dir = search_params[:column] && search_params[:direction] != "none" ? search_params[:direction] : "desc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    search = search.downcase
 | 
					    search = search.downcase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -40,7 +79,7 @@ module APIConcern
 | 
				
			|||||||
      r.delete(:playback)
 | 
					      r.delete(:playback)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    recs = filter_recordings(api_res, search)
 | 
					    recs = filter_recordings(api_res, search, search_name)
 | 
				
			||||||
    recs = sort_recordings(recs, order_col, order_dir)
 | 
					    recs = sort_recordings(recs, order_col, order_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ret_search_params
 | 
					    if ret_search_params
 | 
				
			||||||
@@ -50,7 +89,7 @@ module APIConcern
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def filter_recordings(api_res, search)
 | 
					  def filter_recordings(api_res, search, search_name = false)
 | 
				
			||||||
    api_res[:recordings].select do |r|
 | 
					    api_res[:recordings].select do |r|
 | 
				
			||||||
             (!r[:metadata].nil? && ((!r[:metadata][:name].nil? &&
 | 
					             (!r[:metadata].nil? && ((!r[:metadata][:name].nil? &&
 | 
				
			||||||
                    r[:metadata][:name].downcase.include?(search)) ||
 | 
					                    r[:metadata][:name].downcase.include?(search)) ||
 | 
				
			||||||
@@ -59,7 +98,8 @@ module APIConcern
 | 
				
			|||||||
               ((r[:metadata].nil? || r[:metadata][:name].nil?) &&
 | 
					               ((r[:metadata].nil? || r[:metadata][:name].nil?) &&
 | 
				
			||||||
                 r[:name].downcase.include?(search)) ||
 | 
					                 r[:name].downcase.include?(search)) ||
 | 
				
			||||||
               r[:participants].include?(search) ||
 | 
					               r[:participants].include?(search) ||
 | 
				
			||||||
               !r[:playbacks].select { |p| p[:type].downcase.include?(search) }.empty?
 | 
					               !r[:playbacks].select { |p| p[:type].downcase.include?(search) }.empty? ||
 | 
				
			||||||
 | 
					               (search_name && Room.find_by(bbb_id: r[:meetingID]).owner.email.downcase.include?(search))
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,7 +24,7 @@ module Themer
 | 
				
			|||||||
    # Uses the built in Sass Engine to lighten the color
 | 
					    # Uses the built in Sass Engine to lighten the color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dummy_scss = "h1 { color: $lighten; }"
 | 
					    dummy_scss = "h1 { color: $lighten; }"
 | 
				
			||||||
    compiled = Sass::Engine.new("$lighten:lighten(#{color}, 40%);" + dummy_scss, syntax: :scss).render
 | 
					    compiled = SassC::Engine.new("$lighten:lighten(#{color}, 40%);" + dummy_scss, syntax: :scss).render
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    string_locater = 'color: '
 | 
					    string_locater = 'color: '
 | 
				
			||||||
    color_start = compiled.index(string_locater) + string_locater.length
 | 
					    color_start = compiled.index(string_locater) + string_locater.length
 | 
				
			||||||
@@ -37,7 +37,7 @@ module Themer
 | 
				
			|||||||
    # Uses the built in Sass Engine to darken the color
 | 
					    # Uses the built in Sass Engine to darken the color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dummy_scss = "h1 { color: $darken; }"
 | 
					    dummy_scss = "h1 { color: $darken; }"
 | 
				
			||||||
    compiled = Sass::Engine.new("$darken:darken(#{color}, 10%);" + dummy_scss, syntax: :scss).render
 | 
					    compiled = SassC::Engine.new("$darken:darken(#{color}, 10%);" + dummy_scss, syntax: :scss).render
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    string_locater = 'color: '
 | 
					    string_locater = 'color: '
 | 
				
			||||||
    color_start = compiled.index(string_locater) + string_locater.length
 | 
					    color_start = compiled.index(string_locater) + string_locater.length
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,6 +50,11 @@ class RecordingsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Ensure the user is logged into the room they are accessing.
 | 
					  # Ensure the user is logged into the room they are accessing.
 | 
				
			||||||
  def verify_room_ownership
 | 
					  def verify_room_ownership
 | 
				
			||||||
    redirect_to root_path unless @room.owned_by?(current_user)
 | 
					    if !current_user ||
 | 
				
			||||||
 | 
					       !@room.owned_by?(current_user) ||
 | 
				
			||||||
 | 
					       !current_user.has_cached_role?(:admin) ||
 | 
				
			||||||
 | 
					       !current_user.has_cached_role?(:super_admin)
 | 
				
			||||||
 | 
					      redirect_to root_path
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,12 +19,13 @@
 | 
				
			|||||||
class RoomsController < ApplicationController
 | 
					class RoomsController < ApplicationController
 | 
				
			||||||
  include RecordingsHelper
 | 
					  include RecordingsHelper
 | 
				
			||||||
  include Pagy::Backend
 | 
					  include Pagy::Backend
 | 
				
			||||||
 | 
					  include Recorder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
 | 
					  before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
 | 
				
			||||||
  before_action :validate_verified_email, except: [:show, :join],
 | 
					  before_action :validate_verified_email, except: [:show, :join],
 | 
				
			||||||
                unless: -> { !Rails.configuration.enable_email_verification }
 | 
					                unless: -> { !Rails.configuration.enable_email_verification }
 | 
				
			||||||
  before_action :find_room, except: :create
 | 
					  before_action :find_room, except: :create
 | 
				
			||||||
  before_action :verify_room_ownership, except: [:create, :show, :join, :logout]
 | 
					  before_action :verify_room_ownership, except: [:create, :show, :join, :logout, :login]
 | 
				
			||||||
  before_action :verify_room_owner_verified, only: [:show, :join],
 | 
					  before_action :verify_room_owner_verified, only: [:show, :join],
 | 
				
			||||||
                unless: -> { !Rails.configuration.enable_email_verification }
 | 
					                unless: -> { !Rails.configuration.enable_email_verification }
 | 
				
			||||||
  before_action :verify_user_not_admin, only: [:show]
 | 
					  before_action :verify_user_not_admin, only: [:show]
 | 
				
			||||||
@@ -35,9 +36,10 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded
 | 
					    return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @room = Room.new(name: room_params[:name])
 | 
					    @room = Room.new(name: room_params[:name], access_code: room_params[:access_code])
 | 
				
			||||||
    @room.owner = current_user
 | 
					    @room.owner = current_user
 | 
				
			||||||
    @room.room_settings = create_room_settings_string(room_params[:mute_on_join], room_params[:client])
 | 
					    @room.room_settings = create_room_settings_string(room_params[:mute_on_join], room_params[:client],
 | 
				
			||||||
 | 
					      room_params[:anyone_can_start])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if @room.save
 | 
					    if @room.save
 | 
				
			||||||
      if room_params[:auto_join] == "1"
 | 
					      if room_params[:auto_join] == "1"
 | 
				
			||||||
@@ -54,13 +56,15 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # GET /:room_uid
 | 
					  # GET /:room_uid
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
 | 
					    @is_running = @room.running?
 | 
				
			||||||
 | 
					    @anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if current_user && @room.owned_by?(current_user)
 | 
					    if current_user && @room.owned_by?(current_user)
 | 
				
			||||||
      @search, @order_column, @order_direction, recs =
 | 
					      @search, @order_column, @order_direction, recs =
 | 
				
			||||||
        @room.recordings(params.permit(:search, :column, :direction), true)
 | 
					        recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @pagy, @recordings = pagy_array(recs)
 | 
					      @pagy, @recordings = pagy_array(recs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @is_running = @room.running?
 | 
					 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      # Get users name
 | 
					      # Get users name
 | 
				
			||||||
      @name = if current_user
 | 
					      @name = if current_user
 | 
				
			||||||
@@ -72,7 +76,7 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @search, @order_column, @order_direction, pub_recs =
 | 
					      @search, @order_column, @order_direction, pub_recs =
 | 
				
			||||||
        @room.public_recordings(params.permit(:search, :column, :direction), true)
 | 
					        public_recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @pagy, @public_recordings = pagy_array(pub_recs)
 | 
					      @pagy, @public_recordings = pagy_array(pub_recs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -105,6 +109,12 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    opts = default_meeting_options
 | 
					    opts = default_meeting_options
 | 
				
			||||||
    unless @room.owned_by?(current_user)
 | 
					    unless @room.owned_by?(current_user)
 | 
				
			||||||
 | 
					      # 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]
 | 
				
			||||||
 | 
					        return redirect_to room_path(room_uid: params[:room_uid]), flash: { alert: I18n.t("room.access_code_required") }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # Assign join name if passed.
 | 
					      # Assign join name if passed.
 | 
				
			||||||
      if params[@room.invite_path]
 | 
					      if params[@room.invite_path]
 | 
				
			||||||
        @join_name = params[@room.invite_path][:join_name]
 | 
					        @join_name = params[@room.invite_path][:join_name]
 | 
				
			||||||
@@ -117,31 +127,7 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
    # create or update cookie with join name
 | 
					    # create or update cookie with join name
 | 
				
			||||||
    cookies.encrypted[:greenlight_name] = @join_name unless cookies.encrypted[:greenlight_name] == @join_name
 | 
					    cookies.encrypted[:greenlight_name] = @join_name unless cookies.encrypted[:greenlight_name] == @join_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if @room.running? || @room.owned_by?(current_user)
 | 
					    join_room(opts)
 | 
				
			||||||
      # Determine if the user needs to join as a moderator.
 | 
					 | 
				
			||||||
      opts[:user_is_moderator] = @room.owned_by?(current_user)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      # Check if the user has specified which client to use
 | 
					 | 
				
			||||||
      room_settings = JSON.parse(@room[:room_settings])
 | 
					 | 
				
			||||||
      opts[:join_via_html5] = room_settings["joinViaHtml5"] if room_settings["joinViaHtml5"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if current_user
 | 
					 | 
				
			||||||
        redirect_to @room.join_path(current_user.name, opts, current_user.uid)
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        join_name = params[:join_name] || params[@room.invite_path][:join_name]
 | 
					 | 
				
			||||||
        redirect_to @room.join_path(join_name, opts)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      search_params = params[@room.invite_path] || params
 | 
					 | 
				
			||||||
      @search, @order_column, @order_direction, pub_recs =
 | 
					 | 
				
			||||||
        @room.public_recordings(search_params.permit(:search, :column, :direction), true)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      @pagy, @public_recordings = pagy_array(pub_recs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      # They need to wait until the meeting begins.
 | 
					 | 
				
			||||||
      render :wait
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # DELETE /:room_uid
 | 
					  # DELETE /:room_uid
 | 
				
			||||||
@@ -184,6 +170,8 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
      update_room_attributes("settings")
 | 
					      update_room_attributes("settings")
 | 
				
			||||||
      # Update the rooms name if it has been changed
 | 
					      # Update the rooms name if it has been changed
 | 
				
			||||||
      update_room_attributes("name") if @room.name != room_params[:name]
 | 
					      update_room_attributes("name") if @room.name != room_params[:name]
 | 
				
			||||||
 | 
					      # Update the room's access code if it has changed
 | 
				
			||||||
 | 
					      update_room_attributes("access_code") if @room.access_code != room_params[:access_code]
 | 
				
			||||||
    rescue StandardError
 | 
					    rescue StandardError
 | 
				
			||||||
      flash[:alert] = I18n.t("room.update_settings_error")
 | 
					      flash[:alert] = I18n.t("room.update_settings_error")
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
@@ -198,6 +186,15 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
    redirect_to @room
 | 
					    redirect_to @room
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # POST /:room_uid/login
 | 
				
			||||||
 | 
					  def login
 | 
				
			||||||
 | 
					    session[:access_code] = room_params[:access_code]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    flash[:alert] = I18n.t("room.access_code_required") if session[:access_code] != @room.access_code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    redirect_to room_path(@room.uid)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def update_room_attributes(update_type)
 | 
					  def update_room_attributes(update_type)
 | 
				
			||||||
@@ -205,13 +202,16 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
      if update_type.eql? "name"
 | 
					      if update_type.eql? "name"
 | 
				
			||||||
        @room.update_attributes(name: params[:room_name] || room_params[:name])
 | 
					        @room.update_attributes(name: params[:room_name] || room_params[:name])
 | 
				
			||||||
      elsif update_type.eql? "settings"
 | 
					      elsif update_type.eql? "settings"
 | 
				
			||||||
        room_settings_string = create_room_settings_string(room_params[:mute_on_join], room_params[:client])
 | 
					        room_settings_string = create_room_settings_string(room_params[:mute_on_join], room_params[:client],
 | 
				
			||||||
 | 
					          room_params[:anyone_can_start])
 | 
				
			||||||
        @room.update_attributes(room_settings: room_settings_string)
 | 
					        @room.update_attributes(room_settings: room_settings_string)
 | 
				
			||||||
 | 
					      elsif update_type.eql? "access_code"
 | 
				
			||||||
 | 
					        @room.update_attributes(access_code: room_params[:access_code])
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def create_room_settings_string(mute_res, client_res)
 | 
					  def create_room_settings_string(mute_res, client_res, start_res)
 | 
				
			||||||
    room_settings = {}
 | 
					    room_settings = {}
 | 
				
			||||||
    room_settings["muteOnStart"] = mute_res == "1"
 | 
					    room_settings["muteOnStart"] = mute_res == "1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -221,11 +221,13 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
      room_settings["joinViaHtml5"] = false
 | 
					      room_settings["joinViaHtml5"] = false
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    room_settings["anyoneCanStart"] = start_res == "1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    room_settings.to_json
 | 
					    room_settings.to_json
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def room_params
 | 
					  def room_params
 | 
				
			||||||
    params.require(:room).permit(:name, :auto_join, :mute_on_join, :client)
 | 
					    params.require(:room).permit(:name, :auto_join, :mute_on_join, :client, :access_code, :anyone_can_start)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Find the room from the uid.
 | 
					  # Find the room from the uid.
 | 
				
			||||||
@@ -274,7 +276,7 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def verify_user_not_admin
 | 
					  def verify_user_not_admin
 | 
				
			||||||
    redirect_to admins_path if current_user && current_user&.has_role?(:super_admin)
 | 
					    redirect_to admins_path if current_user && current_user&.has_cached_role?(:super_admin)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def auth_required
 | 
					  def auth_required
 | 
				
			||||||
@@ -287,8 +289,38 @@ class RoomsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Does not apply to admin
 | 
					    # Does not apply to admin
 | 
				
			||||||
    # 15+ option is used as unlimited
 | 
					    # 15+ option is used as unlimited
 | 
				
			||||||
    return false if current_user&.has_role?(:admin) || limit == 15
 | 
					    return false if current_user&.has_cached_role?(:admin) || limit == 15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    current_user.rooms.count >= limit
 | 
					    current_user.rooms.count >= limit
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def join_room(opts)
 | 
				
			||||||
 | 
					    room_settings = JSON.parse(@room[:room_settings])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if @room.running? || @room.owned_by?(current_user) || room_settings["anyoneCanStart"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # Determine if the user needs to join as a moderator.
 | 
				
			||||||
 | 
					      opts[:user_is_moderator] = @room.owned_by?(current_user) ||
 | 
				
			||||||
 | 
					                                 (room_settings["anyoneCanStart"] && !@room.running?)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # Check if the user has specified which client to use
 | 
				
			||||||
 | 
					      opts[:join_via_html5] = room_settings["joinViaHtml5"] if room_settings["joinViaHtml5"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if current_user
 | 
				
			||||||
 | 
					        redirect_to @room.join_path(current_user.name, opts, current_user.uid)
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        join_name = params[:join_name] || params[@room.invite_path][:join_name]
 | 
				
			||||||
 | 
					        redirect_to @room.join_path(join_name, opts)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      search_params = params[@room.invite_path] || params
 | 
				
			||||||
 | 
					      @search, @order_column, @order_direction, pub_recs =
 | 
				
			||||||
 | 
					        public_recordings(@room.bbb_id, @user_domain, search_params.permit(:search, :column, :direction), true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @pagy, @public_recordings = pagy_array(pub_recs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # They need to wait until the meeting begins.
 | 
				
			||||||
 | 
					      render :wait
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ class ThemesController < ApplicationController
 | 
				
			|||||||
    @file_contents = File.read(file_name)
 | 
					    @file_contents = File.read(file_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Include the variables and covert scss file to css
 | 
					    # Include the variables and covert scss file to css
 | 
				
			||||||
    @compiled = Sass::Engine.new("$primary-color:#{color};" \
 | 
					    @compiled = SassC::Engine.new("$primary-color:#{color};" \
 | 
				
			||||||
                                 "$primary-color-lighten:#{lighten_color};" \
 | 
					                                 "$primary-color-lighten:#{lighten_color};" \
 | 
				
			||||||
                                 "$primary-color-darken:#{darken_color};" +
 | 
					                                 "$primary-color-darken:#{darken_color};" +
 | 
				
			||||||
                                 @file_contents, syntax: :scss).render
 | 
					                                 @file_contents, syntax: :scss).render
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@ class UsersController < ApplicationController
 | 
				
			|||||||
  include Pagy::Backend
 | 
					  include Pagy::Backend
 | 
				
			||||||
  include Emailer
 | 
					  include Emailer
 | 
				
			||||||
  include Registrar
 | 
					  include Registrar
 | 
				
			||||||
 | 
					  include Recorder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before_action :find_user, only: [:edit, :update, :destroy]
 | 
					  before_action :find_user, only: [:edit, :update, :destroy]
 | 
				
			||||||
  before_action :ensure_unauthenticated, only: [:new, :create]
 | 
					  before_action :ensure_unauthenticated, only: [:new, :create]
 | 
				
			||||||
@@ -66,6 +67,12 @@ class UsersController < ApplicationController
 | 
				
			|||||||
      flash[:alert] = I18n.t("registration.deprecated.new_signin")
 | 
					      flash[:alert] = I18n.t("registration.deprecated.new_signin")
 | 
				
			||||||
      session[:old_twitter_user_id] = params[:old_twitter_user_id] unless params[:old_twitter_user_id].nil?
 | 
					      session[:old_twitter_user_id] = params[:old_twitter_user_id] unless params[:old_twitter_user_id].nil?
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    providers = configured_providers
 | 
				
			||||||
 | 
					    if (!allow_user_signup? || !allow_greenlight_accounts?) && providers.count == 1 &&
 | 
				
			||||||
 | 
					       !Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
 | 
					      return redirect_to "#{Rails.configuration.relative_url_root}/auth/#{providers.first}"
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # GET /ldap_signin
 | 
					  # GET /ldap_signin
 | 
				
			||||||
@@ -103,6 +110,8 @@ class UsersController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # PATCH /u/:user_uid/edit
 | 
					  # PATCH /u/:user_uid/edit
 | 
				
			||||||
  def update
 | 
					  def update
 | 
				
			||||||
 | 
					    redirect_path = current_user.admin_of?(@user) ? admins_path : edit_user_path(@user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if params[:setting] == "password"
 | 
					    if params[:setting] == "password"
 | 
				
			||||||
      # Update the users password.
 | 
					      # Update the users password.
 | 
				
			||||||
      errors = {}
 | 
					      errors = {}
 | 
				
			||||||
@@ -123,7 +132,7 @@ class UsersController < ApplicationController
 | 
				
			|||||||
      if errors.empty? && @user.save
 | 
					      if errors.empty? && @user.save
 | 
				
			||||||
        # Notify the user that their account has been updated.
 | 
					        # Notify the user that their account has been updated.
 | 
				
			||||||
        flash[:success] = I18n.t("info_update_success")
 | 
					        flash[:success] = I18n.t("info_update_success")
 | 
				
			||||||
        redirect_to edit_user_path(@user)
 | 
					        redirect_to redirect_path
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        # Append custom errors.
 | 
					        # Append custom errors.
 | 
				
			||||||
        errors.each { |k, v| @user.errors.add(k, v) }
 | 
					        errors.each { |k, v| @user.errors.add(k, v) }
 | 
				
			||||||
@@ -132,11 +141,11 @@ class UsersController < ApplicationController
 | 
				
			|||||||
    elsif user_params[:email] != @user.email && @user.update_attributes(user_params)
 | 
					    elsif user_params[:email] != @user.email && @user.update_attributes(user_params)
 | 
				
			||||||
      @user.update_attributes(email_verified: false)
 | 
					      @user.update_attributes(email_verified: false)
 | 
				
			||||||
      flash[:success] = I18n.t("info_update_success")
 | 
					      flash[:success] = I18n.t("info_update_success")
 | 
				
			||||||
      redirect_to edit_user_path(@user)
 | 
					      redirect_to redirect_path
 | 
				
			||||||
    elsif @user.update_attributes(user_params)
 | 
					    elsif @user.update_attributes(user_params)
 | 
				
			||||||
      update_locale(@user)
 | 
					      update_locale(@user)
 | 
				
			||||||
      flash[:success] = I18n.t("info_update_success")
 | 
					      flash[:success] = I18n.t("info_update_success")
 | 
				
			||||||
      redirect_to edit_user_path(@user)
 | 
					      redirect_to redirect_path
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      render :edit, params: { settings: params[:settings] }
 | 
					      render :edit, params: { settings: params[:settings] }
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
@@ -165,7 +174,8 @@ class UsersController < ApplicationController
 | 
				
			|||||||
  def recordings
 | 
					  def recordings
 | 
				
			||||||
    if current_user && current_user.uid == params[:user_uid]
 | 
					    if current_user && current_user.uid == params[:user_uid]
 | 
				
			||||||
      @search, @order_column, @order_direction, recs =
 | 
					      @search, @order_column, @order_direction, recs =
 | 
				
			||||||
        current_user.all_recordings(params.permit(:search, :column, :direction), true)
 | 
					        all_recordings(current_user.rooms.pluck(:bbb_id), current_user.provider,
 | 
				
			||||||
 | 
					         params.permit(:search, :column, :direction), true)
 | 
				
			||||||
      @pagy, @recordings = pagy_array(recs)
 | 
					      @pagy, @recordings = pagy_array(recs)
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      redirect_to root_path
 | 
					      redirect_to root_path
 | 
				
			||||||
@@ -185,7 +195,7 @@ class UsersController < ApplicationController
 | 
				
			|||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def find_user
 | 
					  def find_user
 | 
				
			||||||
    @user = User.find_by!(uid: params[:user_uid])
 | 
					    @user = User.where(uid: params[:user_uid]).includes(:roles).first
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def ensure_unauthenticated
 | 
					  def ensure_unauthenticated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,18 @@
 | 
				
			|||||||
module AdminsHelper
 | 
					module AdminsHelper
 | 
				
			||||||
  include Pagy::Frontend
 | 
					  include Pagy::Frontend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Returns the action method of the current page
 | 
				
			||||||
 | 
					  def active_page
 | 
				
			||||||
 | 
					    route = Rails.application.routes.recognize_path(request.env['PATH_INFO'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    route[:action]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Gets the email of the room owner to which the recording belongs to
 | 
				
			||||||
 | 
					  def recording_owner_email(room_id)
 | 
				
			||||||
 | 
					    Room.find_by(bbb_id: room_id).owner.email
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def display_invite
 | 
					  def display_invite
 | 
				
			||||||
    current_page?(admins_path) && invite_registration
 | 
					    current_page?(admins_path) && invite_registration
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
@@ -43,6 +55,15 @@ module AdminsHelper
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def recording_default_visibility_string
 | 
				
			||||||
 | 
					    if Setting.find_or_create_by!(provider: user_settings_provider)
 | 
				
			||||||
 | 
					              .get_value("Default Recording Visibility") == "public"
 | 
				
			||||||
 | 
					      I18n.t("administrator.site_settings.recording_visibility.public")
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      I18n.t("administrator.site_settings.recording_visibility.private")
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def registration_method_string
 | 
					  def registration_method_string
 | 
				
			||||||
    case registration_method
 | 
					    case registration_method
 | 
				
			||||||
    when Rails.configuration.registration_methods[:open]
 | 
					    when Rails.configuration.registration_methods[:open]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -107,7 +107,7 @@ module ApplicationHelper
 | 
				
			|||||||
  # Returns the page that the logo redirects to when clicked on
 | 
					  # Returns the page that the logo redirects to when clicked on
 | 
				
			||||||
  def home_page
 | 
					  def home_page
 | 
				
			||||||
    return root_path unless current_user
 | 
					    return root_path unless current_user
 | 
				
			||||||
    return admins_path if current_user.has_role? :super_admin
 | 
					    return admins_path if current_user.has_cached_role? :super_admin
 | 
				
			||||||
    current_user.main_room
 | 
					    current_user.main_room
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,7 +37,7 @@ module RoomsHelper
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Does not apply to admin or users that aren't signed in
 | 
					    # Does not apply to admin or users that aren't signed in
 | 
				
			||||||
    # 15+ option is used as unlimited
 | 
					    # 15+ option is used as unlimited
 | 
				
			||||||
    return false if current_user&.has_role?(:admin) || limit == 15
 | 
					    return false if current_user&.has_cached_role?(:admin) || limit == 15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    current_user.rooms.length >= limit
 | 
					    current_user.rooms.length >= limit
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
@@ -46,7 +46,7 @@ module RoomsHelper
 | 
				
			|||||||
    # Get how many rooms need to be deleted to reach allowed room number
 | 
					    # Get how many rooms need to be deleted to reach allowed room number
 | 
				
			||||||
    limit = Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i
 | 
					    limit = Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return false if current_user&.has_role?(:admin) || limit == 15
 | 
					    return false if current_user&.has_cached_role?(:admin) || limit == 15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @diff = current_user.rooms.count - limit
 | 
					    @diff = current_user.rooms.count - limit
 | 
				
			||||||
    @diff.positive? && current_user.rooms.pluck(:id).index(room.id) + 1 > limit
 | 
					    @diff.positive? && current_user.rooms.pluck(:id).index(room.id) + 1 > limit
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,17 @@ module SessionsHelper
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Retrieves the current user.
 | 
					  # Retrieves the current user.
 | 
				
			||||||
  def current_user
 | 
					  def current_user
 | 
				
			||||||
    @current_user ||= User.find_by(id: session[:user_id])
 | 
					    @current_user ||= User.where(id: session[:user_id]).includes(:roles).first
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
 | 
					      if @current_user && !@current_user.has_role?(:super_admin) &&
 | 
				
			||||||
 | 
					         @current_user.provider != @user_domain
 | 
				
			||||||
 | 
					        @current_user = nil
 | 
				
			||||||
 | 
					        session.clear
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @current_user
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def generate_checksum(user_domain, redirect_url, secret)
 | 
					  def generate_checksum(user_domain, redirect_url, secret)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ module ThemingHelper
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Returns the user's provider in the settings context
 | 
					  # Returns the user's provider in the settings context
 | 
				
			||||||
  def user_settings_provider
 | 
					  def user_settings_provider
 | 
				
			||||||
    if Rails.configuration.loadbalanced_configuration && current_user && !current_user&.has_role?(:super_admin)
 | 
					    if Rails.configuration.loadbalanced_configuration && current_user && !current_user&.has_cached_role?(:super_admin)
 | 
				
			||||||
      current_user.provider
 | 
					      current_user.provider
 | 
				
			||||||
    elsif Rails.configuration.loadbalanced_configuration
 | 
					    elsif Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
      @user_domain
 | 
					      @user_domain
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,6 @@
 | 
				
			|||||||
require 'bbb_api'
 | 
					require 'bbb_api'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Room < ApplicationRecord
 | 
					class Room < ApplicationRecord
 | 
				
			||||||
  include ::APIConcern
 | 
					 | 
				
			||||||
  include ::BbbApi
 | 
					  include ::BbbApi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before_create :setup
 | 
					  before_create :setup
 | 
				
			||||||
@@ -40,7 +39,7 @@ class Room < ApplicationRecord
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Checks if a room is running on the BigBlueButton server.
 | 
					  # Checks if a room is running on the BigBlueButton server.
 | 
				
			||||||
  def running?
 | 
					  def running?
 | 
				
			||||||
    bbb.is_meeting_running?(bbb_id)
 | 
					    bbb(owner.provider).is_meeting_running?(bbb_id)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Determines the invite path for the room.
 | 
					  # Determines the invite path for the room.
 | 
				
			||||||
@@ -57,12 +56,15 @@ class Room < ApplicationRecord
 | 
				
			|||||||
      attendeePW: attendee_pw,
 | 
					      attendeePW: attendee_pw,
 | 
				
			||||||
      moderatorOnlyMessage: options[:moderator_message],
 | 
					      moderatorOnlyMessage: options[:moderator_message],
 | 
				
			||||||
      muteOnStart: options[:mute_on_start] || false,
 | 
					      muteOnStart: options[:mute_on_start] || false,
 | 
				
			||||||
      "meta_#{META_LISTED}": false,
 | 
					      "meta_#{META_LISTED}": options[:recording_default_visibility] || false,
 | 
				
			||||||
 | 
					      "meta_bbb-origin-version": Greenlight::Application::VERSION,
 | 
				
			||||||
 | 
					      "meta_bbb-origin": "Greenlight",
 | 
				
			||||||
 | 
					      "meta_bbb-origin-server-name": options[:host]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Send the create request.
 | 
					    # Send the create request.
 | 
				
			||||||
    begin
 | 
					    begin
 | 
				
			||||||
      meeting = bbb.create_meeting(name, bbb_id, create_options)
 | 
					      meeting = bbb(owner.provider).create_meeting(name, bbb_id, create_options)
 | 
				
			||||||
      # Update session info.
 | 
					      # Update session info.
 | 
				
			||||||
      unless meeting[:messageKey] == 'duplicateWarning'
 | 
					      unless meeting[:messageKey] == 'duplicateWarning'
 | 
				
			||||||
        update_attributes(sessions: sessions + 1,
 | 
					        update_attributes(sessions: sessions + 1,
 | 
				
			||||||
@@ -85,10 +87,10 @@ class Room < ApplicationRecord
 | 
				
			|||||||
    options[:user_is_moderator] ||= false
 | 
					    options[:user_is_moderator] ||= false
 | 
				
			||||||
    options[:meeting_recorded] ||= false
 | 
					    options[:meeting_recorded] ||= false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return call_invalid_res unless bbb
 | 
					    return call_invalid_res unless bbb(owner.provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Get the meeting info.
 | 
					    # Get the meeting info.
 | 
				
			||||||
    meeting_info = bbb.get_meeting_info(bbb_id, nil)
 | 
					    meeting_info = bbb(owner.provider).get_meeting_info(bbb_id, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Determine the password to use when joining.
 | 
					    # Determine the password to use when joining.
 | 
				
			||||||
    password = if options[:user_is_moderator]
 | 
					    password = if options[:user_is_moderator]
 | 
				
			||||||
@@ -102,7 +104,7 @@ class Room < ApplicationRecord
 | 
				
			|||||||
    join_opts[:userID] = uid if uid
 | 
					    join_opts[:userID] = uid if uid
 | 
				
			||||||
    join_opts[:joinViaHtml5] = options[:join_via_html5] if options[:join_via_html5]
 | 
					    join_opts[:joinViaHtml5] = options[:join_via_html5] if options[:join_via_html5]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bbb.join_meeting_url(bbb_id, name, password, join_opts)
 | 
					    bbb(owner.provider).join_meeting_url(bbb_id, name, password, join_opts)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Notify waiting users that a meeting has started.
 | 
					  # Notify waiting users that a meeting has started.
 | 
				
			||||||
@@ -112,7 +114,7 @@ class Room < ApplicationRecord
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Retrieves all the users in a room.
 | 
					  # Retrieves all the users in a room.
 | 
				
			||||||
  def participants
 | 
					  def participants
 | 
				
			||||||
    res = bbb.get_meeting_info(bbb_id, nil)
 | 
					    res = bbb(owner.provider).get_meeting_info(bbb_id, nil)
 | 
				
			||||||
    res[:attendees].map do |att|
 | 
					    res[:attendees].map do |att|
 | 
				
			||||||
      User.find_by(uid: att[:userID], name: att[:fullName])
 | 
					      User.find_by(uid: att[:userID], name: att[:fullName])
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
@@ -121,27 +123,18 @@ class Room < ApplicationRecord
 | 
				
			|||||||
    []
 | 
					    []
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Fetches all recordings for a room.
 | 
					  def recording_count
 | 
				
			||||||
  def recordings(search_params = {}, ret_search_params = false)
 | 
					    bbb(owner.provider).get_recordings(meetingID: bbb_id)[:recordings].length
 | 
				
			||||||
    res = bbb.get_recordings(meetingID: bbb_id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    format_recordings(res, search_params, ret_search_params)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Fetches a rooms public recordings.
 | 
					 | 
				
			||||||
  def public_recordings(search_params = {}, ret_search_params = false)
 | 
					 | 
				
			||||||
    search, order_col, order_dir, recs = recordings(search_params, ret_search_params)
 | 
					 | 
				
			||||||
    [search, order_col, order_dir, recs.select { |r| r[:metadata][:"gl-listed"] == "true" }]
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def update_recording(record_id, meta)
 | 
					  def update_recording(record_id, meta)
 | 
				
			||||||
    meta[:recordID] = record_id
 | 
					    meta[:recordID] = record_id
 | 
				
			||||||
    bbb.send_api_request("updateRecordings", meta)
 | 
					    bbb(owner.provider).send_api_request("updateRecordings", meta)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Deletes a recording from a room.
 | 
					  # Deletes a recording from a room.
 | 
				
			||||||
  def delete_recording(record_id)
 | 
					  def delete_recording(record_id)
 | 
				
			||||||
    bbb.delete_recordings(record_id)
 | 
					    bbb(owner.provider).delete_recordings(record_id)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
@@ -156,7 +149,7 @@ class Room < ApplicationRecord
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Deletes all recordings associated with the room.
 | 
					  # Deletes all recordings associated with the room.
 | 
				
			||||||
  def delete_all_recordings
 | 
					  def delete_all_recordings
 | 
				
			||||||
    record_ids = recordings.map { |r| r[:recordID] }
 | 
					    record_ids = bbb(owner.provider).get_recordings(meetingID: bbb_id)[:recordings].pluck(:recordID)
 | 
				
			||||||
    delete_recording(record_ids) unless record_ids.empty?
 | 
					    delete_recording(record_ids) unless record_ids.empty?
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,6 @@ require 'bbb_api'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class User < ApplicationRecord
 | 
					class User < ApplicationRecord
 | 
				
			||||||
  rolify
 | 
					  rolify
 | 
				
			||||||
  include ::APIConcern
 | 
					 | 
				
			||||||
  include ::BbbApi
 | 
					  include ::BbbApi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  attr_accessor :reset_token
 | 
					  attr_accessor :reset_token
 | 
				
			||||||
@@ -119,7 +118,7 @@ class User < ApplicationRecord
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def self.admins_search(string)
 | 
					  def self.admins_search(string, role)
 | 
				
			||||||
    active_database = Rails.configuration.database_configuration[Rails.env]["adapter"]
 | 
					    active_database = Rails.configuration.database_configuration[Rails.env]["adapter"]
 | 
				
			||||||
    # Postgres requires created_at to be cast to a string
 | 
					    # Postgres requires created_at to be cast to a string
 | 
				
			||||||
    created_at_query = if active_database == "postgresql"
 | 
					    created_at_query = if active_database == "postgresql"
 | 
				
			||||||
@@ -128,38 +127,29 @@ class User < ApplicationRecord
 | 
				
			|||||||
      "created_at"
 | 
					      "created_at"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    search_query = ""
 | 
				
			||||||
 | 
					    role_search_param = ""
 | 
				
			||||||
 | 
					    if role.present?
 | 
				
			||||||
 | 
					      search_query = "(users.name LIKE :search OR email LIKE :search OR username LIKE :search" \
 | 
				
			||||||
 | 
					                    " OR users.#{created_at_query} LIKE :search OR provider LIKE :search)" \
 | 
				
			||||||
 | 
					                    " AND roles.name = :roles_search"
 | 
				
			||||||
 | 
					      role_search_param = role
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
      search_query = "users.name LIKE :search OR email LIKE :search OR username LIKE :search" \
 | 
					      search_query = "users.name LIKE :search OR email LIKE :search OR username LIKE :search" \
 | 
				
			||||||
                   " OR users.#{created_at_query} LIKE :search OR provider LIKE :search"
 | 
					                    " OR users.#{created_at_query} LIKE :search OR provider LIKE :search" \
 | 
				
			||||||
 | 
					                    " OR roles.name LIKE :roles_search"
 | 
				
			||||||
 | 
					      role_search_param = "%#{string}%".downcase
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    search_param = "%#{string}%"
 | 
					    search_param = "%#{string}%"
 | 
				
			||||||
    where(search_query, search: search_param)
 | 
					    joins("LEFT OUTER JOIN users_roles ON users_roles.user_id = users.id LEFT OUTER JOIN roles " \
 | 
				
			||||||
 | 
					      "ON roles.id = users_roles.role_id").distinct
 | 
				
			||||||
 | 
					      .where(search_query, search: search_param, roles_search: role_search_param)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def self.admins_order(column, direction)
 | 
					  def self.admins_order(column, direction)
 | 
				
			||||||
    order("#{column} #{direction}")
 | 
					    # Arel.sql to avoid sql injection
 | 
				
			||||||
  end
 | 
					    order(Arel.sql("#{column} #{direction}"))
 | 
				
			||||||
 | 
					 | 
				
			||||||
  def all_recordings(search_params = {}, ret_search_params = false)
 | 
					 | 
				
			||||||
    pag_num = Rails.configuration.pagination_number
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pag_loops = rooms.length / pag_num - 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    res = { recordings: [] }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (0..pag_loops).each do |i|
 | 
					 | 
				
			||||||
      pag_rooms = rooms[pag_num * i, pag_num]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      # bbb.get_recordings returns an object
 | 
					 | 
				
			||||||
      # take only the array portion of the object that is returned
 | 
					 | 
				
			||||||
      full_res = bbb.get_recordings(meetingID: pag_rooms.pluck(:bbb_id))
 | 
					 | 
				
			||||||
      res[:recordings].push(*full_res[:recordings])
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    last_pag_room = rooms[pag_num * (pag_loops + 1), rooms.length % pag_num]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    full_res = bbb.get_recordings(meetingID: last_pag_room.pluck(:bbb_id))
 | 
					 | 
				
			||||||
    res[:recordings].push(*full_res[:recordings])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    format_recordings(res, search_params, ret_search_params)
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Activates an account and initialize a users main room
 | 
					  # Activates an account and initialize a users main room
 | 
				
			||||||
@@ -231,13 +221,17 @@ class User < ApplicationRecord
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  def admin_of?(user)
 | 
					  def admin_of?(user)
 | 
				
			||||||
    if Rails.configuration.loadbalanced_configuration
 | 
					    if Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
      if has_role? :super_admin
 | 
					      # Pulls in the user roles if they weren't request in the original request
 | 
				
			||||||
 | 
					      # So the has_cached_role? doesn't always return false
 | 
				
			||||||
 | 
					      user.roles
 | 
				
			||||||
 | 
					      if has_cached_role? :super_admin
 | 
				
			||||||
        id != user.id
 | 
					        id != user.id
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        (has_role? :admin) && (id != user.id) && (provider == user.provider) && (!user.has_role? :super_admin)
 | 
					        (has_cached_role? :admin) && (id != user.id) && (provider == user.provider) &&
 | 
				
			||||||
 | 
					          (!user.has_cached_role? :super_admin)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      ((has_role? :admin) || (has_role? :super_admin)) && (id != user.id)
 | 
					      ((has_cached_role? :admin) || (has_cached_role? :super_admin)) && (id != user.id)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								app/views/admins/components/_menu_buttons.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/views/admins/components/_menu_buttons.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="list-group list-group-transparent mb-0">
 | 
				
			||||||
 | 
					  <%= link_to admins_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "index"}" do %>
 | 
				
			||||||
 | 
					    <span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					  <%= link_to admin_site_settings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "site_settings"}" do %>
 | 
				
			||||||
 | 
					    <span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					  <%= link_to admin_recordings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "server_recordings"}" do %>
 | 
				
			||||||
 | 
					    <span class="icon mr-4"><i class="fas fa-video"></i></i></span><%= t("administrator.recordings.title") %>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										91
									
								
								app/views/admins/components/_recordings.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								app/views/admins/components/_recordings.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="row">
 | 
				
			||||||
 | 
					  <div class="col-12">
 | 
				
			||||||
 | 
					    <div class="table-responsive">
 | 
				
			||||||
 | 
					      <table id="recordings-table" class="table table-hover table-outline table-vcenter text-nowrap card-table">
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <th data-header="name" data-order="<%= @order_column == "name" ? @order_direction : "none" %>">
 | 
				
			||||||
 | 
					              <%= t("recording.table.name") %>
 | 
				
			||||||
 | 
					              <% if @order_column == "name" && @order_direction == "desc" %>
 | 
				
			||||||
 | 
					                ↓
 | 
				
			||||||
 | 
					              <% elsif @order_column == "name" && @order_direction == "asc" %>
 | 
				
			||||||
 | 
					                ↑
 | 
				
			||||||
 | 
					              <% end %>
 | 
				
			||||||
 | 
					            </th>
 | 
				
			||||||
 | 
					            <th class="text-left" data-header="length" data-order="<%= @order_column == "length" ? @order_direction : "none" %>">
 | 
				
			||||||
 | 
					              <%= t("recording.table.length") %>
 | 
				
			||||||
 | 
					              <% if @order_column == "length" && @order_direction == "desc" %>
 | 
				
			||||||
 | 
					                ↓
 | 
				
			||||||
 | 
					              <% elsif @order_column == "length" && @order_direction == "asc" %>
 | 
				
			||||||
 | 
					                ↑
 | 
				
			||||||
 | 
					              <% end %>
 | 
				
			||||||
 | 
					            </th>
 | 
				
			||||||
 | 
					            <th class="text-left" data-header="users" data-order="<%= @order_column == "users" ? @order_direction : "none" %>">
 | 
				
			||||||
 | 
					              <%= t("recording.table.users") %>
 | 
				
			||||||
 | 
					              <% if @order_column == "users" && @order_direction == "desc" %>
 | 
				
			||||||
 | 
					                ↓
 | 
				
			||||||
 | 
					              <% elsif @order_column == "users" && @order_direction == "asc" %>
 | 
				
			||||||
 | 
					                ↑
 | 
				
			||||||
 | 
					              <% end %>
 | 
				
			||||||
 | 
					            </th>
 | 
				
			||||||
 | 
					            <th class="text-left" data-header="visibility" data-order="<%= @order_column == "visibility" ? @order_direction : "none" %>">
 | 
				
			||||||
 | 
					              <%= t("recording.table.visibility") %>
 | 
				
			||||||
 | 
					              <% if @order_column == "visibility" && @order_direction == "desc" %>
 | 
				
			||||||
 | 
					                ↓
 | 
				
			||||||
 | 
					              <% elsif @order_column == "visibility" && @order_direction == "asc" %>
 | 
				
			||||||
 | 
					                ↑
 | 
				
			||||||
 | 
					              <% end %>
 | 
				
			||||||
 | 
					            </th>
 | 
				
			||||||
 | 
					            <th data-header="formats" data-order="<%= @order_column == "formats" ? @order_direction : "none" %>">
 | 
				
			||||||
 | 
					              <%= t("recording.table.formats") %>
 | 
				
			||||||
 | 
					              <% if @order_column == "formats" && @order_direction == "desc" %>
 | 
				
			||||||
 | 
					                ↓
 | 
				
			||||||
 | 
					              <% elsif @order_column == "formats" && @order_direction == "asc" %>
 | 
				
			||||||
 | 
					                ↑
 | 
				
			||||||
 | 
					              <% end %>
 | 
				
			||||||
 | 
					            </th>
 | 
				
			||||||
 | 
					            <th class="text-center"><i class="icon-settings"></i></th>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody id="recording-table">
 | 
				
			||||||
 | 
					          <tr id="no_recordings_found" style="display: none;">
 | 
				
			||||||
 | 
					            <td colspan="7" class="text-center h4 p-6 font-weight-normal" >
 | 
				
			||||||
 | 
					              <%= t("recording.no_matched_recordings", inject:"") %>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					          <% if @recordings.empty? %>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					              <td colspan="7" class="text-center h4 p-6 font-weight-normal">
 | 
				
			||||||
 | 
					                <%= t("administrator.recordings.no_recordings") %>
 | 
				
			||||||
 | 
					              </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					          <% else %>
 | 
				
			||||||
 | 
					            <% @recordings.each do |recording| %>
 | 
				
			||||||
 | 
					              <%= render "admins/components/server_recording_row", recording: recording %>
 | 
				
			||||||
 | 
					            <% end %>
 | 
				
			||||||
 | 
					          <% end %>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					      </table>
 | 
				
			||||||
 | 
					      <% if !@recordings.empty?%>
 | 
				
			||||||
 | 
					        <div class="float-right mr-4 mt-4">
 | 
				
			||||||
 | 
					          <%== pagy_bootstrap_nav(@pagy) %>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      <% end %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										81
									
								
								app/views/admins/components/_server_recording_row.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/views/admins/components/_server_recording_row.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<tr>
 | 
				
			||||||
 | 
					  <td>
 | 
				
			||||||
 | 
					    <div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= update_room_path(room_uid: room_uid_from_bbb(recording[:meetingID])) %>">
 | 
				
			||||||
 | 
					      <text id='recording-text'>
 | 
				
			||||||
 | 
					        <% if recording[:metadata][:name] %>
 | 
				
			||||||
 | 
					          <%= recording[:metadata][:name] %>
 | 
				
			||||||
 | 
					        <% else %>
 | 
				
			||||||
 | 
					          <%= recording[:name] %>
 | 
				
			||||||
 | 
					        <% end %>
 | 
				
			||||||
 | 
					      </text>
 | 
				
			||||||
 | 
					      <a><i id="edit-record" class="fa fa-edit align-top ml-2" data-edit-recordid="<%= recording[:recordID] %>"></i></a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="small text-muted">
 | 
				
			||||||
 | 
					      <%= t("recording.recorded_on", date: recording_date(recording[:startTime])) %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="small text-muted">
 | 
				
			||||||
 | 
					      <%= recording_owner_email(recording[:meetingID]) %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </td>
 | 
				
			||||||
 | 
					  <td id="recording-length" class="text-left" data-full-length="<%= recording[:playbacks].empty? ? 0 : recording[:playbacks].first[:length]%>">
 | 
				
			||||||
 | 
					    <%= recording_length(recording[:playbacks]) %>
 | 
				
			||||||
 | 
					  </td>
 | 
				
			||||||
 | 
					  <td id="recording-users" class="text-left">
 | 
				
			||||||
 | 
					    <%= recording[:participants] || "-" %>
 | 
				
			||||||
 | 
					  </td>
 | 
				
			||||||
 | 
					  <td class="text-left">
 | 
				
			||||||
 | 
					    <div class="dropdown">
 | 
				
			||||||
 | 
					      <% if recording[:metadata][:"gl-listed"] == "true" %>
 | 
				
			||||||
 | 
					        <button class="btn btn-sm btn-secondary dropdown-toggle" data-toggle="dropdown"><i class="dropdown-icon fas fa-globe px-2"></i> <%= t("recording.visibility.public") %></button>
 | 
				
			||||||
 | 
					      <% else %>
 | 
				
			||||||
 | 
					        <button class="btn btn-sm btn-secondary dropdown-toggle" data-toggle="dropdown"><i class="dropdown-icon fas fa-link px-2"></i> <%= t("recording.visibility.unlisted") %></button>
 | 
				
			||||||
 | 
					      <% end %>
 | 
				
			||||||
 | 
					      <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
 | 
				
			||||||
 | 
					        <%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "public"), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					          <i class="dropdown-icon fas fa-globe"></i> <%= t("recording.visibility.public") %>
 | 
				
			||||||
 | 
					        <% end %>
 | 
				
			||||||
 | 
					        <%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "unlisted"), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					          <i class="dropdown-icon fas fa-link"></i> <%= t("recording.visibility.unlisted") %>
 | 
				
			||||||
 | 
					        <% end %>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </td>
 | 
				
			||||||
 | 
					  <td>
 | 
				
			||||||
 | 
					    <% sorted_formats = recording[:playbacks].sort_by! { |p| p[:type] } %>
 | 
				
			||||||
 | 
					    <% sorted_formats.each do |p| %>
 | 
				
			||||||
 | 
					      <%= link_to t("recording.format.#{p[:type]}"), p[:url], class: "btn btn-sm btn-primary", target: "_blank" %>
 | 
				
			||||||
 | 
					    <% end %>
 | 
				
			||||||
 | 
					  </td>
 | 
				
			||||||
 | 
					  <td class="text-center">
 | 
				
			||||||
 | 
					    <div class="item-action dropdown">
 | 
				
			||||||
 | 
					      <a href="javascript:void(0)" data-toggle="dropdown" class="icon">
 | 
				
			||||||
 | 
					        <i class="fas fa-ellipsis-v px-4"></i>
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					      <div class="dropdown-menu dropdown-menu-right">
 | 
				
			||||||
 | 
					        <% p = recording[:playbacks].find do |p| p.key?(:length) end %>
 | 
				
			||||||
 | 
					        <% if p %>
 | 
				
			||||||
 | 
					          <a class="dropdown-item email-link" data-pres-link="<%= p[:url] %>"><i class="dropdown-icon far fa-envelope"></i> <%= t("recording.email") %></a>
 | 
				
			||||||
 | 
					          <div class="dropdown-divider"></div>
 | 
				
			||||||
 | 
					        <% end %>
 | 
				
			||||||
 | 
					        <%= button_to delete_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]), method: :delete, class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					          <i class="dropdown-icon far fa-trash-alt"></i> <%= t("delete") %>
 | 
				
			||||||
 | 
					        <% end %>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </td>
 | 
				
			||||||
 | 
					</tr>
 | 
				
			||||||
							
								
								
									
										26
									
								
								app/views/admins/components/_setting_view.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/views/admins/components/_setting_view.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= content_tag(:div, id: setting_id, class: "setting-view card") do %>
 | 
				
			||||||
 | 
					  <div class="card-body p-6">
 | 
				
			||||||
 | 
					    <div class="card-title text-primary">
 | 
				
			||||||
 | 
					      <div class="form-group">
 | 
				
			||||||
 | 
					        <%= render "shared/components/subtitle", subtitle: setting_title, search: search %>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <%= render "admins/components/#{setting_id}" %>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					<% end %>
 | 
				
			||||||
@@ -98,6 +98,27 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					   <div class="mb-6 row">
 | 
				
			||||||
 | 
					    <div class="col-12">
 | 
				
			||||||
 | 
					      <div class="form-group">
 | 
				
			||||||
 | 
					        <label class="form-label"><%= t("administrator.site_settings.recording_visibility.title") %></label>
 | 
				
			||||||
 | 
					        <label class="form-label text-muted"><%= t("administrator.site_settings.recording_visibility.info") %></label>
 | 
				
			||||||
 | 
					        <div class="dropdown">
 | 
				
			||||||
 | 
					          <button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
 | 
				
			||||||
 | 
					            <%= recording_default_visibility_string %>
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					          <div class="dropdown-menu" aria-labelledby="room-auth">
 | 
				
			||||||
 | 
					            <%= button_to admin_recording_visibility_path(visibility: "public"), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					              <%= t("administrator.site_settings.recording_visibility.public") %>
 | 
				
			||||||
 | 
					            <% end %>
 | 
				
			||||||
 | 
					            <%= button_to admin_recording_visibility_path(visibility: "private"), class: "dropdown-item" do %>
 | 
				
			||||||
 | 
					              <%= t("administrator.site_settings.recording_visibility.private") %>
 | 
				
			||||||
 | 
					            <% end %>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div class="row">
 | 
					  <div class="row">
 | 
				
			||||||
    <div class="col-12">
 | 
					    <div class="col-12">
 | 
				
			||||||
@@ -13,6 +13,21 @@
 | 
				
			|||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
%>
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<% if @role.present? %>
 | 
					<% if @role.present? %>
 | 
				
			||||||
  <%= render "shared/components/admins_tags" %>
 | 
					  <%= render "shared/components/admins_tags" %>
 | 
				
			||||||
<% end %>
 | 
					<% end %>
 | 
				
			||||||
@@ -146,3 +161,4 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<%= render "shared/modals/invite_user_modal" %>
 | 
					<%= render "shared/modals/invite_user_modal" %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/views/admins/edit_user.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/views/admins/edit_user.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container pt-6">
 | 
				
			||||||
 | 
					  <%= render "shared/components/subtitle", subtitle: t("administrator.title"), search: false %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="row">
 | 
				
			||||||
 | 
					    <div class="col-lg-3 mb-4">
 | 
				
			||||||
 | 
					      <%= render "admins/components/menu_buttons" %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div id="edit_user" class="col-lg-9">
 | 
				
			||||||
 | 
					      <%= render "shared/settings/setting_view", setting_id: "account", setting_title: t("settings.account.subtitle") %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@@ -18,26 +18,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  <div class="row">
 | 
					  <div class="row">
 | 
				
			||||||
    <div class="col-lg-3 mb-4">
 | 
					    <div class="col-lg-3 mb-4">
 | 
				
			||||||
      <div class="list-group list-group-transparent mb-0">
 | 
					      <%= render "admins/components/menu_buttons" %>
 | 
				
			||||||
        <button id="users" class="list-group-item list-group-item-action setting-btn <%= "active" if !params[:setting] || params[:setting] == "users"%>">
 | 
					 | 
				
			||||||
          <span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %>
 | 
					 | 
				
			||||||
        </button>
 | 
					 | 
				
			||||||
        <button id="site_settings" class="list-group-item list-group-item-action setting-btn <%= "active" if params[:setting] == "site_settings"%>">
 | 
					 | 
				
			||||||
          <span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %>
 | 
					 | 
				
			||||||
        </button>
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    </div>
 | 
					    <div id="users" class="col-lg-9">
 | 
				
			||||||
 | 
					      <%= render "admins/components/setting_view", setting_id: "users", setting_title: t("administrator.users.title"), search: true %>
 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div class="col-lg-9">
 | 
					 | 
				
			||||||
      <% if defined?(setting_id) && setting_id == "account" %>
 | 
					 | 
				
			||||||
        <%= render "shared/settings/setting_view", setting_id: "account", setting_title: t("administrator.users.edit.title") %>
 | 
					 | 
				
			||||||
      <% else %>
 | 
					 | 
				
			||||||
        <%= render "shared/settings/setting_view", admin_view: true, setting_id: "users", setting_title: t("administrator.users.title") %>
 | 
					 | 
				
			||||||
        <%= render "shared/settings/setting_view", admin_view: true, setting_id: "site_settings", setting_title: t("administrator.site_settings.subtitle") %>
 | 
					 | 
				
			||||||
      <% end %>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <%= render "shared/modals/delete_account_modal", delete_location: relative_root %>
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								app/views/admins/server_recordings.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/views/admins/server_recordings.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container pt-6">
 | 
				
			||||||
 | 
					  <%= render "shared/components/subtitle", subtitle: t("administrator.title"), search: false %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="row">
 | 
				
			||||||
 | 
					    <div class="col-lg-3 mb-4">
 | 
				
			||||||
 | 
					      <%= render "admins/components/menu_buttons" %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div id="server_recordings" class="col-lg-9">
 | 
				
			||||||
 | 
					        <%= render "admins/components/setting_view", setting_id: "recordings", setting_title: t("administrator.recordings.title"), search: true %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/views/admins/site_settings.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/views/admins/site_settings.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<%
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container pt-6">
 | 
				
			||||||
 | 
					  <%= render "shared/components/subtitle", subtitle: t("administrator.title"), search: false %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="row">
 | 
				
			||||||
 | 
					    <div class="col-lg-3 mb-4">
 | 
				
			||||||
 | 
					      <%= render "admins/components/menu_buttons" %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div id="site_settings" class="col-lg-9">
 | 
				
			||||||
 | 
					      <%= render "admins/components/setting_view", setting_id: "settings", setting_title: t("administrator.site_settings.subtitle"), search: false %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@@ -13,9 +13,21 @@
 | 
				
			|||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
%>
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<%= render 'shared/room_event' do %>
 | 
					<% valid_access_code = @room.access_code.nil? || @room.access_code.empty? || @room.access_code == session[:access_code] %>
 | 
				
			||||||
 | 
					<%= render 'shared/room_event', render_recordings: valid_access_code do %>
 | 
				
			||||||
  <% if room_authentication_required %>
 | 
					  <% if room_authentication_required %>
 | 
				
			||||||
    <h2><%= t("administrator.site_settings.authentication.user-info") %></h2>
 | 
					    <h2><%= t("administrator.site_settings.authentication.user-info") %></h2>
 | 
				
			||||||
 | 
					  <% elsif !valid_access_code %>
 | 
				
			||||||
 | 
					    <%= form_for :room, url: login_room_path(@room.uid) do |f| %>
 | 
				
			||||||
 | 
					      <div class="input-group join-input">
 | 
				
			||||||
 | 
					        <%= f.text_field :access_code,
 | 
				
			||||||
 | 
					              required: true,
 | 
				
			||||||
 | 
					              class: "form-control join-form",
 | 
				
			||||||
 | 
					              placeholder: t("room.enter_the_access_code"),
 | 
				
			||||||
 | 
					              value: "" %>
 | 
				
			||||||
 | 
					        <%= f.submit t("room.login"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    <% end %>
 | 
				
			||||||
  <% else %>
 | 
					  <% else %>
 | 
				
			||||||
    <%= form_for room_path(@room), method: :post do |f| %>
 | 
					    <%= form_for room_path(@room), method: :post do |f| %>
 | 
				
			||||||
      <div class="input-group join-input">
 | 
					      <div class="input-group join-input">
 | 
				
			||||||
@@ -28,7 +40,7 @@
 | 
				
			|||||||
            placeholder: t("enter_your_name"),
 | 
					            placeholder: t("enter_your_name"),
 | 
				
			||||||
            value: "#{@name}",
 | 
					            value: "#{@name}",
 | 
				
			||||||
            readonly: !current_user.nil? %>
 | 
					            readonly: !current_user.nil? %>
 | 
				
			||||||
        <%= f.submit t("room.join"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %>
 | 
					        <%= f.submit (!@is_running && @anyone_can_start)? t("room.start") : t("room.join"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    <% end %>
 | 
					    <% end %>
 | 
				
			||||||
  <% end %>
 | 
					  <% end %>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@
 | 
				
			|||||||
        <% unless exceeds_limit %>
 | 
					        <% unless exceeds_limit %>
 | 
				
			||||||
          <label class="form-label"><%= t("room.invite_participants") %></label>
 | 
					          <label class="form-label"><%= t("room.invite_participants") %></label>
 | 
				
			||||||
          <div class="row">
 | 
					          <div class="row">
 | 
				
			||||||
            <div class="col-lg-5 col-md-12 mt-2 pr-0">
 | 
					            <div class="col-lg-7 col-md-12 mt-2 pr-0">
 | 
				
			||||||
              <div class="input-icon invite-link-input">
 | 
					              <div class="input-icon invite-link-input">
 | 
				
			||||||
                <span class="input-icon-addon">
 | 
					                <span class="input-icon-addon">
 | 
				
			||||||
                  <i class="fas fa-link"></i>
 | 
					                  <i class="fas fa-link"></i>
 | 
				
			||||||
@@ -44,7 +44,7 @@
 | 
				
			|||||||
                <input id="invite-url" type="text" class="form-control w-100" value="<%= request.base_url + @room.invite_path %>" readonly="">
 | 
					                <input id="invite-url" type="text" class="form-control w-100" value="<%= request.base_url + @room.invite_path %>" readonly="">
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div class="col-lg-7 col-md-12 pr-0">
 | 
					            <div class="col-lg-5 col-md-12 pr-0">
 | 
				
			||||||
              <div class="row">
 | 
					              <div class="row">
 | 
				
			||||||
                <div class="col-sm-6">
 | 
					                <div class="col-sm-6">
 | 
				
			||||||
                  <a href="#" id="copy" class="btn btn-primary btn-block mt-2">
 | 
					                  <a href="#" id="copy" class="btn btn-primary btn-block mt-2">
 | 
				
			||||||
@@ -89,7 +89,7 @@
 | 
				
			|||||||
              <%= render "shared/components/room_block", room: room %>
 | 
					              <%= render "shared/components/room_block", room: room %>
 | 
				
			||||||
            <% end %>
 | 
					            <% end %>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <%= render "shared/modals/delete_room_modal", room: room %>
 | 
					          <%= render "shared/modals/delete_room_modal", recording_count: room.recording_count, room: room %>
 | 
				
			||||||
        <% end %>
 | 
					        <% end %>
 | 
				
			||||||
      <% end %>
 | 
					      <% end %>
 | 
				
			||||||
      <% unless room_limit_exceeded %>
 | 
					      <% unless room_limit_exceeded %>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@
 | 
				
			|||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
%>
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<%= render 'shared/room_event' do %>
 | 
					<%= render 'shared/room_event', render_recordings: true do %>
 | 
				
			||||||
  <div class="row">
 | 
					  <div class="row">
 | 
				
			||||||
    <div class="col-9">
 | 
					    <div class="col-9">
 | 
				
			||||||
      <h3><%= t("room.wait.message") %></h3>
 | 
					      <h3><%= t("room.wait.message") %></h3>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@
 | 
				
			|||||||
      <div class="d-flex ml-auto">
 | 
					      <div class="d-flex ml-auto">
 | 
				
			||||||
        <% if current_user %>
 | 
					        <% if current_user %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <% if current_user.has_role? :super_admin %>
 | 
					          <% if current_user.has_cached_role? :super_admin %>
 | 
				
			||||||
            <% admins_page = params[:controller] == "admins" && params[:action] == "index" ? "active" : "" %>
 | 
					            <% admins_page = params[:controller] == "admins" && params[:action] == "index" ? "active" : "" %>
 | 
				
			||||||
            <%= link_to admins_path, class: "px-3 mx-1 mt-1 header-nav #{admins_page}" do %>
 | 
					            <%= link_to admins_path, class: "px-3 mx-1 mt-1 header-nav #{admins_page}" do %>
 | 
				
			||||||
              <i class="fas fa-home pr-1 "></i> <%= t("header.dropdown.home") %>
 | 
					              <i class="fas fa-home pr-1 "></i> <%= t("header.dropdown.home") %>
 | 
				
			||||||
@@ -56,7 +56,7 @@
 | 
				
			|||||||
              <%= link_to edit_user_path(current_user), class: "dropdown-item"  do %>
 | 
					              <%= link_to edit_user_path(current_user), class: "dropdown-item"  do %>
 | 
				
			||||||
                <i class="dropdown-icon fas fa-id-card mr-3"></i><%= t("header.dropdown.settings") %>
 | 
					                <i class="dropdown-icon fas fa-id-card mr-3"></i><%= t("header.dropdown.settings") %>
 | 
				
			||||||
              <% end %>
 | 
					              <% end %>
 | 
				
			||||||
              <% if current_user.has_role? :admin %>
 | 
					              <% if current_user.has_cached_role? :admin %>
 | 
				
			||||||
                <%= link_to admins_path, class: "dropdown-item" do %>
 | 
					                <%= link_to admins_path, class: "dropdown-item" do %>
 | 
				
			||||||
                  <i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
 | 
					                  <i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
 | 
				
			||||||
                <% end %>
 | 
					                <% end %>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,4 +40,6 @@
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<% if render_recordings %>
 | 
				
			||||||
  <%= render "shared/sessions", recordings: @public_recordings, pagy: @pagy, only_public: true, user_recordings: false, title: t("room.recordings") %>
 | 
					  <%= render "shared/sessions", recordings: @public_recordings, pagy: @pagy, only_public: true, user_recordings: false, title: t("room.recordings") %>
 | 
				
			||||||
 | 
					<% end %>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@
 | 
				
			|||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
					# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
%>
 | 
					%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div id="<%= if room == current_user.main_room then 'home_room_block' else 'room-block' end %>" data-room-uid="<%= room.uid %>" data-room-settings=<%= room.room_settings %> class="card">
 | 
					<div id="<%= if room == current_user.main_room then 'home_room_block' else 'room-block' end %>" data-room-uid="<%= room.uid %>" data-room-settings=<%= room.room_settings %> data-room-access-code="<%= room.access_code %>" class="card">
 | 
				
			||||||
  <div class="card-body p-1">
 | 
					  <div class="card-body p-1">
 | 
				
			||||||
    <table class="table table-hover table-vcenter text-wrap table-no-border">
 | 
					    <table class="table table-hover table-vcenter text-wrap table-no-border">
 | 
				
			||||||
      <tbody class="no-border-top">
 | 
					      <tbody class="no-border-top">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,10 +28,21 @@
 | 
				
			|||||||
              <span class="input-icon-addon">
 | 
					              <span class="input-icon-addon">
 | 
				
			||||||
                <i class="fas fa-chalkboard-teacher"></i>
 | 
					                <i class="fas fa-chalkboard-teacher"></i>
 | 
				
			||||||
              </span>
 | 
					              </span>
 | 
				
			||||||
              <%= f.text_field :name, id: "create-room-name", class: "form-control", value: "", placeholder: t("modal.create_room.name_placeholder"), autocomplete: :off %>
 | 
					              <%= f.text_field :name, id: "create-room-name", class: "form-control text-center", value: "", placeholder: t("modal.create_room.name_placeholder"), autocomplete: :off %>
 | 
				
			||||||
              <div class="invalid-feedback text-left"><%= t("modal.create_room.not_blank") %></div>
 | 
					              <div class="invalid-feedback text-left"><%= t("modal.create_room.not_blank") %></div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div class="input-icon mb-2">
 | 
				
			||||||
 | 
					              <span onclick="generateAccessCode()" class="input-icon-addon allow-icon-click">
 | 
				
			||||||
 | 
					                <i class="fas fa-dice"></i>
 | 
				
			||||||
 | 
					              </span>
 | 
				
			||||||
 | 
					              <%= f.label :access_code, t("modal.create_room.access_code_placeholder"), id: "create-room-access-code", class: "form-control" %>
 | 
				
			||||||
 | 
					              <%= f.hidden_field :access_code %>
 | 
				
			||||||
 | 
					              <span onclick="ResetAccessCode()" class="input-icon-addon allow-icon-click">
 | 
				
			||||||
 | 
					                <i class="far fa-trash-alt"></i>
 | 
				
			||||||
 | 
					              </span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <% if Rails.configuration.room_features.include? "default-client" %>
 | 
					            <% if Rails.configuration.room_features.include? "default-client" %>
 | 
				
			||||||
              <label class="mt-3 mb-3 w-100 text-left d-inline-block">
 | 
					              <label class="mt-3 mb-3 w-100 text-left d-inline-block">
 | 
				
			||||||
                <input type="hidden" name="room[client]" id="room_client">
 | 
					                <input type="hidden" name="room[client]" id="room_client">
 | 
				
			||||||
@@ -57,6 +68,14 @@
 | 
				
			|||||||
              </label>
 | 
					              </label>
 | 
				
			||||||
            <% end %>
 | 
					            <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <% if Rails.configuration.room_features.include? "anyone-can-start" %>
 | 
				
			||||||
 | 
					              <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block">
 | 
				
			||||||
 | 
					                <span class="custom-switch-description"><%= t("modal.room_settings.start")%></span>
 | 
				
			||||||
 | 
					                <%= f.check_box :anyone_can_start, class: "custom-switch-input", checked: false %>
 | 
				
			||||||
 | 
					                <span class="custom-switch-indicator float-right"></span>
 | 
				
			||||||
 | 
					              </label>
 | 
				
			||||||
 | 
					            <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <label id="auto-join-label" class="create-only custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block">
 | 
					            <label id="auto-join-label" class="create-only custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block">
 | 
				
			||||||
              <span class="custom-switch-description"><%= t("modal.create_room.auto_join") %></span>
 | 
					              <span class="custom-switch-description"><%= t("modal.create_room.auto_join") %></span>
 | 
				
			||||||
              <%= f.check_box :auto_join, class: "custom-switch-input", checked: false %>
 | 
					              <%= f.check_box :auto_join, class: "custom-switch-input", checked: false %>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,8 +34,8 @@
 | 
				
			|||||||
        <div class="card-footer">
 | 
					        <div class="card-footer">
 | 
				
			||||||
          <p>
 | 
					          <p>
 | 
				
			||||||
            <%= t("modal.delete_room.warning").html_safe %>
 | 
					            <%= t("modal.delete_room.warning").html_safe %>
 | 
				
			||||||
            <% if room.recordings.length > 0 %>
 | 
					            <% if recording_count > 0 %>
 | 
				
			||||||
              <%= t("modal.delete_room.recording_warning", recordings_num: room.recordings.length).html_safe %>
 | 
					              <%= t("modal.delete_room.recording_warning", recordings_num: recording_count).html_safe %>
 | 
				
			||||||
            <% end %>
 | 
					            <% end %>
 | 
				
			||||||
          </p>
 | 
					          </p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,17 +20,17 @@
 | 
				
			|||||||
    <div class="col-lg-3 mb-4">
 | 
					    <div class="col-lg-3 mb-4">
 | 
				
			||||||
      <div class="list-group list-group-transparent mb-0">
 | 
					      <div class="list-group list-group-transparent mb-0">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <button id="account" class="list-group-item list-group-item-action setting-btn <%= "active" if !params[:setting] || params[:setting] == "account"%>">
 | 
					        <button id="account" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if !params[:setting] || params[:setting] == "account"%>">
 | 
				
			||||||
          <span class="icon mr-3"><i class="fas fa-user"></i></span><%= t("settings.account.title") %>
 | 
					          <span class="icon mr-3"><i class="fas fa-user"></i></span><%= t("settings.account.title") %>
 | 
				
			||||||
        </button>
 | 
					        </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <% if @user.social_uid.nil? %>
 | 
					        <% if @user.social_uid.nil? %>
 | 
				
			||||||
          <button id="password" class="list-group-item list-group-item-action setting-btn <%= "active" if params[:setting] == "password"%>">
 | 
					          <button id="password" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if params[:setting] == "password"%>">
 | 
				
			||||||
            <span class="icon mr-3"><i class="fas fa-lock"></i></span><%= t("settings.password.title") %>
 | 
					            <span class="icon mr-3"><i class="fas fa-lock"></i></span><%= t("settings.password.title") %>
 | 
				
			||||||
          </button>
 | 
					          </button>
 | 
				
			||||||
        <% end %>
 | 
					        <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <button id="delete" class="list-group-item list-group-item-action setting-btn <%= "active" if params[:setting] == "delete"%>">
 | 
					        <button id="delete" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if params[:setting] == "delete"%>">
 | 
				
			||||||
          <span class="icon mr-3"><i class="fas fa-trash-alt"></i></span><%= t("settings.delete.title") %>
 | 
					          <span class="icon mr-3"><i class="fas fa-trash-alt"></i></span><%= t("settings.delete.title") %>
 | 
				
			||||||
        </button>
 | 
					        </button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
#!/usr/bin/env ruby
 | 
					#!/usr/bin/env ruby
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
 | 
					ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
 | 
				
			||||||
load Gem.bin_path('bundler', 'bundle')
 | 
					load Gem.bin_path('bundler', 'bundle')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,11 @@
 | 
				
			|||||||
#!/usr/bin/env ruby
 | 
					#!/usr/bin/env ruby
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require 'pathname'
 | 
					 | 
				
			||||||
require 'fileutils'
 | 
					require 'fileutils'
 | 
				
			||||||
include FileUtils
 | 
					include FileUtils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# path to your application root.
 | 
					# path to your application root.
 | 
				
			||||||
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
 | 
					APP_ROOT = File.expand_path('..', __dir__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def system!(*args)
 | 
					def system!(*args)
 | 
				
			||||||
  system(*args) || abort("\n== Command #{args} failed ==")
 | 
					  system(*args) || abort("\n== Command #{args} failed ==")
 | 
				
			||||||
@@ -20,6 +19,9 @@ chdir APP_ROOT do
 | 
				
			|||||||
  system! 'gem install bundler --conservative'
 | 
					  system! 'gem install bundler --conservative'
 | 
				
			||||||
  system('bundle check') || system!('bundle install')
 | 
					  system('bundle check') || system!('bundle install')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Install JavaScript dependencies if using Yarn
 | 
				
			||||||
 | 
					  # system('bin/yarn')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # puts "\n== Copying sample files =="
 | 
					  # puts "\n== Copying sample files =="
 | 
				
			||||||
  # unless File.exist?('config/database.yml')
 | 
					  # unless File.exist?('config/database.yml')
 | 
				
			||||||
  #   cp 'config/database.yml.sample', 'config/database.yml'
 | 
					  #   cp 'config/database.yml.sample', 'config/database.yml'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,11 @@
 | 
				
			|||||||
#!/usr/bin/env ruby
 | 
					#!/usr/bin/env ruby
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require 'pathname'
 | 
					 | 
				
			||||||
require 'fileutils'
 | 
					require 'fileutils'
 | 
				
			||||||
include FileUtils
 | 
					include FileUtils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# path to your application root.
 | 
					# path to your application root.
 | 
				
			||||||
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
 | 
					APP_ROOT = File.expand_path('..', __dir__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def system!(*args)
 | 
					def system!(*args)
 | 
				
			||||||
  system(*args) || abort("\n== Command #{args} failed ==")
 | 
					  system(*args) || abort("\n== Command #{args} failed ==")
 | 
				
			||||||
@@ -20,6 +19,9 @@ chdir APP_ROOT do
 | 
				
			|||||||
  system! 'gem install bundler --conservative'
 | 
					  system! 'gem install bundler --conservative'
 | 
				
			||||||
  system('bundle check') || system!('bundle install')
 | 
					  system('bundle check') || system!('bundle install')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Install JavaScript dependencies if using Yarn
 | 
				
			||||||
 | 
					  # system('bin/yarn')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  puts "\n== Updating database =="
 | 
					  puts "\n== Updating database =="
 | 
				
			||||||
  system! 'bin/rails db:migrate'
 | 
					  system! 'bin/rails db:migrate'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								bin/yarn
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								bin/yarn
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env ruby
 | 
				
			||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					APP_ROOT = File.expand_path('..', __dir__)
 | 
				
			||||||
 | 
					Dir.chdir(APP_ROOT) do
 | 
				
			||||||
 | 
					  begin
 | 
				
			||||||
 | 
					    exec "yarnpkg", *ARGV
 | 
				
			||||||
 | 
					  rescue Errno::ENOENT
 | 
				
			||||||
 | 
					    warn "Yarn executable was not detected in the system."
 | 
				
			||||||
 | 
					    warn "Download Yarn at https://yarnpkg.com/en/docs/install"
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@@ -26,6 +26,9 @@ Bundler.require(*Rails.groups)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module Greenlight
 | 
					module Greenlight
 | 
				
			||||||
  class Application < Rails::Application
 | 
					  class Application < Rails::Application
 | 
				
			||||||
 | 
					    # Initialize configuration defaults for originally generated Rails version.
 | 
				
			||||||
 | 
					    config.load_defaults 5.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Settings in config/environments/* take precedence over those specified here.
 | 
					    # Settings in config/environments/* take precedence over those specified here.
 | 
				
			||||||
    # Application configuration should go into files in config/initializers
 | 
					    # Application configuration should go into files in config/initializers
 | 
				
			||||||
    # -- all .rb files in that directory are automatically loaded.
 | 
					    # -- all .rb files in that directory are automatically loaded.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,3 +3,4 @@
 | 
				
			|||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
 | 
					ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require 'bundler/setup' # Set up gems listed in the Gemfile.
 | 
					require 'bundler/setup' # Set up gems listed in the Gemfile.
 | 
				
			||||||
 | 
					require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,12 +15,13 @@ Rails.application.configure do
 | 
				
			|||||||
  config.consider_all_requests_local = false
 | 
					  config.consider_all_requests_local = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Enable/disable caching. By default caching is disabled.
 | 
					  # Enable/disable caching. By default caching is disabled.
 | 
				
			||||||
  if Rails.root.join('tmp/caching-dev.txt').exist?
 | 
					  # Run rails dev:cache to toggle caching.
 | 
				
			||||||
 | 
					  if Rails.root.join('tmp', 'caching-dev.txt').exist?
 | 
				
			||||||
    config.action_controller.perform_caching = true
 | 
					    config.action_controller.perform_caching = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config.cache_store = :memory_store
 | 
					    config.cache_store = :memory_store
 | 
				
			||||||
    config.public_file_server.headers = {
 | 
					    config.public_file_server.headers = {
 | 
				
			||||||
      'Cache-Control' => 'public, max-age=172800',
 | 
					      'Cache-Control' => "public, max-age=#{2.days.to_i}"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    config.action_controller.perform_caching = false
 | 
					    config.action_controller.perform_caching = false
 | 
				
			||||||
@@ -28,6 +29,9 @@ Rails.application.configure do
 | 
				
			|||||||
    config.cache_store = :null_store
 | 
					    config.cache_store = :null_store
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Store uploaded files on the local file system (see config/storage.yml for options)
 | 
				
			||||||
 | 
					  config.active_storage.service = :local
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Don't wrap form components in field_with_error divs
 | 
					  # Don't wrap form components in field_with_error divs
 | 
				
			||||||
  ActionView::Base.field_error_proc = proc do |html_tag|
 | 
					  ActionView::Base.field_error_proc = proc do |html_tag|
 | 
				
			||||||
    html_tag.html_safe
 | 
					    html_tag.html_safe
 | 
				
			||||||
@@ -57,6 +61,9 @@ Rails.application.configure do
 | 
				
			|||||||
  # Raise an error on page load if there are pending migrations.
 | 
					  # Raise an error on page load if there are pending migrations.
 | 
				
			||||||
  config.active_record.migration_error = :page_load
 | 
					  config.active_record.migration_error = :page_load
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Highlight code that triggered database queries in logs.
 | 
				
			||||||
 | 
					  config.active_record.verbose_query_logs = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Debug mode disables concatenation and preprocessing of assets.
 | 
					  # Debug mode disables concatenation and preprocessing of assets.
 | 
				
			||||||
  # This option may cause significant delays in view rendering with a large
 | 
					  # This option may cause significant delays in view rendering with a large
 | 
				
			||||||
  # number of complex assets.
 | 
					  # number of complex assets.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,10 @@ Rails.application.configure do
 | 
				
			|||||||
  config.consider_all_requests_local       = false
 | 
					  config.consider_all_requests_local       = false
 | 
				
			||||||
  config.action_controller.perform_caching = true
 | 
					  config.action_controller.perform_caching = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
 | 
				
			||||||
 | 
					  # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
 | 
				
			||||||
 | 
					  # config.require_master_key = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Disable serving static files from the `/public` folder by default since
 | 
					  # Disable serving static files from the `/public` folder by default since
 | 
				
			||||||
  # Apache or NGINX already handles this.
 | 
					  # Apache or NGINX already handles this.
 | 
				
			||||||
  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].blank?
 | 
					  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].blank?
 | 
				
			||||||
@@ -36,6 +40,9 @@ Rails.application.configure do
 | 
				
			|||||||
  # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
 | 
					  # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
 | 
				
			||||||
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
 | 
					  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Store uploaded files on the local file system (see config/storage.yml for options)
 | 
				
			||||||
 | 
					  config.active_storage.service = :local
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Mount Action Cable outside main process or domain
 | 
					  # Mount Action Cable outside main process or domain
 | 
				
			||||||
  # config.action_cable.mount_path = nil
 | 
					  # config.action_cable.mount_path = nil
 | 
				
			||||||
  # config.action_cable.url = 'wss://example.com/cable'
 | 
					  # config.action_cable.url = 'wss://example.com/cable'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ Rails.application.configure do
 | 
				
			|||||||
  # Configure public file server for tests with Cache-Control for performance.
 | 
					  # Configure public file server for tests with Cache-Control for performance.
 | 
				
			||||||
  config.public_file_server.enabled = true
 | 
					  config.public_file_server.enabled = true
 | 
				
			||||||
  config.public_file_server.headers = {
 | 
					  config.public_file_server.headers = {
 | 
				
			||||||
    'Cache-Control' => 'public, max-age=3600',
 | 
					    'Cache-Control' => "public, max-age=#{1.hour.to_i}"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Show full error reports and disable caching.
 | 
					  # Show full error reports and disable caching.
 | 
				
			||||||
@@ -29,6 +29,10 @@ Rails.application.configure do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # Disable request forgery protection in test environment.
 | 
					  # Disable request forgery protection in test environment.
 | 
				
			||||||
  config.action_controller.allow_forgery_protection = false
 | 
					  config.action_controller.allow_forgery_protection = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Store uploaded files on the local file system in a temporary directory
 | 
				
			||||||
 | 
					  config.active_storage.service = :test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  config.action_mailer.perform_caching = false
 | 
					  config.action_mailer.perform_caching = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Tell Action Mailer not to deliver emails to the real world.
 | 
					  # Tell Action Mailer not to deliver emails to the real world.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,9 +5,12 @@
 | 
				
			|||||||
# Version of your assets, change this if you want to expire all your assets.
 | 
					# Version of your assets, change this if you want to expire all your assets.
 | 
				
			||||||
Rails.application.config.assets.version = '1.0'
 | 
					Rails.application.config.assets.version = '1.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Add additional assets to the asset load path
 | 
					# Add additional assets to the asset load path.
 | 
				
			||||||
# Rails.application.config.assets.paths << Emoji.images_path
 | 
					# Rails.application.config.assets.paths << Emoji.images_path
 | 
				
			||||||
 | 
					# Add Yarn node_modules folder to the asset load path.
 | 
				
			||||||
 | 
					Rails.application.config.assets.paths << Rails.root.join('node_modules')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Precompile additional assets.
 | 
					# Precompile additional assets.
 | 
				
			||||||
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
 | 
					# application.js, application.css, and all non-JS/CSS in the app/assets
 | 
				
			||||||
# Rails.application.config.assets.precompile += %w()
 | 
					# folder are already added.
 | 
				
			||||||
 | 
					# Rails.application.config.assets.precompile += %w( admin.js admin.css )
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								config/initializers/content_security_policy.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								config/initializers/content_security_policy.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Be sure to restart your server when you modify this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Define an application-wide content security policy
 | 
				
			||||||
 | 
					# For further information see the following documentation
 | 
				
			||||||
 | 
					# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Rails.application.config.content_security_policy do |policy|
 | 
				
			||||||
 | 
					#   policy.default_src :self, :https
 | 
				
			||||||
 | 
					#   policy.font_src    :self, :https, :data
 | 
				
			||||||
 | 
					#   policy.img_src     :self, :https, :data
 | 
				
			||||||
 | 
					#   policy.object_src  :none
 | 
				
			||||||
 | 
					#   policy.script_src  :self, :https
 | 
				
			||||||
 | 
					#   policy.style_src   :self, :https
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#   # Specify URI for violation reports
 | 
				
			||||||
 | 
					#   # policy.report_uri "/csp-violation-report-endpoint"
 | 
				
			||||||
 | 
					# end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# If you are using UJS then enable automatic nonce generation
 | 
				
			||||||
 | 
					# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Report CSP violations to a specified URI
 | 
				
			||||||
 | 
					# For further information see the following documentation:
 | 
				
			||||||
 | 
					# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
 | 
				
			||||||
 | 
					# Rails.application.config.content_security_policy_report_only = true
 | 
				
			||||||
@@ -23,17 +23,11 @@ HealthCheck.setup do |config|
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  config.http_status_for_error_object = 500
 | 
					  config.http_status_for_error_object = 500
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # bucket names to test connectivity - required only if s3 check used, access permissions can be mixed
 | 
					 | 
				
			||||||
  config.buckets = { 'bucket_name' => [:R, :W, :D] }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # You can customize which checks happen on a standard health check, eg to set an explicit list use:
 | 
					  # You can customize which checks happen on a standard health check, eg to set an explicit list use:
 | 
				
			||||||
  config.standard_checks = %w(database migrations custom)
 | 
					  config.standard_checks = %w(database migrations emailconf)
 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Or to exclude one check:
 | 
					 | 
				
			||||||
  config.standard_checks -= %w(emailconf)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # You can set what tests are run with the 'full' or 'all' parameter
 | 
					  # You can set what tests are run with the 'full' or 'all' parameter
 | 
				
			||||||
  config.full_checks = %w(database migrations custom email cache redis resque-redis sidekiq-redis s3)
 | 
					  config.full_checks = %w(database migrations email cache)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # max-age of response in seconds
 | 
					  # max-age of response in seconds
 | 
				
			||||||
  # cache-control is public when max_age > 1 and basic_auth_username is not set
 | 
					  # cache-control is public when max_age > 1 and basic_auth_username is not set
 | 
				
			||||||
@@ -43,7 +37,4 @@ HealthCheck.setup do |config|
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # http status code used when the ip is not allowed for the request
 | 
					  # http status code used when the ip is not allowed for the request
 | 
				
			||||||
  config.http_status_for_ip_whitelist_error = 403
 | 
					  config.http_status_for_ip_whitelist_error = 403
 | 
				
			||||||
 | 
					 | 
				
			||||||
  # When redis url is non-standard
 | 
					 | 
				
			||||||
  config.redis_url = 'redis_url'
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
# frozen_string_literal: true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Be sure to restart your server when you modify this file.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file contains migration options to ease your Rails 5.0 upgrade.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Rails.application.config.action_controller.raise_on_unfiltered_parameters = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Enable per-form CSRF tokens. Previous versions had false.
 | 
					 | 
				
			||||||
Rails.application.config.action_controller.per_form_csrf_tokens = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Enable origin-checking CSRF mitigation. Previous versions had false.
 | 
					 | 
				
			||||||
Rails.application.config.action_controller.forgery_protection_origin_check = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
 | 
					 | 
				
			||||||
# Previous versions had false.
 | 
					 | 
				
			||||||
ActiveSupport.to_time_preserves_timezone = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Require `belongs_to` associations by default. Previous versions had false.
 | 
					 | 
				
			||||||
Rails.application.config.active_record.belongs_to_required_by_default = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Do not halt callback chains when a callback returns false. Previous versions had true.
 | 
					 | 
				
			||||||
ActiveSupport.halt_callback_chains_on_return_false = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Configure SSL options to enable HSTS with subdomains. Previous versions had false.
 | 
					 | 
				
			||||||
Rails.application.config.ssl_options = { hsts: { subdomains: true } }
 | 
					 | 
				
			||||||
@@ -2,4 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Be sure to restart your server when you modify this file.
 | 
					# Be sure to restart your server when you modify this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
 | 
					    Rails.application.config.session_store :cookie_store, key: '_greenlight-2_0_session',
 | 
				
			||||||
 | 
					        domain: ENV['GREENLIGHT_PARENT_DOMAIN'] || 'blindside-dev.com'
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
    Rails.application.config.session_store :cookie_store, key: '_greenlight-2_0_session'
 | 
					    Rails.application.config.session_store :cookie_store, key: '_greenlight-2_0_session'
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,6 +48,12 @@ en:
 | 
				
			|||||||
        regular: Regular
 | 
					        regular: Regular
 | 
				
			||||||
        lighten: Lighten
 | 
					        lighten: Lighten
 | 
				
			||||||
        darken: Darken
 | 
					        darken: Darken
 | 
				
			||||||
 | 
					      recording_visibility:
 | 
				
			||||||
 | 
					        public: Public
 | 
				
			||||||
 | 
					        private: Private
 | 
				
			||||||
 | 
					        info: Set the default recording visbility for new recordings
 | 
				
			||||||
 | 
					        title: Recording Default Visibility
 | 
				
			||||||
 | 
					        warning: This setting will only be applied to rooms that aren't running
 | 
				
			||||||
      registration:
 | 
					      registration:
 | 
				
			||||||
        info: Change the way that users register to the website
 | 
					        info: Change the way that users register to the website
 | 
				
			||||||
        title: Registration Method
 | 
					        title: Registration Method
 | 
				
			||||||
@@ -73,6 +79,9 @@ en:
 | 
				
			|||||||
      registration_method_updated: Registration method successfully updated
 | 
					      registration_method_updated: Registration method successfully updated
 | 
				
			||||||
      settings: Site Settings successfully changed
 | 
					      settings: Site Settings successfully changed
 | 
				
			||||||
      unauthorized: You are not authorized to perform actions on this user
 | 
					      unauthorized: You are not authorized to perform actions on this user
 | 
				
			||||||
 | 
					    recordings:
 | 
				
			||||||
 | 
					      title: Server Recordings
 | 
				
			||||||
 | 
					      no_recordings: This server has no recordings.
 | 
				
			||||||
    title: Organization Settings
 | 
					    title: Organization Settings
 | 
				
			||||||
    users:
 | 
					    users:
 | 
				
			||||||
      invite: Invite User
 | 
					      invite: Invite User
 | 
				
			||||||
@@ -256,6 +265,8 @@ en:
 | 
				
			|||||||
  max_concurrent: The maximum number of concurrent sessions allowed has been reached!
 | 
					  max_concurrent: The maximum number of concurrent sessions allowed has been reached!
 | 
				
			||||||
  modal:
 | 
					  modal:
 | 
				
			||||||
    create_room:
 | 
					    create_room:
 | 
				
			||||||
 | 
					      access_code: Access Code
 | 
				
			||||||
 | 
					      access_code_placeholder: Generate an optional room access code
 | 
				
			||||||
      auto_join: Automatically join me into the room
 | 
					      auto_join: Automatically join me into the room
 | 
				
			||||||
      create: Create Room
 | 
					      create: Create Room
 | 
				
			||||||
      free_delete: You will be free to delete this room at any time.
 | 
					      free_delete: You will be free to delete this room at any time.
 | 
				
			||||||
@@ -288,6 +299,7 @@ en:
 | 
				
			|||||||
      update: Update Room
 | 
					      update: Update Room
 | 
				
			||||||
      client: Select client type
 | 
					      client: Select client type
 | 
				
			||||||
      mute: Mute users when they join
 | 
					      mute: Mute users when they join
 | 
				
			||||||
 | 
					      start: Allow any user to start this meeting
 | 
				
			||||||
      default: Default
 | 
					      default: Default
 | 
				
			||||||
      html: HTML5
 | 
					      html: HTML5
 | 
				
			||||||
      flash: Flash
 | 
					      flash: Flash
 | 
				
			||||||
@@ -359,19 +371,22 @@ en:
 | 
				
			|||||||
    confirm: New Password Confirmation
 | 
					    confirm: New Password Confirmation
 | 
				
			||||||
    update: Update Password
 | 
					    update: Update Password
 | 
				
			||||||
  roles:
 | 
					  roles:
 | 
				
			||||||
    administrator: Administrator
 | 
					    administrator: Admin
 | 
				
			||||||
    banned: Banned
 | 
					    banned: Banned
 | 
				
			||||||
    pending: Pending
 | 
					    pending: Pending
 | 
				
			||||||
    super_admin: Super Admin
 | 
					    super_admin: Super Admin
 | 
				
			||||||
    user: User
 | 
					    user: User
 | 
				
			||||||
  room:
 | 
					  room:
 | 
				
			||||||
 | 
					    access_code_required: Please enter a valid access code to join the room
 | 
				
			||||||
    create_room: Create a Room
 | 
					    create_room: Create a Room
 | 
				
			||||||
    create_room_error: There was an error creating the room
 | 
					    create_room_error: There was an error creating the room
 | 
				
			||||||
    create_room_success: Room created successfully
 | 
					    create_room_success: Room created successfully
 | 
				
			||||||
 | 
					    enter_the_access_code: Enter the room's access code
 | 
				
			||||||
    invited: You have been invited to join
 | 
					    invited: You have been invited to join
 | 
				
			||||||
    invite_participants: Invite Participants
 | 
					    invite_participants: Invite Participants
 | 
				
			||||||
    join: Join
 | 
					    join: Join
 | 
				
			||||||
    last_session: Last session on %{session}
 | 
					    last_session: Last session on %{session}
 | 
				
			||||||
 | 
					    login: Login
 | 
				
			||||||
    owner: Owner
 | 
					    owner: Owner
 | 
				
			||||||
    no_sessions: This room has no sessions, yet!
 | 
					    no_sessions: This room has no sessions, yet!
 | 
				
			||||||
    recordings: Room Recordings
 | 
					    recordings: Room Recordings
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,15 @@
 | 
				
			|||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Puma can serve each request in a thread from an internal thread pool.
 | 
					# Puma can serve each request in a thread from an internal thread pool.
 | 
				
			||||||
# The `threads` method setting takes two numbers a minimum and maximum.
 | 
					# The `threads` method setting takes two numbers: a minimum and maximum.
 | 
				
			||||||
# Any libraries that use thread pools should be configured to match
 | 
					# Any libraries that use thread pools should be configured to match
 | 
				
			||||||
# the maximum value specified for Puma. Default is set to 5 threads for minimum
 | 
					# the maximum value specified for Puma. Default is set to 5 threads for minimum
 | 
				
			||||||
# and maximum, this matches the default thread size of Active Record.
 | 
					# and maximum; this matches the default thread size of Active Record.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
 | 
					threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
 | 
				
			||||||
threads threads_count, threads_count
 | 
					threads threads_count, threads_count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
 | 
					# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
port        ENV.fetch("PORT") { 80 }
 | 
					port        ENV.fetch("PORT") { 80 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,22 +28,9 @@ environment ENV.fetch("RAILS_ENV") { "development" }
 | 
				
			|||||||
# Use the `preload_app!` method when specifying a `workers` number.
 | 
					# Use the `preload_app!` method when specifying a `workers` number.
 | 
				
			||||||
# This directive tells Puma to first boot the application and load code
 | 
					# This directive tells Puma to first boot the application and load code
 | 
				
			||||||
# before forking the application. This takes advantage of Copy On Write
 | 
					# before forking the application. This takes advantage of Copy On Write
 | 
				
			||||||
# process behavior so workers use less memory. If you use this option
 | 
					# process behavior so workers use less memory.
 | 
				
			||||||
# you need to make sure to reconnect any threads in the `on_worker_boot`
 | 
					 | 
				
			||||||
# block.
 | 
					 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# preload_app!
 | 
					# preload_app!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The code in the `on_worker_boot` will be called if you are using
 | 
					 | 
				
			||||||
# clustered mode by specifying a number of `workers`. After each worker
 | 
					 | 
				
			||||||
# process is booted this block will be run, if you are using `preload_app!`
 | 
					 | 
				
			||||||
# option you will want to use this block to reconnect to any threads
 | 
					 | 
				
			||||||
# or connections that may have been created at application boot, Ruby
 | 
					 | 
				
			||||||
# cannot share connections between processes.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# on_worker_boot do
 | 
					 | 
				
			||||||
#   ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
 | 
					 | 
				
			||||||
# end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Allow puma to be restarted by `rails restart` command.
 | 
					# Allow puma to be restarted by `rails restart` command.
 | 
				
			||||||
plugin :tmp_restart
 | 
					plugin :tmp_restart
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,8 @@ Rails.application.routes.draw do
 | 
				
			|||||||
  resources :admins, only: [:index]
 | 
					  resources :admins, only: [:index]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  scope '/admins' do
 | 
					  scope '/admins' do
 | 
				
			||||||
 | 
					    get '/site_settings', to: 'admins#site_settings', as: :admin_site_settings
 | 
				
			||||||
 | 
					    get '/recordings', to: 'admins#server_recordings', as: :admin_recordings
 | 
				
			||||||
    post '/branding', to: 'admins#branding', as: :admin_branding
 | 
					    post '/branding', to: 'admins#branding', as: :admin_branding
 | 
				
			||||||
    post '/coloring', to: 'admins#coloring', as: :admin_coloring
 | 
					    post '/coloring', to: 'admins#coloring', as: :admin_coloring
 | 
				
			||||||
    post '/room_authentication', to: 'admins#room_authentication', as: :admin_room_authentication
 | 
					    post '/room_authentication', to: 'admins#room_authentication', as: :admin_room_authentication
 | 
				
			||||||
@@ -52,6 +54,7 @@ Rails.application.routes.draw do
 | 
				
			|||||||
    post '/registration_method/:method', to: 'admins#registration_method', as: :admin_change_registration
 | 
					    post '/registration_method/:method', to: 'admins#registration_method', as: :admin_change_registration
 | 
				
			||||||
    post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve
 | 
					    post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve
 | 
				
			||||||
    post '/room_limit', to: 'admins#room_limit', as: :admin_room_limit
 | 
					    post '/room_limit', to: 'admins#room_limit', as: :admin_room_limit
 | 
				
			||||||
 | 
					    post '/default_recording_visibility', to: 'admins#default_recording_visibility', as: :admin_recording_visibility
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  scope '/themes' do
 | 
					  scope '/themes' do
 | 
				
			||||||
@@ -100,6 +103,7 @@ Rails.application.routes.draw do
 | 
				
			|||||||
    post '/update_settings', to: 'rooms#update_settings'
 | 
					    post '/update_settings', to: 'rooms#update_settings'
 | 
				
			||||||
    post '/start', to: 'rooms#start', as: :start_room
 | 
					    post '/start', to: 'rooms#start', as: :start_room
 | 
				
			||||||
    get '/logout', to: 'rooms#logout', as: :logout_room
 | 
					    get '/logout', to: 'rooms#logout', as: :logout_room
 | 
				
			||||||
 | 
					    post '/login', to: 'rooms#login', as: :login_room
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Recording operations routes
 | 
					  # Recording operations routes
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%w(
 | 
					%w[
 | 
				
			||||||
  .ruby-version
 | 
					  .ruby-version
 | 
				
			||||||
  .rbenv-vars
 | 
					  .rbenv-vars
 | 
				
			||||||
  tmp/restart.txt
 | 
					  tmp/restart.txt
 | 
				
			||||||
  tmp/caching-dev.txt
 | 
					  tmp/caching-dev.txt
 | 
				
			||||||
).each { |path| Spring.watch(path) }
 | 
					].each { |path| Spring.watch(path) }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								config/storage.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								config/storage.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					test:
 | 
				
			||||||
 | 
					  service: Disk
 | 
				
			||||||
 | 
					  root: <%= Rails.root.join("tmp/storage") %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local:
 | 
				
			||||||
 | 
					  service: Disk
 | 
				
			||||||
 | 
					  root: <%= Rails.root.join("storage") %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
 | 
				
			||||||
 | 
					# amazon:
 | 
				
			||||||
 | 
					#   service: S3
 | 
				
			||||||
 | 
					#   access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
 | 
				
			||||||
 | 
					#   secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
 | 
				
			||||||
 | 
					#   region: us-east-1
 | 
				
			||||||
 | 
					#   bucket: your_own_bucket
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Remember not to checkin your GCS keyfile to a repository
 | 
				
			||||||
 | 
					# google:
 | 
				
			||||||
 | 
					#   service: GCS
 | 
				
			||||||
 | 
					#   project: your_project
 | 
				
			||||||
 | 
					#   credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
 | 
				
			||||||
 | 
					#   bucket: your_own_bucket
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
 | 
				
			||||||
 | 
					# microsoft:
 | 
				
			||||||
 | 
					#   service: AzureStorage
 | 
				
			||||||
 | 
					#   storage_account_name: your_account_name
 | 
				
			||||||
 | 
					#   storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
 | 
				
			||||||
 | 
					#   container: your_container_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# mirror:
 | 
				
			||||||
 | 
					#   service: Mirror
 | 
				
			||||||
 | 
					#   primary: local
 | 
				
			||||||
 | 
					#   mirrors: [ amazon, google, microsoft ]
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AddPasswordDigestToRooms < ActiveRecord::Migration[5.0]
 | 
				
			||||||
 | 
					  def change
 | 
				
			||||||
 | 
					    add_column :rooms, :access_code, :string, null: true, default: nil
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# It's strongly recommended that you check this file into your version control system.
 | 
					# It's strongly recommended that you check this file into your version control system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ActiveRecord::Schema.define(version: 20190522195242) do
 | 
					ActiveRecord::Schema.define(version: 20190711192033) do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create_table "features", force: :cascade do |t|
 | 
					  create_table "features", force: :cascade do |t|
 | 
				
			||||||
    t.integer  "setting_id"
 | 
					    t.integer  "setting_id"
 | 
				
			||||||
@@ -56,6 +56,7 @@ ActiveRecord::Schema.define(version: 20190522195242) do
 | 
				
			|||||||
    t.string   "room_settings",         default: "{ }"
 | 
					    t.string   "room_settings",         default: "{ }"
 | 
				
			||||||
    t.string   "moderator_pw"
 | 
					    t.string   "moderator_pw"
 | 
				
			||||||
    t.string   "attendee_pw"
 | 
					    t.string   "attendee_pw"
 | 
				
			||||||
 | 
					    t.string   "access_code"
 | 
				
			||||||
    t.index ["bbb_id"], name: "index_rooms_on_bbb_id"
 | 
					    t.index ["bbb_id"], name: "index_rooms_on_bbb_id"
 | 
				
			||||||
    t.index ["last_session"], name: "index_rooms_on_last_session"
 | 
					    t.index ["last_session"], name: "index_rooms_on_last_session"
 | 
				
			||||||
    t.index ["name"], name: "index_rooms_on_name"
 | 
					    t.index ["name"], name: "index_rooms_on_name"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,15 +12,9 @@ module BbbApi
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Sets a BigBlueButtonApi object for interacting with the API.
 | 
					  # Sets a BigBlueButtonApi object for interacting with the API.
 | 
				
			||||||
  def bbb
 | 
					  def bbb(user_provider)
 | 
				
			||||||
    if Rails.configuration.loadbalanced_configuration
 | 
					    if Rails.configuration.loadbalanced_configuration
 | 
				
			||||||
      if instance_of? Room
 | 
					      user_domain = retrieve_provider_info(user_provider)
 | 
				
			||||||
        # currently in the Room Model
 | 
					 | 
				
			||||||
        user_domain = retrieve_provider_info(owner.provider)
 | 
					 | 
				
			||||||
      elsif instance_of? User
 | 
					 | 
				
			||||||
        # currently in the User Model
 | 
					 | 
				
			||||||
        user_domain = retrieve_provider_info(provider)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      BigBlueButton::BigBlueButtonApi.new(remove_slash(user_domain["apiURL"]), user_domain["secret"], "0.8")
 | 
					      BigBlueButton::BigBlueButtonApi.new(remove_slash(user_domain["apiURL"]), user_domain["secret"], "0.8")
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								sample.env
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								sample.env
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
				
			|||||||
# Create a Secret Key for Rails
 | 
					# Create a Secret Key for Rails
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# You can generate a secure one through the Greenlight docker image
 | 
					# You can generate a secure one through the Greenlight docker image
 | 
				
			||||||
# with with the command.
 | 
					# with the command.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   docker run --rm bigbluebutton/greenlight:v2 bundle exec rake secret
 | 
					#   docker run --rm bigbluebutton/greenlight:v2 bundle exec rake secret
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@@ -20,7 +20,7 @@ BIGBLUEBUTTON_SECRET=
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# For in-depth steps on setting up a Google Login Provider, see:
 | 
					# For in-depth steps on setting up a Google Login Provider, see:
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   http://docs.bigbluebutton.org/install/greenlight-v2.html#google-oauth2
 | 
					#   https://docs.bigbluebutton.org/greenlight/gl-customize.html#google-oauth2
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# The GOOGLE_OAUTH2_HD variable is used to limit sign-ins to a particular set of Google Apps hosted
 | 
					# The GOOGLE_OAUTH2_HD variable is used to limit sign-ins to a particular set of Google Apps hosted
 | 
				
			||||||
# domains. This can be a string with separating commas such as, 'domain.com, example.com' or
 | 
					# domains. This can be a string with separating commas such as, 'domain.com, example.com' or
 | 
				
			||||||
@@ -32,18 +32,13 @@ GOOGLE_OAUTH2_HD=
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Twitter Login Provider (optional)
 | 
					# Twitter Login Provider (optional)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# For in-depth steps on setting up a Twitter Login Provider, see:
 | 
					# Twitter Authentication is deprecated and will be phased out in a future release.
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
#   http://docs.bigbluebutton.org/install/greenlight-v2.html#twitter-oauth2
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
TWITTER_ID=
 | 
					 | 
				
			||||||
TWITTER_SECRET=
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Microsoft Office365 Login Provider (optional)
 | 
					# Microsoft Office365 Login Provider (optional)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# For in-depth steps on setting up a Office 365 Login Provider, see:
 | 
					# For in-depth steps on setting up a Office 365 Login Provider, see:
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   http://docs.bigbluebutton.org/install/greenlight-v2.html#office365-oauth2
 | 
					#   https://docs.bigbluebutton.org/greenlight/gl-customize.html#office365-oauth2
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
OFFICE365_KEY=
 | 
					OFFICE365_KEY=
 | 
				
			||||||
OFFICE365_SECRET=
 | 
					OFFICE365_SECRET=
 | 
				
			||||||
@@ -55,7 +50,7 @@ OFFICE365_HD=
 | 
				
			|||||||
# Configuring LDAP authentication will take precedence over all other providers.
 | 
					# Configuring LDAP authentication will take precedence over all other providers.
 | 
				
			||||||
# For information about setting up LDAP, see:
 | 
					# For information about setting up LDAP, see:
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   http://docs.bigbluebutton.org/install/greenlight-v2.html#ldap-auth
 | 
					#   https://docs.bigbluebutton.org/greenlight/gl-customize.html#ldap-auth
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   LDAP_SERVER=ldap.example.com
 | 
					#   LDAP_SERVER=ldap.example.com
 | 
				
			||||||
#   LDAP_PORT=389
 | 
					#   LDAP_PORT=389
 | 
				
			||||||
@@ -75,7 +70,7 @@ LDAP_PASSWORD=
 | 
				
			|||||||
# Set this to true if you want GreenLight to support user signup and login without
 | 
					# Set this to true if you want GreenLight to support user signup and login without
 | 
				
			||||||
# Omniauth. For more information, see:
 | 
					# Omniauth. For more information, see:
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   http://docs.bigbluebutton.org/install/greenlight-v2.html#in-application-greenlight
 | 
					#   https://docs.bigbluebutton.org/greenlight/gl-overview.html#accounts-and-profile
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
ALLOW_GREENLIGHT_ACCOUNTS=true
 | 
					ALLOW_GREENLIGHT_ACCOUNTS=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -130,7 +125,8 @@ RELATIVE_URL_ROOT=/b
 | 
				
			|||||||
# Current settings available:
 | 
					# Current settings available:
 | 
				
			||||||
#   default-client: Room owners can decide between the Flash Client and the HTML5 Client for a room
 | 
					#   default-client: Room owners can decide between the Flash Client and the HTML5 Client for a room
 | 
				
			||||||
#   mute-on-join: Automatically mute users by default when they join a room
 | 
					#   mute-on-join: Automatically mute users by default when they join a room
 | 
				
			||||||
ROOM_FEATURES=default-client,mute-on-join
 | 
					#   anyone-can-start: Allows anyone with the join url to start the room in BigBlueButton
 | 
				
			||||||
 | 
					ROOM_FEATURES=default-client,mute-on-join,anyone-can-start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Specify the maximum number of records to be sent to the BigBlueButton API in one call
 | 
					# Specify the maximum number of records to be sent to the BigBlueButton API in one call
 | 
				
			||||||
# Default is set to 25 records
 | 
					# Default is set to 25 records
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										567
									
								
								spec/concerns/recorder_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										567
									
								
								spec/concerns/recorder_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,567 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require "rails_helper"
 | 
				
			||||||
 | 
					require 'bigbluebutton_api'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					shared_examples_for "recorder" do
 | 
				
			||||||
 | 
					  let(:controller) { described_class } # the class that includes the concern
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  before do
 | 
				
			||||||
 | 
					    @user = create(:user)
 | 
				
			||||||
 | 
					    @room = @user.main_room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    allow_any_instance_of(Room).to receive(:owner).and_return(@user)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it "should properly find meeting recordings" do
 | 
				
			||||||
 | 
					    allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
 | 
				
			||||||
 | 
					      recordings: [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          name: "Example",
 | 
				
			||||||
 | 
					          playback: {
 | 
				
			||||||
 | 
					            format:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "presentation"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(recordings(@room.bbb_id, @room.owner.provider)).to contain_exactly(
 | 
				
			||||||
 | 
					      name: "Example",
 | 
				
			||||||
 | 
					      playbacks:
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          type: "presentation"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it "gets all filtered and sorted recordings for the user" do
 | 
				
			||||||
 | 
					    allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
 | 
				
			||||||
 | 
					      recordings: [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "Example",
 | 
				
			||||||
 | 
					          participants: "3",
 | 
				
			||||||
 | 
					          playback: {
 | 
				
			||||||
 | 
					            format:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "presentation"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "true",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "aExamaaa",
 | 
				
			||||||
 | 
					          participants: "5",
 | 
				
			||||||
 | 
					          playback: {
 | 
				
			||||||
 | 
					            format:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "other"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "false",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "test",
 | 
				
			||||||
 | 
					          participants: "1",
 | 
				
			||||||
 | 
					          playback: {
 | 
				
			||||||
 | 
					            format:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "presentation"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "true",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "Exam",
 | 
				
			||||||
 | 
					          participants: "1",
 | 
				
			||||||
 | 
					          playback: {
 | 
				
			||||||
 | 
					            format:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "other"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "false",
 | 
				
			||||||
 | 
					            name: "z",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(all_recordings(@user.rooms.pluck(:bbb_id), @user.provider, search: "Exam", column: "name",
 | 
				
			||||||
 | 
					      direction: "desc")).to eq(
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Example",
 | 
				
			||||||
 | 
					            participants: "3",
 | 
				
			||||||
 | 
					            playbacks:
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  type: "presentation"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "aExamaaa",
 | 
				
			||||||
 | 
					            participants: "5",
 | 
				
			||||||
 | 
					            playbacks:
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  type: "other"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "false",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  context '#filtering' do
 | 
				
			||||||
 | 
					    before do
 | 
				
			||||||
 | 
					      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
 | 
				
			||||||
 | 
					        recordings: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Example",
 | 
				
			||||||
 | 
					            participants: "3",
 | 
				
			||||||
 | 
					            playback: {
 | 
				
			||||||
 | 
					              format:
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "presentation"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "aExamaaa",
 | 
				
			||||||
 | 
					            participants: "5",
 | 
				
			||||||
 | 
					            playback: {
 | 
				
			||||||
 | 
					              format:
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "false",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "test",
 | 
				
			||||||
 | 
					            participants: "1",
 | 
				
			||||||
 | 
					            playback: {
 | 
				
			||||||
 | 
					              format:
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "presentation"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Exam",
 | 
				
			||||||
 | 
					            participants: "1",
 | 
				
			||||||
 | 
					            playback: {
 | 
				
			||||||
 | 
					              format:
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "false",
 | 
				
			||||||
 | 
					              name: "metadata",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should filter recordings on name" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, search: "Exam")).to contain_exactly(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "aExamaaa",
 | 
				
			||||||
 | 
					          participants: "5",
 | 
				
			||||||
 | 
					          playbacks:
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "false",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "Example",
 | 
				
			||||||
 | 
					          participants: "3",
 | 
				
			||||||
 | 
					          playbacks:
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "presentation"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "true",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should filter recordings on participants" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, search: "5")).to contain_exactly(
 | 
				
			||||||
 | 
					        meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					        name: "aExamaaa",
 | 
				
			||||||
 | 
					        participants: "5",
 | 
				
			||||||
 | 
					        playbacks:
 | 
				
			||||||
 | 
					          [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "other"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        metadata: {
 | 
				
			||||||
 | 
					          "gl-listed": "false",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should filter recordings on format" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, search: "presentation")).to contain_exactly(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "test",
 | 
				
			||||||
 | 
					          participants: "1",
 | 
				
			||||||
 | 
					          playbacks:
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  type: "presentation"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "true",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "Example",
 | 
				
			||||||
 | 
					          participants: "3",
 | 
				
			||||||
 | 
					          playbacks:
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  type: "presentation"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "true",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should filter recordings on visibility" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, search: "public")).to contain_exactly(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "test",
 | 
				
			||||||
 | 
					          participants: "1",
 | 
				
			||||||
 | 
					          playbacks:
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  type: "presentation"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "true",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					          meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					          name: "Example",
 | 
				
			||||||
 | 
					          participants: "3",
 | 
				
			||||||
 | 
					          playbacks:
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  type: "presentation"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					          metadata: {
 | 
				
			||||||
 | 
					            "gl-listed": "true",
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should filter recordings on metadata name by default" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, search: "metadata")).to contain_exactly(
 | 
				
			||||||
 | 
					        meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					        name: "Exam",
 | 
				
			||||||
 | 
					        participants: "1",
 | 
				
			||||||
 | 
					        playbacks:
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        metadata: {
 | 
				
			||||||
 | 
					          "gl-listed": "false",
 | 
				
			||||||
 | 
					          name: "metadata",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  context '#sorting' do
 | 
				
			||||||
 | 
					    before do
 | 
				
			||||||
 | 
					      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
 | 
				
			||||||
 | 
					        recordings: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Example",
 | 
				
			||||||
 | 
					            participants: "3",
 | 
				
			||||||
 | 
					            playback: {
 | 
				
			||||||
 | 
					              format: {
 | 
				
			||||||
 | 
					                type: "presentation",
 | 
				
			||||||
 | 
					                length: "4"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "aExamaaa",
 | 
				
			||||||
 | 
					            participants: "1",
 | 
				
			||||||
 | 
					            playback: {
 | 
				
			||||||
 | 
					              format: {
 | 
				
			||||||
 | 
					                type: "other",
 | 
				
			||||||
 | 
					                length: "3"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              name: "Z",
 | 
				
			||||||
 | 
					              "gl-listed": "false"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should sort recordings on name" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, column: "name", direction: "asc")).to eq(
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Example",
 | 
				
			||||||
 | 
					            participants: "3",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "presentation",
 | 
				
			||||||
 | 
					                length: "4"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "aExamaaa",
 | 
				
			||||||
 | 
					            participants: "1",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other",
 | 
				
			||||||
 | 
					                length: "3"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              name: "Z",
 | 
				
			||||||
 | 
					              "gl-listed": "false"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should sort recordings on participants" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, column: "users", direction: "desc")).to eq(
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Example",
 | 
				
			||||||
 | 
					            participants: "3",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "presentation",
 | 
				
			||||||
 | 
					                length: "4"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "aExamaaa",
 | 
				
			||||||
 | 
					            participants: "1",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other",
 | 
				
			||||||
 | 
					                length: "3"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              name: "Z",
 | 
				
			||||||
 | 
					              "gl-listed": "false"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should sort recordings on visibility" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, column: "visibility", direction: "desc")).to eq(
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Example",
 | 
				
			||||||
 | 
					            participants: "3",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "presentation",
 | 
				
			||||||
 | 
					                length: "4"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "aExamaaa",
 | 
				
			||||||
 | 
					            participants: "1",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other",
 | 
				
			||||||
 | 
					                length: "3"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              name: "Z",
 | 
				
			||||||
 | 
					              "gl-listed": "false"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should sort recordings on length" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, column: "length", direction: "asc")).to eq(
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "aExamaaa",
 | 
				
			||||||
 | 
					            participants: "1",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other",
 | 
				
			||||||
 | 
					                length: "3"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              name: "Z",
 | 
				
			||||||
 | 
					              "gl-listed": "false"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Example",
 | 
				
			||||||
 | 
					            participants: "3",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "presentation",
 | 
				
			||||||
 | 
					                length: "4"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should sort recordings on format" do
 | 
				
			||||||
 | 
					      expect(recordings(@room.bbb_id, @room.owner.provider, column: "formats", direction: "desc")).to eq(
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "Example",
 | 
				
			||||||
 | 
					            participants: "3",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "presentation",
 | 
				
			||||||
 | 
					                length: "4"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              "gl-listed": "true",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            meetingID: @room.bbb_id,
 | 
				
			||||||
 | 
					            name: "aExamaaa",
 | 
				
			||||||
 | 
					            participants: "1",
 | 
				
			||||||
 | 
					            playbacks: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                type: "other",
 | 
				
			||||||
 | 
					                length: "3"
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            metadata: {
 | 
				
			||||||
 | 
					              name: "Z",
 | 
				
			||||||
 | 
					              "gl-listed": "false"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@@ -20,6 +20,8 @@ require "rails_helper"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
describe AdminsController, type: :controller do
 | 
					describe AdminsController, type: :controller do
 | 
				
			||||||
  before do
 | 
					  before do
 | 
				
			||||||
 | 
					    allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
 | 
				
			||||||
 | 
					    controller.instance_variable_set(:@user_domain, "provider1")
 | 
				
			||||||
    @user = create(:user, provider: "provider1")
 | 
					    @user = create(:user, provider: "provider1")
 | 
				
			||||||
    @admin = create(:user, provider: "provider1")
 | 
					    @admin = create(:user, provider: "provider1")
 | 
				
			||||||
    @admin.add_role :admin
 | 
					    @admin.add_role :admin
 | 
				
			||||||
@@ -52,7 +54,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        get :edit_user, params: { user_uid: @user.uid }
 | 
					        get :edit_user, params: { user_uid: @user.uid }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(response).to render_template(:index)
 | 
					        expect(response).to render_template(:edit_user)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -144,7 +146,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        email = Faker::Internet.email
 | 
					        email = Faker::Internet.email
 | 
				
			||||||
        post :invite, params: { invite_user: { email: email } }
 | 
					        post :invite, params: { invite_user: { email: email } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        invite = Invitation.find_by(email: email, provider: "greenlight")
 | 
					        invite = Invitation.find_by(email: email, provider: "provider1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(invite.present?).to eq(true)
 | 
					        expect(invite.present?).to eq(true)
 | 
				
			||||||
        expect(flash[:success]).to be_present
 | 
					        expect(flash[:success]).to be_present
 | 
				
			||||||
@@ -197,7 +199,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image")
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(feature[:value]).to eq(fake_image_url)
 | 
					        expect(feature[:value]).to eq(fake_image_url)
 | 
				
			||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admin_site_settings_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -214,7 +216,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(feature[:value]).to eq(primary_color)
 | 
					        expect(feature[:value]).to eq(primary_color)
 | 
				
			||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admin_site_settings_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "changes the primary-lighten on the page" do
 | 
					      it "changes the primary-lighten on the page" do
 | 
				
			||||||
@@ -229,7 +231,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten")
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(feature[:value]).to eq(primary_color)
 | 
					        expect(feature[:value]).to eq(primary_color)
 | 
				
			||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admin_site_settings_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "changes the primary-darken on the page" do
 | 
					      it "changes the primary-darken on the page" do
 | 
				
			||||||
@@ -244,7 +246,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken")
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(feature[:value]).to eq(primary_color)
 | 
					        expect(feature[:value]).to eq(primary_color)
 | 
				
			||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admin_site_settings_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
@@ -264,7 +266,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        expect(feature[:value]).to eq(Rails.configuration.registration_methods[:invite])
 | 
					        expect(feature[:value]).to eq(Rails.configuration.registration_methods[:invite])
 | 
				
			||||||
        expect(flash[:success]).to be_present
 | 
					        expect(flash[:success]).to be_present
 | 
				
			||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admin_site_settings_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "does not allow the user to change to invite if emails are off" do
 | 
					      it "does not allow the user to change to invite if emails are off" do
 | 
				
			||||||
@@ -277,7 +279,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        post :registration_method, params: { method: "invite" }
 | 
					        post :registration_method, params: { method: "invite" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(flash[:alert]).to be_present
 | 
					        expect(flash[:alert]).to be_present
 | 
				
			||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admin_site_settings_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -293,7 +295,7 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication")
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(feature[:value]).to eq("true")
 | 
					        expect(feature[:value]).to eq("true")
 | 
				
			||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admin_site_settings_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -309,6 +311,22 @@ describe AdminsController, type: :controller do
 | 
				
			|||||||
        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit")
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(feature[:value]).to eq("5")
 | 
					        expect(feature[:value]).to eq("5")
 | 
				
			||||||
 | 
					        expect(response).to redirect_to(admin_site_settings_path)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context "POST #default_recording_visibility" do
 | 
				
			||||||
 | 
					      it "changes the default recording visibility setting" do
 | 
				
			||||||
 | 
					        allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
				
			||||||
 | 
					        allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @request.session[:user_id] = @admin.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        post :default_recording_visibility, params: { visibility: "public" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        feature = Setting.find_by(provider: "provider1").features.find_by(name: "Default Recording Visibility")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(feature[:value]).to eq("public")
 | 
				
			||||||
        expect(response).to redirect_to(admins_path)
 | 
					        expect(response).to redirect_to(admins_path)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,8 @@ def random_valid_room_params
 | 
				
			|||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe RoomsController, type: :controller do
 | 
					describe RoomsController, type: :controller do
 | 
				
			||||||
 | 
					  it_behaves_like "recorder"
 | 
				
			||||||
 | 
					  include Recorder
 | 
				
			||||||
  describe "GET #show" do
 | 
					  describe "GET #show" do
 | 
				
			||||||
    before do
 | 
					    before do
 | 
				
			||||||
      @user = create(:user)
 | 
					      @user = create(:user)
 | 
				
			||||||
@@ -39,7 +41,7 @@ describe RoomsController, type: :controller do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      get :show, params: { room_uid: @owner.main_room }
 | 
					      get :show, params: { room_uid: @owner.main_room }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(assigns(:recordings)).to eql(@owner.main_room.recordings)
 | 
					      expect(assigns(:recordings)).to eql(recordings(@owner.main_room.bbb_id, @owner.provider))
 | 
				
			||||||
      expect(assigns(:is_running)).to eql(@owner.main_room.running?)
 | 
					      expect(assigns(:is_running)).to eql(@owner.main_room.running?)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -117,8 +119,8 @@ describe RoomsController, type: :controller do
 | 
				
			|||||||
      @request.session[:user_id] = @owner.id
 | 
					      @request.session[:user_id] = @owner.id
 | 
				
			||||||
      name = Faker::Games::Pokemon.name
 | 
					      name = Faker::Games::Pokemon.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      room_params = { name: name, "client": "html5", "mute_on_join": "1" }
 | 
					      room_params = { name: name, "client": "html5", "mute_on_join": "1", "anyone_can_start": "1" }
 | 
				
			||||||
      json_room_settings = "{\"muteOnStart\":true,\"joinViaHtml5\":true}"
 | 
					      json_room_settings = "{\"muteOnStart\":true,\"joinViaHtml5\":true,\"anyoneCanStart\":true}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      post :create, params: { room: room_params }
 | 
					      post :create, params: { room: room_params }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -201,6 +203,46 @@ describe RoomsController, type: :controller do
 | 
				
			|||||||
      expect(response).to render_template(:wait)
 | 
					      expect(response).to render_template(:wait)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should join the room if the room has the anyone_can_start setting" do
 | 
				
			||||||
 | 
					      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      room = Room.new(name: "test")
 | 
				
			||||||
 | 
					      room.room_settings = "{\"muteOnStart\":false,\"joinViaHtml5\":false,\"anyoneCanStart\":true}"
 | 
				
			||||||
 | 
					      room.owner = @owner
 | 
				
			||||||
 | 
					      room.save
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @request.session[:user_id] = @user.id
 | 
				
			||||||
 | 
					      post :join, params: { room_uid: room, join_name: @user.name }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(response).to redirect_to(room.join_path(@user.name, { user_is_moderator: true }, @user.uid))
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should render wait if the correct access code is supplied" do
 | 
				
			||||||
 | 
					      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      protected_room = Room.new(name: 'test', access_code: "123456")
 | 
				
			||||||
 | 
					      protected_room.owner = @owner
 | 
				
			||||||
 | 
					      protected_room.save
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @request.session[:user_id] = @user.id
 | 
				
			||||||
 | 
					      post :join, params: { room_uid: protected_room, join_name: @user.name }, session: { access_code: "123456" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(response).to render_template(:wait)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should redirect to login if the correct access code isn't supplied" do
 | 
				
			||||||
 | 
					      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      protected_room = Room.new(name: 'test', access_code: "123456")
 | 
				
			||||||
 | 
					      protected_room.owner = @owner
 | 
				
			||||||
 | 
					      protected_room.save
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @request.session[:user_id] = @user.id
 | 
				
			||||||
 | 
					      post :join, params: { room_uid: protected_room, join_name: @user.name }, session: { access_code: "123455" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(response).to redirect_to room_path(protected_room.uid)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should join owner as moderator if meeting running" do
 | 
					    it "should join owner as moderator if meeting running" do
 | 
				
			||||||
      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
 | 
					      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -315,7 +357,8 @@ describe RoomsController, type: :controller do
 | 
				
			|||||||
      @request.session[:user_id] = @user.id
 | 
					      @request.session[:user_id] = @user.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      room_params = { "client": "html5", "mute_on_join": "1", "name": @secondary_room.name }
 | 
					      room_params = { "client": "html5", "mute_on_join": "1", "name": @secondary_room.name }
 | 
				
			||||||
      formatted_room_params = "{\"muteOnStart\":true,\"joinViaHtml5\":true}" # JSON string format
 | 
					      formatted_room_params = "{\"muteOnStart\":true,\"joinViaHtml5\":true,\"anyoneCanStart\":false}"
 | 
				
			||||||
 | 
					      # JSON string format
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect { post :update_settings, params: { room_uid: @secondary_room.uid, room: room_params } }
 | 
					      expect { post :update_settings, params: { room_uid: @secondary_room.uid, room: room_params } }
 | 
				
			||||||
        .to change { @secondary_room.reload.room_settings }
 | 
					        .to change { @secondary_room.reload.room_settings }
 | 
				
			||||||
@@ -372,4 +415,27 @@ describe RoomsController, type: :controller do
 | 
				
			|||||||
      expect(response).to redirect_to(@room)
 | 
					      expect(response).to redirect_to(@room)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe "POST #login" do
 | 
				
			||||||
 | 
					    before do
 | 
				
			||||||
 | 
					      @user = create(:user)
 | 
				
			||||||
 | 
					      @room = @user.main_room
 | 
				
			||||||
 | 
					      @room.access_code = "123456"
 | 
				
			||||||
 | 
					      @room.save
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should redirect to show with valid access code" do
 | 
				
			||||||
 | 
					      post :login, params: { room_uid: @room.uid, room: { access_code: "123456" } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(response).to redirect_to room_path(@room.uid)
 | 
				
			||||||
 | 
					      expect(flash[:alert]).to be_nil
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "should redirect to show with and notify user of invalid access code" do
 | 
				
			||||||
 | 
					      post :login, params: { room_uid: @room.uid, room: { access_code: "123455" } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(response).to redirect_to room_path(@room.uid)
 | 
				
			||||||
 | 
					      expect(flash[:alert]).to eq(I18n.t("room.access_code_required"))
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,9 +42,13 @@ describe ThemesController, type: :controller do
 | 
				
			|||||||
    it "returns the correct color based on provider" do
 | 
					    it "returns the correct color based on provider" do
 | 
				
			||||||
      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
					      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
				
			||||||
      allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
					      allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
				
			||||||
 | 
					      allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      color1 = Faker::Color.hex_color
 | 
					      color1 = Faker::Color.hex_color
 | 
				
			||||||
      provider1 = Faker::Company.name
 | 
					      provider1 = Faker::Company.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      controller.instance_variable_set(:@user_domain, provider1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Setting.create(provider: provider1).features.create(name: "Primary Color", value: color1, enabled: true)
 | 
					      Setting.create(provider: provider1).features.create(name: "Primary Color", value: color1, enabled: true)
 | 
				
			||||||
      user1 = create(:user, provider: provider1)
 | 
					      user1 = create(:user, provider: provider1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,6 +87,8 @@ describe UsersController, type: :controller do
 | 
				
			|||||||
    it "allows admins to edit other users" do
 | 
					    it "allows admins to edit other users" do
 | 
				
			||||||
      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
					      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
				
			||||||
      allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
					      allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
				
			||||||
 | 
					      allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
 | 
				
			||||||
 | 
					      controller.instance_variable_set(:@user_domain, "provider1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      user = create(:user, provider: "provider1")
 | 
					      user = create(:user, provider: "provider1")
 | 
				
			||||||
      user.add_role :admin
 | 
					      user.add_role :admin
 | 
				
			||||||
@@ -302,6 +304,7 @@ describe UsersController, type: :controller do
 | 
				
			|||||||
  describe "PATCH #update" do
 | 
					  describe "PATCH #update" do
 | 
				
			||||||
    it "properly updates user attributes" do
 | 
					    it "properly updates user attributes" do
 | 
				
			||||||
      user = create(:user)
 | 
					      user = create(:user)
 | 
				
			||||||
 | 
					      @request.session[:user_id] = user.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      params = random_valid_user_params
 | 
					      params = random_valid_user_params
 | 
				
			||||||
      patch :update, params: params.merge!(user_uid: user)
 | 
					      patch :update, params: params.merge!(user_uid: user)
 | 
				
			||||||
@@ -315,6 +318,7 @@ describe UsersController, type: :controller do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    it "renders #edit on unsuccessful save" do
 | 
					    it "renders #edit on unsuccessful save" do
 | 
				
			||||||
      @user = create(:user)
 | 
					      @user = create(:user)
 | 
				
			||||||
 | 
					      @request.session[:user_id] = @user.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      patch :update, params: invalid_params.merge!(user_uid: @user)
 | 
					      patch :update, params: invalid_params.merge!(user_uid: @user)
 | 
				
			||||||
      expect(response).to render_template(:edit)
 | 
					      expect(response).to render_template(:edit)
 | 
				
			||||||
@@ -337,6 +341,8 @@ describe UsersController, type: :controller do
 | 
				
			|||||||
      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
					      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
				
			||||||
      allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
					      allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
				
			||||||
      allow_any_instance_of(Room).to receive(:delete_all_recordings).and_return('')
 | 
					      allow_any_instance_of(Room).to receive(:delete_all_recordings).and_return('')
 | 
				
			||||||
 | 
					      allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
 | 
				
			||||||
 | 
					      controller.instance_variable_set(:@user_domain, "provider1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      user = create(:user, provider: "provider1")
 | 
					      user = create(:user, provider: "provider1")
 | 
				
			||||||
      admin = create(:user, provider: "provider1")
 | 
					      admin = create(:user, provider: "provider1")
 | 
				
			||||||
@@ -352,6 +358,8 @@ describe UsersController, type: :controller do
 | 
				
			|||||||
    it "doesn't allow admins of other providers to delete users" do
 | 
					    it "doesn't allow admins of other providers to delete users" do
 | 
				
			||||||
      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
					      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
 | 
				
			||||||
      allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
					      allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
 | 
				
			||||||
 | 
					      allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider2")
 | 
				
			||||||
 | 
					      controller.instance_variable_set(:@user_domain, "provider2")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      user = create(:user, provider: "provider1")
 | 
					      user = create(:user, provider: "provider1")
 | 
				
			||||||
      admin = create(:user, provider: "provider2")
 | 
					      admin = create(:user, provider: "provider2")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -133,420 +133,6 @@ describe Room, type: :model do
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  context "#recordings" do
 | 
					  context "#recordings" do
 | 
				
			||||||
    it "should properly find meeting recordings" do
 | 
					 | 
				
			||||||
      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
 | 
					 | 
				
			||||||
        recordings: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "Example",
 | 
					 | 
				
			||||||
            playback: {
 | 
					 | 
				
			||||||
              format:
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                type: "presentation"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      expect(@room.recordings).to contain_exactly(
 | 
					 | 
				
			||||||
        name: "Example",
 | 
					 | 
				
			||||||
        playbacks:
 | 
					 | 
				
			||||||
        [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            type: "presentation"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    context '#filtering' do
 | 
					 | 
				
			||||||
      before do
 | 
					 | 
				
			||||||
        allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
 | 
					 | 
				
			||||||
          recordings: [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "Example",
 | 
					 | 
				
			||||||
              participants: "3",
 | 
					 | 
				
			||||||
              playback: {
 | 
					 | 
				
			||||||
                format:
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "true",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "aExamaaa",
 | 
					 | 
				
			||||||
              participants: "5",
 | 
					 | 
				
			||||||
              playback: {
 | 
					 | 
				
			||||||
                format:
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "false",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "test",
 | 
					 | 
				
			||||||
              participants: "1",
 | 
					 | 
				
			||||||
              playback: {
 | 
					 | 
				
			||||||
                format:
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "true",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "Exam",
 | 
					 | 
				
			||||||
              participants: "1",
 | 
					 | 
				
			||||||
              playback: {
 | 
					 | 
				
			||||||
                format:
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "false",
 | 
					 | 
				
			||||||
                name: "z",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should filter recordings on name" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(search: "Exam")).to contain_exactly(
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "aExamaaa",
 | 
					 | 
				
			||||||
            participants: "5",
 | 
					 | 
				
			||||||
            playbacks:
 | 
					 | 
				
			||||||
              [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "false",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
            name: "Example",
 | 
					 | 
				
			||||||
            participants: "3",
 | 
					 | 
				
			||||||
            playbacks:
 | 
					 | 
				
			||||||
              [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "true",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should filter recordings on participants" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(search: "5")).to contain_exactly(
 | 
					 | 
				
			||||||
          name: "aExamaaa",
 | 
					 | 
				
			||||||
          participants: "5",
 | 
					 | 
				
			||||||
          playbacks:
 | 
					 | 
				
			||||||
            [
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                type: "other"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
          metadata: {
 | 
					 | 
				
			||||||
            "gl-listed": "false",
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should filter recordings on format" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(search: "presentation")).to contain_exactly(
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "test",
 | 
					 | 
				
			||||||
            participants: "1",
 | 
					 | 
				
			||||||
            playbacks:
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                  {
 | 
					 | 
				
			||||||
                    type: "presentation"
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "true",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
            name: "Example",
 | 
					 | 
				
			||||||
            participants: "3",
 | 
					 | 
				
			||||||
            playbacks:
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                  {
 | 
					 | 
				
			||||||
                    type: "presentation"
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "true",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should filter recordings on visibility" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(search: "public")).to contain_exactly(
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "test",
 | 
					 | 
				
			||||||
            participants: "1",
 | 
					 | 
				
			||||||
            playbacks:
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                  {
 | 
					 | 
				
			||||||
                    type: "presentation"
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "true",
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
            name: "Example",
 | 
					 | 
				
			||||||
            participants: "3",
 | 
					 | 
				
			||||||
            playbacks:
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                  {
 | 
					 | 
				
			||||||
                    type: "presentation"
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "true",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should filter recordings on metadata name by default" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(search: "z")).to contain_exactly(
 | 
					 | 
				
			||||||
          name: "Exam",
 | 
					 | 
				
			||||||
          participants: "1",
 | 
					 | 
				
			||||||
          playbacks:
 | 
					 | 
				
			||||||
              [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
          metadata: {
 | 
					 | 
				
			||||||
            "gl-listed": "false",
 | 
					 | 
				
			||||||
            name: "z",
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    context '#sorting' do
 | 
					 | 
				
			||||||
      before do
 | 
					 | 
				
			||||||
        allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
 | 
					 | 
				
			||||||
          recordings: [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "Example",
 | 
					 | 
				
			||||||
              participants: "3",
 | 
					 | 
				
			||||||
              playback: {
 | 
					 | 
				
			||||||
                format: {
 | 
					 | 
				
			||||||
                  type: "presentation",
 | 
					 | 
				
			||||||
                  length: "4"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "true",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "aExamaaa",
 | 
					 | 
				
			||||||
              participants: "1",
 | 
					 | 
				
			||||||
              playback: {
 | 
					 | 
				
			||||||
                format: {
 | 
					 | 
				
			||||||
                  type: "other",
 | 
					 | 
				
			||||||
                  length: "3"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                name: "Z",
 | 
					 | 
				
			||||||
                "gl-listed": "false"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should sort recordings on name" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(column: "name", direction: "asc")).to eq(
 | 
					 | 
				
			||||||
          [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "Example",
 | 
					 | 
				
			||||||
              participants: "3",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation",
 | 
					 | 
				
			||||||
                  length: "4"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "true",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "aExamaaa",
 | 
					 | 
				
			||||||
              participants: "1",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other",
 | 
					 | 
				
			||||||
                  length: "3"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                name: "Z",
 | 
					 | 
				
			||||||
                "gl-listed": "false"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should sort recordings on participants" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(column: "users", direction: "desc")).to eq(
 | 
					 | 
				
			||||||
          [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "Example",
 | 
					 | 
				
			||||||
              participants: "3",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation",
 | 
					 | 
				
			||||||
                  length: "4"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "true",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "aExamaaa",
 | 
					 | 
				
			||||||
              participants: "1",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other",
 | 
					 | 
				
			||||||
                  length: "3"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                name: "Z",
 | 
					 | 
				
			||||||
                "gl-listed": "false"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should sort recordings on visibility" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(column: "visibility", direction: "desc")).to eq(
 | 
					 | 
				
			||||||
          [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "Example",
 | 
					 | 
				
			||||||
              participants: "3",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation",
 | 
					 | 
				
			||||||
                  length: "4"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "true",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "aExamaaa",
 | 
					 | 
				
			||||||
              participants: "1",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other",
 | 
					 | 
				
			||||||
                  length: "3"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                name: "Z",
 | 
					 | 
				
			||||||
                "gl-listed": "false"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should sort recordings on length" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(column: "length", direction: "asc")).to eq(
 | 
					 | 
				
			||||||
          [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "aExamaaa",
 | 
					 | 
				
			||||||
              participants: "1",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other",
 | 
					 | 
				
			||||||
                  length: "3"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                name: "Z",
 | 
					 | 
				
			||||||
                "gl-listed": "false"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "Example",
 | 
					 | 
				
			||||||
              participants: "3",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation",
 | 
					 | 
				
			||||||
                  length: "4"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "true",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it "should sort recordings on format" do
 | 
					 | 
				
			||||||
        expect(@room.recordings(column: "formats", direction: "desc")).to eq(
 | 
					 | 
				
			||||||
          [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "Example",
 | 
					 | 
				
			||||||
              participants: "3",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation",
 | 
					 | 
				
			||||||
                  length: "4"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                "gl-listed": "true",
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              name: "aExamaaa",
 | 
					 | 
				
			||||||
              participants: "1",
 | 
					 | 
				
			||||||
              playbacks: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other",
 | 
					 | 
				
			||||||
                  length: "3"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              metadata: {
 | 
					 | 
				
			||||||
                name: "Z",
 | 
					 | 
				
			||||||
                "gl-listed": "false"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it "deletes the recording" do
 | 
					    it "deletes the recording" do
 | 
				
			||||||
      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
 | 
					      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
 | 
				
			||||||
        returncode: true, deleted: true
 | 
					        returncode: true, deleted: true
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -173,97 +173,4 @@ describe User, type: :model do
 | 
				
			|||||||
        .to raise_exception(ActiveRecord::RecordInvalid, "Validation failed: Email can't be blank")
 | 
					        .to raise_exception(ActiveRecord::RecordInvalid, "Validation failed: Email can't be blank")
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 | 
				
			||||||
  context '#recordings' do
 | 
					 | 
				
			||||||
    it "gets all filtered and sorted recordings for the user" do
 | 
					 | 
				
			||||||
      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
 | 
					 | 
				
			||||||
        recordings: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "Example",
 | 
					 | 
				
			||||||
            participants: "3",
 | 
					 | 
				
			||||||
            playback: {
 | 
					 | 
				
			||||||
              format:
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                type: "presentation"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "true",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "aExamaaa",
 | 
					 | 
				
			||||||
            participants: "5",
 | 
					 | 
				
			||||||
            playback: {
 | 
					 | 
				
			||||||
              format:
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                type: "other"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "false",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "test",
 | 
					 | 
				
			||||||
            participants: "1",
 | 
					 | 
				
			||||||
            playback: {
 | 
					 | 
				
			||||||
              format:
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                type: "presentation"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "true",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "Exam",
 | 
					 | 
				
			||||||
            participants: "1",
 | 
					 | 
				
			||||||
            playback: {
 | 
					 | 
				
			||||||
              format:
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                type: "other"
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "false",
 | 
					 | 
				
			||||||
              name: "z",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      expect(@user.all_recordings(search: "Exam", column: "name", direction: "desc")).to eq(
 | 
					 | 
				
			||||||
        [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "Example",
 | 
					 | 
				
			||||||
            participants: "3",
 | 
					 | 
				
			||||||
            playbacks:
 | 
					 | 
				
			||||||
              [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "presentation"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "true",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: "aExamaaa",
 | 
					 | 
				
			||||||
            participants: "5",
 | 
					 | 
				
			||||||
            playbacks:
 | 
					 | 
				
			||||||
              [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  type: "other"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
            metadata: {
 | 
					 | 
				
			||||||
              "gl-listed": "false",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user