forked from External/greenlight
Merge branch 'v2.2.1-alpha' into master
This commit is contained in:
commit
f7c88cfc6a
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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" %>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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) }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue