540 Commits
Author SHA1 Message Date
Joshua Arts 637ff5d485 update links in README.md 2018-07-09 13:52:30 -04:00
Joshua Arts d239356b1e Merge pull request #217 from ffdixon/update-env
Updated instructions for setting up OAuth2
2018-05-16 13:02:51 -04:00
Joshua Arts 585d9a2dd4 Merge pull request #218 from bigbluebutton/ffdixon-patch-1
Update bbb_api.rb
2018-05-16 12:45:04 -04:00
Fred Dixon 1655014478 Update bbb_api.rb
Update GreenLight for new way to launch HTML5 client
2018-05-16 11:59:22 -04:00
Fred Dixon ca3a2b8238 Updated instructions for setting up OAuth2 2018-05-15 09:12:09 -05:00
Jesus Federico 8179bd3d22 Updated rails (#216) 2018-05-03 11:31:20 -04:00
JDenhartogh 994179cadc added new languague locales (#214) 2018-05-03 11:28:42 -04:00
Bruck Wubete 5d56d10bb9 Enableing SAML auth co-exist with other OAuth services (#215)
* Enableing SAML auth co-exist with other OAuth services
* removing cert file
2018-05-03 11:18:43 -04:00
jfederico 042a4738f4 Merge branch 'saml' 2018-04-24 18:56:48 +00:00
Fred Dixon 8e3ba8bda3 Merge pull request #207 from JDenhartogh/gemupdate
Loofah gem updated
2018-03-22 17:39:12 -04:00
jeremydenhartogh a44ddaa3ad loofah gem updated 2018-03-21 16:50:48 -04:00
Peter Havekes ab62fc3e13 Added SAML2 support (#185)
* ~ in gitignore

* add config options for SAML authentication

* add information about SP metadata

* add gem for omniauth-saml

* Add the SAML strategy as a middleware

* add gem for omniauth-saml

* Send SAML request to saml module

* Pass env parameters to saml provider

* Add options for specifying saml signing certificate

* Almost there

* Re-enable SAML redirection

* Correctly map saml attributes

* change full certificate to only the fingerprint

* change full certificate to only the fingerprint

* revert changes to gitgnore

* cleanup
2018-03-02 09:31:12 -05:00
Jesus Federico 8c64087395 Merge pull request #200 from JDenhartogh/gemupdate
Update paperclip gem
2018-02-26 16:38:09 -05:00
jeremydenhartogh 20ee45f481 Update paperclip gem 2018-02-20 10:39:34 -05:00
Jesus Federico ba1fec5b72 Merge pull request #195 from JDenhartogh/master
Update gems
2018-01-22 17:02:10 -05:00
jeremydenhartogh be287098ef Update gems 2018-01-22 13:05:24 -05:00
Joshua Arts 3b32a92c36 Merge pull request #191 from joshua-arts/html5-support
Add support for HTML5 client
2017-10-12 17:01:57 -04:00
Josh 16443584ab fix multiple notifications when user has multiple tabs 2017-10-12 14:50:42 -04:00
Josh 8ac2c5d6d7 fix recording ready email for 2.0 2017-10-12 14:20:23 -04:00
Josh 3036e3d470 update schema.rb 2017-10-12 11:02:40 -04:00
Josh 2372b48e6a fix endless loading spinner 2017-10-05 16:47:03 -04:00
Josh f4d760fb11 fixes for html5 support 2017-10-05 15:51:45 -04:00
Josh ce761ce994 handle mobile case for HTML5 2017-09-29 17:10:51 -04:00
Josh da07eb749f add HTML5 support 2017-09-28 16:03:47 -04:00
Joshua Arts bca906ff6d Merge pull request #189 from joshua-arts/master
Update GreenLight to work with changes introduced in BigBlueButton 2.0 .
2017-09-15 09:25:43 -04:00
Josh 40ee86a6a4 add temp fix for recording length in milliseconds 2017-09-14 16:14:47 -04:00
Josh fbc8a56fc0 add support for BBB 2.0 webhooks 2017-09-14 15:59:42 -04:00
Josh 133dc664a4 re-include sample.env in docker image 2017-08-28 10:47:15 -04:00
Josh 61182448ad fix QR code whitespace under invite URL 2017-08-24 10:02:30 -04:00
Josh f282f1a1d8 Merge branch 'master' of https://github.com/bigbluebutton/greenlight 2017-08-22 16:52:51 -04:00
Josh 141660eabf bump ruby version in Dockerfiles 2017-08-22 16:51:36 -04:00
Joshua Arts c5c4afe493 Merge pull request #186 from joshua-arts/master
Fix Google authentication and update Omniauth to 1.6.1.
2017-08-22 15:40:35 -04:00
Josh be136fe255 update omniauth to 1.6.1 2017-08-21 11:49:53 -04:00
Josh 2e439e08da fix Google authentication 2017-08-21 11:46:07 -04:00
Jesus Federico 83c3a63583 Merge pull request #184 from jfederico/feature-qrcode
Feature qrcode
2017-08-15 17:06:27 -04:00
jfederico 22d0f4423d Fixed conflict with master 2017-08-15 20:44:06 +00:00
Jesus Federico 0719cbd1bf Merge pull request #183 from jfederico/updates
Updates to the environment variables
2017-08-15 16:41:05 -04:00
jfederico 4b7f104808 Removed duplicated code introduced in previous commit 2017-08-15 20:37:26 +00:00
jfederico 4590725c79 A warning message is shown when the BBB server configured is the one that comes by default 2017-08-15 20:33:19 +00:00
jfederico 20830c0e72 Restored definition of helper 2017-08-15 19:44:53 +00:00
jfederico 9db643a533 Merge branch 'updates' into feature-qrcode 2017-08-15 19:25:10 +00:00
jfederico f66f3d4dab Fixed issues reported by Scrutinizer 2017-08-15 19:21:19 +00:00
jfederico ce4c9456a7 Merge branch 'updates' into feature-qrcode 2017-08-15 19:15:56 +00:00
jfederico 4d915b6c1f Fixed issues reported by Scrutinizer 2017-08-15 19:12:24 +00:00
jfederico ad3c07d1de Fixed issues reported by Scrutinizer 2017-08-15 19:10:34 +00:00
jfederico f0321367f8 Fixed issue with circle-ci not able to use env variables 2017-08-15 19:03:17 +00:00
jfederico e0c856522f Added 'QR Code generation' as an optional feature 2017-08-15 19:01:36 +00:00
jfederico 970670ba6f Rework on landingController to reduce duplication 2017-08-14 21:31:01 +00:00
jfederico 5a5693cb33 Added defaults for omniauth 2017-08-14 21:08:56 +00:00
jfederico ea5c78db47 Updated unified sample.env and setup default values to some variables 2017-08-14 20:26:43 +00:00
jfederico 582ab30eb0 Updated ruby version and some gems 2017-08-14 20:23:54 +00:00
Josh 9135898f1d handle outlier cases where the number of join/leave events dont match 2017-08-01 16:41:28 -04:00
Josh 949fce701c refactor share button & add ability to disable youtube uploading 2017-07-28 14:58:51 -04:00
Joshua Arts 10c2f1f6e5 Merge pull request #182 from phavekes/master
add ability to restrict google authentication to a specific domain.
2017-07-26 09:44:06 -04:00
peter fe6e7c3efe should fix my gitignore 2017-07-25 16:56:23 +02:00
peter de948a9299 Formatting of comment about GOOGLE_OAUTH2_HD 2017-07-25 16:55:00 +02:00
peter 9edf2bc225 correctly handle empty GOOGLE_OAUTH2_hd 2017-07-25 16:11:36 +02:00
peter 9ff5519abb pass GOOGLE_OAUTH2_ID to provider 2017-07-25 11:28:55 +02:00
peter 1e4719e818 add GOOGLE_OAUTH2_HD parameter 2017-07-25 11:26:58 +02:00
Josh f40ef121c8 use root_url instead of relative_root to satisfy test 2017-07-24 15:28:10 -04:00
Josh f4e9e01782 fix ldap auth failure redirect 2017-07-24 15:04:06 -04:00
Josh 23815ca118 properly handle certain characters in active meetings 2017-07-21 11:59:51 -04:00
Josh 3bc31048f4 fix issue where webhooks were not always removed 2017-07-21 11:58:36 -04:00
Josh 2d7ab0006c log to production.log instead of STDOUT by default 2017-07-19 16:12:14 -04:00
Josh baec82f661 ensure user is in wait list before attempting to remove 2017-07-19 14:30:36 -04:00
Josh c9ce897c66 add LDAP auth to readme 2017-07-17 11:59:22 -04:00
Josh 42bf2b1e54 clean active_meetings.js and landing.js 2017-07-14 13:21:02 -04:00
Josh 5f2a561922 fix bug when handling recently ended meeting status 2017-07-14 11:13:11 -04:00
Josh ab5c56c27d add guest landing page when guest access disabled 2017-07-13 12:11:16 -04:00
Josh ec16f51926 hide preferences link when not logged in 2017-07-13 11:00:17 -04:00
Josh 3a882f85c6 add ability to disable guest access 2017-07-12 16:34:16 -04:00
Josh 0cbb587fc0 don't register webhooks for guest meetings 2017-07-12 14:06:53 -04:00
Josh 29ca709c85 notice when trying to upload to Youtube with Twitter auth 2017-07-11 15:28:30 -04:00
Josh 042622cb01 fix production LDAP routing 2017-07-10 11:11:10 -04:00
Joshua Arts a45f4d4fd0 Merge pull request #177 from joshua-arts/master
LDAP Authentication Support
2017-07-07 10:37:29 -04:00
Josh 0b1ae2497f remove debug code 2017-07-07 10:32:48 -04:00
Josh 0040baecbf display ldap error to help with troubleshooting 2017-07-07 10:32:01 -04:00
Josh 43496a6cf1 change sessions#new test to allow redirect 2017-07-07 10:23:19 -04:00
Josh d80fd262bc add LDAP method as environment variable 2017-07-06 14:41:54 -04:00
Josh a0c39c91a5 add LDAP docs link 2017-07-06 14:16:55 -04:00
Josh 704dab1e5c add footer to Youtube prompt 2017-07-06 13:17:12 -04:00
Josh 034c5ba617 handle invalid credentials 2017-07-06 11:45:56 -04:00
Josh f8d2540665 remove LDAP login button 2017-07-06 09:16:53 -04:00
Josh 0eb26ae8ec only use LDAP when enabled 2017-07-06 09:08:49 -04:00
Josh ae774b90ce add LDAP authentication 2017-07-05 16:26:27 -04:00
Josh 9bbb669cc1 move WaitingList.empty() to controller 2017-07-04 14:51:24 -04:00
Josh d774200296 notification when meeting is empty 2017-07-04 14:30:39 -04:00
Josh 27f6076954 improvements to active meetings 2017-07-04 11:52:35 -04:00
Josh 44e2cb7027 delay webhooks destroy 2017-06-30 15:57:54 -04:00
Josh 89b733f633 destroy webhook on meeting end 2017-06-30 14:27:07 -04:00
Josh 5390c9d22c clean active_meetings.js 2017-06-26 12:07:26 -04:00
Josh 261bb314f2 make active meetings room specific 2017-06-23 13:55:23 -04:00
Josh 91499ff2e5 Merge branch 'master' of https://github.com/bigbluebutton/greenlight 2017-06-22 16:43:21 -04:00
Josh 69406f9ec5 hide thumbnails subtitle if no thumbnails 2017-06-22 16:40:59 -04:00
Joshua Arts 9dab509eb5 Merge pull request #176 from joshua-arts/master
Add more information to recording ready email.
2017-06-22 15:25:26 -04:00
Josh 7e16f042a5 add more information to recording ready email 2017-06-22 15:15:03 -04:00
Josh 78a2f33f2d properly handle post_publish event 2017-06-19 09:35:54 -04:00
Josh 6e343740e8 better error handling for youtube uploading 2017-06-16 11:22:25 -04:00
Josh 14bb88ad77 fix some recordings not being youtube compatible 2017-06-15 14:50:39 -04:00
Josh 23127f1119 reduce can_upload post requests 2017-06-15 13:59:55 -04:00
Josh e001c79aa8 prevent duplicates in previous meetings 2017-06-15 11:04:36 -04:00
Josh 9a74de431a increase buffer time & fix share load icon 2017-06-15 09:43:34 -04:00
Josh 4539219182 simplifying 2017-06-14 16:51:56 -04:00
Josh 8df0dd0a00 fix error in previous commit 2017-06-14 16:11:57 -04:00
Josh c14bb90eb5 handle no previous meetings 2017-06-14 15:54:13 -04:00
Josh e6fb0dbf15 dont show active meetings on root 2017-06-14 14:40:53 -04:00
Josh fce383d858 small fixes 2017-06-14 14:04:16 -04:00
Josh 8a613c8a00 change request url format 2017-06-14 13:09:31 -04:00
Joshua Arts a2f2f7f44c Merge pull request #175 from joshua-arts/webhooks
Add active meetings on landing page.
2017-06-14 09:12:47 -04:00
Joshua Arts 9e96f4e08e Merge branch 'master' into webhooks 2017-06-14 09:08:33 -04:00
Jesus Federico d02e5118ec Merge pull request #174 from joshua-arts/youtube
Add share button to recordings, and ability to upload to Youtube.
2017-06-13 17:25:38 -04:00
Josh 688120045b fix callback tests 2017-06-13 09:22:30 -04:00
Josh 206f293194 fix actioncable issue 2017-06-12 13:35:00 -04:00
Josh b1e65e4ca7 fix pluralization in initial populate 2017-06-12 10:52:00 -04:00
Josh 31f0e0a3e9 clean active_meetings.js 2017-06-08 10:43:06 -04:00
Josh 42f0c14b49 add/remove from previous meetings & loading spinner 2017-06-08 10:28:56 -04:00
Josh b9ace4dfa6 redirect to user when clicking logo if found 2017-06-07 16:24:29 -04:00
Josh 291d815056 don't show active meetings when not logged in 2017-06-07 15:48:47 -04:00
Josh de20200b5a move active meeting js to it's own file 2017-06-07 11:46:01 -04:00
Josh f5095b1e4d change checksum handling & show active meetings 2017-06-07 11:06:31 -04:00
Josh ad60c95118 fix invalid token error 2017-06-06 15:46:57 -04:00
Fred Dixon e1687bb86b Update README.md 2017-06-06 10:23:17 -04:00
Josh 1ddc16af86 added indicator when uploading to youtube 2017-05-29 11:14:49 -04:00
Josh 4c34526a57 added footer to share email 2017-05-26 16:49:44 -04:00
Josh 93f2a83e46 fix title & privacy_status 2017-05-26 15:14:02 -04:00
Josh 02d1e726f0 auto populate video title input 2017-05-26 13:11:55 -04:00
Josh 10c5a06561 set public to default 2017-05-26 12:04:16 -04:00
Josh 3e31be3885 change youtube popover UI 2017-05-23 17:24:43 -04:00
Josh 7d96eadbbf upload recordings to youtube 2017-05-23 14:43:53 -04:00
Joshua Arts 24c8952e59 add preferences and customization (#171) 2017-05-11 09:58:51 -04:00
Jesus Federico 45c55efd04 Added Circle-ci badge 2017-05-09 15:53:34 +00:00
Jesus Federico f1b34628fa Added Scrutinizer-ci badges 2017-05-09 15:45:19 +00:00
Joshua Arts a2cfdc838f Slack Integration (#170)
* slack integration

* recomment server variables

* recomment server variables
2017-05-09 10:26:01 -04:00
Zachary Chai 924ca25ef1 Merge pull request #167 from zach-chai/errors_controller_authenticity
skip authenticity token on errors controller
2017-04-25 11:04:05 -04:00
Zachary Chai e1615a439f skip authenticity token on errors controller 2017-04-25 10:39:02 -04:00
Zachary Chai d0d39c477a Merge pull request #155 from zach-chai/email_subject
add recording name to subject
2017-04-24 11:23:20 -04:00
Zachary Chai aae1c2ff12 add recording name to subject 2017-04-21 17:21:06 -04:00
Zachary Chai 3d216ba41f remove redundant logging 2017-04-21 16:33:06 -04:00
Zachary Chai b27f82bbb4 Merge pull request #166 from zach-chai/email_check
email configuration check
2017-04-21 16:12:46 -04:00
Zachary Chai af9995ef5b email configuration check 2017-04-21 15:16:36 -04:00
Zachary Chai 62ef95128c Merge pull request #165 from zach-chai/encoding
encode room id separately from meeting id
2017-04-21 13:56:15 -04:00
Zachary Chai 30838f4b36 encode room id separately from meeting id 2017-04-21 13:51:45 -04:00
Zachary Chai 7c0b5613df Merge pull request #164 from zach-chai/encoding_error
encode slash properly for base URL
2017-04-18 16:56:45 -04:00
Zachary Chai d35b55400c encode slash properly for base URL 2017-04-18 16:40:35 -04:00
Zachary Chai 8bae80742b Merge pull request #163 from zach-chai/config_check
rake task to check configuration
2017-04-18 11:18:57 -04:00
Zachary Chai 8e056cdff2 rake task to check basic configuration and test connection to BBB server 2017-04-18 11:15:25 -04:00
Zachary Chai 3229f460f7 Merge pull request #162 from zach-chai/update_ruby
update ruby to 2.3.4
2017-04-11 13:37:33 -04:00
Zachary Chai e0dfa68e9d update ruby to 2.3.4 2017-04-11 13:19:14 -04:00
Zachary Chai 8173c4a803 Merge pull request #161 from zach-chai/room_id_param
override constraints to allow periods in room_id routes param
2017-04-11 11:26:07 -04:00
Zachary Chai 16a43711ca override constraints to allow periods in room_id routes param 2017-03-28 13:46:44 -04:00
Zachary Chai 926396e825 Merge pull request #159 from zach-chai/restrict_characters
restrict some characters in meeting name
2017-03-26 15:24:44 -04:00
Zachary Chai 280b28742d restrict some characters in meeting name 2017-03-26 15:06:10 -04:00
Zachary Chai 28e5d064da Merge pull request #158 from zach-chai/override_constraints
override rails meeting id param constraints for routes
2017-03-26 15:00:20 -04:00
Zachary Chai cb2e1e1f6b override rails id param constraints 2017-03-26 14:16:06 -04:00
Fred Dixon ae916de296 Update README.md 2017-03-25 18:05:27 -04:00
Fred Dixon 32fcd5fb79 Update README.md 2017-03-25 18:04:58 -04:00
Zachary Chai 6e5fdb8d14 Merge pull request #154 from zach-chai/exceptions
enable routes as exceptions app
2017-03-21 18:23:21 -04:00
Zachary Chai 3dd2a5e5ea enable routes as exceptions app 2017-03-21 18:18:16 -04:00
Zachary Chai a7903dddba Merge pull request #153 from zach-chai/error_controller
add errors controller with error pages for 404 500 422
2017-03-21 17:40:43 -04:00
Zachary Chai b55d535d33 add errors controller with error pages for 404 500 422 2017-03-21 17:20:30 -04:00
Zachary Chai 8cf75b6051 Merge pull request #152 from zach-chai/meeting_name_strip
strip spaces and newlines from meeting names
2017-03-21 14:01:28 -04:00
Zachary Chai 19929c4553 strip spaces and newlines from meeting names 2017-03-21 13:53:51 -04:00
Zachary Chai ef309eb491 Merge pull request #151 from zach-chai/delete_recording
treat 404 as success for deleting recordings
2017-03-21 13:20:39 -04:00
Zachary Chai 8e0cca5b4a remove recording from client if 404 2017-03-21 12:04:17 -04:00
Zachary Chai 97e1c6840b Merge pull request #150 from zach-chai/bbb_create
rescue on bbb create if meeting already exists
2017-03-21 10:41:37 -04:00
Zachary Chai 577cefaf71 rescue on bbb create if meeting already exists 2017-03-21 10:24:11 -04:00
Zachary Chai b937018d24 Merge pull request #149 from zach-chai/end_meeting
send 200 on end meeting even if not found
2017-03-17 16:12:06 -04:00
Zachary Chai fdf7fd54c5 send 200 on end meeting even if not found 2017-03-17 16:02:52 -04:00
Zachary Chai 89d8c9170e Merge pull request #148 from zach-chai/end_meeting
handle ending meeting when it doesn't exist
2017-03-17 15:15:05 -04:00
Zachary Chai 9901904d2a handle ending meeting when it doesn't exist 2017-03-17 15:07:20 -04:00
Zachary Chai 59be45c875 Merge pull request #147 from zach-chai/check_name_entered
notify user when joining without name provided
2017-03-14 17:07:49 -04:00
Zachary Chai 4d652463ec notify user when joining without name provided 2017-03-14 16:09:20 -04:00
Zachary Chai 8d4aaeff03 Merge pull request #146 from zach-chai/tutorial_video
only show tutorial video on root
2017-03-14 15:33:42 -04:00
Zachary Chai 36b6b5652f only show tutorial video on root 2017-03-14 15:17:04 -04:00
Zachary Chai cce5af3369 Merge pull request #145 from zach-chai/better_encoding
Better encoding
2017-03-14 14:37:48 -04:00
Zachary Chai b2031c97a3 add rails flash messages that dismiss after 5 seconds 2017-03-14 14:29:06 -04:00
Zachary Chai b0512a0569 allow periods in meeting name 2017-03-14 14:27:16 -04:00
Fred Dixon dd4cf365e9 Update README.md 2017-03-10 11:19:25 -05:00
Zachary Chai 1f1da89856 Merge pull request #144 from ffdixon/modify-footer
Added link to overview video for GreenLight to footer
2017-03-10 10:48:05 -05:00
Fred Dixon 6c19d192f2 Added link to overview video for GreenLight to footer 2017-03-10 09:44:07 -06:00
Zachary Chai b98185b540 Merge pull request #143 from alexandrekreis/master
Adding list of participants to post publish script
2017-03-07 10:41:39 -05:00
alexandre 10fd807156 Adding list of participants to post publish script 2017-03-06 19:49:38 -03:00
Zachary Chai d9603fccb9 Merge pull request #142 from zach-chai/more_testing
more testing and code cleanup
2017-03-03 15:34:13 -05:00
Zachary Chai 7c86aa8e7f more testing and code cleanup and enable coverage reports on circle 2017-03-03 15:26:41 -05:00
Zachary Chai bee42c8148 Merge pull request #141 from zach-chai/test_recording_callback
test recording ready callback
2017-03-03 14:16:28 -05:00
Zachary Chai 7ebe90d27b test recording ready callback 2017-03-03 14:05:37 -05:00
Zachary Chai 736bf89ce0 Merge pull request #140 from zach-chai/update_tests
Update tests
2017-03-03 10:54:29 -05:00
Zachary Chai b70ea41f4d test bbb controller 2017-03-03 10:49:14 -05:00
Zachary Chai 246e7ec3ed removed unused code 2017-03-03 10:49:14 -05:00
Zachary Chai d4d8228cbf hide login page if omniauth isn't configured 2017-03-03 10:49:14 -05:00
Zachary Chai bfd815abe0 test sessions controller 2017-03-03 10:49:14 -05:00
Zachary Chai eaaec47fe6 add test gems 2017-03-03 10:49:11 -05:00
Zachary Chai eac6edf2e0 add landing controller tests 2017-03-03 10:48:10 -05:00
Zachary Chai 3e6cd3a9ed Merge pull request #139 from zach-chai/redirect_help
redirect help to BBB videos
2017-03-02 13:45:09 -05:00
Zachary Chai a13e6b991e redirect help to BBB videos 2017-03-02 13:40:20 -05:00
Zachary Chai 66535e6881 Merge pull request #138 from zach-chai/logging
add condensed logging
2017-03-02 10:49:51 -05:00
Zachary Chai ce7292e581 add condensed logging 2017-03-02 10:34:01 -05:00
Zachary Chai 668886826f Merge pull request #137 from zach-chai/scope_recording_create
scope recording create notifications to room owner only
2017-03-02 09:28:56 -05:00
Zachary Chai 94d77249b5 scope recording create notifications to room owner only 2017-03-02 09:22:51 -05:00
Zachary Chai 71505a18d2 Merge pull request #136 from zach-chai/update_notification
update user waiting notification to show meeting name
2017-02-28 17:54:19 -05:00
Zachary Chai 03cae1ed19 update user waiting notification to show meeting name 2017-02-28 16:43:54 -05:00
Zachary Chai 7bb1340fef Merge pull request #135 from zach-chai/fix_delete
Fix delete
2017-02-28 10:45:46 -05:00
Zachary Chai a72656465b fix recording delete not sending notification 2017-02-28 10:38:57 -05:00
Zachary Chai 059a56e5a6 fix translation not working 2017-02-28 10:22:13 -05:00
Zachary Chai c96e5d3ba3 Merge pull request #134 from zach-chai/character_limits
meeting and user name character limits
2017-02-24 11:08:38 -05:00
Zachary Chai f89bca5967 meeting and user name character limits 2017-02-24 10:56:37 -05:00
Zachary Chai 8767788d3e add nginx config file 2017-02-23 11:58:51 -05:00
Zachary Chai d16470386f Merge pull request #132 from zach-chai/minor_email_change
change email template table styling
2017-02-22 17:26:15 -05:00
Zachary Chai 21b1e275b7 change email template table styling 2017-02-22 17:18:48 -05:00
Zachary Chai a4efa3b3a3 Merge pull request #131 from zach-chai/update_email
update recording notification email
2017-02-22 14:55:57 -05:00
Zachary Chai ebc52d2271 update recording notification email 2017-02-22 14:44:38 -05:00
Zachary Chai 80374e02a5 fix email link 2017-02-21 16:27:54 -05:00
Zachary Chai 55f2041b7c Merge pull request #130 from zach-chai/uri_encode
uri encode webhook URL
2017-02-21 13:15:06 -05:00
Zachary Chai f165a2354f uri encode webhook URL 2017-02-21 12:47:18 -05:00
Zachary Chai 4be08f993d Merge pull request #129 from zach-chai/previous_meetings
make previous meetings per room instead of global
2017-02-21 11:01:28 -05:00
Zachary Chai 38ffce7d10 Merge pull request #125 from zach-chai/participants
add participants to recordings table
2017-02-21 10:44:43 -05:00
Zachary Chai 4d1bbe76a3 add participants to recordings table 2017-02-21 10:38:30 -05:00
Zachary Chai 7b52e2ef61 make previous meetings per room instead of global 2017-02-21 10:33:58 -05:00
Zachary Chai 47464d35b2 update env 2017-02-21 09:10:22 -05:00
Zachary Chai 7873f640bc use route url helpers instead of hardcoding 2017-02-17 16:05:59 -05:00
Zachary Chai 16a1626130 Merge pull request #128 from zach-chai/update_recording_notify
update recording notify to work with new workflow
2017-02-17 16:06:47 -05:00
Zachary Chai 63fbc27bca update recording notify to work with new workflow 2017-02-17 15:44:40 -05:00
Zachary Chai dbfed8eba4 Merge pull request #127 from zach-chai/help
Help page
2017-02-16 17:37:08 -05:00
Zachary Chai 6637983d4e add help link to center panel 2017-02-16 17:29:20 -05:00
Zachary Chai 64ac93f65f getting started page 2017-02-16 17:03:58 -05:00
Zachary Chai c8f8f09226 change default port to 5000 2017-02-16 14:37:59 -05:00
Zachary Chai 71bc125a61 Merge pull request #126 from zach-chai/fix_notifications
add user waiting notifications back to main room
2017-02-16 14:30:35 -05:00
Zachary Chai 7adba52824 add user waiting notifications back to main room 2017-02-16 14:24:55 -05:00
Zachary Chai 74f1f4c071 allow different action cable host 2017-02-16 10:34:47 -05:00
Zachary Chai 82df7d209a Merge pull request #124 from zach-chai/button_tooltips
button tooltips
2017-02-14 18:20:36 -05:00
Zachary Chai fa1bb0683e button tooltips 2017-02-14 18:13:30 -05:00
Zachary Chai 7d227fd383 Merge pull request #123 from zach-chai/force_ssl
force SSL
2017-02-14 17:37:40 -05:00
Zachary Chai b9dcb65a92 force SSL 2017-02-14 17:30:12 -05:00
Zachary Chai 6b868b4b58 union recording names in previous meetings 2017-02-14 16:12:07 -05:00
Zachary Chai 349f4c51c6 limit previous meetings container to 5 2017-02-14 15:00:23 -05:00
Zachary Chai 2cc5c9e949 Merge pull request #122 from zach-chai/past_meetings_from_recordings
past meetings from recordings
2017-02-14 14:30:01 -05:00
Zachary Chai 88191b67e8 past meetings from recordings 2017-02-14 11:33:44 -05:00
Zachary Chai 31a1464393 use constants for column positions 2017-02-14 10:10:24 -05:00
Zachary Chai ad311f3999 remove recording visibility column for anonymous users 2017-02-14 09:20:52 -05:00
Zachary Chai 5a6c8372f9 update recording labels 2017-02-14 08:03:06 -05:00
Zachary Chai 404bb93d1a fix background image 2017-02-10 17:41:53 -05:00
Zachary Chai add6a95c4b Merge pull request #120 from zach-chai/updates
Updates
2017-02-10 16:56:59 -05:00
Zachary Chai d6c7bcfade pressing enter while focused on meeting-name input triggers start event 2017-02-10 16:45:53 -05:00
Zachary Chai 88af18a642 modify invite join on root page to match room page 2017-02-10 16:44:51 -05:00
Zachary Chai f2dd5df845 Merge pull request #119 from zach-chai/recordings_play
recordings play button
2017-02-10 09:27:48 -05:00
Zachary Chai 4596664b97 recordings play button 2017-02-09 18:13:50 -05:00
Zachary Chai 330ce144ad small fixes 2017-02-09 17:54:53 -05:00
Zachary Chai c44b38c3da update docker compose file to version 3 2017-02-09 16:10:21 -05:00
Zachary Chai 85485d1bf2 fallback to rails default when '/' root supplied 2017-02-09 14:47:49 -05:00
Zachary Chai a45a704be3 Merge pull request #118 from zach-chai/fix_assets
Fix some assets not working in production
2017-02-09 11:38:51 -05:00
Zachary Chai eacde6bde5 update env doc 2017-02-09 11:34:18 -05:00
Zachary Chai 3dd3f43b24 serve fa assets from relative root 2017-02-09 11:28:11 -05:00
Zachary Chai 6c374bd0c0 reorganize stylesheet directory structure 2017-02-09 11:26:49 -05:00
Zachary Chai abe532afcf use official font awesome gem 2017-02-09 10:17:19 -05:00
Zachary Chai 9ecbd7f29d fix some assets not loading with relative root URLs 2017-02-07 16:21:53 -05:00
Zachary Chai adb0314701 Merge pull request #117 from zach-chai/update_routes
Update routes to support relative root urls
2017-02-07 14:49:23 -05:00
Zachary Chai 3db284b8bf support relative root urls for deploy to subdirectories 2017-02-07 14:43:18 -05:00
Zachary Chai b09ec1fc69 properly generate some urls 2017-02-07 14:41:24 -05:00
Zachary Chai bfbdfc645e update routes file 2017-02-07 10:02:16 -05:00
Zachary Chai 3521436bc8 remove signin background 2017-02-03 16:36:36 -05:00
Zachary Chai 77c66c5be5 Merge pull request #112 from zach-chai/add_license
add license to some files and change comment type in html
2017-02-03 16:31:43 -05:00
Zachary Chai c6cd728eea add license to some files and change comment type in html 2017-02-03 16:25:58 -05:00
Zachary Chai aa5d216312 Merge pull request #111 from zach-chai/update_mod_message
add invite link to moderator message
2017-02-03 16:01:26 -05:00
Zachary Chai beeef29d0a add invite link to moderator message 2017-02-03 15:47:43 -05:00
Zachary Chai e7e792ec94 Merge pull request #110 from zach-chai/more_rewording
More rewording
2017-02-03 14:49:04 -05:00
Zachary Chai 8f04967b28 select randomized title from pool on root page 2017-02-03 14:29:05 -05:00
Zachary Chai 4a90de057c rewording and consolidating some conditions 2017-02-03 14:10:01 -05:00
Zachary Chai 8719956ba4 swap visbility and watch columns 2017-02-03 12:09:02 -05:00
Zachary Chai 5232fd1ab1 Merge pull request #109 from zach-chai/previously_joined
update previously joined meetings on root page
2017-02-03 11:59:56 -05:00
Zachary Chai 253ae4d86a update previously joined meetings on root page 2017-02-03 11:45:53 -05:00
Zachary Chai 70d2189ee0 Merge pull request #108 from bigbluebutton/workflow_redesign
Simplify workflow of starting a meeting
2017-02-03 10:54:46 -05:00
Zachary Chai b923367e5c Merge pull request #107 from zach-chai/add_logout
add link to personal room and logout on every landing page
2017-02-03 10:22:53 -05:00
Zachary Chai fc7d3fd94e add link to personal room and logout on every landing page 2017-02-03 10:16:28 -05:00
Zachary Chai c62424ffb6 Merge pull request #106 from zach-chai/move_url_buttons
move url buttons in room below the url
2017-02-03 10:00:28 -05:00
Zachary Chai f6505df4e1 move url buttons in room below the url 2017-02-03 09:55:39 -05:00
Zachary Chai ae7029b5f2 Merge pull request #105 from zach-chai/logout_text
replace logout with return to personal room
2017-02-02 17:16:43 -05:00
Zachary Chai e2fc9863fe replace logout with return to personal room 2017-02-02 17:09:29 -05:00
Zachary Chai 40add376b2 Merge pull request #104 from zach-chai/update_footer
update footer and remove build version
2017-02-02 15:49:25 -05:00
Zachary Chai 49aa9bd29b update footer and remove build version 2017-02-02 15:17:41 -05:00
Zachary Chai c05ce293df Merge pull request #103 from zach-chai/previous_room_meetings
store previously joined authenticated meetings
2017-02-02 15:07:42 -05:00
Zachary Chai 5a29a344fe store previously joined authenticated meetings 2017-02-02 14:55:19 -05:00
Zachary Chai 126993dc08 Merge pull request #102 from zach-chai/recordings
Recordings
2017-02-02 11:18:44 -05:00
Zachary Chai 0ba1b2bf41 add visibility column to recordings 2017-02-02 11:06:28 -05:00
Zachary Chai 4311c3be8c change display names for recording visibility states 2017-02-02 10:09:42 -05:00
Zachary Chai 1494dfebf0 show recordings for anonymous users 2017-02-02 10:08:41 -05:00
Zachary Chai cbafd95d19 Merge pull request #101 from zach-chai/quick_changes
minor text changes
2017-02-02 09:18:33 -05:00
Zachary Chai 16fd597b1a minor text changes 2017-01-31 18:12:05 -05:00
Zachary Chai 9cf8042a69 Merge pull request #100 from zach-chai/fix_anonymous_meeting
fix anonymouse meetings
2017-01-31 17:00:09 -05:00
Zachary Chai 73debe7c28 fix anonymouse meetings 2017-01-31 16:56:12 -05:00
Zachary Chai 051a93e175 Merge pull request #99 from zach-chai/recording_updates
Recording updates
2017-01-31 16:34:22 -05:00
Zachary Chai 2c2590cf18 add recording name to table 2017-01-31 16:19:09 -05:00
Zachary Chai 43e58e402e organize routes and update comments 2017-01-31 15:59:28 -05:00
Zachary Chai 77fd74dd8f add recording events to other meeting pages under room 2017-01-31 15:06:04 -05:00
Zachary Chai 02f59c49e6 main room recordings 2017-01-31 12:10:15 -05:00
Zachary Chai 9667e3757b fix recording update channel and routes 2017-01-31 11:42:47 -05:00
Zachary Chai c70ad42d8b Merge pull request #98 from zach-chai/multi_meeting_rooms
Multi meeting rooms
2017-01-31 11:15:25 -05:00
Zachary Chai a06ba91596 fix tests 2017-01-31 11:08:21 -05:00
Zachary Chai 9a55ac9376 cleanup old websockets on page load 2017-01-31 11:01:34 -05:00
Zachary Chai d67663fbf1 multi meeting rooms 2017-01-27 18:12:36 -05:00
Zachary Chai 0ce2a226a7 Merge pull request #97 from zach-chai/room_rework
Room rework
2017-01-26 16:06:09 -08:00
Zachary Chai 5180a99c32 allow meeting name separately when joining from room 2017-01-26 18:59:25 -05:00
Zachary Chai 066755c56c add invite and join to room 2017-01-26 18:03:42 -05:00
Zachary Chai 31a8c0ea66 Merge pull request #96 from zach-chai/home_page_rework2
Home page rework2
2017-01-26 07:55:52 -08:00
Zachary Chai ac74041aca create components for new layout 2017-01-26 10:42:42 -05:00
Zachary Chai 540ab7d369 URI encode meeting name and only show invite/join when a name is entered 2017-01-26 09:34:05 -05:00
Zachary Chai e3e154b99c Merge pull request #95 from zach-chai/home_page_rework
Home page rework
2017-01-24 16:26:48 -05:00
Zachary Chai f7363df80e remove unused style 2017-01-24 16:21:38 -05:00
Zachary Chai d7cd9eb8bb update javascript and neaten up layout 2017-01-24 16:13:12 -05:00
Zachary Chai b30acae006 refactor meeting object naming 2017-01-24 14:25:25 -05:00
Zachary Chai e339dcd5b7 rework home layout 2017-01-24 14:15:20 -05:00
Zachary Chai 1c54f3cc6f Merge pull request #93 from zach-chai/change_paperclip_icon
change paperclip to clipboard icon
2017-01-24 11:15:52 -05:00
Zachary Chai f5a1ce5a6c Merge pull request #92 from zach-chai/update_readme
update readme and env
2017-01-24 10:41:04 -05:00
Zachary Chai fff39bd777 change paperclip to clipboard icon 2017-01-24 10:31:05 -05:00
Zachary Chai bcd012bef5 update readme and env 2017-01-24 10:27:36 -05:00
Zachary Chai 15760ebf0b Merge pull request #87 from zach-chai/update_login_text
update login logout text
2017-01-20 18:04:07 -05:00
Zachary Chai 2d0ca5f16b update login logout text 2017-01-20 16:46:51 -05:00
Fred Dixon afce542431 Merge pull request #86 from zach-chai/login_updates
Login updates
2017-01-20 15:10:49 -05:00
Zachary Chai ca79ba6317 style login description 2017-01-20 14:46:52 -05:00
Zachary Chai 9057948750 oauth signin buttons per provider spec 2017-01-20 14:34:30 -05:00
Zachary Chai 3039bd168b create separate page for login 2017-01-19 19:33:06 -05:00
Zachary Chai ceeafa3208 move signup area 2017-01-19 17:54:52 -05:00
Zachary Chai e5932d805b Merge pull request #85 from zach-chai/add_postgres_gem
postgres support
2017-01-19 15:13:56 -05:00
Zachary Chai 3a3b054786 postgres support 2017-01-19 15:09:34 -05:00
Zachary Chai dcc20f875c Merge pull request #84 from zach-chai/fix_build_script
fix dockerfile refernce in build image script
2017-01-17 19:37:16 -05:00
Zachary Chai 489e09c93a fix dockerfile refernce in build image script 2017-01-17 19:35:01 -05:00
Zachary Chai 1cc0010ceb Merge pull request #82 from zach-chai/update_docker_dev
create dockerfile for dev and update compose
2017-01-17 13:48:41 -05:00
Zachary Chai cef36d112c create dockerfile for dev and update compose 2017-01-17 11:29:10 -05:00
Fred Dixon bc6eb444ce Merge pull request #81 from daronco/issue-78
Don't ask for a name in the landing page, redir to the room/meeting
2017-01-11 12:24:52 -05:00
Leonardo Crauss Daronco b6cb7add17 Reuse variable in landing.js 2017-01-11 15:02:09 -02:00
Leonardo Crauss Daronco b8c4ffe80b Don't ask for a name in the landing page, redir to the room/meeting
Instead of asking the user for a name in the landing page, it just
redirects to the room/meeting page, where the user is asked to enter a
name. If the user is signed in, no redirect is necessary and the user's
name is used automatically.
2017-01-11 14:55:39 -02:00
Fred Dixon b82f693bff Merge pull request #80 from daronco/fix-missing-smtp_from
Fix missing 'smtp_from' variable when notifications are turned off
2017-01-06 15:08:09 -05:00
Fred Dixon d030605748 Merge pull request #79 from ffdixon/config-updates
Updates to Docerfile and env for documentation
2017-01-06 14:47:27 -05:00
Fred Dixon d49e2e539e Updates to Docerfile and env for documentation 2017-01-06 13:46:08 -06:00
Leonardo Crauss Daronco 78abef12af Fix missing 'smtp_from' variable when notifications are turned off
Application would break in production because Rails.config.smtp_from
was not set if GREENLIGHT_MAIL_NOTIFICATIONS was false.
2017-01-06 17:45:29 -02:00
Fred Dixon e988f5e5dd Update en-us.yml
Make the text more consistent by using the term meeting instead of session
2017-01-06 13:02:07 -05:00
Fred Dixon 76acc9d331 Merge pull request #75 from erickadbay/dev-erick
Fix for when User with encrypted_id is not found
2016-12-19 16:54:30 -04:00
Erick Kad-Bay a9ff1c7d9a Fix for when User with encrypted_id is not found 2016-12-19 15:44:58 -05:00
Fred Dixon 520aacf302 Merge pull request #74 from daronco/summit-9
Several improvements made during the Summit IX
2016-12-11 11:35:36 -05:00
Leonardo Crauss Daronco 219ea625e0 Use a different banner image for personal rooms 2016-12-09 15:43:38 -02:00
Leonardo Crauss Daronco 87bccb1204 Require browser notification permissions only when the user signs in
The only notification right now is for signed in users that are viewing
their room's page, so request permission only in this case.
2016-12-09 15:18:41 -02:00
Leonardo Crauss Daronco bf7d087f45 Show a browser notification when a user is waiting to join a room
The owner of a room receives a browser notification if he has the page open
and another person tries to join his room.
2016-12-09 13:52:53 -02:00
Leonardo Crauss Daronco 6726504ec3 Add timeago js library to show in the start_time of recordings 2016-12-09 11:50:09 -02:00
Leonardo Crauss Daronco 04ae45e4f4 Use 'unpublished' instead of 'inaccessible' 2016-12-09 10:26:28 -02:00
Leonardo Crauss Daronco f763d8394e Add flag to enable/disable mail notifications 2016-12-08 18:55:41 -02:00
Leonardo Crauss Daronco e94f3d7a10 Send an email to the user when a recording is done processing
Had to add an email attribute to users to store their email to send the
notification. Will only send it for user rooms since they are the only
ones we know who to notify.
2016-12-08 18:33:19 -02:00
Leonardo Crauss Daronco 09c30bb5bd Add flag to use webhooks and API call to register a hook
It almost works with webhooks now. Still TODO is:
* Remove the hook after the recording is published
* To process the publish_ended event from the webhooks either the webhook
  needs to include the metadata (currently it doesn't) or GreenLight has
  find out the meeting token without reading it from the metadata.
2016-12-08 14:01:57 -02:00
Leonardo Crauss Daronco 906b21ab0e Fix clicking buttons inside popovers
They would work only occasionally because of the way bootstrap handles
popovers with trigger:focus.
Had to change to trigger:click and manually close the popovers when
clicking outside of them or in buttons marked to close popovers.
2016-12-07 18:38:53 -02:00
Leonardo Crauss Daronco 03e9646502 Add an example of a post publish script to send data to greenlight 2016-12-07 16:32:59 -02:00
Leonardo Crauss Daronco e5efb05a01 Add endpoint to detect new recordings and update the interface
The endpoint receives events from BigBlueButton via webhooks or scripts
in the record and playback workflow.
For now it only treats the event for when a recording is ready.
When it happens, it uses action cable to update the interface dynamically
with the new recording.
2016-12-07 16:20:10 -02:00
Leonardo Crauss Daronco b518458622 Allow recordings to be 'unlisted'
Unlisted is a state between published and unpublished. They are still
published in the server, but will not appear to anyone other than the
user that created the recording.
It is done using a metadata attribute and required several changes in how
the application handles publishing and unpublishing.
2016-12-06 12:03:53 -02:00
Leonardo Crauss Daronco 40cbc8a575 Move the refresh button to be inside the meeting URL input
Less buttons, better interface.
2016-12-05 16:51:13 -02:00
Leonardo Crauss Daronco 45e173d132 Add a button with a "mailto:" link to send invitations 2016-12-05 16:32:03 -02:00
Zachary Chai 71831639f9 update readme and add new env file 2016-12-02 18:02:33 -05:00
Zachary Chai de85c5d1c6 Merge pull request #69 from zach-chai/downscale_background_image
downscale background image
2016-12-02 17:02:37 -05:00
Zachary Chai f6e895271e downscale background image 2016-12-02 16:58:30 -05:00
Zachary Chai 692e864434 Merge pull request #68 from zach-chai/transfer_bigbluebutton
point docker image to bigbluebutton repo
2016-12-02 16:23:19 -05:00
Zachary Chai a6aed404f0 point docker image to bigbluebutton repo 2016-12-02 16:20:48 -05:00
Zachary Chai 75fcc5af97 Merge pull request #67 from zach-chai/background
Background
2016-12-02 15:35:16 -05:00
Zachary Chai d8eff2087a add bbb logo 2016-12-02 15:28:01 -05:00
Zachary Chai 906d184f46 add background image 2016-12-02 15:25:47 -05:00
Zachary Chai 773e9689dc Merge pull request #66 from zach-chai/duration
add units to duration header
2016-12-02 15:01:37 -05:00
Zachary Chai 2194c45fe7 add units to duration header 2016-12-02 14:56:13 -05:00
Zachary Chai 76316b96ec add build numbers 2016-12-02 12:36:11 -05:00
Zachary Chai 98a8cdbd2a use new latest id from page in setup 2016-12-01 18:18:13 -05:00
Zachary Chai f63ea9c4b8 Merge pull request #63 from zach-chai/join_meeting_name
use the user's name for the bbb meeting name
2016-12-01 17:04:21 -05:00
Zachary Chai 7c916ae632 use the user's name for the bbb meeting name 2016-12-01 16:55:43 -05:00
Zachary Chai 37a75152ef logout docker after pushing image 2016-12-01 15:55:18 -05:00
Zachary Chai 41c9e7798f Merge pull request #62 from zach-chai/caching_fix
destroy recordings table before caching page
2016-12-01 15:38:02 -05:00
Zachary Chai 02ea99e8b9 destroy recordings table before caching page 2016-12-01 15:21:19 -05:00
Zachary Chai 05a7830cc3 Merge pull request #61 from zach-chai/updates
remember name for logged out users and other ui updates
2016-12-01 11:19:48 -05:00
Zachary Chai 36c429d4bb remember name for logged out users 2016-12-01 11:14:10 -05:00
Zachary Chai f545daca26 update recording text and orderable columns 2016-12-01 10:49:20 -05:00
Zachary Chai ae9e52f077 override circle database 2016-11-30 17:36:14 -05:00
Zachary Chai 44085a6b1a Merge pull request #58 from zach-chai/hide_empty_session_panel
hide joined sessions panel when empty
2016-11-30 17:15:50 -05:00
Zachary Chai 8402b8d06e hide joined sessions panel when empty 2016-11-30 17:12:19 -05:00
Zachary Chai ad6621b3ef change script permission 2016-11-30 16:19:35 -05:00
Zachary Chai 07bf1e2c15 circleci configuration and docker build 2016-11-30 16:19:27 -05:00
Zachary Chai f0128951f4 Merge pull request #56 from erickadbay/dev-erick
Fixed recording duration
2016-11-29 17:43:44 -05:00
Erick Kad-Bay f4a7c35e35 Duration is just shown as a number for now 2016-11-29 17:17:11 -05:00
Erick Kad-Bay 98802234a7 Fixed recording duration 2016-11-29 15:51:56 -05:00
Zachary Chai f400ca390e Merge pull request #55 from zach-chai/previously_joined_sessions
Previously joined sessions
2016-11-29 15:49:38 -05:00
Zachary Chai 4d4ccddc6e order sessions last joined at top 2016-11-29 15:37:20 -05:00
Zachary Chai bdee16f715 previously joined sessions 2016-11-29 15:37:20 -05:00
Zachary Chai 54347ac11b Merge pull request #54 from erickadbay/dev-erick
Added hover for thumbnails using css
2016-11-29 15:36:15 -05:00
Erick Kad-Bay 44701c0cd9 Merge remote-tracking branch 'upstream/master' into dev-erick 2016-11-29 15:27:53 -05:00
Zachary Chai ffddb0e834 Merge pull request #53 from zach-chai/tests
add basic tests
2016-11-29 15:25:20 -05:00
Zachary Chai 693cb3202b lock ruby version 2016-11-29 15:21:54 -05:00
Zachary Chai 0573927851 add basic tests 2016-11-29 15:21:36 -05:00
Erick Kad-Bay 067f5f1a08 Added hover for thumbnails 2016-11-29 15:20:16 -05:00
Zachary Chai a8e2aa37fc Merge pull request #52 from erickadbay/dev-erick
Added LGPL 3.0 license to all source/config files
2016-11-29 14:48:40 -05:00
Erick Kad-Bay 47e0e948d1 Added LGPL 3.0 license to all source/config files 2016-11-29 14:44:13 -05:00
Zachary Chai 0088eae7e4 Merge pull request #50 from zach-chai/join_as_moderator
all join as moderator in anonymous meeting
2016-11-25 12:16:43 -05:00
Zachary Chai 97435b63bc all join as moderator in anonymous meeting 2016-11-25 12:14:04 -05:00
Zachary Chai 77ba8c614b Merge pull request #49 from zach-chai/room_updates
Room updates
2016-11-24 18:20:20 -05:00
Zachary Chai 25f8b547e5 modify encrypted id 2016-11-24 17:42:08 -05:00
Zachary Chai 6fd3554af8 more obvious when no recordings 2016-11-24 17:37:12 -05:00
Zachary Chai 3f6111795a place recording popovers in table for handlers 2016-11-24 17:13:32 -05:00
Zachary Chai 48fe071af1 update room title 2016-11-24 16:55:54 -05:00
Zachary Chai 40e7540673 Merge pull request #48 from zach-chai/minor_redesign
Minor redesign
2016-11-24 16:24:24 -05:00
Zachary Chai f5fc08d58c show new publish icon on hover 2016-11-24 16:21:01 -05:00
Zachary Chai 0e0d744fe3 bigbluebutton link in footer 2016-11-24 14:40:41 -05:00
Zachary Chai 08ecae0ef6 move meeting refresh to the url input field 2016-11-24 14:23:01 -05:00
Zachary Chai ded0f9b056 meetings page changes 2016-11-24 11:49:54 -05:00
Zachary Chai 269ce7915e separate root page and meetings page 2016-11-24 11:16:56 -05:00
Zachary Chai fe0ce271d0 remove page header 2016-11-24 10:42:13 -05:00
Zachary Chai 9ee0fbc038 Merge pull request #44 from zach-chai/optional_omniauth
hide oauth login when not configured
2016-11-23 14:23:26 -05:00
Zachary Chai 423b649480 hide oauth login when not configured 2016-11-23 14:20:28 -05:00
Zachary Chai d11c998fa9 fix bad concat usage 2016-11-23 11:38:05 -05:00
Zachary Chai c9e339e5e1 Merge pull request #43 from zach-chai/fix_url_generate
generate url with ports
2016-11-22 18:18:20 -05:00
Zachary Chai 2f10203d85 generate url with ports 2016-11-22 18:16:34 -05:00
Zachary Chai e8cf988604 Merge pull request #42 from zach-chai/final_prod
easy_deploy_configs
2016-11-22 16:56:15 -05:00
Zachary Chai 8e7eef4b57 easy_deploy_configs 2016-11-22 16:51:14 -05:00
Zachary Chai 8fc8182672 Merge pull request #41 from zach-chai/cleanup
room updates in job
2016-11-21 16:35:56 -05:00
Zachary Chai f35012a5f2 room updates in job 2016-11-21 16:29:41 -05:00
Zachary Chai c79ae3c1d6 Merge pull request #40 from zach-chai/ui_updates
Ui updates
2016-11-21 15:18:50 -05:00
Zachary Chai 6144a7b45b increase width of center panel and make responsive 2016-11-21 15:04:55 -05:00
Zachary Chai 62dbefcb68 remove my room from header 2016-11-21 15:04:38 -05:00
Zachary Chai 445de38860 loading inidicator 2016-11-18 17:37:13 -05:00
Zachary Chai 25bccb7699 open recordings in new tab and hide from viewers when unpublished 2016-11-18 17:22:11 -05:00
Zachary Chai 6620df9c65 update text strings 2016-11-18 14:05:13 -05:00
Zachary Chai b8ec40c35f use body as container for tooltips 2016-11-17 17:16:57 -05:00
Zachary Chai 8b7dc9fc5d Merge pull request #39 from zach-chai/usability
Usability
2016-11-17 16:59:11 -05:00
Zachary Chai 8b536c4934 recording actions tooltips 2016-11-17 16:58:52 -05:00
Zachary Chai fd044fc75d copy url tooltip 2016-11-17 16:27:20 -05:00
Zachary Chai 459740cb36 Merge pull request #38 from zach-chai/usability
focus input on load and enter key submits join
2016-11-15 17:41:05 -05:00
Zachary Chai b0d0d13855 focus input on load and enter key submits join 2016-11-15 17:39:09 -05:00
Zachary Chai 878f72cc56 Merge pull request #37 from zach-chai/fix_guest_join
fix guest join
2016-11-15 16:49:27 -05:00
Zachary Chai a39f1beb0a fix guest join 2016-11-15 16:47:44 -05:00
Zachary Chai dbea6f1f9f Merge pull request #36 from zach-chai/cleanup_meetings
cleanup meetings
2016-11-15 14:28:15 -05:00
Zachary Chai c9f0dead12 cleanup meetings 2016-11-15 13:54:39 -05:00
Zachary Chai 68d3e8da5a configuration_updates 2016-11-15 11:28:37 -05:00
Zachary Chai e5c31f81c2 Merge pull request #34 from zach-chai/coffeescript_classes
coffeescript classes instead of es6
2016-11-14 17:35:28 -05:00
Zachary Chai 38aba2d29f coffeescript classes instead of es6 2016-11-14 17:34:51 -05:00
Zachary Chai c45e08a821 Merge pull request #33 from zach-chai/recordings
recordings table
2016-11-14 15:22:33 -05:00
Zachary Chai 8d2d4299f9 recordings table 2016-11-14 15:18:45 -05:00
Zachary Chai 18a1c0f835 Merge pull request #32 from zach-chai/meeting_class
finish meeting class
2016-11-10 17:15:56 -05:00
Zachary Chai 1d879993d5 finish meeting class 2016-11-10 17:05:43 -05:00
Zachary Chai ef06c4133b Merge pull request #31 from zach-chai/client_i18n
send translated strings to javascript
2016-11-10 14:46:55 -05:00
Zachary Chai c7d2c8f27e send translated strings to javascript 2016-11-10 14:26:21 -05:00
Zachary Chai c32b513d6c Merge pull request #30 from zach-chai/order_recordings
default ordering on recordings
2016-11-09 17:30:25 -05:00
Zachary Chai 6a6aa2aa02 default ordering on recordings 2016-11-09 17:28:55 -05:00
Zachary Chai 2259e9c11d add favicon 2016-11-09 17:21:48 -05:00
Zachary Chai a1f88a6615 Merge pull request #29 from zach-chai/dynamic_room_content
Dynamic room content
2016-11-09 17:00:54 -05:00
Zachary Chai 552ea39ddd meeting action alerts 2016-11-09 16:46:24 -05:00
Zachary Chai d22cc3e6d0 dynamic room content 2016-11-09 16:46:08 -05:00
Zachary Chai 7068d0b023 Merge pull request #28 from zach-chai/oauth_update
oauth update
2016-11-09 13:57:33 -05:00
Zachary Chai b4e0e73692 oauth update 2016-11-09 13:29:29 -05:00
Zachary Chai e093ead683 Merge pull request #27 from zach-chai/delete_sync
finish delete recording feature
2016-11-08 16:22:51 -05:00
Zachary Chai 83bdf4c387 finish delete recording feature 2016-11-08 16:03:24 -05:00
Zachary Chai 93b5e9a1b3 Merge pull request #26 from zach-chai/dialogs
Dialogs
2016-11-08 10:15:21 -05:00
Zachary Chai 1eb168a780 other ui changes 2016-11-07 17:37:46 -05:00
Zachary Chai bc7a77ef77 dialog confirmation for publish unpublish 2016-11-07 17:19:54 -05:00
Zachary Chai 9fad2a4ef8 delete confirmation 2016-11-07 15:48:23 -05:00
Zachary Chai 5a8e6026d9 Merge pull request #25 from zach-chai/end_meeting
End meeting
2016-11-07 13:30:23 -05:00
Zachary Chai bee0b88d97 refresh session status on meeting actions 2016-11-07 12:12:39 -05:00
Zachary Chai 58d5e7e6c5 combine channels for meeting updates 2016-11-07 11:19:54 -05:00
Zachary Chai b8c876443f add end button to views 2016-11-04 18:28:52 -04:00
Zachary Chai e11098c7a9 add end meeting to bbb controller 2016-11-04 16:32:10 -04:00
Zachary Chai c9aaf2346a Merge pull request #24 from zach-chai/localization
Localization
2016-11-03 17:37:48 -04:00
Zachary Chai f40d0ee65b localize recording dates 2016-11-03 17:34:06 -04:00
Zachary Chai bea502a5a2 localize app 2016-11-03 17:34:01 -04:00
Zachary Chai 84fb5c617f configure i18n 2016-11-03 17:22:33 -04:00
Zachary Chai 9a6b75d15b Merge pull request #23 from zach-chai/ui_changes
Ui changes
2016-11-02 17:06:14 -04:00
Zachary Chai 4def9bbbb9 update edit page 2016-11-02 17:04:37 -04:00
Zachary Chai 29a0796a5c add background 2016-11-02 16:32:23 -04:00
Zachary Chai 595ff619c8 Merge pull request #22 from zach-chai/recording_previews
recording previews
2016-11-02 16:19:18 -04:00
Zachary Chai ae82c80308 recording previews 2016-11-02 16:18:42 -04:00
Zachary Chai ac6fa7c6b4 Merge pull request #21 from zach-chai/join_form_changes
Join form changes
2016-11-01 17:21:31 -04:00
Zachary Chai 0c4e264d7e set room name in html 2016-11-01 17:18:39 -04:00
Zachary Chai 7da04d3334 remove refresh on specific pages and change join form 2016-11-01 17:04:57 -04:00
Zachary Chai bef04f0465 Merge pull request #20 from zach-chai/move_configuration
application configuration
2016-11-01 16:10:02 -04:00
Zachary Chai 8427547698 application configuration 2016-11-01 16:09:24 -04:00
Zachary Chai a9230616bc Merge pull request #19 from zach-chai/recordings
Recordings
2016-11-01 15:27:30 -04:00
Zachary Chai 15411d76fa only allow room owner to perform recording actions 2016-11-01 15:02:32 -04:00
Zachary Chai e400bf41e8 recording async update 2016-11-01 11:39:26 -04:00
Zachary Chai db9d06b72f add recordings table 2016-10-31 14:12:08 -04:00
Zachary Chai 3871e0129c add recordings api actions 2016-10-28 16:21:44 -04:00
Zachary Chai fdf6f0e2c4 Merge pull request #18 from zach-chai/wait_for_mod
Wait for mod
2016-10-27 13:58:54 -04:00
Zachary Chai b701f2e9a6 wait for moderator with action cable 2016-10-27 13:57:26 -04:00
Zachary Chai 3aeef0a4cf refactor bbb helper and implement wait for mod 2016-10-26 13:41:55 -04:00
Zachary Chai dadaa52387 Merge pull request #17 from zach-chai/redesigned_views
Redesigned views
2016-10-25 11:16:15 -04:00
Zachary Chai f71f46427f cleanup controllers and routes 2016-10-25 10:51:20 -04:00
Zachary Chai d3ad6980d9 redesigned meeting and room page 2016-10-25 10:47:25 -04:00
Zachary Chai 551b64bb59 shared components for redesigned layout 2016-10-25 10:47:21 -04:00
Zachary Chai 3529e97a08 header layout 2016-10-24 16:27:20 -04:00
Zachary Chai 50e98e4bcd Merge pull request #16 from zach-chai/login_provider
login with provider in personal room
2016-10-20 10:23:56 -04:00
Zachary Chai 4ec17344eb login with provider in personal room 2016-10-20 10:16:11 -04:00
Jesus Federico e1ab78ec63 Merge pull request #15 from jfederico/master
Minor fix to UI
2016-10-20 09:57:31 -04:00
jfederico 31a0dd4100 Removed text for sharing the meeting/room 2016-10-20 09:57:04 -04:00
jfederico 45856384d9 Merge branch 'master' of github.com:blindsidenetworks/greenlight 2016-10-20 09:53:35 -04:00
Jesus Federico 5fecb98d0b Input for name should be shown only to anonymous users 2016-10-20 00:13:26 +00:00
Zachary Chai 201a3ca0f5 Merge pull request #14 from zach-chai/username_step
username validations
2016-10-19 16:33:16 -04:00
Zachary Chai 51d9551877 username validations 2016-10-19 16:31:43 -04:00
Jesus Federico d313c5d373 Merge pull request #13 from jfederico/master
Some rework for generalizing code that is used by the two resources
2016-10-19 16:01:23 -04:00
jfederico 36d83b99c6 Changed the routes so we have only 3 locations to configure in nginx 2016-10-19 15:57:03 -04:00
jfederico 12aac189a8 Rework for generalizing some methods 2016-10-19 15:41:15 -04:00
jfederico 8d6904e183 Relocated code for login/logout in meetings 2016-10-19 14:52:23 -04:00
Zachary Chai b6e17b88c7 Merge pull request #12 from zach-chai/username_step
username
2016-10-19 14:32:07 -04:00
Zachary Chai 015dd7cda4 add users controller and intermediate username step 2016-10-19 14:22:16 -04:00
Jesus Federico d26d4a86bd Merge pull request #11 from jfederico/master
Fixes and refactoring to views and controllers
2016-10-19 14:03:17 -04:00
jfederico 05bc7718e1 Merge branch 'master' of github.com:blindsidenetworks/greenlight 2016-10-19 14:02:05 -04:00
jfederico bd3cbee2b4 Fixes required for making the logouturl work 2016-10-19 13:59:40 -04:00
jfederico 061f9c794a Refactored meetings resource and breaked up view into components 2016-10-19 13:43:58 -04:00
Jesus Federico 855746dc08 Updated icons to oauth authentication buttons 2016-10-19 13:58:07 +00:00
jfederico f195cff339 Added icons to social buttons 2016-10-18 18:12:11 -04:00
jfederico d4a9fd9147 Cleaned up code 2016-10-18 17:25:06 -04:00
jfederico ad807b636b Removed reference to helper from LandingController 2016-10-18 17:17:05 -04:00
Zachary Chai df8c265750 add end tag 2016-10-18 16:39:30 -04:00
Jesus Federico caf6d0bcae Merge pull request #10 from jfederico/master
Fixed issue with new meeting url not updated in copiable text
2016-10-18 16:36:10 -04:00
Jesus Federico 4ac239c65d Merge branch 'master' of github.com:blindsidenetworks/greenlight 2016-10-18 20:35:14 +00:00
jfederico 8eab21c2c2 Fixed issue with new meeting url not updated in copiable text 2016-10-18 16:34:46 -04:00
Jesus Federico d9f1af8889 Merge pull request #9 from jfederico/master
Implemented refresh URL
2016-10-18 16:26:29 -04:00
jfederico 875f2d2a12 Merge branch 'master' of github.com:blindsidenetworks/greenlight 2016-10-18 16:26:02 -04:00
jfederico 0d216adc52 Implemented refresh URL 2016-10-18 16:23:52 -04:00
Zachary Chai 421e0c3c37 Merge pull request #8 from zach-chai/fix_links
add links to personal room and root
2016-10-18 16:10:59 -04:00
Zachary Chai b16212a2e9 add links to personal room and root 2016-10-18 16:09:56 -04:00
Zachary Chai 83c9b1b324 Merge pull request #7 from zach-chai/tests
basic tests and user data
2016-10-18 15:42:03 -04:00
Zachary Chai 407e7f23ec basic tests and user data 2016-10-18 15:41:08 -04:00
Zachary Chai 4534cf28ea Merge pull request #6 from zach-chai/auth_landing
personalized rooms page
2016-10-18 15:25:20 -04:00
Zachary Chai 8693ba5860 personalized rooms page 2016-10-18 15:19:16 -04:00
Jesus Federico 14ad57d4d1 Merge pull request #5 from jfederico/master
Encapsulated javascript for landingController
2016-10-18 14:15:27 -04:00
jfederico e9f77b4e2e Encapsulated javascript for landingController 2016-10-18 14:14:37 -04:00
Jesus Federico e1a6effda5 Merge pull request #4 from jfederico/master
Removed code for autoclose as the bbb session will be open in the sam…
2016-10-18 13:57:25 -04:00
jfederico f8ff8cdd28 Removed code for autoclose as the bbb session will be open in the same tab/window 2016-10-18 13:56:54 -04:00
jfederico cd867f9e20 bbb_endpoint and bbb_secret can be configured with environment variables 2016-10-18 13:50:51 -04:00
jfederico c47bcd5aee Fixed typo on password for meeting create 2016-10-18 10:12:04 -04:00
Jesus Federico d10c92497f Merge pull request #3 from jfederico/master
Extended the landing page
2016-10-18 10:08:47 -04:00
jfederico e9caa740aa Merge branch 'master' of github.com:blindsidenetworks/greenlight 2016-10-18 10:03:50 -04:00
jfederico f725b7f1bc Implemented join to BBB first approach 2016-10-17 18:36:56 -04:00
Zachary Chai 352abe78af Merge pull request #2 from zach-chai/devise
Omniauth
2016-10-17 16:21:36 -04:00
Zachary Chai 3eeaacc6f4 add twitter and google oauth login 2016-10-17 15:06:11 -04:00
Zachary Chai 0d73a77f1f omniauth strategy 2016-10-17 14:26:31 -04:00
jfederico 682cbadbf0 Added some style to the landing page 2016-10-17 13:45:24 -04:00
Zachary Chai c32b48213a docker 2016-10-17 10:53:35 -04:00
jfederico f4b8348e43 Added extra gems required for ui and authentication 2016-10-17 10:37:44 -04:00
Jesus Federico 0fc0e27d02 Merge pull request #1 from jfederico/master
Baby steps on landing page
2016-10-17 10:22:07 -04:00
jfederico 3376a929f5 Statics landing page, first approach 2016-10-17 10:21:18 -04:00
jfederico fb5afb7d9b Aded bigbluebutton-api gem 2016-10-17 10:20:08 -04:00
jfederico c318d7c5d8 Added controller/view for landing page 2016-10-14 11:59:21 -04:00
Jesus Federico a15bf5b3a9 first commit 2016-10-13 17:30:58 +00:00
454 changed files with 7177 additions and 48320 deletions
+10 -13
View File
@@ -2,11 +2,10 @@
.git
.gitignore
README.md
SECURITY.md
.github
# Rails
.env
.env.prod
*.rbc
capybara-*.html
.rspec
@@ -14,16 +13,14 @@ log
tmp
/db/**/*.sqlite3
/db/**/*.sqlite3-journal
/db/production
/db/production-postgres
public/assets
public/b
public/system
coverage/
spec/tmp
.rvmrc
vendor/bundle
.bundle
Dockerfile
.gitlab-ci.yml
.rubocop.yml
spec
test
.byebug_history
# docker
docker-compose.yml
production-compose.yml
.atom
-16
View File
@@ -1,16 +0,0 @@
<!---
IMPORTANT
This template is mandatory for all Pull Requests.
Please follow the template to ensure your Pull Request is reviewed.
-->
<!--- Provide a general summary of your changes in the Title above -->
## Description
<!--- Describe your changes in detail -->
## Testing Steps
<!--- Please describe in detail how to test your changes. -->
## Screenshots (if appropriate):
<!--- Please include screenshots that may help to visualize your changes. -->
-95
View File
@@ -1,95 +0,0 @@
env:
RUBY_VERSION: 2.7
name: CI Build Pre-Release
on:
release:
types: [prereleased]
jobs:
main:
name: Build Docker Image
env:
DOCKER_REPOSITORY: ${{ secrets.DOCKER_REPOSITORY }}
DOCKER_BUILD_ENABLED: ${{ secrets.DOCKER_BUILD_ENABLED }}
DOCKER_BUILD_ALTERNATE_ENABLED: ${{ secrets.DOCKER_BUILD_ALTERNATE_ENABLED }}
runs-on: ubuntu-20.04
steps:
- name: Checkout
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: actions/checkout@v2
- name: Set up Docker Buildx
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract Docker Repository
id: ci_docker_repository
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=repository;]$(echo ${DOCKER_REPOSITORY:-$GITHUB_REPOSITORY})"
- name: Extract Tag Release
id: ci_tag_release_version
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=tag;]$(echo ${GITHUB_REF#refs/tags/} | cut -c 9-)"
- name: Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:v${{ steps.ci_tag_release_version.outputs.tag }}"
build-args: "version_code=release-${{ steps.ci_tag_release_version.outputs.tag }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
# Alternate Images with alpine
- name: Alternate Alpine Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true') && contains(env.DOCKER_BUILD_ALTERNATE_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
file: dockerfiles/v2/alpine
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:v${{ steps.ci_tag_release_version.outputs.tag }}-alpine"
build-args: "version_code=release-${{ steps.ci_tag_release_version.outputs.tag }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
# Alternate Images with amazonlinux
- name: Alternate Amazon Linux Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true') && contains(env.DOCKER_BUILD_ALTERNATE_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
file: dockerfiles/v2/amazonlinux
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:v${{ steps.ci_tag_release_version.outputs.tag }}-amazonlinux"
build-args: "version_code=release-${{ steps.ci_tag_release_version.outputs.tag }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Move cache
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
-101
View File
@@ -1,101 +0,0 @@
env:
RUBY_VERSION: 2.7
name: CI Build Push
on:
push:
branches: "*"
jobs:
main:
name: Build Docker Image
env:
DOCKER_REPOSITORY: ${{ secrets.DOCKER_REPOSITORY }}
DOCKER_BUILD_ENABLED: ${{ secrets.DOCKER_BUILD_ENABLED }}
DOCKER_BUILD_ALTERNATE_ENABLED: ${{ secrets.DOCKER_BUILD_ALTERNATE_ENABLED }}
runs-on: ubuntu-20.04
steps:
- name: Checkout
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: actions/checkout@v2
- name: Set up Docker Buildx
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract Docker Repository
id: ci_docker_repository
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=repository;]$(echo ${DOCKER_REPOSITORY:-$GITHUB_REPOSITORY})"
- name: Extract Branch Name
id: ci_branch_name
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
- name: Extract Commit Short SHA
id: ci_commit_short_sha
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=short_sha;]$(echo ${GITHUB_SHA} | cut -c1-7)"
- name: Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:${{ steps.ci_branch_name.outputs.branch }}"
build-args: "version_code=${{ steps.ci_branch_name.outputs.branch }}-${{ steps.ci_commit_short_sha.outputs.short_sha }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
# Alternate Image with alpine
- name: Alternate Alpine Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true') && contains(env.DOCKER_BUILD_ALTERNATE_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
file: dockerfiles/v2/alpine
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:${{ steps.ci_branch_name.outputs.branch }}-alpine"
build-args: "version_code=${{ steps.ci_branch_name.outputs.branch }}-${{ steps.ci_commit_short_sha.outputs.short_sha }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
# Alternate Images for bbb-bionic-230 with amazonlinux
- name: Alternate Amazon Linux Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true') && contains(env.DOCKER_BUILD_ALTERNATE_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
file: dockerfiles/v2/amazonlinux
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:${{ steps.ci_branch_name.outputs.branch }}-amazonlinux"
build-args: "version_code=${{ steps.ci_branch_name.outputs.branch }}-${{ steps.ci_commit_short_sha.outputs.short_sha }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Move cache
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
-110
View File
@@ -1,110 +0,0 @@
env:
RUBY_VERSION: 2.7
name: CI Build Release
on:
release:
types: [released]
jobs:
main:
name: Build Docker Image
env:
DOCKER_REPOSITORY: ${{ secrets.DOCKER_REPOSITORY }}
DOCKER_BUILD_ENABLED: ${{ secrets.DOCKER_BUILD_ENABLED }}
DOCKER_BUILD_ALTERNATE_ENABLED: ${{ secrets.DOCKER_BUILD_ALTERNATE_ENABLED }}
runs-on: ubuntu-20.04
steps:
- name: Checkout
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: actions/checkout@v2
- name: Set up Docker Buildx
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract Docker Repository
id: ci_docker_repository
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=repository;]$(echo ${DOCKER_REPOSITORY:-$GITHUB_REPOSITORY})"
- name: Extract Tag Release
id: ci_tag_release
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=tag;]$(echo ${GITHUB_REF#refs/tags/})"
- name: Extract Tag Release Major
id: ci_tag_release_major
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=tag;]$(echo ${{steps.ci_tag_release.outputs.tag}} | cut -c 9- | cut -f1-1 -d'.')"
- name: Extract Tag Release Minor
id: ci_tag_release_minor
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
shell: bash
run: echo "##[set-output name=tag;]$(echo ${{steps.ci_tag_release.outputs.tag}} | cut -c 9- | cut -f1-2 -d'.')"
- name: Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:${{ steps.ci_tag_release.outputs.tag }}"
"${{ steps.ci_docker_repository.outputs.repository }}:v${{ steps.ci_tag_release_major.outputs.tag }}"
"${{ steps.ci_docker_repository.outputs.repository }}:v${{ steps.ci_tag_release_minor.outputs.tag }}"
"${{ steps.ci_docker_repository.outputs.repository }}:latest"
build-args: "version_code=${{ steps.ci_tag_release_revision.outputs.tag }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
# Alternate Image with alpine
- name: Alternate Alpine Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true') && contains(env.DOCKER_BUILD_ALTERNATE_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
file: dockerfiles/v2/alpine
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:${{ steps.ci_tag_release.outputs.tag }}-alpine"
build-args: "version_code=${{ steps.ci_tag_release_revision.outputs.tag }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
# Alternate Image with amazonlinux
- name: Alternate Amazon Linux Build and Push
if: contains(env.DOCKER_BUILD_ENABLED, 'true') && contains(env.DOCKER_BUILD_ALTERNATE_ENABLED, 'true')
uses: docker/build-push-action@v2
with:
file: dockerfiles/v2/amazonlinux
push: true
tags: |
"${{ steps.ci_docker_repository.outputs.repository }}:${{ steps.ci_tag_release.outputs.tag }}-amazonlinux"
build-args: "version_code=${{ steps.ci_tag_release_revision.outputs.tag }}"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Move cache
if: contains(env.DOCKER_BUILD_ENABLED, 'true')
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
-68
View File
@@ -1,68 +0,0 @@
env:
RUBY_VERSION: 2.7
DB_ADAPTER: postgresql
DB_HOST: localhost
DB_NAME: postgres
DB_USERNAME: postgres
DB_PASSWORD: postgres
DB_PORT: 5432
name: CI
on:
push:
branches-ignore: "master"
pull_request:
branches: "*"
jobs:
test:
name: Rubocop + RSpec
runs-on: ubuntu-18.04
services:
postgres:
image: postgres:13.2-alpine
env:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
# Health checks to wait until postgres is ready
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Ruby ${{ env.RUBY_VERSION }}
uses: actions/setup-ruby@v1
with:
ruby-version: ${{ env.RUBY_VERSION }}
- name: Bundle cache
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Setup database
run: |
bundler exec rails db:create RAILS_ENV=test
bundler exec rails db:migrate RAILS_ENV=test
- name: Run Rubocop
run: bundle exec rubocop --parallel --fail-level F
- name: Run RSpec
run: bundle exec rspec
+7 -31
View File
@@ -6,45 +6,21 @@
# Ignore bundler config.
/.bundle
vendor/.bundle
# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal
# Ignore static assets.
/db/**/*.sqlite3
/db/**/*.sqlite3-journal
/public/system/**
/public/assets/**
/public/b/**
# Ignore uploaded files
/storage
# Ignore production paths.
/db/production
/db/production-postgres
# Ignore all logfiles and tempfiles.
/log/*
/tmp
/tmp/*
!/log/.keep
!/tmp/.keep
.env
coverage
# Ignore Byebug command history file.
.byebug_history
# Ignore environment configuration.
.env
env
# Ignore yarn configs
/node_modules
# IDEs
.idea
.idea/**
.vscode
.vscode/**
config/terms.md
coverage*
/atom-sftp-sync.json
-71
View File
@@ -1,71 +0,0 @@
stages:
- test
- build
- deploy
cache:
paths:
- /cache
before_script:
test:
stage: test
image: ruby:2.5
script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
- bundle install --path /cache
- bundle exec rake db:create RAILS_ENV=test
- bundle exec rake test & bundle exec rspec & bundle exec rubocop
except:
variables:
- $CD_TEST_IGNORE
build:
stage: build
image: docker:stable
services:
- docker:dind
script:
# Install bash, curl, git for deployment script
- apk update && apk add --no-cache bash curl git
# Install CA certs, openssl to https downloads, python for gcloud sdk
- apk add --update make ca-certificates openssl python
- update-ca-certificates
# Build.
- ./scripts/image_build.sh $CI_PROJECT_PATH $CI_COMMIT_REF_NAME $CI_COMMIT_SHA
only:
refs:
- branches
- tags
variables:
- $CD_DOCKER_USERNAME
- $CD_DOCKER_PASSWORD
except:
variables:
- $CD_BUILD_IGNORE
deploy:
stage: deploy
image: docker:stable
services:
- docker:dind
script:
# Install bash, curl, git for deployment script
- apk update && apk add --no-cache bash curl git
# Install CA certs, openssl to https downloads, python for gcloud sdk
- apk add --update make ca-certificates openssl python
- update-ca-certificates
# Deploy.
- ./scripts/image_deploy.sh $CI_PROJECT_PATH $CI_COMMIT_REF_NAME $CI_COMMIT_SHA $CI_COMMIT_BEFORE_SHA
only:
refs:
- branches
- tags
variables:
- $CD_DOCKER_USERNAME
- $CD_DOCKER_PASSWORD
- $CD_DEPLOY_SCRIPT
except:
variables:
- $CD_DEPLOY_IGNORE
-42
View File
@@ -1,42 +0,0 @@
about
app:template
app:update
assets:clean[keep]
assets:clobber
assets:environment
assets:precompile
autoprefixer:info
cache_digests:dependencies
cache_digests:nested_dependencies
conf:check
db:create
db:drop
db:environment:set
db:fixtures:load
db:migrate
db:migrate:status
db:rollback
db:schema:cache:clear
db:schema:cache:dump
db:schema:dump
db:schema:load
db:seed
db:setup
db:structure:dump
db:structure:load
db:version
dev:cache
initializers
log:clear
middleware
notes
notes:custom
restart
routes
secret
stats
test
test:db
time:zones[country_or_offset]
tmp:clear
tmp:create
-3
View File
@@ -1,3 +0,0 @@
--require spec_helper
--format documentation
--color
-191
View File
@@ -1,191 +0,0 @@
AllCops:
Exclude:
- 'db/schema.rb'
- 'vendor/**/*'
DisabledByDefault: false
TargetRubyVersion: 2.7
NewCops: enable
Style/BlockDelimiters:
Enabled: false
# Checks if uses of quotes match the configured preference.
Style/StringLiterals:
Enabled: false
# Document classes and non-namespace modules.
Style/Documentation:
Enabled: false
# Check for conditionals that can be replaced with guard clauses
Style/GuardClause:
Enabled: false
# Checks the formatting of empty method definitions.
Style/EmptyMethod:
Enabled: false
# Checks for trailing comma in hash literals.
Style/TrailingCommaInHashLiteral:
Enabled: false
# Checks for trailing comma in argument lists.
Style/TrailingCommaInArguments:
Enabled: false
# Checks that `include`, `extend` and `prepend` exists at the top level.
Style/MixinUsage:
Enabled: false
# Use %i or %I for arrays of symbols.
Style/SymbolArray:
Enabled: false
# Don't use begin blocks when they are not needed.
Style/RedundantBegin:
Enabled: false
# Use `%`-literal delimiters consistently
Style/PercentLiteralDelimiters:
Enabled: false
# Only use if/unless modifiers on single line statements.
Style/MultilineIfModifier:
Enabled: false
# Checks for trailing comma in array literals.
Style/TrailingCommaInArrayLiteral:
Enabled: false
# Use `expand_path(__dir__)` instead of `expand_path('..', __FILE__)`.
Style/ExpandPathArguments:
Enabled: false
# Do not assign mutable objects to constants.
Style/MutableConstant:
Enabled: false
# Avoid rescuing without specifying an error class.
Style/RescueStandardError:
Enabled: false
# Align the elements of a hash literal if they span more than one line.
Layout/HashAlignment:
Enabled: false
# Align the parameters of a method definition if they span more than one line.
Layout/ParameterAlignment:
Enabled: false
# Align ends corresponding to defs correctly.
Layout/EndAlignment:
Enabled: false
# Align elses and elsifs correctly.
Layout/ElseAlignment:
Enabled: false
# Add empty line after guard clause.
Layout/EmptyLineAfterGuardClause:
Enabled: false
# Align the arguments of a method call if they span more than one line.
Layout/ArgumentAlignment:
Enabled: false
#
Layout/IndentationWidth:
Enabled: false
Layout/CaseIndentation:
Enabled: false
# Checks for ambiguous block association with method when param passed without parentheses.
Lint/AmbiguousBlockAssociation:
Enabled: false
# Avoid long blocks with many lines.
Metrics/BlockLength:
Enabled: false
# A complexity metric geared towards measuring complexity for a human reader.
Metrics/PerceivedComplexity:
Max: 17
# Avoid classes longer than 100 lines of code.
Metrics/ClassLength:
Enabled: false
# Limit lines to 80 characters.
Layout/LineLength:
Max: 130
# Avoid methods longer than 10 lines of code.
Metrics/MethodLength:
Enabled: false
Metrics/ModuleLength:
Enabled: false
# A calculated magnitude based on number of assignments,
# branches, and conditions.
Metrics/AbcSize:
Max: 60
# A complexity metric that is strongly correlated to the number
# of test cases needed to validate a method.
Metrics/CyclomaticComplexity:
Max: 20
# Checks for method parameter names that contain capital letters, end in numbers, or do not meet a minimal length.
Naming/MethodParameterName:
Enabled: false
Lint/LiteralInInterpolation:
Enabled: false
Layout/EmptyLinesAroundAttributeAccessor:
Enabled: true
Layout/SpaceAroundMethodCallOperator:
Enabled: true
Lint/DeprecatedOpenSSLConstant:
Enabled: true
Lint/RaiseException:
Enabled: true
Lint/StructNewOverride:
Enabled: true
Style/ExponentialNotation:
Enabled: true
Style/HashEachMethods:
Enabled: true
Style/HashTransformKeys:
Enabled: true
Style/HashTransformValues:
Enabled: true
Style/SlicingWithRange:
Enabled: true
Style/OptionalBooleanParameter:
Enabled: false
Lint/DuplicateBranch:
Enabled: false
Lint/ConstantDefinitionInBlock:
Enabled: false
Lint/EmptyBlock:
Enabled: false
Style/HashLikeCase:
Enabled: false
-1
View File
@@ -1 +0,0 @@
2.7.2
+13 -67
View File
@@ -1,74 +1,20 @@
FROM ruby:2.7.2-alpine AS base
FROM ruby:2.4.0
# Set a variable for the install location.
ARG RAILS_ROOT=/usr/src/app
# Set Rails environment.
ENV RAILS_ENV production
ENV BUNDLE_APP_CONFIG="$RAILS_ROOT/.bundle"
# app dependencies
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
# Make the directory and set as working.
RUN mkdir -p $RAILS_ROOT
WORKDIR $RAILS_ROOT
ARG BUILD_PACKAGES="build-base curl-dev git"
ARG DEV_PACKAGES="postgresql-dev sqlite-libs sqlite-dev yaml-dev zlib-dev nodejs yarn"
ARG RUBY_PACKAGES="tzdata"
# Install app dependencies.
RUN apk update \
&& apk upgrade \
&& apk add --update --no-cache $BUILD_PACKAGES $DEV_PACKAGES $RUBY_PACKAGES
COPY Gemfile* ./
COPY Gemfile Gemfile.lock $RAILS_ROOT/
RUN bundle config --global frozen 1 \
&& bundle config set deployment 'true' \
&& bundle config set without 'development:test:assets' \
&& bundle install -j4 --path=vendor/bundle \
&& rm -rf vendor/bundle/ruby/2.7.0/cache/*.gem \
&& find vendor/bundle/ruby/2.7.0/gems/ -name "*.c" -delete \
&& find vendor/bundle/ruby/2.7.0/gems/ -name "*.o" -delete
# Adding project files.
COPY . .
# Remove folders not needed in resulting image
RUN rm -rf tmp/cache spec
############### Build step done ###############
FROM ruby:2.7.2-alpine
# Set a variable for the install location.
ARG RAILS_ROOT=/usr/src/app
ARG PACKAGES="tzdata curl postgresql-client sqlite-libs yarn nodejs bash"
ENV RAILS_ENV=production
ENV BUNDLE_APP_CONFIG="$RAILS_ROOT/.bundle"
WORKDIR $RAILS_ROOT
RUN apk update \
&& apk upgrade \
&& apk add --update --no-cache $PACKAGES
ENV RAILS_ENV=production \
APP_HOME=/usr/src/app
COPY --from=base $RAILS_ROOT $RAILS_ROOT
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
# Expose port 80.
EXPOSE 80
# Add the greenlight app
ADD . $APP_HOME
# Sets the footer of greenlight application with current build version
ARG version_code
ENV VERSION_CODE=$version_code
# Install app dependencies
RUN bundle install --without development test doc --deployment --clean
RUN bundle exec rake assets:precompile --trace
# Set executable permission to start file
RUN chmod +x bin/start
# FIXME / to remove / https://github.com/nahi/httpclient/issues/445
RUN cat /etc/ssl/certs/ca-certificates.crt \
>/usr/src/app/vendor/bundle/ruby/2.7.0/gems/httpclient-2.8.3/lib/httpclient/cacert.pem
# Start the application.
CMD ["bin/start"]
CMD ["scripts/default_start.sh"]
+10
View File
@@ -0,0 +1,10 @@
FROM ruby:2.4.0
# app dependencies
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
ENV RAILS_ENV=development \
APP_HOME=/usr/src/app
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
+87 -68
View File
@@ -1,79 +1,98 @@
# frozen_string_literal: true
source 'https://rubygems.org'
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
"https://github.com/#{repo_name}.git"
end
ruby '2.4.0'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'aws-sdk-s3', '~> 1.88.1'
gem 'bcrypt', '~> 3.1.7'
gem 'bigbluebutton-api-ruby', git: 'https://github.com/mconf/bigbluebutton-api-ruby.git', branch: 'master'
gem 'bn-ldap-authentication', '~> 0.1.4'
gem 'bootsnap', '~> 1.7.2', require: false
gem 'bootstrap', '~> 4.3.1'
gem 'cancancan', '~> 2.3.0'
gem 'coveralls', '~> 0.8.23', require: false
gem 'font-awesome-sass', '~> 5.9.0'
gem 'google-cloud-storage', '~> 1.30.0'
gem 'http_accept_language', '~> 2.1.1'
gem 'i18n-language-mapping', '~> 0.1.3.1'
gem 'jbuilder', '~> 2.11.2'
gem 'jquery-rails', '~> 4.4.0'
gem 'jquery-ui-rails', '~> 6.0.1'
gem 'local_time', '~> 2.1.0'
gem 'net-ldap', '~> 0.17.0'
gem 'omniauth', '~> 1.9.1'
gem 'omniauth-bn-launcher', '~> 0.1.3'
gem 'omniauth-bn-office365', '~> 0.1.1'
gem 'omniauth-google-oauth2', '~> 0.7.0'
gem 'omniauth_openid_connect', '~> 0.3.5'
gem 'omniauth-twitter', '~> 1.4.0'
gem 'pagy', '~> 3.11.0'
gem 'pluck_to_hash', '~> 1.0.2'
gem 'puma', '~> 4.3.8'
gem 'rails', '~> 5.2.6'
gem 'random_password', '~> 0.1.1'
gem "recaptcha", '~> 5.7.0'
gem 'redcarpet', '~> 3.5.1'
gem 'remote_syslog_logger', '~> 1.0.4'
gem 'rubocop', '~> 1.10.0'
gem 'sassc-rails', '~> 2.1.2'
gem 'sprockets', '~> 3.7.2'
gem 'sqlite3', '~> 1.3.6'
gem 'tabler-rubygem', git: 'https://github.com/blindsidenetworks/tabler-rubygem.git', tag: '0.1.4.1'
gem 'turbolinks', '~> 5.2.1'
gem 'tzinfo-data', '~> 1.2021.1'
gem 'uglifier', '~> 4.2.0'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use postgres as the database for Active Record
gem 'pg'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# See https://github.com/rails/execjs#readme for more supported runtimes
gem 'therubyracer', platforms: :ruby
group :production do
gem 'hiredis', '~> 0.6.3'
gem "lograge", '~> 0.11.2'
gem 'pg', '~> 0.18'
gem 'redis', '~> 4.2.5'
gem 'sequel', '~> 5.41.0'
end
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
group :development, :test do
gem 'byebug', '~> 11.1', platform: :mri
gem 'dotenv-rails', '~> 2.7'
end
group :test do
gem 'action-cable-testing', '~> 0.6'
gem "factory_bot_rails", '~> 6.1'
gem 'faker', '~> 2.16'
gem 'rails-controller-testing', '~> 1.0'
gem 'rspec-rails', '~> 3.7'
gem 'shoulda-matchers', '~> 3.1'
gem 'webmock', '~> 3.11'
# For environment configuration
gem 'dotenv-rails'
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platform: :mri
end
group :development do
gem 'listen', '~> 3.0'
gem 'spring', '~> 2.1'
gem 'spring-watcher-listen', '~> 2.0'
gem 'web-console', '~> 3.7'
# Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
gem 'web-console'
gem 'listen', '~> 3.0.5'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
group :test do
gem 'mocha'
gem 'simplecov', :require => false
end
group :production do
# For more condensed logging
gem "lograge"
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'omniauth', '1.6.1'
gem 'omniauth-twitter', '1.2.1'
gem 'omniauth-google-oauth2', '0.4.1'
gem 'omniauth-ldap'
gem 'bigbluebutton-api-ruby'
gem 'bootstrap-sass', '3.3.0.0'
gem 'bootstrap-social-rails', '~> 4.12'
gem 'font-awesome-sass', '4.7.0'
gem 'jquery-ui-rails'
gem 'jquery-datatables-rails', '~> 3.4.0'
gem 'rails-timeago', '~> 2.0'
gem 'http_accept_language'
# For sending slack notifications.
gem 'slack-notifier'
# For landing background image uploading.
gem 'paperclip', '~> 5.1'
# For uploading recordings to Youtube.
gem 'yt', '~> 0.28.0'
# Simple HTTP client.
gem 'faraday'
# For SAML authentication
gem 'omniauth-saml'
# For device detection to determine BigBlueButton client.
gem 'browser'
+261 -443
View File
@@ -1,521 +1,339 @@
GIT
remote: https://github.com/blindsidenetworks/tabler-rubygem.git
revision: 4c16e6dc930f6b92dec093abaf9652d768b46d97
tag: 0.1.4.1
specs:
tabler-rubygem (0.1.4.1)
autoprefixer-rails (>= 6.0.3)
GIT
remote: https://github.com/mconf/bigbluebutton-api-ruby.git
revision: 91dc495324a6b7e162773227ec3650f8a5b39c50
branch: master
specs:
bigbluebutton-api-ruby (1.7.0)
childprocess (>= 1.0.1)
ffi (>= 1.9.24)
json (>= 1.8.6)
nokogiri (>= 1.10.4)
rack (>= 1.6.11)
rubyzip (>= 1.3.0)
xml-simple (~> 1.1)
GEM
remote: https://rubygems.org/
specs:
action-cable-testing (0.6.1)
actioncable (>= 5.0)
actioncable (5.2.6)
actionpack (= 5.2.6)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.6)
actionpack (= 5.2.6)
actionview (= 5.2.6)
activejob (= 5.2.6)
actioncable (5.0.7)
actionpack (= 5.0.7)
nio4r (>= 1.2, < 3.0)
websocket-driver (~> 0.6.1)
actionmailer (5.0.7)
actionpack (= 5.0.7)
actionview (= 5.0.7)
activejob (= 5.0.7)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.6)
actionview (= 5.2.6)
activesupport (= 5.2.6)
rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3)
actionpack (5.0.7)
actionview (= 5.0.7)
activesupport (= 5.0.7)
rack (~> 2.0)
rack-test (~> 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.6)
activesupport (= 5.2.6)
actionview (5.0.7)
activesupport (= 5.0.7)
builder (~> 3.1)
erubi (~> 1.4)
erubis (~> 2.7.0)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (5.2.6)
activesupport (= 5.2.6)
activejob (5.0.7)
activesupport (= 5.0.7)
globalid (>= 0.3.6)
activemodel (5.2.6)
activesupport (= 5.2.6)
activerecord (5.2.6)
activemodel (= 5.2.6)
activesupport (= 5.2.6)
arel (>= 9.0)
activestorage (5.2.6)
actionpack (= 5.2.6)
activerecord (= 5.2.6)
marcel (~> 1.0.0)
activesupport (5.2.6)
activemodel (5.0.7)
activesupport (= 5.0.7)
activerecord (5.0.7)
activemodel (= 5.0.7)
activesupport (= 5.0.7)
arel (~> 7.0)
activesupport (5.0.7)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
aes_key_wrap (1.1.0)
arel (9.0.0)
ast (2.4.2)
attr_required (1.0.1)
autoprefixer-rails (10.2.4.0)
arel (7.1.4)
bigbluebutton-api-ruby (1.6.0)
xml-simple (~> 1.1)
bindex (0.5.0)
bootstrap-sass (3.3.0.0)
sass (~> 3.2)
bootstrap-social-rails (4.12.0)
railties (>= 3.1)
browser (2.5.2)
builder (3.2.3)
byebug (9.1.0)
climate_control (0.2.0)
cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
railties (>= 4.0.0)
coffee-script (2.4.1)
coffee-script-source
execjs
aws-eventstream (1.1.1)
aws-partitions (1.435.0)
aws-sdk-core (3.113.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.43.0)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.88.2)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.3)
aws-eventstream (~> 1, >= 1.0.2)
bcrypt (3.1.16)
bindata (2.4.10)
bindex (0.8.1)
bn-ldap-authentication (0.1.4)
net-ldap (~> 0)
bootsnap (1.7.3)
msgpack (~> 1.0)
bootstrap (4.3.1)
autoprefixer-rails (>= 9.1.0)
popper_js (>= 1.14.3, < 2)
sassc-rails (>= 2.0.0)
builder (3.2.4)
byebug (11.1.3)
cancancan (2.3.0)
childprocess (4.0.0)
concurrent-ruby (1.1.8)
coveralls (0.8.23)
json (>= 1.8, < 3)
simplecov (~> 0.16.1)
term-ansicolor (~> 1.3)
thor (>= 0.19.4, < 2.0)
tins (~> 1.6)
crack (0.4.5)
rexml
crass (1.0.6)
declarative (0.0.20)
declarative-option (0.1.0)
diff-lcs (1.4.4)
digest-crc (0.6.3)
rake (>= 12.0.0, < 14.0.0)
docile (1.3.5)
dotenv (2.7.6)
dotenv-rails (2.7.6)
dotenv (= 2.7.6)
railties (>= 3.2)
erubi (1.10.0)
coffee-script-source (1.12.2)
concurrent-ruby (1.0.5)
concurrent-ruby (1.0.5-java)
crass (1.0.4)
docile (1.1.5)
dotenv (2.2.1)
dotenv-rails (2.2.1)
dotenv (= 2.2.1)
railties (>= 3.2, < 5.2)
erubis (2.7.0)
execjs (2.7.0)
factory_bot (6.1.0)
activesupport (>= 5.0.0)
factory_bot_rails (6.1.0)
factory_bot (~> 6.1.0)
railties (>= 5.0.0)
faker (2.17.0)
i18n (>= 1.6, < 2)
faraday (1.3.0)
faraday-net_http (~> 1.0)
faraday (0.12.2)
multipart-post (>= 1.2, < 3)
ruby2_keywords
faraday-net_http (1.0.1)
ffi (1.15.0)
font-awesome-sass (5.9.0)
sassc (>= 1.11)
globalid (0.4.2)
ffi (1.9.18)
ffi (1.9.18-java)
ffi (1.9.18-x64-mingw32)
ffi (1.9.18-x86-mingw32)
font-awesome-sass (4.7.0)
sass (>= 3.2)
globalid (0.4.1)
activesupport (>= 4.2.0)
google-apis-core (0.3.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.14)
httpclient (>= 2.8.1, < 3.0)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
rexml
signet (~> 0.14)
webrick
google-apis-iamcredentials_v1 (0.2.0)
google-apis-core (~> 0.1)
google-apis-storage_v1 (0.3.0)
google-apis-core (~> 0.1)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.1.0)
google-cloud-storage (1.30.0)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.1)
google-cloud-core (~> 1.2)
googleauth (~> 0.9)
mini_mime (~> 1.0)
googleauth (0.16.0)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.14)
hashdiff (1.0.1)
hashie (4.1.0)
hiredis (0.6.3)
hashie (3.5.7)
http_accept_language (2.1.1)
httpclient (2.8.3)
i18n (1.8.10)
i18n (1.0.1)
concurrent-ruby (~> 1.0)
i18n-language-mapping (0.1.3.1)
jbuilder (2.11.2)
activesupport (>= 5.0.0)
jmespath (1.4.0)
jquery-rails (4.4.0)
jbuilder (2.7.0)
activesupport (>= 4.2.0)
multi_json (>= 1.2)
jquery-datatables-rails (3.4.0)
actionpack (>= 3.1)
jquery-rails
railties (>= 3.1)
sass-rails
jquery-rails (4.3.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jquery-ui-rails (6.0.1)
railties (>= 3.2.16)
json (2.5.1)
json-jwt (1.13.0)
activesupport (>= 4.2)
aes_key_wrap
bindata
jwt (2.2.2)
listen (3.5.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
local_time (2.1.0)
lograge (0.11.2)
json (1.8.6)
json (1.8.6-java)
jwt (1.5.6)
libv8 (3.16.14.19)
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
lograge (0.9.0)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
loofah (2.9.1)
loofah (2.2.2)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mail (2.7.0)
mini_mime (>= 0.1.1)
marcel (1.0.1)
memoist (0.16.2)
method_source (1.0.0)
mini_mime (1.1.0)
mini_portile2 (2.6.1)
minitest (5.14.4)
msgpack (1.4.2)
multi_json (1.15.0)
metaclass (0.0.4)
method_source (0.9.0)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mimemagic (0.3.2)
mini_mime (1.0.0)
mini_portile2 (2.3.0)
minitest (5.11.3)
mocha (1.3.0)
metaclass (~> 0.0.1)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.1.1)
net-ldap (0.17.0)
nio4r (2.5.7)
nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
racc (~> 1.4)
oauth (0.5.5)
oauth2 (1.4.7)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multipart-post (2.0.0)
net-ldap (0.16.1)
nio4r (2.3.1)
nio4r (2.3.1-java)
nokogiri (1.8.2)
mini_portile2 (~> 2.3.0)
nokogiri (1.8.2-java)
nokogiri (1.8.2-x64-mingw32)
mini_portile2 (~> 2.3.0)
nokogiri (1.8.2-x86-mingw32)
mini_portile2 (~> 2.3.0)
oauth (0.5.4)
oauth2 (1.4.0)
faraday (>= 0.8, < 0.13)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (1.9.1)
hashie (>= 3.4.6)
omniauth (1.6.1)
hashie (>= 3.4.6, < 3.6.0)
rack (>= 1.6.2, < 3)
omniauth-bn-launcher (0.1.3)
omniauth (~> 1.3, >= 1.3.2)
omniauth-oauth2 (= 1.5.0)
omniauth-bn-office365 (0.1.1)
omniauth (>= 1.3.2)
omniauth-oauth2 (>= 1.5.0)
omniauth-google-oauth2 (0.7.0)
jwt (>= 2.0)
omniauth-google-oauth2 (0.4.1)
jwt (~> 1.5.2)
multi_json (~> 1.3)
omniauth (>= 1.1.1)
omniauth-oauth2 (>= 1.5)
omniauth-oauth (1.2.0)
omniauth-oauth2 (>= 1.3.1)
omniauth-ldap (1.0.5)
net-ldap (~> 0.12)
omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.2)
rubyntlm (~> 0.3.4)
omniauth-oauth (1.1.0)
oauth
omniauth (>= 1.0, < 3)
omniauth (~> 1.0)
omniauth-oauth2 (1.5.0)
oauth2 (~> 1.1)
omniauth (~> 1.2)
omniauth-twitter (1.4.0)
omniauth-saml (1.8.1)
omniauth (~> 1.3)
ruby-saml (~> 1.4, >= 1.4.3)
omniauth-twitter (1.2.1)
json (~> 1.3)
omniauth-oauth (~> 1.1)
rack
omniauth_openid_connect (0.3.5)
addressable (~> 2.5)
omniauth (~> 1.9)
openid_connect (~> 1.1)
openid_connect (1.2.0)
activemodel
attr_required (>= 1.0.0)
json-jwt (>= 1.5.0)
rack-oauth2 (>= 1.6.1)
swd (>= 1.0.0)
tzinfo
validate_email
validate_url
webfinger (>= 1.0.1)
os (1.1.1)
pagy (3.11.0)
parallel (1.20.1)
parser (3.0.0.0)
ast (~> 2.4.1)
pg (0.21.0)
pluck_to_hash (1.0.2)
activerecord (>= 4.0.2)
activesupport (>= 4.0.2)
popper_js (1.16.0)
public_suffix (4.0.6)
puma (4.3.8)
nio4r (~> 2.0)
racc (1.5.2)
rack (2.2.3)
rack-oauth2 (1.16.0)
activesupport
attr_required
httpclient
json-jwt (>= 1.11.0)
rack (>= 2.1.0)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.6)
actioncable (= 5.2.6)
actionmailer (= 5.2.6)
actionpack (= 5.2.6)
actionview (= 5.2.6)
activejob (= 5.2.6)
activemodel (= 5.2.6)
activerecord (= 5.2.6)
activestorage (= 5.2.6)
activesupport (= 5.2.6)
paperclip (5.2.1)
activemodel (>= 4.2.0)
activesupport (>= 4.2.0)
cocaine (~> 0.5.5)
mime-types
mimemagic (~> 0.3.0)
pg (1.0.0)
pg (1.0.0-x64-mingw32)
pg (1.0.0-x86-mingw32)
puma (3.11.2)
puma (3.11.2-java)
pyu-ruby-sasl (0.0.3.3)
rack (2.0.5)
rack-test (0.6.3)
rack (>= 1.0)
rails (5.0.7)
actioncable (= 5.0.7)
actionmailer (= 5.0.7)
actionpack (= 5.0.7)
actionview (= 5.0.7)
activejob (= 5.0.7)
activemodel (= 5.0.7)
activerecord (= 5.0.7)
activesupport (= 5.0.7)
bundler (>= 1.3.0)
railties (= 5.2.6)
railties (= 5.0.7)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
activesupport (>= 5.0.1.rc1)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.3.0)
loofah (~> 2.3)
railties (5.2.6)
actionpack (= 5.2.6)
activesupport (= 5.2.6)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
rails-timeago (2.16.0)
actionpack (>= 3.1)
activesupport (>= 3.1)
railties (5.0.7)
actionpack (= 5.0.7)
activesupport (= 5.0.7)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
rake (13.0.3)
random_password (0.1.1)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
recaptcha (5.7.0)
json
redcarpet (3.5.1)
redis (4.2.5)
regexp_parser (2.1.1)
remote_syslog_logger (1.0.4)
syslog_protocol
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
request_store (1.5.0)
thor (>= 0.18.1, < 2.0)
rake (12.3.1)
rb-fsevent (0.10.2)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
ref (2.0.0)
request_store (1.4.0)
rack (>= 1.4)
retriable (3.1.2)
rexml (3.2.5)
rspec-core (3.9.3)
rspec-support (~> 3.9.3)
rspec-expectations (3.9.4)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-rails (3.9.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.4)
rubocop (1.10.0)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.2.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.4.1)
parser (>= 2.7.1.5)
ruby-progressbar (1.11.0)
ruby2_keywords (0.0.4)
rubyzip (2.3.0)
sassc (2.4.0)
ffi (~> 1.9)
sassc-rails (2.1.2)
railties (>= 4.0.0)
sassc (>= 2.0)
sprockets (> 3.0)
sprockets-rails
tilt
sequel (5.41.0)
shoulda-matchers (3.1.3)
activesupport (>= 4.0.0)
signet (0.15.0)
addressable (~> 2.3)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simplecov (0.16.1)
docile (~> 1.1)
ruby-saml (1.4.3)
nokogiri (>= 1.5.10)
rubyntlm (0.3.4)
sass (3.5.5)
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)
simplecov (0.15.1)
docile (~> 1.1.0)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
spring (2.1.1)
slack-notifier (2.3.2)
spring (2.0.2)
activesupport (>= 4.2)
spring-watcher-listen (2.0.1)
listen (>= 2.7, < 4.0)
spring (>= 1.2, < 3.0)
sprockets (3.7.2)
sprockets (3.7.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.2)
sprockets-rails (3.2.1)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.13)
swd (1.2.0)
activesupport (>= 3)
attr_required (>= 0.0.5)
httpclient (>= 2.4)
sync (0.5.0)
syslog_protocol (0.9.2)
term-ansicolor (1.7.1)
tins (~> 1.0)
thor (1.1.0)
sqlite3 (1.3.13-x64-mingw32)
sqlite3 (1.3.13-x86-mingw32)
sqlite3 (1.3.13-x86-mswin32-60)
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
ref
thor (0.20.0)
thread_safe (0.3.6)
tilt (2.0.10)
tins (1.28.0)
sync
turbolinks (5.2.1)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
tzinfo (1.2.9)
thread_safe (0.3.6-java)
tilt (2.0.8)
turbolinks (5.1.0)
turbolinks-source (~> 5.1)
turbolinks-source (5.1.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
tzinfo-data (1.2021.1)
tzinfo-data (1.2017.3)
tzinfo (>= 1.0.0)
uber (0.1.0)
uglifier (4.2.0)
uglifier (4.1.3)
execjs (>= 0.3.0, < 3)
unicode-display_width (2.0.0)
validate_email (0.1.6)
activemodel (>= 3.0)
mail (>= 2.2.5)
validate_url (1.0.13)
activemodel (>= 3.0.0)
public_suffix
web-console (3.7.0)
web-console (3.5.1)
actionview (>= 5.0)
activemodel (>= 5.0)
bindex (>= 0.4.0)
railties (>= 5.0)
webfinger (1.1.0)
activesupport
httpclient (>= 2.4)
webmock (3.12.1)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.7.0)
websocket-driver (0.7.3)
websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xml-simple (1.1.8)
websocket-driver (0.6.5-java)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
xml-simple (1.1.5)
yt (0.28.5)
activesupport
PLATFORMS
java
ruby
x64-mingw32
x86-mingw32
x86-mswin32
DEPENDENCIES
action-cable-testing (~> 0.6)
aws-sdk-s3 (~> 1.88.1)
bcrypt (~> 3.1.7)
bigbluebutton-api-ruby!
bn-ldap-authentication (~> 0.1.4)
bootsnap (~> 1.7.2)
bootstrap (~> 4.3.1)
byebug (~> 11.1)
cancancan (~> 2.3.0)
coveralls (~> 0.8.23)
dotenv-rails (~> 2.7)
factory_bot_rails (~> 6.1)
faker (~> 2.16)
font-awesome-sass (~> 5.9.0)
google-cloud-storage (~> 1.30.0)
hiredis (~> 0.6.3)
http_accept_language (~> 2.1.1)
i18n-language-mapping (~> 0.1.3.1)
jbuilder (~> 2.11.2)
jquery-rails (~> 4.4.0)
jquery-ui-rails (~> 6.0.1)
listen (~> 3.0)
local_time (~> 2.1.0)
lograge (~> 0.11.2)
net-ldap (~> 0.17.0)
omniauth (~> 1.9.1)
omniauth-bn-launcher (~> 0.1.3)
omniauth-bn-office365 (~> 0.1.1)
omniauth-google-oauth2 (~> 0.7.0)
omniauth-twitter (~> 1.4.0)
omniauth_openid_connect (~> 0.3.5)
pagy (~> 3.11.0)
pg (~> 0.18)
pluck_to_hash (~> 1.0.2)
puma (~> 4.3.8)
rails (~> 5.2.6)
rails-controller-testing (~> 1.0)
random_password (~> 0.1.1)
recaptcha (~> 5.7.0)
redcarpet (~> 3.5.1)
redis (~> 4.2.5)
remote_syslog_logger (~> 1.0.4)
rspec-rails (~> 3.7)
rubocop (~> 1.10.0)
sassc-rails (~> 2.1.2)
sequel (~> 5.41.0)
shoulda-matchers (~> 3.1)
spring (~> 2.1)
spring-watcher-listen (~> 2.0)
sprockets (~> 3.7.2)
sqlite3 (~> 1.3.6)
tabler-rubygem!
turbolinks (~> 5.2.1)
tzinfo-data (~> 1.2021.1)
uglifier (~> 4.2.0)
web-console (~> 3.7)
webmock (~> 3.11)
bigbluebutton-api-ruby
bootstrap-sass (= 3.3.0.0)
bootstrap-social-rails (~> 4.12)
browser
byebug
coffee-rails (~> 4.2)
dotenv-rails
faraday
font-awesome-sass (= 4.7.0)
http_accept_language
jbuilder (~> 2.5)
jquery-datatables-rails (~> 3.4.0)
jquery-rails
jquery-ui-rails
listen (~> 3.0.5)
lograge
mocha
omniauth (= 1.6.1)
omniauth-google-oauth2 (= 0.4.1)
omniauth-ldap
omniauth-saml
omniauth-twitter (= 1.2.1)
paperclip (~> 5.1)
pg
puma (~> 3.0)
rails (~> 5.0.0, >= 5.0.0.1)
rails-timeago (~> 2.0)
sass-rails (~> 5.0)
simplecov
slack-notifier
spring
spring-watcher-listen (~> 2.0.0)
sqlite3
therubyracer
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
web-console
yt (~> 0.28.0)
RUBY VERSION
ruby 2.4.0p0
BUNDLED WITH
1.16.1
-165
View File
@@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
+16 -22
View File
@@ -1,37 +1,31 @@
# Greenlight
![Coverage
!Status](https://coveralls.io/repos/github/bigbluebutton/greenlight/badge.svg?branch=master)
![Docker Pulls](https://img.shields.io/docker/pulls/bigbluebutton/greenlight.svg)
GreenLight is a simple (but powerful) front-end interface for your BigBlueButton server. At its core, GreenLight provides a minimalistic web-based application that lets users
Greenlight is a simple front-end interface for your BigBlueButton server. At its heart, Greenlight provides a minimalistic web-based application that allows users to:
* Create a meeting
* Invite others to the meeting
* Join a meeting
* Signup/Login with Google, Office365, OpenID Connect, or through the application itself.
* Manage your account settings and user preferences.
* Create and manage your own personal rooms ([BigBlueButton](https://github.com/bigbluebutton/bigbluebutton) sessions).
* Invite others to your room using a simple URL.
* View recordings and share them with others.
Furthermore, if you configure GreenLight to use either Google, Twitter (both via OAuth2) or LDAP for authentication, users can login to record meetings and manage recordings.
Interested? Try Greenlight out on our [demo server](https://demo.bigbluebutton.org/gl)!
## Overview video
Greenlight is also completely configurable. This means you can turn on/off features to make Greenlight fit your specific use case. For more information on Greenlight and its features, see our [documentation](http://docs.bigbluebutton.org/greenlight/gl-install.html).
For a overview of how GreenLight works, see the following video
For a overview of how Greenlight works, checkout our Introduction to Greenlight Video:
[![GreenLight Overview](https://img.youtube.com/vi/yGX3JCv7OVM/0.jpg)](https://youtu.be/yGX3JCv7OVM)
[![GreenLight Overview](https://img.youtube.com/vi/Hso8yLzkqj8/0.jpg)](https://youtu.be/Hso8yLzkqj8)
## Installation on a BigBlueButton Server
## Installation on the BigBlueButton server
We designed GreenLight to install on a [BigBlueButton 1.1-beta](http://docs.bigbluebutton.org/greenlight-v1.html) (or later) server. This means you don't need a separate server to run GreenLight.
Greenlight is designed to work on a [BigBlueButton 2.0](https://github.com/bigbluebutton/bigbluebutton) (or later) server.
For more informaiton see [Installing GreenLight](http://docs.bigbluebutton.org/greenlight-v1.html#installing-greenlight).
For information on installing Greenlight, checkout our [Installing Greenlight on a BigBlueButton Server](http://docs.bigbluebutton.org/greenlight/gl-install.html#installing-on-a-bigbluebutton-server) documentation.
# Source Code
## Source Code & Contributing
GreenLight is a rails 5 application.
Greenlight is built using Ruby on Rails. Many developers already know Rails well, and we wanted to create both a full front-end to BigBlueButton but also a reference implementation of how to fully leverage the [BigBlueButton API](http://docs.bigbluebutton.org/dev/api.html).
Many developers already know Rails well, and we wanted to create both a full front-end to BigBlueButton but also a reference implementation of how to fully leverage the [BigBlueButton API](http://docs.bigbluebutton.org/dev/api.html).
We invite you to build upon Greenlight and help make it better. See [Contributing to BigBlueButton](http://docs.bigbluebutton.org/support/faq.html#contributing-to-bigbluebutton).
We invite you to build upon GreenLight and help make it better. See [Contributing to BigBlueButton](http://docs.bigbluebutton.org/support/faq.html#contributing-to-bigbluebutton).
We invite your feedback, questions, and suggests about Greenlight too. Please post them to the [Greenlight mailing list](https://groups.google.com/forum/#!forum/bigbluebutton-greenlight).
To help with organization and consistency, we have implemented a Pull Request template that must be used for all Pull Requests. This template helps ensure that the project maintainers can review all PRs in a timely manner. When creating a Pull Request, please provide as much information as possible.
We invite your feedback, questions, and suggests about GreenLight too. Please post them to the [developer mailing list](https://groups.google.com/forum/#!forum/bigbluebutton-dev).
-9
View File
@@ -1,15 +1,6 @@
# frozen_string_literal: true
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative 'config/application'
require 'rake/testtask'
Rake::TestTask.new do |t|
t.libs << "test"
t.test_files = FileList['test/test*.rb']
t.verbose = true
end
Rails.application.load_tasks
-11
View File
@@ -1,11 +0,0 @@
# Security Policy
## Supported Versions
We support only the latest version of this project.
## Reporting a Vulnerability
If you think youve found a security issue with BigBlueButton or Greenlight, we ask that you do a [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure) and e-mail us directly at security@bigbluebutton.org.
We will respond to you quickly, work with you to examine the scope of the issue, and give priority to fixing it as soon as possible.
+1 -1
View File
@@ -1,6 +1,6 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
// Copyright (c) 2016 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
-93
View File
@@ -1,93 +0,0 @@
Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name Source.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

+236
View File
@@ -0,0 +1,236 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
// Handles live updating and initial population of the previous meetings and active meetings lists on
// the landing page using custom Actioncable events.
var MEETINGS = {}
var WAITING = {}
var LOADING_DELAY = 1750 // milliseconds.
// Updates the previous meetings section.
var updatePreviousMeetings = function(){
$("ul.previously-joined li").each(function(idx, li) {
var previous_meeting = $(li);
if(Object.keys(MEETINGS).indexOf(previous_meeting.text()) > -1){
previous_meeting.remove()
}
});
}
// Ignore excess on either side of user_id.
var trimUserId = function(user_id){
components = user_id.split('_')
return components.sort(function (a, b) {return b.length - a.length;})[0]
}
// Finds a user by their user_id.
var findByUserId = function(users, user_id){
for(i = 0; i < users.length; i++){
if(trimUserId(users[i]['user_id']) == trimUserId(user_id)){
return i
}
}
return undefined
}
// Adds a user to a meeting.
var addUser = function(data){
if(data['role'] == 'MODERATOR'){
MEETINGS[data['meeting']]['moderators'].push({'name': data['user'], 'user_id': data['user_id']})
} else {
MEETINGS[data['meeting']]['participants'].push({'name':data['user'], 'user_id': data['user_id']})
}
updateMeetingText(MEETINGS[data['meeting']])
}
// Removes a user from a meeting.
var removeUser = function(data){
user = findByUserId(MEETINGS[data['meeting']]['moderators'], data['user_id'])
if(user == undefined){
user = findByUserId(MEETINGS[data['meeting']]['participants'], data['user_id']);
if(user == undefined){ return; }
MEETINGS[data['meeting']]['participants'].splice(user, 1);
} else {
MEETINGS[data['meeting']]['moderators'].splice(user, 1);
}
updateMeetingText(MEETINGS[data['meeting']])
}
// Updates the display text for an active meeting.
var updateMeetingText = function(m){
// If a meeting has a moderators property, it is running.
var body;
if(m.hasOwnProperty('moderators')){
var list;
if(m['moderators'].length + m['participants'].length == 0){
list = '(empty)'
} else {
list = m['moderators'].map(function(x){ return x['name']; }).join('(mod), ') +
(m['moderators'].length > 0 ? '(mod)' : '') +
(m['participants'].length > 0 && m['moderators'].length != 0 ? ', ' : '') +
(m['participants'].map(function(x){ return x['name']; }).join(', '))
}
body = '<a>' + m['name'] + '</a><i>: ' + list + '</i>'
// Otherwise it hasn't started (users waiting the join).
} else {
body = '<a>' + m['name'] + '</a><i> (not yet started): ' + m['users'].join(', ') + '</i>'
}
// If the item doesn't exist, add it and set up join meeting event.
if($("li[id='" + m['name'].replace(' ', '_') + "']").length == 0){
var meeting_item = $("<li>" + body + "</li>")
meeting_item.attr('id', m['name'].replace(' ', '_'))
$('.actives').append(meeting_item);
// Set up join on click.
meeting_item.click(function(){
joinMeeting(m['name']);
});
// Otherwise, just change the body.
} else {
$("li[id='" + m['name'].replace(' ', '_') + "']").html(body)
}
}
// Initially populates the active meetings when the page loads using the API.
var initialPopulate = function(){
// Only populate on room resources.
var chopped = window.location.href.split('/')
if (!window.location.href.includes('rooms') || chopped[chopped.length - 2] == $('body').data('current-user')) { return; }
$.post((window.location.href + '/statuses').replace('#', ''), {previously_joined: getPreviouslyJoined()})
.done(function(data) {
// Populate waiting meetings.
Object.keys(data['waiting']).forEach(function(key) {
WAITING[key] = {'name': key, 'users': data['waiting'][key]}
updateMeetingText(WAITING[key])
})
// Add the meetings to the active meetings list.
for(var i = 0; i < data['active'].length; i++){
var meeting = data['active'][i]
var name = meeting['name']
var participants = meeting['participants']
var moderators = meeting['moderators']
// Create meeting.
MEETINGS[name] = {'name': name, 'participants': participants, 'moderators': moderators}
updateMeetingText(MEETINGS[name])
}
// Remove from previous meetings if they are active.
updatePreviousMeetings();
$('.hidden-list').show();
$('.active-spinner').hide();
});
}
// Gets a list of known previously joined meetings.
var getPreviouslyJoined = function(){
var joinedMeetings = localStorage.getItem('joinedRooms-' + $('body').data('current-user'));
if (joinedMeetings == '' || joinedMeetings == null){ return []; }
return joinedMeetings.split(',')
}
// Removes an active meeting.
var removeActiveMeeting = function(meeting){
if(meeting){ $("li[id='" + meeting['name'].replace(' ', '_') + "']").remove() }
}
// Directly join a meeting from active meetings.
var joinMeeting = function(meeting_name){
if (meeting_name == undefined || meeting_name == null) { return; }
Meeting.getInstance().setUserName(localStorage.getItem('lastJoinedName'));
Meeting.getInstance().setMeetingId(meeting_name);
var jqxhr = Meeting.getInstance().getJoinMeetingResponse();
if (jqxhr) {
jqxhr.done(function(data) {
if (data.messageKey === 'wait_for_moderator') {
waitForModerator(Meeting.getInstance().getURL());
} else {
$(location).attr("href", data.response.join_url);
}
});
jqxhr.fail(function() {
console.info("meeting join failed");
});
} else {
$('.meeting-user-name').parent().addClass('has-error');
}
}
// Only need to register for logged in users.
$(document).on('turbolinks:load', function(){
if($('body').data('current-user')){
MEETINGS = {}
// Ensure actives is empty.
$('.actives').empty();
if(!App.messages){
// Setup actioncable.
App.messages = App.cable.subscriptions.create('RefreshMeetingsChannel', {
received: function(data) {
console.log('Recieved ' + data['method'] + ' action for ' + data['meeting'] + ' with room id ' + data['room'] + '.')
if(data['room'] == $('body').data('current-user')){
// Handle webhook event.
if(data['method'] == 'create'){
// Create an empty meeting.
MEETINGS[data['meeting']] = {'name': data['meeting'],
'participants': [],
'moderators': []}
updateMeetingText(MEETINGS[data['meeting']])
updatePreviousMeetings();
if (WAITING.hasOwnProperty(data['meeting'])){ delete WAITING[data['meeting']]; }
} else if(data['method'] == 'destroy'){
removeActiveMeeting(MEETINGS[data['meeting']])
PreviousMeetings.uniqueAdd([data['meeting']])
delete MEETINGS[data['meeting']]
} else if(data['method'] == 'join'){
addUser(data)
} else if(data['method'] == 'leave'){
removeUser(data)
} else if(data['method'] == 'waiting'){
// Handle waiting meeting.
if(WAITING.hasOwnProperty(data['meeting'])){
WAITING[data['meeting']]['users'].push(data['user'])
updateMeetingText(WAITING[data['meeting']])
} else {
WAITING[data['meeting']] = {'name': data['meeting'],
'users': [data['user']]}
updateMeetingText(WAITING[data['meeting']])
}
} else if((data['method'] == 'no_longer_waiting') && (WAITING.hasOwnProperty(data['meeting']))){
WAITING[data['meeting']]['users'].splice(WAITING[data['meeting']]['users'].indexOf(data['user']), 1)
updateMeetingText(WAITING[data['meeting']])
if(WAITING[data['meeting']]['users'].length == 0){
removeActiveMeeting(WAITING[data['meeting']])
delete WAITING[data['meeting']]
}
}
}
}
});
}
console.log('Populating active meetings.');
// Short delay to hide the previous meetings population.
setTimeout(initialPopulate, LOADING_DELAY);
}
});
-340
View File
@@ -1,340 +0,0 @@
// 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/>.
$(document).on('turbolinks:load', function(){
var controller = $("body").data('controller');
var action = $("body").data('action');
// Only run on the admins page.
if (controller == "admins") {
if(action == "index") {
//clear the role filter if user clicks on the x
$(".clear-role").click(function() {
var search = new URL(location.href).searchParams.get('search')
var url = window.location.pathname + "?page=1"
if (search) {
url += "&search=" + search
}
window.location.replace(url);
})
// Handle selected user tags
$(".manage-users-tab").click(function() {
$(".manage-users-tab").removeClass("selected")
$(this).addClass("selected")
updateTabParams(this.id)
})
$('.selectpicker').selectpicker({
liveSearchPlaceholder: getLocalizedString('javascript.search.start')
});
// Fixes turbolinks issue with bootstrap select
$(window).trigger('load.bs.select.data-api');
// Display merge accounts modal with correct info
$(".merge-user").click(function() {
// Update the path of save button
$("#merge-save-access").attr("data-path", $(this).data("path"))
let userInfo = $(this).data("info")
$("#merge-to").html("") // Clear current inputs
let spanName = document.createElement("span"),
spanEmail = document.createElement("span"),
spanUid = document.createElement("span");
spanName.innerText = userInfo.name
spanEmail.setAttribute('class', 'text-muted d-block')
spanEmail.innerText = userInfo.email
spanUid.setAttribute('class', 'text-muted d-block')
spanUid.innerText = userInfo.uid
$("#merge-to").append(spanName, spanEmail, spanUid)
})
$("#mergeUserModal").on("show.bs.modal", function() {
$(".selectpicker").selectpicker('val','')
})
$(".bootstrap-select").on("click", function() {
$(".bs-searchbox").siblings().hide()
})
$("#merge-user-select ~ button").on("click", function() {
$(".bs-searchbox").siblings().hide()
})
$(".bs-searchbox input").on("input", function() {
if ($(".bs-searchbox input").val() == '' || $(".bs-searchbox input").val().length < 3) {
$(".select-options").remove()
$(".bs-searchbox").siblings().hide()
} else {
// Manually populate the dropdown
$.get($("#merge-user-select").data("path"), { search: $(".bs-searchbox input").val() }, function(users) {
$(".select-options").remove()
if (users.length > 0) {
users.forEach(function(user) {
let opt = document.createElement("option")
$(opt).val(JSON.stringify({uid: user.uid, email: user.email, name: user.name}))
$(opt).text(user.name)
$(opt).addClass("select-options")
$(opt).attr("data-subtext", user.email)
$("#merge-user-select").append(opt)
})
// Only refresh the select dropdown if there are results to show
$('#merge-user-select').selectpicker('refresh');
}
$(".bs-searchbox").siblings().show()
})
}
})
// User selects an option from the Room Access dropdown
$(".bootstrap-select").on("changed.bs.select", function(){
// Get the uid of the selected user
let user = $(".selectpicker").selectpicker('val')
if (user != "") {
let userInfo = JSON.parse(user)
$("#merge-from").html("") // Clear current input
let spanName = document.createElement("span"),
spanEmail = document.createElement("span"),
spanUid = document.createElement("span");
spanName.innerText = userInfo.name
spanEmail.setAttribute('class', 'text-muted d-block')
spanEmail.innerText = userInfo.email
spanUid.setAttribute('class', 'text-muted d-block')
spanUid.id = 'from-uid'
spanUid.innerText = userInfo.uid
$("#merge-from").append(spanName, spanEmail, spanUid)
}
})
}
else if(action == "site_settings"){
var urlParams = new URLSearchParams(window.location.search);
// Only load the colour selectors if on the appearance tab
if (urlParams.get("tab") == null || urlParams.get("tab") == "appearance") {
loadColourSelectors()
}
}
else if (action == "roles"){
// Refreshes the new role modal
$("#newRoleButton").click(function(){
$("#createRoleName").val("")
})
// Updates the colour picker to the correct colour
let role_colour = $("#role-colorinput-regular").data("colour")
$("#role-colorinput-regular").css("background-color", role_colour);
$("#role-colorinput-regular").css("border-color", role_colour);
loadRoleColourSelector(role_colour, $("#role-colorinput-regular").data("disabled"));
// Loads the jquery sortable so users can manually sort roles
$("#rolesSelect").sortable({
items: "a:not(.sort-disabled)",
update: function() {
$.ajax({
url: $(this).data("url"),
type: 'PATCH',
data: $(this).sortable('serialize')
});
}
});
}
}
});
// Change the branding image to the image provided
function changeBrandingImage(path) {
var url = $("#branding-url").val()
$.post(path, {value: url, tab: "appearance"})
}
// Change the Legal URL to the one provided
function changeLegalURL(path) {
var url = $("#legal-url").val()
$.post(path, {value: url, tab: "administration"})
}
// Change the Privacy Policy URL to the one provided
function changePrivacyPolicyURL(path) {
var url = $("#privpolicy-url").val()
$.post(path, {value: url, tab: "administration"})
}
// Display the maintenance Banner
function displayMaintenanceBanner(path) {
var message = $("#maintenance-banner").val()
$.post(path, {value: message, tab: "administration"})
}
// Clear the maintenance Banner
function clearMaintenanceBanner(path) {
$.post(path, {value: "", tab: "administration"})
}
// Change the email mapping to the string provided
function changeEmailMapping(path) {
var url = $("#email-mapping").val()
$.post(path, {value: url, tab: "registration"})
}
function mergeUsers() {
let userToMerge = $("#from-uid").text()
$.post($("#merge-save-access").data("path"), {merge: userToMerge})
}
// Filters by role
function filterRole(role) {
var search = new URL(location.href).searchParams.get('search')
var url = window.location.pathname + "?page=1" + "&role=" + role
if (search) {
url += "&search=" + search
}
window.location.replace(url);
}
function updateTabParams(tab) {
var search_params = new URLSearchParams(window.location.search)
if (window.location.href.includes("tab=")) {
search_params.set("tab", tab)
} else {
search_params.append("tab", tab)
}
search_params.delete("page")
window.location.search = search_params.toString()
}
function loadColourSelectors() {
const pickrRegular = new Pickr({
el: '#colorinput-regular',
theme: 'monolith',
useAsButton: true,
lockOpacity: true,
defaultRepresentation: 'HEX',
closeWithKey: 'Enter',
default: $("#colorinput-regular").css("background-color"),
components: {
palette: true,
preview: true,
hue: true,
interaction: {
input: true,
save: true,
},
},
});
const pickrLighten = new Pickr({
el: '#colorinput-lighten',
theme: 'monolith',
useAsButton: true,
lockOpacity: true,
defaultRepresentation: 'HEX',
closeWithKey: 'Enter',
default: $("#colorinput-lighten").css("background-color"),
components: {
palette: true,
preview: true,
hue: true,
interaction: {
input: true,
save: true,
},
},
});
const pickrDarken = new Pickr({
el: '#colorinput-darken',
theme: 'monolith',
useAsButton: true,
lockOpacity: true,
defaultRepresentation: 'HEX',
closeWithKey: 'Enter',
default: $("#colorinput-darken").css("background-color"),
components: {
palette: true,
preview: true,
hue: true,
interaction: {
input: true,
save: true,
},
},
});
pickrRegular.on("save", (color, instance) => {
$.post($("#coloring-path-regular").val(), {value: color.toHEXA().toString()}).done(function() {
location.reload()
});
})
pickrLighten.on("save", (color, instance) => {
$.post($("#coloring-path-lighten").val(), {value: color.toHEXA().toString(), tab: "appearance"}).done(function() {
location.reload()
});
})
pickrDarken.on("save", (color, instance) => {
$.post($("#coloring-path-darken").val(), {value: color.toHEXA().toString(), tab: "appearance"}).done(function() {
location.reload()
});
})
}
function loadRoleColourSelector(role_colour, disabled) {
if (!disabled) {
const pickrRoleRegular = new Pickr({
el: '#role-colorinput-regular',
theme: 'monolith',
useAsButton: true,
lockOpacity: true,
defaultRepresentation: 'HEX',
closeWithKey: 'Enter',
default: role_colour,
components: {
palette: true,
preview: true,
hue: true,
interaction: {
input: true,
save: true,
},
},
});
// On save update the colour input's background colour and update the role colour input
pickrRoleRegular.on("save", (color, instance) => {
$("#role-colorinput-regular").css("background-color", color.toHEXA().toString());
$("#role-colorinput-regular").css("border-color", color.toHEXA().toString());
$("#role-colour").val(color.toHEXA().toString());
});
}
}
+9 -22
View File
@@ -1,6 +1,6 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
// Copyright (c) 2016 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
@@ -14,26 +14,13 @@
// You should have received a copy of the GNU Lesser General Public License along
// with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery2
//= require jquery-ui
//= require dataTables/jquery.dataTables
//= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
//= require rails-timeago-all
//= require bootstrap-sprockets
//= require qrcode/qrcode.js
//= require turbolinks
//= require jquery3
//= require tabler
//= require tabler.plugins
//= require jquery_ujs
//= require jquery-ui/widget
//= require jquery-ui/widgets/sortable
//= require pickr.min.js
//= require bootstrap-select.min.js
//= require local-time
//= require_self
//= require_tree .
@@ -1,7 +1,6 @@
<%
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
# Copyright (c) 2016 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
@@ -14,14 +13,7 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%>
<%= t('mailer.user.invite.subject') %>
<%= t('mailer.user.invite.info', name: @name) %>
<%= t('mailer.user.invite.username', email: @email) %>
<%= t('mailer.user.invite.signup_info') %>
<%= @url %>
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
+5 -3
View File
@@ -1,6 +1,6 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
// Copyright (c) 2016 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
@@ -22,11 +22,13 @@
//= require_tree ./channels
(function() {
var protocol = (window.location.protocol === "https:" ? "wss://" : "ws://");
var protocol = window.location.protocol === "https:" ? "wss://" : "ws://";
var host = window.GreenLight.WEBSOCKET_HOST || window.location.host + window.GreenLight.RELATIVE_ROOT;
var url = protocol + host + '/cable';
var path = window.GreenLight.WEBSOCKET_PATH || '/cable';
var url = protocol + host + path;
this.App || (this.App = {});
App.cable = ActionCable.createConsumer(url);
}).call(this);
@@ -0,0 +1,81 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
(function() {
var sessionStatusRefresh = function(url) {
$.get(url + "/session_status_refresh", function(html) {
$(".center-panel-wrapper").html(html);
displayRoomURL();
});
};
var enableMeetingUpdates = function() {
var meetingId = ''
if (!$(".page-wrapper.rooms").data('main-room')) {
meetingId = $(".page-wrapper.rooms").data('id');
}
App.meeting_update = App.cable.subscriptions.create({
channel: 'MeetingUpdatesChannel',
admin_id: $(".page-wrapper.rooms").data('admin-id'),
meeting_id: meetingId
},
{
received: function(data) {
if (data.action === 'moderator_joined') {
if (!Meeting.getInstance().getModJoined()) {
Meeting.getInstance().setModJoined(true);
if (Meeting.getInstance().getWaitingForMod()) {
loopJoin();
} else {
sessionStatusRefresh($('.meeting-url').val());
showAlert(I18n.meeting_started, 4000);
}
}
} else if (data.action === 'meeting_ended') {
sessionStatusRefresh($('.meeting-url').val());
showAlert(I18n.meeting_ended, 4000);
} else if (data.action === 'user_waiting') {
// show a browser notification only to the owner
if (isRoomOwner()) {
showNotification(I18n.user_waiting_title, {
body: I18n.user_waiting_body.replace(/%{user}/, data.user).replace(/%{meeting}/, '"'+data.meeting_name+'"')
});
}
} else if(data.action === 'unable_to_join') {
showAlert(I18n.unable_to_join_mobile, 6000)
}
}
});
};
var disableMeetingUpdates = function() {
App.meeting_update.unsubscribe();
delete App.meeting_update
};
$(document).on("turbolinks:load", function() {
// disable meeting updates if enabled from a previous page
if (App.meeting_update) {
disableMeetingUpdates();
}
if ($("body[data-controller=landing]").get(0)) {
if ($("body[data-action=rooms]").get(0)) {
enableMeetingUpdates();
}
}
});
}).call(this);
@@ -0,0 +1,75 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
(function() {
var enableRecordingUpdates = function() {
App.recording_update = App.cable.subscriptions.create({
channel: 'RecordingUpdatesChannel',
admin_id: $(".page-wrapper.rooms").data('admin-id'),
meeting_id: $(".page-wrapper.rooms").data('id')
},
{
received: function(data) {
var recordings = Recordings.getInstance();
var table = recordings.table.api();
var row = table.row("#"+data.id);
if (data.action === 'update') {
var rowData = row.data();
rowData.published = data.published;
rowData.listed = data.listed;
table.row("#"+data.id).data(rowData);
recordings.draw();
var status = data.published ? (data.listed ? 'published' : 'unlisted') : 'unpublished';
showAlert(I18n['recording_'+status], 4000);
} else if (data.action === 'delete') {
row.remove();
recordings.draw();
showAlert(I18n.recording_deleted, 4000);
} else if (data.action === 'create') {
if (isRoomOwner() && row.length == 0) {
recordings.refresh();
showAlert(I18n.recording_created, 4000);
}
}
}
});
};
var disableRecordingUpdates = function() {
App.recording_update.unsubscribe();
delete App.recording_update
};
$(document).on("turbolinks:load", function() {
// disable recording updates if enabled from a previous page
if (App.recording_update) {
disableRecordingUpdates();
}
if ($("body[data-controller=landing]").get(0)) {
if ($("body[data-action=rooms]").get(0)) {
enableRecordingUpdates();
}
}
});
}).call(this);
-37
View File
@@ -1,37 +0,0 @@
// 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/>.
$(document).on('turbolinks:load', function(){
$("#cookies-agree-button").click(function() {
//create a cookie that lasts 1 year
var cookieDate = new Date();
cookieDate.setFullYear(cookieDate.getFullYear() + 1); //1 year from now
document.cookie = "cookie_consented=true; path=/; expires=" + cookieDate.toUTCString() + ";"
//hide the banner at the bottom
$(".cookies-banner").attr("style","display:none !important")
})
$("#maintenance-close").click(function(event) {
//create a cookie that lasts 1 day
var cookieDate = new Date()
cookieDate.setDate(cookieDate.getDate() + 1) //1 day from now
console.log("maintenance_window=" + $(event.target).data("date") + "; path=/; expires=" + cookieDate.toUTCString() + ";")
document.cookie = "maintenance_window=" + $(event.target).data("date") + "; path=/; expires=" + cookieDate.toUTCString() + ";"
})
})
-57
View File
@@ -1,57 +0,0 @@
// 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/>.
$(document).on('turbolinks:load', function(){
var controller = $("body").data('controller');
var action = $("body").data('action');
// Only run on the admins page.
if (controller == "admins" && action == "index") {
// show the modal with the correct form action url
$(".delete-user").click(function(){
$("#delete-confirm").parent().attr("action", $(this).data("path"))
if ($(this).data("delete") == "temp-delete") {
$("#perm-delete").hide()
$("#delete-warning").show()
} else {
$("#perm-delete").show()
$("#delete-warning").hide()
}
})
}
$(".delete-user").click(function(data){
document.getElementById("delete-checkbox").checked = false
$("#delete-confirm").prop("disabled", "disabled")
if ($(data.target).data("delete") == "temp-delete") {
$("#perm-delete").hide()
$("#delete-warning").show()
} else {
$("#perm-delete").show()
$("#delete-warning").hide()
}
})
$("#delete-checkbox").click(function(data){
if (document.getElementById("delete-checkbox").checked) {
$("#delete-confirm").removeAttr("disabled")
} else {
$("#delete-confirm").prop("disabled", "disabled")
}
})
})
+297
View File
@@ -0,0 +1,297 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
/** global: Meeting */
/** global: PreviousMeetings */
/** global: QRCode */
/** global: Recordings */
/** global: Turbolinks */
(function() {
var qrcode;
var waitForModerator = function(url) {
window.localStorage.setItem("waitingName", $('.meeting-user-name').val());
$.post(url + "/wait", {name: $('.meeting-user-name').val()}, function(html) {
$(".center-panel-wrapper").html(html);
});
if (!Meeting.getInstance().getWaitingForMod()) {
Meeting.getInstance().setWaitingForMod(true);
if (Meeting.getInstance().getModJoined()) {
loopJoin();
}
}
};
var init = function() {
Meeting.clear();
var nameInput = $('.meeting-user-name');
if (!nameInput.val()) {
var lastName = window.localStorage.getItem('lastJoinedName');
if (lastName !== 'undefined') {
nameInput.val(lastName);
}
}
// setup event handlers
$('.center-panel-wrapper').on ('click', '.meeting-join', function () {
var name = $('.meeting-user-name').val();
Meeting.getInstance().setUserName(name);
Meeting.getInstance().setMeetingId($(".page-wrapper").data('id'));
// a user name is set, join the user into the session
if (name !== undefined && name !== null) {
var jqxhr = Meeting.getInstance().getJoinMeetingResponse();
if (jqxhr) {
jqxhr.done(function(data) {
if (data.messageKey === 'wait_for_moderator') {
waitForModerator(Meeting.getInstance().getURL());
} else if (data.messageKey === 'ok') {
$(location).attr("href", data.response.join_url);
}
});
jqxhr.fail(function() {
console.info("meeting join failed");
});
} else {
$('.meeting-user-name').parent().addClass('has-error');
}
// if not user name was set it means we must ask for a name
} else {
$(location).attr("href", Meeting.getInstance().getURL());
}
});
$('.center-panel-wrapper').on ('click', '.meeting-start', function () {
Turbolinks.visit($('.meeting-url').val());
});
$('.center-panel-wrapper').on ('input', '.meeting-user-name', function () {
if ($(this).val() === '') {
$(this).parent().addClass('has-error')
} else {
$(this).parent().removeClass('has-error')
}
});
$('.center-panel-wrapper').on ('keypress', '.meeting-user-name', function (event) {
if (event.keyCode === 13) {
event.preventDefault();
$('.meeting-join').click();
}
});
$('.center-panel-wrapper').on ('keypress', '.meeting-name', function (event) {
if (event.keyCode === 13) {
event.preventDefault();
$('.meeting-start').click();
}
});
$('.center-panel-wrapper').on ('click', '.meeting-end', function () {
var jqxhr = Meeting.getInstance().endMeeting();
var btn = $(this);
btn.prop("disabled", true);
jqxhr.fail(function() {
console.info("meeting end failed");
});
});
$('.center-panel-wrapper').on ('click', '.meeting-url-copy', function () {
var meetingURLInput = $('.meeting-url');
// copy URL
meetingURLInput.select();
try {
var success = document.execCommand("copy");
if (success) {
meetingURLInput.blur();
$(this).trigger('hint', [$(this).data('copied-hint')]);
} else {
$(this).trigger('hint', [$(this).data('copy-error')]);
}
} catch (err) {
$(this).trigger('hint', [$(this).data('copy-error')]);
}
});
$('.center-panel-wrapper').on('hint', '.meeting-url-copy', function (event, msg) {
$(this).focus();
$(this).attr('title', msg)
.tooltip('fixTitle')
.tooltip('show')
.attr('title', $(this).data('copy-hint'))
.tooltip('fixTitle');
});
$('.center-panel-wrapper').on('mouseleave', '.meeting-url-copy', function () {
$(this).blur();
});
// button used to send invitations to the meeting (i.e. "mailto:" link)
$('.center-panel-wrapper').on('click', '.meeting-invite', function () {
var meetingURL = Meeting.getInstance().getURL();
var subject = $(this).data("invite-subject");
var body = $(this).data("invite-body").replace("&&URL&&", meetingURL);
var mailto = "mailto:?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body);
window.open(mailto);
});
$('.center-panel-wrapper').on ('click', '.meeting-url-qrcode', function () {
var meetingURL;
try {
meetingURL = $('.meeting-url').val();
if ($('.meeting-url-qrcode-group').is(':empty')) {
// generate code
qrcode = new QRCode($(".meeting-url-qrcode-group")[0], {
text: meetingURL,
width: 128,
height: 128,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
} else {
// clear the code.
qrcode.clear();
// make another code.
qrcode.makeCode(meetingURL);
}
$(this).trigger('hint', [$(this).data('qrcode-generated-hint')]);
} catch (err) {
$(this).trigger('hint', [$(this).data('qrcode-generate-error')]);
}
});
$('.center-panel-wrapper').on('hint', '.meeting-url-qrcode', function (event, msg) {
$(this).focus();
$(this).attr('title', msg)
.tooltip('fixTitle')
.tooltip('show')
.attr('title', $(this).data('qrcode-generate-hint'))
.tooltip('fixTitle');
});
$('.center-panel-wrapper').on('mouseleave', '.meeting-url-qrcode', function () {
$(this).blur();
});
$('.center-panel-wrapper').on('focus', '.meeting-url', function () {
$(this).select();
});
// only allow ctrl commands
$('.center-panel-wrapper').on('keydown', '.meeting-url', function (event) {
if(!event.ctrlKey) {
event.preventDefault();
}
});
// enable tooltips
var options = {
selector: '.has-tooltip',
container: 'body'
};
$(document).tooltip(options);
options = {
selector: '.bottom-tooltip',
container: 'body',
placement: 'bottom'
};
$(document).tooltip(options);
// focus name input or join button
if ($('.meeting-name').is(':visible')) {
$('.meeting-name').focus();
} else if ($('.meeting-user-name').is(':visible')) {
$('.meeting-user-name').focus();
} else {
$('.meeting-join').focus();
}
};
var initIndex = function() {
$('.center-panel-wrapper').on('input', '.meeting-name', function () {
var newId = $(this).val();
Meeting.getInstance().setMeetingId(newId);
$(".page-wrapper.meetings").data('id', newId);
$('.meeting-url').val(Meeting.getInstance().getURL());
$('.join-meeting-title').text('"'+newId+'"');
if (newId === '') {
$('.invite-join-wrapper').addClass('hidden');
} else {
$('.invite-join-wrapper').removeClass('hidden');
}
if (!$('.meeting-url-qrcode-group').is(':empty')) {
$('.meeting-url-qrcode-group').empty();
}
});
PreviousMeetings.init('joinedMeetings');
};
var initMeetings = function() {
$('.meeting-url').val(Meeting.getInstance().getURL());
};
var initRooms = function() {
displayRoomURL();
var roomAdmin = $('.page-wrapper.rooms').data('admin-id');
$('.center-panel-wrapper').on('input', '.meeting-name', function () {
var newId = $(this).val();
Meeting.getInstance().setMeetingId(newId);
$('.meeting-url').val(Meeting.getInstance().getURL());
$('.join-meeting-title').text('"'+newId+'"');
if (newId === '') {
$('.invite-join-wrapper').addClass('hidden');
} else {
$('.invite-join-wrapper').removeClass('hidden');
}
if (!$('.meeting-url-qrcode-group').is(':empty')) {
$('.meeting-url-qrcode-group').empty();
}
});
if ($(".page-wrapper.rooms").data('main-room')) {
PreviousMeetings.init('joinedRooms-'+roomAdmin);
if ($('input.meeting-name').val() !== '') {
$('input.meeting-name').trigger('input');
}
}
Recordings.getInstance().refresh();
Recordings.getInstance().setupActionHandlers();
};
$(document).on("turbolinks:load", function() {
if ($("body[data-controller=landing]").get(0)) {
init();
if ($("body[data-action=index]").get(0)) {
initIndex();
} else if ($("body[data-action=meetings]").get(0)) {
initMeetings();
} else if ($("body[data-action=rooms]").get(0)) {
initRooms();
}
}
});
}).call(this);
-51
View File
@@ -1,51 +0,0 @@
// 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/>.
$(document).on('turbolinks:load', function(){
$.rails.refreshCSRFTokens();
})
document.addEventListener("turbolinks:before-cache", function() {
$(".alert").remove()
})
// Gets the localized string
function getLocalizedString(key) {
var keyArr = key.split(".")
var translated = I18n
// Search current language for the key
try {
keyArr.forEach(function(k) {
translated = translated[k]
})
} catch (e) {
// Key is missing in selected language so default to english
translated = undefined;
}
// If key is not found, search the fallback language for the key
if (translated === null || translated === undefined) {
translated = I18nFallback
keyArr.forEach(function(k) {
translated = translated[k]
})
}
return translated
}
+135
View File
@@ -0,0 +1,135 @@
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2016 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/>.
# Meeting class
_meetingInstance = null
class @Meeting
constructor: (@meetingId, @type, @userName, @adminId) ->
# Gets the current instance or creates a new one
@getInstance: ->
if _meetingInstance
return _meetingInstance
meetingId = $(".page-wrapper").data('id')
type = $("body").data('resource')
name = $('.meeting-user-name').val()
adminId = $(".page-wrapper").data('admin-id')
_meetingInstance = new Meeting(meetingId, type, name, adminId)
return _meetingInstance
@clear: ->
_meetingInstance = null
@buildMeetingURL: (meetingId, type, adminId) ->
fullId = ''
if adminId
fullId = encodeURIComponent(adminId) + '/' + encodeURIComponent(meetingId)
else
fullId = encodeURIComponent(meetingId)
return @buildRootURL() + '/' + type + '/' + fullId
@buildRootURL: ->
url = location.protocol + '//' + location.hostname
if location.port
url += ':' + location.port
if GreenLight.RELATIVE_ROOT
url += GreenLight.RELATIVE_ROOT
return url
# Sends the end meeting request
# Returns a response object
endMeeting: ->
return $.ajax({
url: @getURL() + "/end",
type: 'DELETE'
})
# Makes a call to get the join meeting url
# Returns a response object
# The response object contains the URL to join the meeting
getJoinMeetingResponse: ->
if !@userName
showAlert(I18n.enter_name, 4000, 'danger')
return false
return $.get @getURL() + "/join?name=" + @userName, (data) =>
# update name used to join meeting
localStorage.setItem('lastJoinedName', @getUserName())
if data.messageKey == 'ok'
key = ''
if @type == 'meetings'
key = 'joinedMeetings'
else if @type == 'rooms'
key = 'joinedRooms-'+@adminId
# update previously joined meetings/rooms on client
try
joinedMeetings = localStorage.getItem(key) || ''
joinedMeetings = joinedMeetings.split(',')
joinedMeetings = joinedMeetings.filter (item) => item != @meetingId.toString()
if joinedMeetings.length >= 5
joinedMeetings.splice(0, 1)
joinedMeetings.push(@meetingId)
localStorage.setItem(key, joinedMeetings.join(','))
catch err
localStorage.setItem(key, @meetingId)
getMeetingId: ->
return @meetingId
setMeetingId: (id) ->
@meetingId = id
return this
getAdminId: ->
return @adminId
setAdminId: (id) ->
@adminId = id
return this
getType: ->
return @type
setType: (type) ->
@type = type
return this
getURL: ->
return Meeting.buildMeetingURL(@meetingId, @type, @adminId)
getUserName: ->
return @userName
setUserName: (name) ->
@userName = name
return this
getModJoined: ->
return @modJoined
setModJoined: (modJoined) ->
@modJoined = modJoined
return this
getWaitingForMod: ->
return @waitingForMod
setWaitingForMod: (wMod) ->
@waitingForMod = wMod
return this
@@ -0,0 +1,55 @@
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2016 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/>.
# Previous Meetings class
class @PreviousMeetings
MAX_MEETINGS = 5
# initializes and populates previous meetings list with entries from localStorage
@init: (type) ->
$('.center-panel-wrapper').off 'click', '.fill-meeting-name'
$('.center-panel-wrapper').on 'click', '.fill-meeting-name', (event, msg) ->
name = $(this).text()
$('input.meeting-name').val(name).trigger('input')
$('ul.previously-joined').empty()
joinedMeetings = localStorage.getItem(type)
if joinedMeetings && joinedMeetings.length > 0
joinedMeetings = joinedMeetings.split(',')
PreviousMeetings.append(joinedMeetings.reverse())
# adds to previous meetings list if its unique
@uniqueAdd: (names) ->
meetings = $('ul.previously-joined > li').toArray().map( (li) ->
return li.innerText
)
index = meetings.indexOf('')
if index > 1
meetings.splice(index, 1)
if Array.isArray(names)
names = names.filter( (value) ->
return $.inArray(value, meetings) == -1
)
PreviousMeetings.append(names)
@append: (meeting_names) ->
for m in meeting_names
if $('ul.previously-joined > li').length > MAX_MEETINGS
break
$('ul.previously-joined').append('<li><a class="fill-meeting-name">'+m+'</a></li>')
$('.center-panel-wrapper .previously-joined-wrapper').removeClass('hidden')
-48
View File
@@ -1,48 +0,0 @@
// 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() + " " + getLocalizedString('javascript.room.mailer.subject');
var body = getLocalizedString('javascript.room.mailer.body') + "\n\n" + $(this).attr("data-pres-link");
var autogenerated = getLocalizedString('javascript.room.mailer.autogenerated') + "\n";
var footer = getLocalizedString('javascript.room.mailer.footer');
var url = "mailto:?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body) + encodeURIComponent(autogenerated) + encodeURIComponent(footer);
var win = window.open(url, '_blank');
win.focus();
});
});
// Handle recording delete modal
$(".delete-rec").click(function() {
$("#delete-rec-confirm").parent().attr("action", $(this).data("path"))
})
}
});
+430
View File
@@ -0,0 +1,430 @@
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2016 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/>.
# Recordings class
_recordingsInstance = null
class @Recordings
# adding or removing a column will require updates to all subsequent column positions
COLUMNS = [
'DATE',
'NAME',
'PREVIEW',
'DURATION',
'PARTICIPANTS',
'PLAYBACK',
'VISIBILITY',
'LISTED',
'ACTION'
]
COLUMN = {}
i = 0
for c in COLUMNS
COLUMN[c] = i++
constructor: ->
recordingsObject = this
# configure the datatable for recordings
this.table = $('#recordings').dataTable({
data: [],
rowId: 'id',
paging: false,
dom: 't',
info: false,
order: [[ COLUMN.DATE, "desc" ]],
language: {
emptyTable: '<h3>'+I18n.no_recordings_yet+'</h3>',
zeroRecords: '<h3>'+I18n.no_recordings+'</h3>'
},
columns: [
{ data: "start_time" },
{ data: "name", visible: $(".page-wrapper.rooms").data('main-room') },
{ data: "previews", orderable: false },
{ data: "duration" },
{ data: "participants" },
{ data: "playbacks", orderable: false },
{ data: "published" },
{ data: "listed", visible: false },
{ data: "id", orderable: false }
],
columnDefs: [
{
targets: COLUMN.DATE,
render: (data, type, row) ->
if type == 'display'
date = new Date(data)
title = date
.toLocaleString($('html').attr('lang'),
{month: 'long', day: 'numeric', year: 'numeric',
hour12: 'true', hour: '2-digit', minute: '2-digit'})
timeago = '<time datetime="'+date.toISOString()+'" data-time-ago="'+date.toISOString()+'">'+date.toISOString()+'</time>'
return title+'<span class="timeago">('+timeago+')</span>'
return data
},
{
targets: COLUMN.PREVIEW,
render: (data, type, row) ->
if type == 'display'
str = ''
if row.published
for d in data
str += '<img height="50" width="50" class="img-thumbnail" src="'+d.url+'" alt="'+d.alt+'"></img><img class="img-thumbnail large" src="'+d.url+'"></img>'
return str
return data
},
{
targets: COLUMN.PLAYBACK,
render: (data, type, row) ->
if type == 'display'
str = ''
if row.published
if data.length == 1
str = '<a class="btn btn-default play-tooltip" href="'+data[0].url+'" target="_blank"><i class="fa fa-play-circle"></i></a>'
else
for d in data
str += '<a href="'+d.url+'" target="_blank">'+d.type_i18n+'</a> '
return str
return data
},
{
targets: COLUMN.VISIBILITY,
render: (data, type, row) ->
visibility = ['unpublished', 'unlisted', 'published']
if row.published
if row.listed
state = visibility[2]
else
state = visibility[1]
else
state = visibility[0]
if type == 'display'
return I18n[state]
return state
},
{
targets: COLUMN.ACTION,
render: (data, type, row) ->
if type == 'display'
roomName = Meeting.getInstance().getMeetingId()
recordingActions = $('.hidden-elements').find('.recording-actions')
classes = ['recording-unpublished', 'recording-unlisted', 'recording-published']
if row.published
if row.listed
cls = classes[2]
else
cls = classes[1]
else
cls = classes[0]
trigger = recordingActions.find('.recording-update-trigger')
trigger.removeClass(classes.join(' '))
trigger.addClass(cls)
return recordingActions.html()
return data
}
]
})
options = {
selector: '.delete-tooltip',
placement: 'bottom',
title: I18n.delete_recording
};
$('#recordings').tooltip(options)
options.selector = '.visibility-tooltip'
options.title = I18n.change_visibility
$('#recordings').tooltip(options)
options.selector = '.play-tooltip'
options.title = I18n.play_recording
$('#recordings').tooltip(options)
options.selector = '.youtube-tooltip'
options.title = I18n.upload_youtube
$('#recordings').tooltip(options)
options.selector = '.upload-tooltip'
options.title = I18n.share
$('#recordings').tooltip(options)
options.selector = '.mail-tooltip'
options.title = I18n.mail_recording
$('#recordings').tooltip(options)
$(document).one "turbolinks:before-cache", =>
@getTable().api().clear().draw().destroy()
# enable popovers
# can't use trigger:'focus' because it doesn't work will with buttons inside
# the popover
options = {
selector: '.has-popover',
html: true,
trigger: 'click',
title: ->
return $(this).data("popover-title");
content: ->
bodySelector = $(this).data("popover-body")
return $(bodySelector).html()
}
$('#recordings').popover(options)
# close popovers manually when clicking outside of them or in buttons
# with [data-dismiss="popover"]
# careful to hide only the open popover and not all of them, otherwise they won't reopen
$('body').on 'click', (e) ->
$('.has-popover').each ->
if !$(this).is(e.target) and $(this).has(e.target).length == 0 and $('.popover.in').has(e.target).length == 0
if $(this).next(".popover.in").length > 0
$(this).popover('hide')
$(document).on 'click', '[data-dismiss="popover"]', (e) ->
$('.has-popover').each ->
if $(this).next(".popover.in").length > 0
$(this).popover('hide')
# Gets the current instance or creates a new one
@getInstance: ->
if _recordingsInstance && Recordings.initialized()
return _recordingsInstance
_recordingsInstance = new Recordings()
return _recordingsInstance
@initialize: ->
Recordings.getInstance()
@initialized: ->
return $.fn.DataTable.isDataTable('#recordings') && _recordingsInstance
draw: ->
if !@isOwner()
@table.api().columns(COLUMN.LISTED).search('true')
@table.api().columns.adjust().draw()
# refresh the recordings from the server
refresh: ->
table_api = this.table.api()
$.get @getRecordingsURL(), (data) =>
@setOwner(data.is_owner)
if !@owner
table_api.column(COLUMN.ACTION).visible(false)
table_api.column(COLUMN.VISIBILITY).visible(false)
for recording in data.recordings
# NOTE: Temporary fix for the minutes to milliseconds bug some recordings may have
# experienced when transitioning from BigBlueButton 1.1 to BigBlueButton 2.0.
recording.duration = if recording.duration < 1000 then recording.duration else parseInt(recording.length / 60000)
data.recordings.sort (a,b) ->
return new Date(b.start_time) - new Date(a.start_time)
table_api.clear()
table_api.rows.add(data.recordings)
@draw()
if $(".page-wrapper.rooms").data('main-room')
recording_names = data.recordings.map (r) ->
return r.name
output = {}
for key in [0...recording_names.length]
output[recording_names[key]] = recording_names[key]
PreviousMeetings.uniqueAdd(value for key, value of output)
# setup click handlers for the action buttons
setupActionHandlers: ->
table_api = this.table.api()
recordingsObject = this
selectedUpload = null
canUpload = false
@getTable().on 'click', '.recording-update', (event) ->
btn = $(this)
row = table_api.row($(this).closest('tr')).data()
url = recordingsObject.getRecordingsURL()
id = row.id
published = btn.data('visibility') == "unlisted" ||
btn.data('visibility') == "published"
listed = btn.data('visibility') == "published"
btn.prop('disabled', true)
data = { published: published.toString() }
data["meta_" + GreenLight.META_LISTED] = listed.toString();
$.ajax({
method: 'PATCH',
url: url+'/'+id,
data: data
}).done((data) ->
btn.prop('disabled', false)
).fail((xhr, text) ->
btn.prop('disabled', false)
)
@getTable().on 'click', '.recording-delete', (event) ->
btn = $(this)
row = table_api.row($(this).closest('tr'))
url = recordingsObject.getRecordingsURL()
id = row.data().id
btn.prop('disabled', true)
$.ajax({
method: 'DELETE',
url: url+'/'+id
}).done((data) ->
btn.prop('disabled', false)
).fail((xhr, text) ->
btn.prop('disabled', false)
if xhr.status == 404
row.remove();
recordingsObject.draw()
showAlert(I18n.recording_deleted, 4000);
)
@getTable().on 'click', '.upload-button', (event) ->
btn = $(this)
row = table_api.row($(this).closest('tr')).data()
url = recordingsObject.getRecordingsURL()
id = row.id
title = $('#video-title').val()
privacy_status = $('input[name=privacy_status]:checked').val()
if title == ''
title = row.name
$.ajax({
method: 'POST',
url: url+'/'+id
data: {video_title: title, privacy_status: privacy_status}
success: (data) ->
if data['url'] != null
window.location.href = data['url']
else
cloud = selectedUpload.find('.cloud-blue')
check = selectedUpload.find('.green-check')
spinner = selectedUpload.find('.load-spinner')
showAlert(I18n.successful_upload, 4000);
spinner.hide()
check.show()
setTimeout ( ->
cloud.show()
check.hide()
), 2500
})
selectedUpload.find('.cloud-blue').hide()
selectedUpload.find('.load-spinner').show()
@getTable().on 'click', '.mail-recording', (event) ->
btn = $(this)
row = table_api.row($(this).closest('tr')).data()
url = recordingsObject.getRecordingsURL()
id = row.id
# Take the username from the header.
username = $('#title-header').text().replace('Welcome ', '').trim()
recording_url = row.playbacks[0].url
webcams_url = getHostName(recording_url) + '/presentation/' + id + '/video/webcams.webm'
subject = username + I18n.recording_mail_subject
body = I18n.recording_mail_body + "\n\n" + recording_url + "\n\n" + I18n.email_footer_1 + "\n" + I18n.email_footer_2
mailto = "mailto:?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body);
window.open(mailto);
@getTable().on 'click', '.youtube-upload', (event) ->
row = table_api.row($(this).closest('tr')).data()
$('#video-title').attr('value', row.name)
@getTable().on 'click', '.cloud-upload', (event) ->
btn = $(this)
row = table_api.row($(this).closest('tr')).data()
id = row.id
selectedUpload = $(this)
# Determine if the recording can be uploaded to Youtube.
$.ajax({
method: 'POST',
data: {'rec_id': id},
async: false,
url: recordingsObject.getRecordingsURL() + '/can_upload'
}).success((res_data) ->
canUpload = res_data['uploadable']
)
youtube_button = $('.share-popover').find('.youtube-upload')
attr = $(this).attr('data-popover-body');
# Check if the cloud button has a popover body.
if (typeof attr == typeof undefined || attr == false)
switch canUpload
# We can upload the recording.
when 'true'
youtube_button.attr('title', I18n.upload_youtube)
youtube_button.removeClass('disabled-button')
youtube_button.addClass('has-popover')
youtube_button.show()
# Can't upload because uploading is disabled.
when 'uploading_disabled'
youtube_button.hide()
# Can't upload because account is not authenticated with Google.
when 'invalid_provider'
youtube_button.attr('title', I18n.invalid_provider)
youtube_button.addClass('disabled-button')
youtube_button.removeClass('has-popover')
youtube_button.show()
# Can't upload because recording does not contain video.
else
youtube_button.attr('title', I18n.no_video)
youtube_button.addClass('disabled-button')
youtube_button.removeClass('has-popover')
youtube_button.show()
$(this).attr('data-popover-body', '.share-popover')
$(this).popover('show')
else
$(this).popover('hide')
$(this).removeAttr('data-popover-body')
@getTable().on 'draw.dt', (event) ->
$('time[data-time-ago]').timeago();
getTable: ->
@table
getHostName = (url) ->
parser = document.createElement('a');
parser.href = url;
parser.origin;
getRecordingsURL: ->
if $(".page-wrapper.rooms").data('main-room')
base_url = Meeting.buildRootURL()+'/'+$('body').data('resource')+'/'+Meeting.getInstance().getAdminId()
else
base_url = $('.meeting-url').val()
base_url+'/recordings'
isOwner: ->
@owner
setOwner: (owner) ->
@owner = owner
-162
View File
@@ -1,162 +0,0 @@
// 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/>.
$(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"){
// Set a room header rename event
var configure_room_header = function(room_title){
function register_room_title_event(e){
// Remove current window events
$(window).off('mousedown keydown');
if(e.type == 'focusout'){
submit_rename_request(room_title);
return;
}
room_title.addClass("dotted_underline");
room_title.find('#user-text').fadeTo('medium', 0.7);
room_title.find('#user-text').attr("contenteditable", true);
room_title.find('#user-text').focus();
// Stop automatic refresh
e.preventDefault();
register_window_event(room_title, 'user-text', '#edit-room', 'edit-room');
}
room_title.find('#user-text').on('dblclick focusout', function(e){
if(room_title.find('#edit-room').length){
register_room_title_event(e);
}
});
room_title.find('.fa-edit').on('click', function(e){
register_room_title_event(e);
});
}
// Set a recording row rename event
var configure_recording_row = function(recording_title){
function register_recording_title_event(e){
// Remove current window events
$(window).off('mousedown keydown');
if(e.type == 'focusout'){
submit_rename_request(recording_title);
return;
}
recording_title.addClass("dotted_underline");
recording_title.fadeTo('medium', 0.7);
recording_title.find('span').attr("contenteditable", true);
recording_title.find('span').focus();
// Stop automatic refresh
e.preventDefault();
register_window_event(recording_title, 'recording-text', '#edit-record', 'edit-recordid');
}
recording_title.find('a').on('click focusout', function(e){
register_recording_title_event(e);
});
recording_title.find('#recording-text').on('dblclick focusout', function(e){
register_recording_title_event(e);
});
}
// Register window event to submit new name
// upon click or upon pressing the enter key
var register_window_event = function(element, textfield_id, edit_button_id, edit_button_data){
$(window).on('mousedown keydown', function(clickEvent){
// Return if the text is clicked
if(clickEvent.type == "mousedown" && clickEvent.target.id == textfield_id){
return;
}
// Return if the edit icon is clicked
if(clickEvent.type == "mousedown" && $(clickEvent.target).is(edit_button_id) &&
$(clickEvent.target).data(edit_button_data) === element.find(edit_button_id).data(edit_button_data)){
return;
}
// Check if event is keydown and enter key is not pressed
if(clickEvent.type == "keydown" && clickEvent.which !== 13){
return;
}
clickEvent.preventDefault();
submit_rename_request(element);
// Remove window event when ajax call to update name is submitted
$(window).off('mousedown keydown');
});
}
// Apply ajax request depending on the element that triggered the event
var submit_rename_request = function(element){
if(element.is('#room-title')){
submit_update_request({
setting: "rename_header",
name: element.find('#user-text').text(),
}, element.data('path'), "POST");
}
else if(element.is('#recording-title')){
submit_update_request({
setting: "rename_recording",
record_id: element.data('recordid'),
record_name: element.find('span').text(),
room_uid: element.data('room-uid'),
}, element.data('path'), "PATCH");
}
}
// Helper for submitting ajax requests
var submit_update_request = function(data, path, action){
// Send ajax request for update
$.ajax({
url: path,
type: action,
data: data,
});
}
// Elements that can be renamed
var room_title = $('#room-title');
var recording_rows = $('#recording-table').find('tr');
// Configure renaming for room header
configure_room_header(room_title);
// Configure renaming for recording rows
recording_rows.each(function(){
var recording_title = $(this).find('#recording-title');
configure_recording_row(recording_title);
});
}
});
-502
View File
@@ -1,502 +0,0 @@
// 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/>.
// Room specific js for copy button and email link.
$(document).on('turbolinks:load', function(){
var controller = $("body").data('controller');
var action = $("body").data('action');
// highlight current room
$('.room-block').removeClass('current');
$('a[href="' + window.location.pathname + '"] .room-block').addClass('current');
// Only run on room pages.
if (controller == "rooms" && action == "show"){
// Display and update all fields related to creating a room in the createRoomModal
$("#create-room-block").click(function(){
showCreateRoom(this)
})
checkIfAutoJoin()
}
// Autofocus on the Room Name label when creating a room only
$('#createRoomModal').on('shown.bs.modal', function (){
if ($(".create-only").css("display") == "block"){
$('#create-room-name').focus()
}
})
if (controller == "rooms" && action == "show" || controller == "admins" && action == "server_rooms"){
// Display and update all fields related to creating a room in the createRoomModal
$(".update-room").click(function(){
showUpdateRoom(this)
})
// share room pop up accessibility
manageAccessAccessibility();
$(".delete-room").click(function() {
showDeleteRoom(this)
})
// For keyboard users to be able to generate access code
generateAccessCodeAccessibility()
$('.selectpicker').selectpicker({
liveSearchPlaceholder: getLocalizedString('javascript.search.start')
});
// Fixes turbolinks issue with bootstrap select
$(window).trigger('load.bs.select.data-api');
$(".share-room").click(function() {
// Update the path of save button
$("#save-access").attr("data-path", $(this).data("path"))
$("#room-owner-uid").val($(this).data("owner"))
// Get list of users shared with and display them
displaySharedUsers($(this).data("users-path"))
})
$("#shareRoomModal").on("show.bs.modal", function() {
$(".selectpicker").selectpicker('val','')
})
$(".bootstrap-select").on("click", function() {
$(".bs-searchbox").siblings().hide()
})
$("#share-room-select ~ button").on("click", function() {
$(".bs-searchbox").siblings().hide()
})
$(".bs-searchbox input").on("input", function() {
if ($(".bs-searchbox input").val() == '' || $(".bs-searchbox input").val().length < 3) {
$(".select-options").remove()
$(".bs-searchbox").siblings().hide()
} else {
// Manually populate the dropdown
$.get($("#share-room-select").data("path"), { search: $(".bs-searchbox input").val(), owner_uid: $("#room-owner-uid").val() }, function(users) {
$(".select-options").remove()
if (users.length > 0) {
users.forEach(function(user) {
let opt = document.createElement("option")
$(opt).val(user.uid)
$(opt).text(user.name)
$(opt).addClass("select-options")
$(opt).attr("data-subtext", user.uid)
$("#share-room-select").append(opt)
})
// Only refresh the select dropdown if there are results to show
$('#share-room-select').selectpicker('refresh');
}
$(".bs-searchbox").siblings().show()
})
}
})
$(".remove-share-room").click(function() {
$("#remove-shared-confirm").parent().attr("action", $(this).data("path"))
})
// User selects an option from the Room Access dropdown
$(".bootstrap-select").on("changed.bs.select", function(){
// Get the uid of the selected user
let uid = $(".selectpicker").selectpicker('val')
// If the value was changed to blank, ignore it
if (uid == "") return
let currentListItems = $("#user-list li").toArray().map(user => $(user).data("uid"))
// Check to make sure that the user is not already there
if (!currentListItems.includes(uid)) {
// Create the faded list item and display it
let option = $("option[value='" + uid + "']")
let listItem = document.createElement("li")
listItem.setAttribute('class', 'list-group-item text-left not-saved add-access');
listItem.setAttribute("data-uid", uid)
let spanItemAvatar = document.createElement("span"),
spanItemName = document.createElement("span"),
spanItemUser = document.createElement("span");
spanItemAvatar.setAttribute('class', 'avatar float-left mr-2');
spanItemAvatar.innerText = option.text().charAt(0);
spanItemName.setAttribute('class', 'shared-user');
spanItemName.innerText = option.text();
spanItemUser.setAttribute('class', 'text-muted');
spanItemUser.innerText = option.data('subtext');
spanItemName.append(spanItemUser);
listItem.innerHTML = "<span class='text-primary float-right shared-user cursor-pointer' onclick='removeSharedUser(this)'><i class='fas fa-times'></i></span>"
listItem.prepend(spanItemName);
listItem.prepend(spanItemAvatar);
$("#user-list").append(listItem)
}
})
$("#presentation-upload").change(function(data) {
var file = data.target.files[0]
// Check file type and size to make sure they aren't over the limit
if (validFileUpload(file)) {
$("#presentation-upload-label").text(file.name)
} else {
$("#invalid-file-type").show()
$("#presentation-upload").val("")
$("#presentation-upload-label").text($("#presentation-upload-label").data("placeholder"))
}
})
$(".preupload-room").click(function() {
updatePreuploadPresentationModal(this)
})
$("#remove-presentation").click(function(data) {
removePreuploadPresentation($(this).data("remove"))
})
// trigger initial room filter
filterRooms();
}
});
function copyInvite() {
$('#invite-url').select()
if (document.execCommand("copy")) {
$('#invite-url').blur();
copy = $("#copy-invite")
copy.addClass('btn-success');
copy.html("<i class='fas fa-check mr-1'></i>" + getLocalizedString("copied"))
setTimeout(function(){
copy.removeClass('btn-success');
copy.html("<i class='fas fa-copy mr-1'></i>" + getLocalizedString("copy"))
}, 1000)
}
}
function copyAccess(target) {
input = target ? $("#copy-" + target + "-code") : $("#copy-code")
input.attr("type", "text")
input.select()
if (document.execCommand("copy")) {
input.attr("type", "hidden")
copy = target ? $("#copy-" + target + "-access") : $("#copy-access")
copy.addClass('btn-success');
copy.html("<i class='fas fa-check mr-1'></i>" + getLocalizedString("copied"))
setTimeout(function(){
copy.removeClass('btn-success');
originalString = target ? getLocalizedString("room.copy_" + target + "_access") : getLocalizedString("room.copy_access")
copy.html("<i class='fas fa-copy mr-1'></i>" + originalString)
}, 1000)
}
}
function showCreateRoom(target) {
$("#create-room-name").val("")
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
$("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code_placeholder"))
$("#room_access_code").val(null)
$("#room_moderator_access_code").val(null)
$("#createRoomModal form").attr("action", $("body").data('relative-root'))
$("#room_mute_on_join").prop("checked", $("#room_mute_on_join").data("default"))
$("#room_require_moderator_approval").prop("checked", $("#room_require_moderator_approval").data("default"))
$("#room_anyone_can_start").prop("checked", $("#room_anyone_can_start").data("default"))
$("#room_all_join_moderator").prop("checked", $("#room_all_join_moderator").data("default"))
$("#room_recording").prop("checked", $("#room_recording").data("default"))
//show all elements & their children with a create-only class
$(".create-only").each(function() {
$(this).show()
if($(this).children().length > 0) { $(this).children().show() }
})
//hide all elements & their children with a update-only class
$(".update-only").each(function() {
$(this).attr('style',"display:none !important")
if($(this).children().length > 0) { $(this).children().attr('style',"display:none !important") }
})
}
function showUpdateRoom(target) {
var modal = $(target)
var update_path = modal.closest(".room-block").data("path")
var settings_path = modal.data("settings-path")
$("#create-room-name").val(modal.closest(".room-block").find(".room-name-text").text().trim())
$("#createRoomModal form").attr("action", update_path)
//show all elements & their children with a update-only class
$(".update-only").each(function() {
$(this).show()
if($(this).children().length > 0) { $(this).children().show() }
})
//hide all elements & their children with a create-only class
$(".create-only").each(function() {
$(this).attr('style',"display:none !important")
if($(this).children().length > 0) { $(this).children().attr('style',"display:none !important") }
})
updateCurrentSettings(settings_path)
var accessCode = modal.closest(".room-block").data("room-access-code")
if(accessCode){
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code") + ": " + accessCode)
$("#room_access_code").val(accessCode)
} else {
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
$("#room_access_code").val(null)
}
var moderatorAccessCode = modal.closest(".room-block").data("room-moderator-access-code")
if(moderatorAccessCode){
$("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code") + ": " + moderatorAccessCode)
$("#room_moderator_access_code").val(moderatorAccessCode)
} else {
$("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code_placeholder"))
$("#room_moderator_access_code").val(null)
}
}
function showDeleteRoom(target) {
$("#delete-header").text(getLocalizedString("modal.delete_room.confirm").replace("%{room}", $(target).data("name")))
$("#delete-confirm").parent().attr("action", $(target).data("path"))
}
//Update the createRoomModal to show the correct current settings
function updateCurrentSettings(settings_path){
// Get current room settings and set checkbox
$.get(settings_path, function(settings) {
$("#room_mute_on_join").prop("checked", $("#room_mute_on_join").data("default") || settings.muteOnStart)
$("#room_require_moderator_approval").prop("checked", $("#room_require_moderator_approval").data("default") || settings.requireModeratorApproval)
$("#room_anyone_can_start").prop("checked", $("#room_anyone_can_start").data("default") || settings.anyoneCanStart)
$("#room_all_join_moderator").prop("checked", $("#room_all_join_moderator").data("default") || settings.joinModerator)
$("#room_recording").prop("checked", $("#room_recording").data("default") || Boolean(settings.recording))
})
}
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(getLocalizedString("modal.create_room.access_code") + ": " + accessCode)
$("#room_access_code").val(accessCode)
}
function ResetAccessCode(){
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
$("#room_access_code").val(null)
}
function generateModeratorAccessCode(){
const accessCodeLength = 6
var validCharacters = "abcdefghijklmopqrstuvwxyz"
var accessCode = ""
for( var i = 0; i < accessCodeLength; i++){
accessCode += validCharacters.charAt(Math.floor(Math.random() * validCharacters.length));
}
$("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code") + ": " + accessCode)
$("#room_moderator_access_code").val(accessCode)
}
function ResetModeratorAccessCode(){
$("#create-room-moderator-access-code").text(getLocalizedString("modal.create_room.moderator_access_code_placeholder"))
$("#room_moderator_access_code").val(null)
}
function saveAccessChanges() {
let listItemsToAdd = $("#user-list li:not(.remove-shared)").toArray().map(user => $(user).data("uid"))
$.post($("#save-access").data("path"), {add: listItemsToAdd})
}
// Get list of users shared with and display them
function displaySharedUsers(path) {
$.get(path, function(users) {
// Create list element and add to user list
var user_list_html = ""
users.forEach(function(user) {
user_list_html += "<li class='list-group-item text-left' data-uid='" + user.uid + "'>"
if (user.image) {
user_list_html += "<img id='user-image' class='avatar float-left mr-2' src='" + user.image + "'></img>"
} else {
user_list_html += "<span class='avatar float-left mr-2'>" + user.name.charAt(0) + "</span>"
}
user_list_html += "<span class='shared-user'>" + user.name + "<span class='text-muted ml-1'>" + user.uid + "</span></span>"
user_list_html += "<span class='text-primary float-right shared-user cursor-pointer' onclick='removeSharedUser(this)'><i class='fas fa-times'></i></span>"
user_list_html += "</li>"
})
$("#user-list").html(user_list_html)
});
}
// Removes the user from the list of shared users
function removeSharedUser(target) {
let parentLI = target.closest("li")
if (parentLI.classList.contains("not-saved")) {
parentLI.parentNode.removeChild(parentLI)
} else {
parentLI.removeChild(target)
parentLI.classList.add("remove-shared")
}
}
function updatePreuploadPresentationModal(target) {
$.get($(target).data("settings-path"), function(presentation) {
if(presentation.attached) {
$("#current-presentation").show()
$("#presentation-name").text(presentation.name)
$("#change-pres").show()
$("#use-pres").hide()
} else {
$("#current-presentation").hide()
$("#change-pres").hide()
$("#use-pres").show()
}
});
$("#preuploadPresentationModal form").attr("action", $(target).data("path"))
$("#remove-presentation").data("remove", $(target).data("remove"))
// Reset values to original to prevent confusion
$("#presentation-upload").val("")
$("#presentation-upload-label").text($("#presentation-upload-label").data("placeholder"))
$("#invalid-file-type").hide()
}
function removePreuploadPresentation(path) {
$.post(path, {})
}
function validFileUpload(file) {
return file.size/1024/1024 <= 30
}
// Automatically click the join button if this is an action cable reload
function checkIfAutoJoin() {
var url = new URL(window.location.href)
if (url.searchParams.get("reload") == "true") {
$("#joiner-consent").click()
$("#room-join").click()
}
}
function filterRooms() {
let search = $('#room-search').val()
if (search == undefined) { return }
let search_term = search.toLowerCase(),
rooms = $('#room_block_container > div:not(:last-child)');
clear_room_search = $('#clear-room-search');
if (search_term) {
clear_room_search.show();
} else {
clear_room_search.hide();
}
rooms.each(function(i, room) {
let text = $(this).find('h4').text();
room.style.display = (text.toLowerCase().indexOf(search_term) < 0) ? 'none' : 'block';
})
}
function clearRoomSearch() {
$('#room-search').val('');
filterRooms()
}
function manageAccessAccessibility() {
// share room pop up accessibility
var holdModal = false;
$("#shareRoomModal").on("show.bs.modal", function() {
// for screen reader to be able to read results
$("#shareRoomModal .form-control").attr("aria-atomic", true);
$("#shareRoomModal .dropdown-menu div.inner").attr("role", "alert");
$("#shareRoomModal ul.dropdown-menu").attr("role", "listbox");
$("#shareRoomModal div.dropdown-menu").find("*").keyup(function(event) {
$("#shareRoomModal ul.dropdown-menu li").attr("aria-selected", false);
$("#shareRoomModal ul.dropdown-menu li.active").attr("aria-selected", true);
$("#shareRoomModal ul.dropdown-menu li.active a").attr("aria-selected", true);
});
// for keyboard support
// so that it can escape / close search user without closing the modal
$("#shareRoomModal div.dropdown-menu input").keydown(function(event) {
if (event.keyCode === 27) {
holdModal = true;
}
});
});
// reset escape button if the search is closed / done
$("#shareRoomModal").on("hide.bs.modal", function(e) {
if (holdModal) {
holdModal = false;
e.stopPropagation();
return false;
}
});
}
function generateAccessCodeAccessibility() {
// For keyboard users to be able to generate access code
$("#generate-room-access-code").keyup(function(event) {
if (event.keyCode === 13 || event.keyCode === 32) {
generateAccessCode();
}
})
// For keyboard users to be able to reset access code
$("#reset-access-code").keyup(function(event) {
if (event.keyCode === 13 || event.keyCode === 32) {
ResetAccessCode();
}
})
// For keyboard users to be able to generate access code
// for moderator
$("#generate-moderator-room-access-code").keyup(function(event) {
if (event.keyCode === 13 || event.keyCode === 32) {
generateModeratorAccessCode();
}
})
// For keyboard users to be able to reset access code
// for moderator
$("#reset-moderator-access-code").keyup(function(event) {
if (event.keyCode === 13 || event.keyCode === 32) {
ResetModeratorAccessCode();
}
})
}
-103
View File
@@ -1,103 +0,0 @@
// 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/>.
$(document).on('turbolinks:load', function(){
var controller = $("body").data('controller');
var action = $("body").data('action');
if ((controller == "admins" && action == "index") ||
(controller == "rooms" && action == "show") ||
(controller == "rooms" && action == "update") ||
(controller == "rooms" && action == "join") ||
(controller == "users" && action == "recordings") ||
(controller == "admins" && action == "server_recordings") ||
(controller == "admins" && action == "server_rooms")) {
// Submit search if the user hits enter
$("#search-input").keypress(function(key) {
if (key.which == 13) {
searchPage()
}
})
// Add listeners for sort
$("th[data-order]").click(function(data){
var header_elem = $(data.target)
if(header_elem.data('order') === 'asc'){ // asc
header_elem.data('order', 'desc');
}
else if(header_elem.data('order') === 'desc'){ // desc
header_elem.data('order', 'none');
}
else{ // none
header_elem.data('order', 'asc');
}
var search = $("#search-input").val();
var url = window.location.pathname + "?page=1&search=" + search + "&column=" + header_elem.data("header") +
"&direction=" + header_elem.data('order')
window.location.replace(addRecordingTable(url))
})
if(controller === "rooms" && action === "show"){
$(".page-item > a").each(function(){
if(!$(this).attr('href').endsWith("#")){
$(this).attr('href', $(this).attr('href') + "#recordings-table")
}
})
}
}
})
// Searches the user table for the given string
function searchPage() {
var search = $("#search-input").val();
// Check if the user filtered by role
var role = new URL(location.href).searchParams.get('role')
var tab = new URL(location.href).searchParams.get('tab')
var url = window.location.pathname + "?page=1&search=" + search
if (role) { url += "&role=" + role }
if (tab) { url += "&tab=" + tab }
window.location.replace(addRecordingTable(url));
}
// Clears the search bar
function clearSearch() {
var role = new URL(location.href).searchParams.get('role')
var tab = new URL(location.href).searchParams.get('tab')
var url = window.location.pathname + "?page=1"
if (role) { url += "&role=" + role }
if (tab) { url += "&tab=" + tab }
window.location.replace(addRecordingTable(url));
var search_params = new URLSearchParams(window.location.search)
}
function addRecordingTable(url) {
if($("body").data('controller') === "rooms" && $("body").data('action') === "show") {
url += "#recordings-table"
}
return url
}
-42
View File
@@ -1,42 +0,0 @@
// 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');
// Only run on the settings page.
if ((controller == "users" && action == "edit") || (controller == "users" && action == "update")){
var settingsButtons = $('.setting-btn');
var settingsViews = $('.setting-view');
settingsButtons.each(function(i, btn) {
if(!$(btn).hasClass("active")){ $(settingsViews[i]).hide(); }
$(btn).click(function(){
$(btn).addClass("active");
settingsViews.each(function(i, view){
if($(view).attr("id") == $(btn).attr("id")){
$(view).show();
} else {
$(settingsButtons[i]).removeClass("active");
$(view).hide();
}
});
});
});
}
});
+93
View File
@@ -0,0 +1,93 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
var loopJoin = function() {
var jqxhr = Meeting.getInstance().getJoinMeetingResponse();
jqxhr.done(function(data) {
if (data.messageKey === 'wait_for_moderator') {
setTimeout(loopJoin, 5000);
} else {
$(location).attr("href", data.response.join_url);
}
});
jqxhr.fail(function(xhr, status, error) {
console.info("meeting join failed");
});
};
var alertTimeout = null;
var showAlert = function(html, timeout_delay, type) {
type = type || 'success'
if (!html) {
return;
}
$('.alert-template .alert-message').html(html);
$('.alert-template .alert').removeClass('alert-success alert-danger alert-info alert-warning').addClass('alert-'+type);
$('#alerts').html($('.alert-template').html());
if (timeout_delay) {
clearTimeout(alertTimeout);
alertTimeout = setTimeout(function() {
$('#alerts > .alert').alert('close');
}, timeout_delay);
}
};
// remove flash alerts after 5 seconds
var flashAlertDelayedDismiss = function() {
setTimeout(function(){
$('.flash-alerts').remove();
}, 5000);
};
var displayRoomURL = function() {
$('.meeting-url').val(Meeting.getInstance().getURL());
};
var showNotification = function(title, options) {
if (Notification.permission === "granted") {
var icon = '<%= asset_path("bbb-logo.png") %>';
options = $.extend(options, {
icon: icon,
tag: 'UserWaiting'
});
var notification = new Notification(title, options);
notification.onclick = function() {
window.focus();
};
}
};
var isRoomOwner = function() {
return $('body').data('current-user') === $('.page-wrapper.rooms').data('admin-id')
}
// For now there are notifications only for users signed in and when they
// are in their room's page
$(document).on("turbolinks:load", function() {
if (isRoomOwner()) {
Notification.requestPermission();
}
flashAlertDelayedDismiss();
});
-105
View File
@@ -1,105 +0,0 @@
// 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/>.
$(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"){
// Choose active header
// (Name, Length or Users)
$('th').each(function(){
if($(this).data("header")){
$(this).on('click', function(){
set_active_header($(this).data("header"));
sort_by($(this).data("header"), $(this).data('order'));
});
}
});
// Based on the header (Name, Length or Users) clicked,
// Modify the ui for the tables
var set_active_header = function(active_header){
$('th').each(function(){
if($(this).data("header") == active_header){
configure_order($(this));
}
else{
$(this).text($(this).data("header"));
$(this).data('order', 'none');
}
});
}
// Based on the header (Name, Length or Users) clicked,
// Modify the ui for the tables
var configure_order = function(header_elem){
if(header_elem.data('order') === 'asc'){ // asc
header_elem.data('order', 'desc');
}
else if(header_elem.data('order') === 'desc'){ // desc
header_elem.data('order', 'none');
}
else{ // none
header_elem.data('order', 'asc');
}
}
// Given a label and an order, sort recordings by order
// under a given label
var sort_by = function(label, order){
var recording_list_tbody = $('.table-responsive').find('tbody');
if(label === "Name"){
sort_recordings(recording_list_tbody, order, "#recording-title");
}
else if(label === "Length"){
sort_recordings(recording_list_tbody, order, "#recording-length");
}
else if(label === "Users"){
sort_recordings(recording_list_tbody, order, "#recording-users");
}
}
// Generalized function for sorting recordings
var sort_recordings = function(recording_list_tbody, order, recording_id){
recording_list_tbody.find('tr').sort(function(a, b){
var a_val, b_val;
if (recording_id == "#recording-length") {
a_val = $.trim($(a).find(recording_id).data("full-length"));
b_val = $.trim($(b).find(recording_id).data("full-length"));
} else {
a_val = $.trim($(a).find(recording_id).text());
b_val = $.trim($(b).find(recording_id).text());
}
if(order === "asc"){
return a_val.localeCompare(b_val);
}
else if(order === "desc"){
return b_val.localeCompare(a_val);
} else {
return undefined;
}
}).appendTo(recording_list_tbody);
}
}
});
-46
View File
@@ -1,46 +0,0 @@
// 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/>.
$(document).on('turbolinks:load', function(){
var controller = $("body").data('controller');
var action = $("body").data('action');
if ((controller == "admins" && action == "edit_user") || (controller == "users" && action == "edit")) {
// Hack to make it play nice with turbolinks
if ($("#role-dropdown:visible").length == 0){
$(window).trigger('load.bs.select.data-api')
}
// Check to see if the role dropdown was set up
if ($("#role-dropdown").length != 0){
$("#role-dropdown").selectpicker('val', $("#user_role_id").val())
}
// Update hidden field with new value
$("#role-dropdown").on("changed.bs.select", function(){
$("#user_role_id").val($("#role-dropdown").selectpicker('val'))
})
// Update hidden field with new value
// $("#language-dropdown").on("show.bs.select", function(){
// $("#language-dropdown").selectpicker('val', $("#user_language").val())
// })
// Update hidden field with new value
$("#language-dropdown").on("changed.bs.select", function(){
$("#user_language").val($("#language-dropdown").selectpicker('val'))
})
}
})
-67
View File
@@ -1,67 +0,0 @@
// 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 client request to join when meeting starts.
$(document).on("turbolinks:load", function(){
var controller = $("body").data('controller');
var action = $("body").data('action');
if(controller == "rooms" && action == "join"){
App.waiting = App.cable.subscriptions.create({
channel: "WaitingChannel",
roomuid: $(".background").attr("room"),
useruid: $(".background").attr("user")
}, {
connected: function() {
console.log("connected");
setTimeout(startRefreshTimeout, 120000);
},
disconnected: function(data) {
console.log("disconnected");
console.log(data);
},
rejected: function() {
console.log("rejected");
},
received: function(data){
console.log(data);
if(data.action == "started"){
request_to_join_meeting();
}
}
});
}
});
var join_attempts = 0;
function request_to_join_meeting() {
$.post(window.location.pathname, { join_name: $(".background").attr("join-name") }, function() {
//Successful post - set up retry incase
if(join_attempts < 4){ setTimeout(request_to_join_meeting, 10000); }
join_attempts++;
})
}
// Refresh the page after 2 mins and attempt to reconnect to ActionCable
function startRefreshTimeout() {
var url = new URL(window.location.href)
url.searchParams.set("reload","true")
window.location.href = url.href
}
@@ -1,81 +0,0 @@
/* 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/>.
*/
@import "tabler/functions";
@import "tabler/core";
@import "tabler/type";
@import "tabler/grid";
@import "tabler/layout";
@import "tabler/aside";
@import "tabler/header";
@import "tabler/footer";
@import "tabler/colors";
@import "tabler/text";
@import "tabler/utilities";
@import "tabler/nav";
@import "tabler/button";
@import "tabler/alert";
//@import "tabler/close";
//@import "tabler/badge";
@import "tabler/tables";
//@import "tabler/breadcrumb";
//@import "tabler/pagination";
@import "tabler/cards";
//@import "tabler/popover";
@import "tabler/dropdown";
@import "tabler/list";
@import "tabler/list-group";
@import "tabler/avatar";
//@import "tabler/product";
@import "tabler/progress";
@import "tabler/icon";
//@import "tabler/image";
//@import "tabler/link";
//@import "tabler/media";
@import "tabler/form";
//@import "tabler/sparkline";
@import "tabler/social";
//@import "tabler/maps";
//@import "tabler/statuses";
//@import "tabler/charts";
//@import "tabler/chips";
@import "tabler/stamp";
//@import "tabler/chat";
//@import "tabler/example";
@import "tabler/tag";
//@import "tabler/syntax";
//@import "tabler/infobox";
//@import "tabler/carousel";
//@import "tabler/forms/custom-range";
//@import "tabler/forms/custom-selectgroup";
@import "tabler/forms/custom-switch";
//@import "tabler/forms/custom-imagecheck";
@import "tabler/forms/custom-colorinput";
//@import "tabler/timeline";
//@import "tabler/browser";
//@import "tabler/flag";
//@import "tabler/payments";
//@import "tabler/jvectormap";
//@import "tabler/selectize";
//@import "tabler/fonts/feather";
-105
View File
@@ -1,105 +0,0 @@
// 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/>.
#users-table {
.user-role {
color: white !important;
}
.user-email {
max-width: 250px;
}
}
#clear-search {
z-index: 9;
position: absolute;
right: 55px;
top: 8px;
&:hover {
cursor: pointer;
}
}
.tag i {
color: white !important;
}
#branding-image{
z-index: auto;
}
.authentication-required{
padding-top: 2px;
}
#site_settings {
.colorinput-color {
text-align: center;
padding-top: 4px;
height: 2rem;
width: 2rem;
}
}
.sort-disabled{
background: #e6e6e6 !important;
color: rgb(110, 118, 135) !important;
opacity: 0.75;
&:hover{
opacity: 0.9;
}
}
.form-disable{
background-color: #e6e6e6;
}
.role-colour-picker{
color: white !important;
}
.custom-role-tag{
color: white !important;
// Make it consistent with the manage users tab tags
padding-top: 1px;
padding-bottom: 1px;
}
.user-role-tag{
color: white !important;
}
#manage-users-nav.nav-tabs .nav-item {
margin-bottom: -1px;
}
#merge-account-arrow {
position: absolute;
top: 47%;
right: 47%;
z-index: 999;
background: white;
}
.admin-tabs {
justify-content: space-around;
}
#rooms-table-div {
overflow: visible;
}
+34
View File
@@ -0,0 +1,34 @@
/* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
*
* Copyright (c) 2016 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/>.
*/
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require jquery-ui
*= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
*= require_tree ./main
*= require_self
*/
-193
View File
@@ -1,193 +0,0 @@
/* 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/>.
*/
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_self
*/
@import "tabler/variables";
@import "bootstrap";
@import "jquery-ui/sortable";
@import "tabler-custom";
@import "font-awesome-sprockets";
@import "font-awesome";
@import "monolith.min.scss";
@import "bootstrap-select.min";
@import "utilities/variables";
@import "admins";
@import "main";
@import "rooms";
@import "sessions";
@import "utilities/fonts";
@import "users";
* {
outline: none !important;
}
html, body {
font-family: "Source Sans Pro" !important;
position: relative;
width: 100%;
height: 100%;
background-color: white;
}
a {
text-decoration: none !important;
cursor: pointer;
}
.dotted_underline {
border-bottom: 3px dashed #d3d3d3;
width: 100%;
}
.disable-click {
pointer-events: none;
}
.header {
height: $header-height;
}
.wrapper {
position: relative;
height: auto;
min-height: calc(100% - #{$header-height} - #{$footer-height});
}
.footer {
height: $footer-height;
width: 100%;
}
.background {
background-color: $background-color;
}
.error-section {
background-color: $error-background-color;
}
.font-weight-400 {
font-weight: 400;
}
.subtitle {
font-size: 25px;
}
.force-bottom {
display: flex;
justify-content: flex-end;
flex-direction: column;
}
.invite-link-input {
width: 100%;
}
.no-border-top {
td {
border-top: none;
}
}
.force-text-normal {
color: #495057;
}
.terms {
overflow: scroll;
height: 55vh;
}
[contenteditable]:focus {
outline: 0px solid transparent;
}
.cookies-banner {
color: white;
background-color: $button-color-blue;
#cookies-agree-button {
margin: 0;
}
}
input:focus {
border-color: $primary !important;
}
.input-group button:focus {
box-shadow: none !important;
}
.list-group-item-action.active {
color: $primary;
}
.header .header-nav {
color: $text-muted !important;
&:hover {
padding-bottom: 21px;
border-bottom: 1px solid $primary;
}
&.active {
color: $primary !important;
padding-bottom: 21px;
border-bottom: 1px solid $primary;
}
}
table {
thead {
th[data-order]:hover {
cursor: pointer;
}
}
}
.cursor-pointer{
cursor: pointer;
}
#delete-confirm:disabled {
cursor: not-allowed;
}
.btn i {
transition: all .15s;
}
.nav-icon i {
width: 35px;
}
-20
View File
@@ -1,20 +0,0 @@
/* 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/>.
*/
// Place all the styles related to the Errors controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
@@ -1,6 +1,6 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
// Copyright (c) 2016 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
@@ -14,23 +14,5 @@
// You should have received a copy of the GNU Lesser General Public License along
// with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
$(document).on('turbolinks:load', function(){
// Stores the current url when the user clicks the sign in button
$(".sign-in-button").click(function(){
var url = location.href
// Add the slash at the end if it's missing
url += url.endsWith("/") ? "" : "/"
document.cookie ="return_to=" + url
})
// Checks to see if the user provided an image url and displays it if they did
$("#user-image")
.on("load", function() {
$("#user-image").show()
$("#user-avatar").hide()
})
.on("error", function() {
$("#user-image").hide()
$("#user-avatar").show()
})
})
@import "font-awesome-sprockets";
@import "font-awesome";
-178
View File
@@ -1,178 +0,0 @@
/* 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/>.
*/
// Place all the styles related to the Main controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.responsive-header {
font-size: 3.3vw;
}
.landing-section {
position: relative;
height: 40%;
}
.lead {
font-size:18px;
}
.feature-stamp {
.stamp {
padding:1em 1.5em;
height:auto;
}
}
.or-line {
div {
width: 100%;
height: 16px;
border-bottom: 1px solid #d3d3d3;
text-align: center;
span {
font-size: 120%;
background-color: #ffffff;
padding: 0 10px;
color: #d3d3d3
}
}
}
.display-4 {
font-weight: normal;
}
.customBtn {
display: block;
text-align: center;
background: #cccccc;
color: #ffffff;
box-shadow: 0 2px 4px 0 rgba(0,0,0,.25);
-webkit-transition: background-color .218s,border-color .218s,box-shadow .218s;
transition: background-color .218s,border-color .218s,box-shadow .218s;
white-space: nowrap;
border-radius: 2px;
border: 1px solid transparent;
margin-bottom:20px;
&:hover {
cursor: pointer;
color: #ffffff;
-webkit-box-shadow: 0 0 3px 3px rgba(66,133,244,.3);
box-shadow: 0 0 3px 3px rgba(66,133,244,.3);
}
.customBtn-icon {
display: inline-block;
vertical-align: middle;
padding:13px 15px 13px 15px;
float:left;
background: #ffffff;
}
.customBtn-text {
font-size: 19px;
line-height: 48px;
font-weight: 600;
letter-spacing: .21px;
padding:0 25px;
}
.customBtn-image {
background: #ffffff;
background-size: 18px 18px;
padding:10px 10px 10px 10px;
}
}
.customBtn-google {
@extend .customBtn;
background: #4688f1;
.customBtn-image {
background: #ffffff image-url("google-logo.png") no-repeat left top;
background-size: 18px 18px;
padding:10px 10px 10px 10px;
}
}
.customBtn-twitter {
@extend .customBtn;
background: #1da1f2;
.customBtn-image {
background: #ffffff image-url("twitter-logo.png") no-repeat left top;
background-size: 18px 18px;
padding:10px 10px 10px 10px;
}
}
.customBtn-office365 {
@extend .customBtn;
background: #f65314;
.customBtn-image {
background: #ffffff image-url("office365-logo.jpeg") no-repeat left top;
background-size: 18px 18px;
padding:10px 10px 10px 10px;
}
}
.customBtn-microsoft_windows {
@extend .customBtn;
background: #00a1f1;
.customBtn-image {
background: #ffffff image-url("windows-logo.png") no-repeat left top;
background-size: 18px 18px;
padding:10px 10px 10px 10px;
}
}
.customBtn-ldap {
@extend .customBtn;
background: #d61515;
.customBtn-image {
background: #ffffff image-url("ldap-logo.png") no-repeat left top;
background-size: 18px 18px;
padding:10px 10px 10px 10px;
}
}
.customBtn-openid_connect {
@extend .customBtn;
background: #ef8e1f;
.customBtn-image {
background: #ffffff image-url("openid-logo.png") no-repeat left top;
background-size: 18px 18px;
padding:10px 10px 10px 10px;
}
}
.signin-button {
font-size: 16px;
}
.table-responsive tbody td:first-child > *:first-child {
max-height: 3em;
overflow: hidden;
max-width: 200px;
display: flex;
}
+15
View File
@@ -0,0 +1,15 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
+133
View File
@@ -0,0 +1,133 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
.meeting-url-button-group {
padding-top: 5px;
width: 150px;
text-align: center;
}
.meeting-url-qrcode-group {
padding-top: 5px;
width: 128px;
text-align: center;
}
.previously-joined, .actives {
list-style-type: none;
margin:auto;
width: 200px;
padding: 0;
cursor: pointer;
}
.meetings {
}
.rooms {
.table-wrapper {
padding: 40px 50px 10px 50px;
#recordings {
thead {
th:after {
content: none; //removes the sort icon in table header
}
}
.dataTables_empty {
text-align: center;
}
.timeago {
margin-left: 5px;
font-size: 13px;
cursor: pointer;
color: #999;
}
}
}
}
.img-thumbnail{
padding: 4px;
background-color: white;
border: 1px solid #dddddd;
border-radius: 4px;
&.large{
display: none;
}
&:hover + &.large{
display: inline-block;
position: absolute;
z-index: 1;
}
}
.meeting-url-group {
position: relative;
}
.recording-update-trigger {
&.recording-unpublished {
color: red;
}
&.recording-unlisted {
color: #e3a91e;
}
&.recording-published {
color: green;
}
}
.fa-spinner {
width: 100%;
text-align: center;
}
.disabled-button {
opacity: 0.5;
}
.youtube-red {
color: red;
}
.cloud-blue {
color: cornflowerblue;
}
.green-check {
color: limegreen;
}
.top-buffer {
margin-top: 8px;
}
.tooltip-wrapper {
display: inline-block;
}
#youtube-footer{
font-size: 10px;
text-align: center;
margin-top: 10px;
}
+23
View File
@@ -0,0 +1,23 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
.login {
.center-panel {
.center-panel-size {
max-width: 400px
}
}
}
+187
View File
@@ -0,0 +1,187 @@
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
//
// Copyright (c) 2016 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/>.
@import "bootstrap-sprockets";
@import "bootstrap";
@import "bootstrap-social";
html, body {
width: 100%;
height: 100%;
background: #ffffff;
}
.container-fluid {
height: 100%;
}
.background {
height: 350px;
width: 100%;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
body[data-controller=landing].app-background {
@extend .background;
}
#alerts {
position: absolute;
top: 10px;
left: 50%;
margin-left: -250px;
width: 500px;
z-index: 999;
}
.header {
padding: 20px 40px;
margin-bottom: 160px;
.logo {
max-width: 150px;
max-height: 50px;
}
}
.footer {
padding: 20px;
}
.center-block {
float: none;
}
.center-panel-wrapper {
height: 100%;
}
.center-panel {
height: 100%;
.center-panel-size {
max-width: 1200px
}
.center-panel-content-size {
height: 100%;
max-width: 1100px;
}
.panel {
position: relative;
overflow: hidden;
}
.input-spacing {
margin-top: 15px;
}
.panel-footer {
background-color: white;
}
.panel-body {
padding-bottom: 40px;
}
.title-wrapper {
margin-bottom: 30px;
}
.join-form-wrapper {
.center-block {
max-width: 400px;
}
.join-form {
width: 100%;
}
.btn {
width: initial;
}
}
.meeting-url-wrapper {
.meeting-url {
cursor: default;
}
}
.loading-wrapper {
text-align: center;
}
}
.popover {
max-width: none;
}
a.signin-link {
&:hover, &:focus {
cursor: pointer;
text-decoration: none;
}
}
.signin-link {
.signin-icon {
vertical-align: middle;
width: 35px;
height: 35px;
}
.signin-button {
background: white;
width: 250px;
border: thin solid #888;
border-radius: 2px;
white-space: nowrap;
padding: 5px;
margin-bottom: 14px;
}
.signin-icon-wrapper {
display: inline-block;
width: 40px;
}
.signin-text-wrapper {
display: inline-block;
width: 200px;
}
.signin-text {
font-family: 'Roboto', sans-serif;
vertical-align: middle;
font-size: 14px;
font-weight: bold;
color: #444;
}
}
.verticle-line {
// parent must be position relative to work
width: 1px;
background-color: lightgray;
height: 100%;
position: absolute;
left: 50%;
}
.invite-join-wrapper {
position: relative;
}
.help-link {
position: absolute;
top: 0;
right: 0;
padding-right: 3px;
}
-146
View File
@@ -1,146 +0,0 @@
/* 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/>.
*/
// Place all the styles related to the Rooms controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.start-button {
font-size: 26px !important;
}
.thumbnail {
height: 60px !important;
width: auto;
}
.join-form {
font-size: 20px !important;
}
.moderator-code-label {
margin-top: 150px !important;
}
.home-indicator {
font-size: 22px !important;
}
.btn-del-room {
width: 70% !important;
}
.edit_hover_class a{
visibility: hidden;
}
.edit_hover_class:hover a {
visibility: visible;
}
#room-settings-dropdown-label {
vertical-align: middle;
padding-top: 12px;
}
.room-block {
&:not(.current) {
.stamp {
opacity: 0.5;
}
}
}
#create-room-block {
border: 1px dashed lightgray;
&:hover {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.04);
}
}
.allow-icon-click{
pointer-events: auto;
}
.cant-create-rooms-title{
align-items: center;
justify-content: center;
}
.avatar-xxxl{
width: 8rem;
height: 8rem;
line-height: 8rem;
max-width: 8rem;
margin-top: -6rem;
font-size: 5rem;
}
.bootstrap-select .dropdown-menu li.active small.text-muted{
color: #9aa0ac !important
}
.not-saved {
color: grey;
background: rgba(0, 40, 100, 0.12);
}
.dropdown-menu.show {
min-height: 0px !important;
}
.remove-shared {
text-decoration: line-through;
}
.enabled-setting {
background: lightgray;
pointer-events: none;
}
#recording-table .edit_hover_class {
word-break: break-word;
white-space: normal;
}
#room-owner-name {
line-height: 12px;
}
.create-room-button {
width: 49%;
}
#presentation-upload-label {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
padding-right: 75px;
}
#clear-room-search {
z-index: 9;
position: absolute;
right: 15px;
top: 8px;
&:hover {
cursor: pointer;
}
}
-66
View File
@@ -1,66 +0,0 @@
/* 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/>.
*/
// Place all the styles related to the Sessions controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.login {
.center-panel {
.center-panel-size {
max-width: 400px;
}
}
}
a.signin-link {
&:hover, &:focus {
cursor: pointer;
text-decoration: none;
}
}
.signin-link {
.signin-icon {
vertical-align: middle;
width: 35px;
height: 35px;
}
.signin-button {
background: white;
width: 250px;
border: thin solid #888;
border-radius: 2px;
white-space: nowrap;
padding: 5px;
margin-bottom: 14px;
}
.signin-icon-wrapper {
display: inline-block;
width: 40px;
}
.signin-text-wrapper {
display: inline-block;
width: 200px;
}
.signin-text {
vertical-align: middle;
font-size: 14px;
font-weight: bold;
color: #444;
}
}
-32
View File
@@ -1,32 +0,0 @@
/* 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/>.
*/
// Place all the styles related to the Users controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.user-role-tag{
color: white !important;
}
.shared-user {
line-height: 30px;
}
.bootstrap-select {
border: 1px solid rgba(0, 40, 100, 0.12);
}
@@ -1,504 +0,0 @@
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-LightItalic.ttf')) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-LightItalic.ttf')) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-LightItalic.ttf')) format('truetype');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-LightItalic.ttf')) format('truetype');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-LightItalic.ttf')) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-LightItalic.ttf')) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-LightItalic.ttf')) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Italic.ttf')) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Italic.ttf')) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Italic.ttf')) format('truetype');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Italic.ttf')) format('truetype');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Italic.ttf')) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Italic.ttf')) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Italic.ttf')) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBoldItalic.ttf')) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBoldItalic.ttf')) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBoldItalic.ttf')) format('truetype');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBoldItalic.ttf')) format('truetype');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBoldItalic.ttf')) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBoldItalic.ttf')) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBoldItalic.ttf')) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-BoldItalic.ttf')) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-BoldItalic.ttf')) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-BoldItalic.ttf')) format('truetype');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-BoldItalic.ttf')) format('truetype');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-BoldItalic.ttf')) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-BoldItalic.ttf')) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-BoldItalic.ttf')) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Light.ttf')) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Light.ttf')) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Light.ttf')) format('truetype');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Light.ttf')) format('truetype');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Light.ttf')) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Light.ttf')) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Light.ttf')) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Regular.ttf')) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Regular.ttf')) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Regular.ttf')) format('truetype');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Regular.ttf')) format('truetype');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Regular.ttf')) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Regular.ttf')) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Regular.ttf')) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBold.ttf')) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBold.ttf')) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBold.ttf')) format('truetype');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBold.ttf')) format('truetype');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBold.ttf')) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBold.ttf')) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-SemiBold.ttf')) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Bold.ttf')) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Bold.ttf')) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Bold.ttf')) format('truetype');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Bold.ttf')) format('truetype');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Bold.ttf')) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Bold.ttf')) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: asset-url(font-path('SourceSansPro/SourceSansPro-Bold.ttf')) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -1,24 +0,0 @@
/* 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/>.
*/
// Declare all variables here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
$background-color: #F5F7FB;
$error-background-color: #EFE6E6;
$button-color-blue: #467FCF;
$header-height: 65px;
$footer-height: 65px;
+1 -3
View File
@@ -1,8 +1,6 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
# Copyright (c) 2016 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
+1 -3
View File
@@ -1,8 +1,6 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
# Copyright (c) 2016 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
+27
View File
@@ -0,0 +1,27 @@
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2016 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/>.
class MeetingUpdatesChannel < ApplicationCable::Channel
def subscribed
full_id = if params[:meeting_id].present?
"#{params[:admin_id]}-#{params[:meeting_id]}"
else
params[:admin_id]
end
stream_from "#{full_id}_meeting_updates_channel"
end
end
+26
View File
@@ -0,0 +1,26 @@
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2016 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/>.
class RecordingUpdatesChannel < ApplicationCable::Channel
def subscribed
full_id = if params[:meeting_id].present?
"#{params[:admin_id]}-#{params[:meeting_id]}"
else
params[:admin_id]
end
stream_from "#{full_id}_recording_updates_channel"
end
end
@@ -1,8 +1,6 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
# Copyright (c) 2016 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
@@ -16,8 +14,8 @@
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class WaitingChannel < ApplicationCable::Channel
class RefreshMeetingsChannel < ApplicationCable::Channel
def subscribed
stream_from "#{params[:roomuid]}_waiting_channel"
stream_from "refresh_meetings"
end
end
@@ -1,78 +0,0 @@
# 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/>.
class AccountActivationsController < ApplicationController
include Emailer
include Authenticator
before_action :ensure_unauthenticated
before_action :find_user_by_token, only: :edit
before_action :find_user_by_digest, only: :resend
# GET /account_activations
def show
end
# GET /account_activations/edit
def edit
# If the user exists and is not verified and provided the correct token
if @user && !@user.activated?
# Verify user
@user.set_role(initial_user_role(@user.email)) if @user.role.nil?
@user.activate
# Redirect user to root with account pending flash if account is still pending
return redirect_to root_path,
flash: { success: I18n.t("registration.approval.signup") } if @user.has_role?(:pending)
# Redirect user to sign in path with success flash
redirect_to signin_path, flash: { success: "#{I18n.t('verify.activated')} #{I18n.t('verify.signin')}" }
else
redirect_to root_path, flash: { alert: I18n.t("verify.invalid") }
end
end
# POST /account_activations/resend
def resend
if @user.activated?
# User is already verified
flash[:alert] = I18n.t("verify.already_verified")
else
# Resend
send_activation_email(@user, @user.create_activation_token)
end
redirect_to root_path
end
private
def find_user_by_token
return redirect_to root_path, flash: { alert: I18n.t("verify.invalid") } unless params[:token].present?
@user = User.find_by!(activation_digest: User.hash_token(params[:token]), provider: @user_domain)
end
def find_user_by_digest
@user = User.find_by!(activation_digest: params[:digest], provider: @user_domain)
end
def ensure_unauthenticated
redirect_to current_user.main_room || root_path if current_user
end
end
-379
View File
@@ -1,379 +0,0 @@
# 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/>.
class AdminsController < ApplicationController
include Pagy::Backend
include Themer
include Emailer
include Recorder
include Rolify
include Populator
manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve, :reset, :merge_user]
manage_deleted_users = [:undelete]
authorize_resource class: false
before_action :find_user, only: manage_users
before_action :find_deleted_user, only: manage_deleted_users
before_action :verify_admin_of_user, only: [manage_users, manage_deleted_users]
# GET /admins
def index
# Initializa the data manipulation variables
@search = params[:search] || ""
@order_column = params[:column] && params[:direction] != "none" ? params[:column] : "created_at"
@order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC"
@tab = params[:tab] || "active"
@role = params[:role] ? Role.find_by(name: params[:role], provider: @user_domain) : nil
users = if @tab == "invited"
invited_users_list
else
manage_users_list
end
@pagy, @users = pagy(users)
end
# GET /admins/site_settings
def site_settings
@tab = params[:tab] || "appearance"
end
# GET /admins/server_recordings
def server_recordings
@search = params[:search] || ""
if @search.present?
if @search.include? "@"
user_email = @search
else
room_uid = @search
end
else
@latest = true
end
@pagy, @recordings = pagy_array(recordings_to_show(user_email, room_uid))
end
# GET /admins/rooms
def server_rooms
@search = params[:search] || ""
@order_column = params[:column] && params[:direction] != "none" ? params[:column] : "status"
@order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC"
begin
meetings = all_running_meetings[:meetings]
rescue BigBlueButton::BigBlueButtonException
flash[:alert] = I18n.t("administrator.rooms.timeout", server: I18n.t("bigbluebutton"))
meetings = []
end
@order_column = "created_at" if meetings.empty?
@running_room_bbb_ids = meetings.pluck(:meetingID)
@participants_count = {}
meetings.each do |meet|
@participants_count[meet[:meetingID]] = meet[:participantCount]
end
@pagy, @rooms = pagy_array(server_rooms_list)
end
# GET /admins/room_configuration
def room_configuration
end
# MANAGE USERS
# GET /admins/edit/:user_uid
def edit_user
session[:prev_url] = request.referer if request.referer.present?
end
# POST /admins/ban/:user_uid
def ban_user
@user.set_role :denied
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.banned") }
end
# POST /admins/unban/:user_uid
def unban_user
@user.set_role :user
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.unbanned") }
end
# POST /admins/approve/:user_uid
def approve
@user.set_role :user
send_user_approved_email(@user)
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.approved") }
end
# POST /admins/approve/:user_uid
def undelete
# Undelete the user and all of his rooms
@user.undelete!
@user.rooms.deleted.each(&:undelete!)
redirect_back fallback_location: admins_path, flash: { success: I18n.t("administrator.flash.restored") }
end
# POST /admins/invite
def invite
emails = params[:invite_user][:email].split(",")
emails.each do |email|
invitation = create_or_update_invite(email)
send_invitation_email(current_user.name, email, invitation)
end
redirect_back fallback_location: admins_path,
flash: { success: I18n.t("administrator.flash.invite", email: emails.join(", ")) }
end
# GET /admins/reset
def reset
send_password_reset_email(@user, @user.create_reset_digest)
if session[:prev_url].present?
redirect_path = session[:prev_url]
session.delete(:prev_url)
else
redirect_path = admins_path
end
redirect_to redirect_path, flash: { success: I18n.t("administrator.flash.reset_password") }
end
# POST /admins/merge/:user_uid
def merge_user
begin
# Get uid of user that will be merged into the other account
uid_to_merge = params[:merge]
logger.info "#{current_user.uid} is attempting to merge #{uid_to_merge} into #{@user.uid}"
# Check to make sure the 2 users are unique
raise "Can not merge the user into themself" if uid_to_merge == @user.uid
# Find user to merge
user_to_merge = User.find_by(uid: uid_to_merge)
# Move over user's rooms
user_to_merge.rooms.each do |room|
room.owner = @user
room.name = "(#{I18n.t('merged')}) #{room.name}"
room.save!
end
# Reload user to update merge rooms
user_to_merge.reload
# Delete merged user
user_to_merge.destroy(true)
rescue => e
logger.info "Failed to merge #{uid_to_merge} into #{@user.uid}: #{e}"
flash[:alert] = I18n.t("administrator.flash.merge_fail")
else
logger.info "#{current_user.uid} successfully merged #{uid_to_merge} into #{@user.uid}"
flash[:success] = I18n.t("administrator.flash.merge_success")
end
redirect_back fallback_location: admins_path
end
# GET /admins/merge_list
def merge_list
# Returns a list of users that can merged into another user
initial_list = User.without_role(:super_admin)
.where.not(uid: current_user.uid)
.merge_list_search(params[:search])
initial_list = initial_list.where(provider: @user_domain) if Rails.configuration.loadbalanced_configuration
# Respond with JSON object of users
respond_to do |format|
format.json { render body: initial_list.pluck_to_hash(:uid, :name, :email).to_json }
end
end
# SITE SETTINGS
# POST /admins/update_settings
def update_settings
tab = params[:tab] || "settings"
@settings.update_value(params[:setting], params[:value])
flash_message = I18n.t("administrator.flash.settings")
if params[:value] == "Default Recording Visibility"
flash_message += ". #{I18n.t('administrator.site_settings.recording_visibility.warning')}"
end
redirect_to admin_site_settings_path(tab: tab), flash: { success: flash_message }
end
# POST /admins/color
def coloring
@settings.update_value("Primary Color", params[:value])
@settings.update_value("Primary Color Lighten", color_lighten(params[:value]))
@settings.update_value("Primary Color Darken", color_darken(params[:value]))
redirect_to admin_site_settings_path(tab: "appearance"), flash: { success: I18n.t("administrator.flash.settings") }
end
# POST /admins/registration_method/:method
def registration_method
new_method = Rails.configuration.registration_methods[params[:value].to_sym]
# 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]
redirect_to admin_site_settings_path(tab: "settings"),
flash: { alert: I18n.t("administrator.flash.invite_email_verification") }
else
@settings.update_value("Registration Method", new_method)
redirect_to admin_site_settings_path(tab: "settings"),
flash: { success: I18n.t("administrator.flash.registration_method_updated") }
end
end
# POST /admins/clear_auth
def clear_auth
User.include_deleted.where(provider: @user_domain).update_all(social_uid: nil)
redirect_to admin_site_settings_path(tab: "settings"), flash: { success: I18n.t("administrator.flash.settings") }
end
# POST /admins/clear_cache
def clear_cache
Rails.cache.delete("#{@user_domain}/getUser")
Rails.cache.delete("#{@user_domain}/getUserGreenlightCredentials")
redirect_to admin_site_settings_path(tab: "settings"), flash: { success: I18n.t("administrator.flash.settings") }
end
# POST /admins/log_level
def log_level
Rails.logger.level = params[:value].to_i
redirect_to admin_site_settings_path(tab: "administration"), flash: { success: I18n.t("administrator.flash.settings") }
end
# ROOM CONFIGURATION
# POST /admins/update_room_configuration
def update_room_configuration
@settings.update_value(params[:setting], params[:value])
flash_message = I18n.t("administrator.flash.room_configuration")
redirect_to admin_room_configuration_path, flash: { success: flash_message }
end
# ROLES
# GET /admins/roles
def roles
@roles = all_roles(params[:selected_role])
end
# POST /admins/role
# This method creates a new role scoped to the users provider
def new_role
new_role = create_role(params[:role][:name])
return redirect_to admin_roles_path, flash: { alert: I18n.t("administrator.roles.invalid_create") } if new_role.nil?
redirect_to admin_roles_path(selected_role: new_role.id)
end
# PATCH /admin/roles/order
# This updates the priority of a site's roles
# Note: A lower priority role will always get used before a higher priority one
def change_role_order
unless update_priority(params[:role])
redirect_to admin_roles_path, flash: { alert: I18n.t("administrator.roles.invalid_order") }
end
end
# POST /admin/role/:role_id
# This method updates the permissions assigned to a role
def update_role
role = Role.find(params[:role_id])
flash[:alert] = I18n.t("administrator.roles.invalid_update") unless update_permissions(role)
redirect_to admin_roles_path(selected_role: role.id)
end
# DELETE admins/role/:role_id
# This deletes a role
def delete_role
role = Role.find(params[:role_id])
# Make sure no users are assigned to the role and the role isn't a reserved role
# before deleting
if role.users.count.positive?
flash[:alert] = I18n.t("administrator.roles.role_has_users", user_count: role.users.count)
return redirect_to admin_roles_path(selected_role: role.id)
elsif Role::RESERVED_ROLE_NAMES.include?(role) || role.provider != @user_domain ||
role.priority <= current_user.role.priority
return redirect_to admin_roles_path(selected_role: role.id)
else
role.role_permissions.delete_all
role.delete
end
redirect_to admin_roles_path
end
private
def find_user
@user = User.find_by(uid: params[:user_uid])
end
def find_deleted_user
@user = User.deleted.find_by(uid: params[:user_uid])
end
# Verifies that admin is an administrator of the user in the action
def verify_admin_of_user
redirect_to admins_path,
flash: { alert: I18n.t("administrator.flash.unauthorized") } unless current_user.admin_of?(@user, "can_manage_users")
end
# Creates the invite if it doesn't exist, or updates the updated_at time if it does
def create_or_update_invite(email)
invite = Invitation.find_by(email: email, provider: @user_domain)
# Invite already exists
if invite.present?
# Updates updated_at to now
invite.touch
else
# Creates invite
invite = Invitation.create(email: email, provider: @user_domain)
end
invite
end
end
+25 -282
View File
@@ -1,8 +1,6 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
# Copyright (c) 2016 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
@@ -16,301 +14,46 @@
# 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 'bigbluebutton_api'
require 'digest/sha1'
class ApplicationController < ActionController::Base
include BbbServer
include Errors
protect_from_forgery with: :exception
before_action :set_locale
MEETING_NAME_LIMIT = 200
USER_NAME_LIMIT = 100
before_action :block_unknown_hosts, :redirect_to_https, :set_user_domain, :set_user_settings, :maintenance_mode?,
:migration_error?, :user_locale, :check_admin_password, :check_user_role
protect_from_forgery with: :exceptions
# Retrieves the current user.
def current_user
@current_user ||= User.includes(:role, :main_room).find_by(id: session[:user_id])
if Rails.configuration.loadbalanced_configuration && (@current_user && !@current_user.has_role?(:super_admin) &&
@current_user.provider != @user_domain)
@current_user = nil
session.clear
def set_locale
I18n.locale = http_accept_language.language_region_compatible_from(I18n.available_locales)
end
@current_user
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
helper_method :current_user
def bbb_server
@bbb_server ||= Rails.configuration.loadbalanced_configuration ? bbb(@user_domain) : bbb("greenlight")
end
# Block unknown hosts to mitigate host header injection attacks
def block_unknown_hosts
return if Rails.configuration.hosts.blank?
raise UnsafeHostError, "#{request.host} is not a safe host" unless Rails.configuration.hosts.include?(request.host)
end
# Force SSL
def redirect_to_https
if Rails.configuration.loadbalanced_configuration && request.headers["X-Forwarded-Proto"] == "http"
redirect_to protocol: "https://"
end
end
# Sets the user domain variable
def set_user_domain
if Rails.env.test? || !Rails.configuration.loadbalanced_configuration
@user_domain = "greenlight"
else
@user_domain = parse_user_domain(request.host)
check_provider_exists
end
end
# Sets the settinfs variable
def set_user_settings
@settings = Setting.includes(:features).find_or_create_by(provider: @user_domain)
end
# Redirects the user to a Maintenance page if turned on
def maintenance_mode?
if ENV["MAINTENANCE_MODE"] == "true"
render "errors/greenlight_error", status: 503, formats: :html,
locals: {
status_code: 503,
message: I18n.t("errors.maintenance.message"),
help: I18n.t("errors.maintenance.help"),
}
end
maintenance_string = @settings.get_value("Maintenance Banner").presence || Rails.configuration.maintenance_window
if maintenance_string.present? && cookies[:maintenance_window] != maintenance_string
flash.now[:maintenance] = maintenance_string
end
end
# Show an information page when migration fails and there is a version error.
def migration_error?
render :migration_error, status: 500 unless ENV["DB_MIGRATE_FAILED"].blank?
end
# Determines proper locale to be used by calling user_locale with params based on if room owner exists
def determine_locale(user)
if user && user.language != 'default'
user.language
else
Rails.configuration.default_locale.presence || http_accept_language.language_region_compatible_from(I18n.available_locales)
end
end
# Sets the appropriate locale.
def user_locale(user = current_user)
locale = determine_locale(user)
begin
I18n.locale = locale.tr('-', '_') unless locale.nil?
rescue
# Default to English if there are any issues in language
logger.error("Support: User locale is not supported (#{locale}")
I18n.locale = "en"
end
end
helper_method :user_locale
# Checks to make sure that the admin has changed his password from the default
def check_admin_password
if current_user&.has_role?(:admin) && current_user.email == "admin@example.com" &&
current_user&.greenlight_account? && current_user&.authenticate(Rails.configuration.admin_password_default)
flash.now[:alert] = I18n.t("default_admin",
edit_link: change_password_path(user_uid: current_user.uid)).html_safe
end
end
# Checks if the user is banned and logs him out if he is
def check_user_role
if current_user&.has_role? :denied
session.delete(:user_id)
redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") }
elsif current_user&.has_role? :pending
session.delete(:user_id)
redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") }
end
end
# Relative root helper (when deploying to subdirectory).
def relative_root
Rails.configuration.relative_url_root || ""
end
helper_method :relative_root
# Determines if the BigBlueButton endpoint is configured (or set to default).
def meeting_name_limit
MEETING_NAME_LIMIT
end
helper_method :meeting_name_limit
def user_name_limit
USER_NAME_LIMIT
end
helper_method :user_name_limit
def bigbluebutton_endpoint_default?
return false if Rails.configuration.loadbalanced_configuration
Rails.configuration.bigbluebutton_endpoint_default == Rails.configuration.bigbluebutton_endpoint
end
helper_method :bigbluebutton_endpoint_default?
def allow_greenlight_accounts?
return Rails.configuration.allow_user_signup unless Rails.configuration.loadbalanced_configuration
return false unless @user_domain && !@user_domain.empty? && Rails.configuration.allow_user_signup
return false if @user_domain == "greenlight"
# Proceed with retrieving the provider info
begin
provider_info = retrieve_provider_info(@user_domain, 'api2', 'getUserGreenlightCredentials')
provider_info['provider'] == 'greenlight'
rescue => e
logger.error "Error in checking if greenlight accounts are allowed: #{e}"
false
end
end
helper_method :allow_greenlight_accounts?
# Determine if Greenlight is configured to allow user signups.
def allow_user_signup?
Rails.configuration.allow_user_signup
end
helper_method :allow_user_signup?
# Gets all configured omniauth providers.
def configured_providers
Rails.configuration.providers.select do |provider|
Rails.configuration.send("omniauth_#{provider}")
end
end
helper_method :configured_providers
# Indicates whether users are allowed to share rooms
def shared_access_allowed
@settings.get_value("Shared Access") == "true"
end
helper_method :shared_access_allowed
# Indicates whether users should consent recoding when joining rooms
def recording_consent_required?
@settings.get_value("Require Recording Consent") == "true"
end
helper_method :recording_consent_required?
# Indicates whether users are allowed to add moderator access codes to rooms
def moderator_code_allowed?
@settings.get_value("Room Configuration Moderator Access Codes") == "optional"
end
helper_method :moderator_code_allowed?
# Returns a list of allowed file types
def allowed_file_types
Rails.configuration.allowed_file_types
end
helper_method :allowed_file_types
# Allows admins to edit a user's details
def can_edit_user?(user_to_edit, editting_user)
return user_to_edit.greenlight_account? if user_to_edit == editting_user
editting_user.admin_of?(user_to_edit, "can_manage_users")
end
helper_method :can_edit_user?
# Returns the page that the logo redirects to when clicked on
def home_page
return admins_path if current_user.has_role? :super_admin
return current_user.main_room if current_user.role.get_permission("can_create_rooms")
cant_create_rooms_path
end
helper_method :home_page
# Parses the url for the user domain
def parse_user_domain(hostname)
return hostname.split('.').first if Rails.configuration.url_host.empty?
Rails.configuration.url_host.split(',').each do |url_host|
return hostname.chomp(url_host).chomp('.') if hostname.include?(url_host)
end
''
end
# Include user domain in lograge logs
def append_info_to_payload(payload)
super
payload[:host] = @user_domain
end
# Manually handle BigBlueButton errors
rescue_from BigBlueButton::BigBlueButtonException do |ex|
logger.error "BigBlueButtonException: #{ex}"
render "errors/bigbluebutton_error"
end
# Manually deal with 401 errors
rescue_from CanCan::AccessDenied do |_exception|
if current_user
render "errors/greenlight_error"
else
# Store the current url as a cookie to redirect to after sigining in
cookies[:return_to] = request.url
# Get the correct signin path
path = if allow_greenlight_accounts?
signin_path
elsif Rails.configuration.loadbalanced_configuration
"#{Rails.configuration.relative_url_root}/auth/bn_launcher"
else
signin_path
end
redirect_to path
end
end
private
def check_provider_exists
# Checks to see if the user exists
begin
# Check if the session has already checked that the user exists
# and return true if they did for this domain
return if session[:provider_exists] == @user_domain
retrieve_provider_info(@user_domain, 'api2', 'getUserGreenlightCredentials')
# Add a session variable if the provider exists
session[:provider_exists] = @user_domain
rescue => e
logger.error "Error in retrieve provider info: #{e}"
@hide_signin = true
case e.message
when "No user with that id exists"
set_default_settings
render "errors/greenlight_error", locals: { message: I18n.t("errors.not_found.user_not_found.message"),
help: I18n.t("errors.not_found.user_not_found.help") }
when "Provider not included."
set_default_settings
render "errors/greenlight_error", locals: { message: I18n.t("errors.not_found.user_missing.message"),
help: I18n.t("errors.not_found.user_missing.help") }
when "That user has no configured provider."
if Setting.exists?(provider: @user_domain)
# Keep the branding
@settings = Setting.find_by(provider: @user_domain)
else
set_default_settings
end
render "errors/greenlight_error", locals: { status_code: 501,
message: I18n.t("errors.no_provider.message"),
help: I18n.t("errors.no_provider.help") }
else
set_default_settings
render "errors/greenlight_error", locals: { status_code: 500, message: I18n.t("errors.internal.message"),
help: I18n.t("errors.internal.help"), display_back: true }
end
end
end
def set_default_settings
# Use the default site settings
@user_domain = "greenlight"
@settings = Setting.find_or_create_by(provider: @user_domain)
def qrcode_generation_enabled?
Rails.configuration.enable_qrcode_generation
end
helper_method :qrcode_generation_enabled?
end
+383
View File
@@ -0,0 +1,383 @@
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2016 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/>.
class BbbController < ApplicationController
include BbbApi
before_action :authorize_recording_owner!, only: [:update_recordings, :delete_recordings]
before_action :load_and_authorize_room_owner!, only: [:end]
skip_before_action :verify_authenticity_token, only: :callback
# GET /:resource/:id/join
# GET /:resource/:room_id/:id/join
def join
if params[:name].blank?
return render_bbb_response(
messageKey: "missing_parameter",
message: "user name was not included",
status: :unprocessable_entity
)
elsif params[:name].size > user_name_limit
return render_bbb_response(
messageKey: "invalid_parameter",
message: "user name is too long",
status: :unprocessable_entity
)
elsif params[:id].size > meeting_name_limit
return render_bbb_response(
messageKey: "invalid_parameter",
message: "meeting name is too long",
status: :unprocessable_entity
)
else
if params[:room_id]
user = User.find_by encrypted_id: params[:room_id]
if !user
return render_bbb_response(
messageKey: "not_found",
message: "User Not Found",
status: :not_found
)
end
meeting_id = "#{params[:room_id]}-#{params[:id]}"
meeting_name = params[:id]
meeting_path = "#{URI.encode(params[:room_id])}/#{URI.encode(params[:id]).gsub('/','%2F')}"
else
user = User.find_by encrypted_id: params[:id]
meeting_id = params[:id]
meeting_path = URI.encode(meeting_id).gsub('/','%2F')
end
options = if user
{
wait_for_moderator: true,
meeting_recorded: true,
meeting_name: meeting_name,
room_owner: params[:room_id],
user_is_moderator: current_user == user
}
else
{
user_is_moderator: true
}
end
base_url = "#{request.base_url}#{relative_root}/#{params[:resource]}/#{meeting_path}"
options[:meeting_logout_url] = base_url
options[:hook_url] = "#{base_url}/callback"
options[:moderator_message] = t('moderator_default_message', url: "<a href=\"#{base_url}\" target=\"_blank\"><u>#{base_url}</u></a>")
bbb_res = bbb_join_url(
meeting_id,
params[:name],
options
)
# the user can join the meeting
if user
if bbb_res[:returncode] && current_user == user
JoinMeetingJob.perform_later(user, params[:id], base_url)
WaitingList.empty(options[:room_owner], options[:meeting_name])
# the user can't join because they are on mobile and HTML5 is not enabled.
elsif bbb_res[:messageKey] == 'unable_to_join'
NotifyUserCantJoinJob.perform_later(user.encrypted_id, params[:id], params[:name])
# user will be waiting for a moderator
else
NotifyUserWaitingJob.perform_later(user.encrypted_id, params[:id], params[:name])
end
end
render_bbb_response bbb_res, bbb_res[:response]
end
end
# POST /:resource/:room_id/:id/callback
# Endpoint for webhook calls from BigBlueButton
def callback
# respond with 200 anyway so BigBlueButton knows the hook call was ok
# but abort execution
head(:ok) && return unless validate_checksum
begin
event = params['event']
data = event.is_a?(String) ? JSON.parse(params['event']) : event
treat_callback_event(data)
rescue Exception => e
logger.error "Error parsing webhook data. Data: #{data}, exception: #{e.inspect}"
# respond with 200 anyway so BigBlueButton knows the hook call was ok
head(:ok) && return
end
end
# DELETE /rooms/:room_id/:id/end
def end
load_and_authorize_room_owner!
bbb_res = bbb_end_meeting "#{@user.encrypted_id}-#{params[:id]}"
if bbb_res[:returncode] || bbb_res[:status] == :not_found
EndMeetingJob.perform_later(@user.encrypted_id, params[:id])
bbb_res[:status] = :ok
end
render_bbb_response bbb_res
end
# GET /rooms/:room_id/recordings
# GET /rooms/:room_id/:id/recordings
def recordings
load_room!
# bbb_res = bbb_get_recordings "#{@user.encrypted_id}-#{params[:id]}"
options = { "meta_room-id": @user.encrypted_id }
if params[:id]
options["meta_meeting-name"] = params[:id]
end
bbb_res = bbb_get_recordings(options)
render_bbb_response bbb_res, bbb_res[:recordings]
end
# PATCH /rooms/:room_id/recordings/:record_id
# PATCH /rooms/:room_id/:id/recordings/:record_id
def update_recordings
published = params[:published] == 'true'
metadata = params.select{ |k, v| k.match(/^meta_/) }
bbb_res = bbb_update_recordings(params[:record_id], published, metadata)
if bbb_res[:returncode]
RecordingUpdatesJob.perform_later(@user.encrypted_id, params[:record_id])
end
render_bbb_response bbb_res
end
# DELETE /rooms/:room_id/recordings/:record_id
# DELETE /rooms/:room_id/:id/recordings/:record_id
def delete_recordings
recording = bbb_get_recordings({recordID: params[:record_id]})[:recordings].first
bbb_res = bbb_delete_recordings(params[:record_id])
if bbb_res[:returncode]
RecordingDeletesJob.perform_later(@user.encrypted_id, params[:record_id], recording[:metadata][:"meeting-name"])
end
render_bbb_response bbb_res
end
# POST /rooms/:room_id/recordings/:record_id
# POST /rooms/:room_id/:id/recordings/:record_id
def youtube_publish
# If we can't get the client, then they don't have a Youtube account.
begin
client = Yt::Account.new(access_token: current_user.token)
video = client.upload_video(get_webcams_url(params[:record_id]),
title: params[:video_title],
description: t('youtube_description', url: 'https://bigbluebutton.org/'),
privacy_status: params[:privacy_status])
rescue => e
errors = e.response_body['error']['errors']
# Many complications, start by getting them to refresh their token.
if errors.length > 1
redirect_url = user_login_url
else
error = errors[0]
if error['message'] == "Unauthorized"
redirect_url = 'https://m.youtube.com/create_channel'
else
# In this case, they don't have a youtube channel connected to their account, so prompt to create one.
redirect_url = user_login_url
end
end
end
render json: {:url => redirect_url}
end
# POST /rooms/:room_id/recordings/can_upload
def can_upload
# The recording is uploadable if it contains webcam data and they are logged in through Google.
if Rails.configuration.enable_youtube_uploading == false then
uploadable = 'uploading_disabled'
elsif current_user.provider != 'google'
uploadable = 'invalid_provider'
else
uploadable = (Faraday.head(get_webcams_url(params[:rec_id])).status == 200 && current_user.provider == 'google').to_s
end
render json: {:uploadable => uploadable}
end
def get_webcams_url(recording_id)
uri = URI.parse(Rails.configuration.bigbluebutton_endpoint)
uri.scheme + '://' + uri.host + '/presentation/' + recording_id + '/video/webcams.webm'
end
private
def load_room!
@user = User.find_by encrypted_id: params[:room_id]
if !@user
render head(:not_found) && return
end
end
def load_and_authorize_room_owner!
load_room!
if !current_user || current_user != @user
render head(:unauthorized) && return
end
end
def authorize_recording_owner!
load_and_authorize_room_owner!
recordings = bbb_get_recordings({recordID: params[:record_id]})[:recordings]
recordings.each do |recording|
if recording[:recordID] == params[:record_id]
return true
end
end
render head(:not_found) && return
end
def render_bbb_response(bbb_res, response={})
@messageKey = bbb_res[:messageKey]
@message = bbb_res[:message]
@status = bbb_res[:status]
@response = response
render status: @status
end
def read_body(request)
request.body.read.force_encoding("UTF-8")
end
def treat_callback_event(event)
# Check if the event is a BigBlueButton 2.0 event.
if event.has_key?('envelope')
eventName = (event.present? && event['envelope'].present?) ? event['envelope']['name'] : nil
else # The event came from BigBlueButton 1.1 (or earlier).
eventName = (event.present? && event['header'].present?) ? event['header']['name'] : nil
end
# a recording is ready
if eventName == "publish_ended"
if event['payload'] && event['payload']['metadata'] && event['payload']['meeting_id']
token = event['payload']['metadata'][META_TOKEN]
room_id = event['payload']['metadata']['room-id']
record_id = event['payload']['meeting_id']
duration_data = event['payload']['duration']
# the webhook event doesn't have all the data we need, so we need
# to send a getRecordings anyway
# TODO: if the webhooks included all data in the event we wouldn't need this
rec_info = bbb_get_recordings({recordID: record_id})
rec_info = rec_info[:recordings].first
RecordingCreatedJob.perform_later(token, room_id, parse_recording_for_view(rec_info))
rec_info[:duration] = duration_data.to_json
# send an email to the owner of this recording, if defined
if Rails.configuration.mail_notifications
owner = User.find_by(encrypted_id: room_id)
RecordingReadyEmailJob.perform_later(owner, parse_recording_for_view(rec_info)) if owner.present?
end
else
logger.error "Bad format for event #{event}, won't process"
end
elsif eventName == "meeting_created_message" || eventName == "MeetingCreatedEvtMsg"
# Fire an Actioncable event that updates _previously_joined for the client.
actioncable_event('create')
elsif eventName == "meeting_destroyed_event" || eventName == "MeetingEndedEvtMsg"
actioncable_event('destroy')
# Since the meeting is destroyed we have no way get the callback url to remove the meeting, so we must build it.
remove_url = build_callback_url(params[:id], params[:room_id])
# Remove webhook for the meeting.
webhook_remove(remove_url)
elsif eventName == "user_joined_message"
actioncable_event('join', {user_id: event['payload']['user']['extern_userid'], user: event['payload']['user']['name'], role: event['payload']['user']['role']})
elsif eventName == "UserJoinedMeetingEvtMsg"
actioncable_event('join', {user_id: event['core']['body']['intId'], user: event['core']['body']['name'], role: event['core']['body']['role']})
elsif eventName == "user_left_message"
actioncable_event('leave', {user_id: event['payload']['user']['extern_userid']})
elsif eventName == "UserLeftMeetingEvtMsg"
actioncable_event('leave', {user_id: event['core']['body']['intId']})
else
logger.info "Callback event will not be treated. Event name: #{eventName}"
end
render head(:ok) && return
end
def build_callback_url(id, room_id)
"#{request.base_url}#{relative_root}/rooms/#{room_id}/#{URI.encode(id)}/callback"
end
def actioncable_event(method, data = {})
data = {method: method, meeting: params[:id], room: params[:room_id]}.merge(data)
ActionCable.server.broadcast('refresh_meetings', data)
end
# Validates the checksum received in a callback call.
# If the checksum doesn't match, renders an ok and aborts execution.
def validate_checksum
secret = ENV['BIGBLUEBUTTON_SECRET']
checksum = params["checksum"]
return false unless checksum
# Message is only encoded if it comes from the bbb-webhooks node application.
# The post process script does not encode it's response body.
begin
# Decode and break the body into parts.
parts = URI.decode_www_form(read_body(request))
# Convert the data into the correct checksum format, replace ruby hash arrows.
converted_data = {parts[0][0]=>parts[0][1],parts[1][0]=>parts[1][1].to_i}.to_s.gsub!('=>', ':')
# Manually remove the space between the two elements.
converted_data[converted_data.rindex("timestamp") - 2] = ''
callback_url = uri_remove_param(request.original_url, "checksum")
checksum_str = "#{callback_url}#{converted_data}#{secret}"
rescue
# Data was not recieved encoded (sent from post process script).
data = read_body(request)
callback_url = uri_remove_param(request.original_url, "checksum")
checksum_str = "#{callback_url}#{data}#{secret}"
end
calculated_checksum = Digest::SHA1.hexdigest(checksum_str)
if calculated_checksum != checksum
logger.error "Checksum did not match. Calculated: #{calculated_checksum}, received: #{checksum}"
false
else
true
end
end
# Removes parameters from an URI
def uri_remove_param(uri, params = nil)
return uri unless params
params = Array(params)
uri_parsed = URI.parse(uri)
return uri unless uri_parsed.query
new_params = uri_parsed.query.gsub(/&amp;/, '&').split('&').reject { |q| params.include?(q.split('=').first) }
uri = uri.split('?').first
if new_params.count > 0
"#{uri}?#{new_params.join('&')}"
else
uri
end
end
end
-130
View File
@@ -1,130 +0,0 @@
# 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/>.
module Authenticator
extend ActiveSupport::Concern
# Logs a user into GreenLight.
def login(user)
migrate_twitter_user(user)
session[:user_id] = user.id
user.update(last_login: Time.zone.now)
logger.info("Support: #{user.email} has successfully logged in.")
# If there are not terms, or the user has accepted them, check for email verification
if !Rails.configuration.terms || user.accepted_terms
check_email_verified(user)
else
redirect_to terms_path
end
end
# If email verification is disabled, or the user has verified, go to their room
def check_email_verified(user)
# Admin users should be redirected to the admin page
if user.has_role? :super_admin
redirect_to admins_path
elsif user.activated?
# Dont redirect to any of these urls
dont_redirect_to = [root_url, signin_url, ldap_signin_url, ldap_callback_url, signup_url, unauthorized_url,
internal_error_url, not_found_url]
unless ENV['OAUTH2_REDIRECT'].nil?
dont_redirect_to.push(File.join(ENV['OAUTH2_REDIRECT'], "auth", "openid_connect", "callback"))
end
url = if cookies[:return_to] && !dont_redirect_to.include?(cookies[:return_to])
cookies[:return_to]
elsif user.role.get_permission("can_create_rooms")
user.main_room
else
cant_create_rooms_path
end
# Delete the cookie if it exists
cookies.delete :return_to if cookies[:return_to]
redirect_to url
else
session[:user_id] = nil
user.create_activation_token
redirect_to account_activation_path(digest: user.activation_digest)
end
end
def ensure_unauthenticated_except_twitter
redirect_to current_user.main_room || root_path if current_user && params[:old_twitter_user_id].nil?
end
# Logs current user out of GreenLight.
def logout
session.delete(:user_id) if current_user
end
# Check if the user is using local accounts
def auth_changed_to_local?(user)
Rails.configuration.loadbalanced_configuration && user.social_uid.present? && allow_greenlight_accounts?
end
# Check if the user exists under the same email with no social uid and that social accounts are allowed
def auth_changed_to_social?(email)
Rails.configuration.loadbalanced_configuration &&
User.exists?(email: email, provider: @user_domain, social_uid: nil) &&
!allow_greenlight_accounts?
end
# Sets the initial user role based on the email mapping
def initial_user_role(email)
mapping = @settings.get_value("Email Mapping")
return "user" unless mapping.present?
mapping.split(",").each do |map|
email_role = map.split("=")
return email_role[1] if email.ends_with?(email_role[0])
end
"user" # default to user if role not found
end
private
# Migrates all of the twitter users rooms to the new account
def migrate_twitter_user(user)
if !session["old_twitter_user_id"].nil? && user.provider != "twitter"
old_user = User.find(session["old_twitter_user_id"])
old_user.rooms.each do |room|
room.owner = user
room.name = "Old #{room.name}" if room.id == old_user.main_room.id
room.save!
end
# Query for the old user again so the migrated rooms don't get deleted
old_user.reload
old_user.destroy!
session["old_twitter_user_id"] = nil
flash[:success] = I18n.t("registration.deprecated.merge_success")
end
end
end
-146
View File
@@ -1,146 +0,0 @@
# 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 'bigbluebutton_api'
module BbbServer
extend ActiveSupport::Concern
include BbbApi
META_LISTED = "gl-listed"
# Checks if a room is running on the BigBlueButton server.
def room_running?(bbb_id)
bbb_server.is_meeting_running?(bbb_id)
end
# Returns a list of all running meetings
def all_running_meetings
bbb_server.get_meetings
end
def get_recordings(meeting_id)
bbb_server.get_recordings(meetingID: meeting_id)
end
def get_multiple_recordings(meeting_ids)
bbb_server.get_recordings(meetingID: meeting_ids)
end
# Returns a URL to join a user into a meeting.
def join_path(room, name, options = {}, uid = nil)
# Create the meeting, even if it's running
start_session(room, options)
# Determine the password to use when joining.
password = options[:user_is_moderator] ? room.moderator_pw : room.attendee_pw
# Generate the join URL.
join_opts = {}
join_opts[:userID] = uid if uid
join_opts[:join_via_html5] = true
join_opts[:avatarURL] = options[:avatarURL] if options[:avatarURL].present?
join_opts[:createTime] = room.last_session.to_datetime.strftime("%Q") if room.last_session
bbb_server.join_meeting_url(room.bbb_id, name, password, join_opts)
end
# Creates a meeting on the BigBlueButton server.
def start_session(room, options = {})
create_options = {
record: options[:record].to_s,
logoutURL: options[:meeting_logout_url] || '',
moderatorPW: room.moderator_pw,
attendeePW: room.attendee_pw,
moderatorOnlyMessage: options[:moderator_message],
"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]
}
create_options[:muteOnStart] = options[:mute_on_start] if options[:mute_on_start]
create_options[:guestPolicy] = "ASK_MODERATOR" if options[:require_moderator_approval]
# Send the create request.
begin
meeting = if room.presentation.attached?
modules = BigBlueButton::BigBlueButtonModules.new
url = rails_blob_url(room.presentation).gsub("&", "%26")
logger.info("Support: Room #{room.uid} starting using presentation: #{url}")
modules.add_presentation(:url, url)
bbb_server.create_meeting(room.name, room.bbb_id, create_options, modules)
else
bbb_server.create_meeting(room.name, room.bbb_id, create_options)
end
unless meeting[:messageKey] == 'duplicateWarning'
room.update_attributes(sessions: room.sessions + 1, last_session: DateTime.strptime(meeting[:createTime].to_s, "%Q"))
end
rescue BigBlueButton::BigBlueButtonException => e
puts "BigBlueButton failed on create: #{e.key}: #{e.message}"
raise e
end
end
# Gets the number of recordings for this room
def recording_count(bbb_id)
bbb_server.get_recordings(meetingID: bbb_id)[:recordings].length
end
# Update a recording from a room
def update_recording(record_id, meta)
meta[:recordID] = record_id
bbb_server.send_api_request("updateRecordings", meta)
end
# Update a recording from a room
def publish_recording(record_id)
bbb_server.publish_recordings(record_id, true)
end
# Update a recording from a room
def unpublish_recording(record_id)
bbb_server.publish_recordings(record_id, false)
end
# Protect a recording
def protect_recording(record_id, meta = {})
meta[:recordID] = record_id
meta[:protect] = true
bbb_server.send_api_request("updateRecordings", meta)
end
# Unprotect a recording
def unprotect_recording(record_id, meta = {})
meta[:recordID] = record_id
meta[:protect] = false
bbb_server.send_api_request("updateRecordings", meta)
end
# Deletes a recording from a room.
def delete_recording(record_id)
bbb_server.delete_recordings(record_id)
end
# Deletes all recordings associated with the room.
def delete_all_recordings(bbb_id)
record_ids = bbb_server.get_recordings(meetingID: bbb_id)[:recordings].pluck(:recordID)
bbb_server.delete_recordings(record_ids) unless record_ids.empty?
end
end

Some files were not shown because too many files have changed in this diff Show More