diff --git a/Makefile b/Makefile index 03eb0087d..7d945eb01 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ BROWSERIFY = ./node_modules/.bin/browserify UGLIFYJS = ./node_modules/.bin/uglifyjs EXORCIST = ./node_modules/.bin/exorcist CLEANCSS = ./node_modules/.bin/cleancss -CSS_FILES = font.css toastr.css main.css videolayout_default.css font-awesome.css jquery-impromptu.css modaldialog.css notice.css popup_menu.css login_menu.css popover.css jitsi_popover.css contact_list.css chat.css welcome_page.css settingsmenu.css feedback.css jquery.contextMenu.css +CSS_FILES = font.css toastr.css main.css overlay.css videolayout_default.css font-awesome.css jquery-impromptu.css modaldialog.css notice.css popup_menu.css login_menu.css popover.css jitsi_popover.css contact_list.css chat.css welcome_page.css settingsmenu.css feedback.css jquery.contextMenu.css DEPLOY_DIR = libs BROWSERIFY_FLAGS = -d OUTPUT_DIR = . diff --git a/app.js b/app.js index 1f84d4b3c..2b592ff25 100644 --- a/app.js +++ b/app.js @@ -23,6 +23,7 @@ import conference from './conference'; import API from './modules/API/API'; import UIEvents from './service/UI/UIEvents'; +import getTokenData from "./modules/TokenData/TokenData"; /** * Tries to push history state with the following parameters: @@ -84,10 +85,24 @@ const APP = { require("./modules/keyboardshortcut/keyboardshortcut"); this.translation = require("./modules/translation/translation"); this.configFetch = require("./modules/config/HttpConfigFetch"); + this.tokenData = getTokenData(); } }; +/** + * If JWT token data it will be used for local user settings + */ +function setTokenData() { + let localUser = APP.tokenData.caller; + if(localUser) { + APP.settings.setEmail((localUser.getEmail() || "").trim()); + APP.settings.setAvatarUrl((localUser.getAvatarUrl() || "").trim()); + APP.settings.setDisplayName((localUser.getName() || "").trim()); + } +} + function init() { + setTokenData(); var isUIReady = APP.UI.start(); if (isUIReady) { APP.conference.init({roomName: buildRoomName()}).then(function () { @@ -100,6 +115,11 @@ function init() { APP.keyboardshortcut.init(); }).catch(function (err) { + APP.UI.hideRingOverLay(); + APP.API.sendPostisMessage({ + method: 'video-conference-left', + params: {roomName: APP.conference.roomName} + }); console.error(err); }); } @@ -151,7 +171,7 @@ $(document).ready(function () { APP.translation.init(settings.getLanguage()); - APP.API.init(); + APP.API.init(APP.tokenData.externalAPISettings); obtainConfigAndInit(); }); diff --git a/conference.js b/conference.js index 82537e97c..169d030ab 100644 --- a/conference.js +++ b/conference.js @@ -26,6 +26,18 @@ let currentAudioInputDevices, currentVideoInputDevices; import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/LargeVideo"; +/** + * Known custom conference commands. + */ +const commands = { + CONNECTION_QUALITY: "stats", + EMAIL: "email", + AVATAR_URL: "avatar-url", + ETHERPAD: "etherpad", + SHARED_VIDEO: "shared-video", + CUSTOM_ROLE: "custom-role" +}; + /** * Open Connection. When authentication failed it shows auth dialog. * @param roomName the room name to use @@ -44,17 +56,13 @@ function connect(roomName) { } /** - * Share email with other users. - * @param emailCommand the email command - * @param {string} email new email + * Share data to other users. + * @param command the command + * @param {string} value new value */ -function sendEmail (emailCommand, email) { - room.sendCommand(emailCommand, { - value: email, - attributes: { - id: room.myUserId() - } - }); +function sendData (command, value) { + room.removeCommand(command); + room.sendCommand(command, {value: value}); } /** @@ -144,7 +152,12 @@ function maybeRedirectToWelcomePage() { * @returns Promise. */ function disconnectAndShowFeedback(requestFeedback) { + APP.UI.hideRingOverLay(); connection.disconnect(); + APP.API.sendPostisMessage({ + method: 'video-conference-left', + params: {roomName: APP.conference.roomName} + }); if (requestFeedback) { return APP.UI.requestFeedback(); } else { @@ -209,6 +222,55 @@ function setCurrentMediaDevices(devices) { d => d.kind === 'videoinput'); } +/** + * Changes the email for the local user + * @param email {string} the new email + */ +function changeLocalEmail(email = '') { + email = email.trim(); + + if (email === APP.settings.getEmail()) { + return; + } + + APP.settings.setEmail(email); + APP.UI.setUserEmail(room.myUserId(), email); + sendData(commands.EMAIL, email); +} + + +/** + * Changes the local avatar url for the local user + * @param avatarUrl {string} the new avatar url + */ +function changeLocalAvatarUrl(avatarUrl = '') { + avatarUrl = avatarUrl.trim(); + + if (avatarUrl === APP.settings.getAvatarUrl()) { + return; + } + + APP.settings.setAvatarUrl(avatarUrl); + APP.UI.setUserAvatarUrl(room.myUserId(), avatarUrl); + sendData(commands.AVATAR_URL, avatarUrl); +} + +/** + * Changes the display name for the local user + * @param nickname {string} the new display name + */ +function changeLocalDisplayName(nickname = '') { + nickname = nickname.trim(); + + if (nickname === APP.settings.getDisplayName()) { + return; + } + + APP.settings.setDisplayName(nickname); + room.setDisplayName(nickname); + APP.UI.changeDisplayName(APP.conference.localId, nickname); +} + class ConferenceConnector { constructor(resolve, reject) { this._resolve = resolve; @@ -227,6 +289,7 @@ class ConferenceConnector { } _onConferenceFailed(err, ...params) { console.error('CONFERENCE FAILED:', err, ...params); + APP.UI.hideRingOverLay(); switch (err) { // room is locked by the password case ConferenceErrors.PASSWORD_REQUIRED: @@ -412,6 +475,9 @@ export default { this._createRoom(tracks); this.isDesktopSharingEnabled = JitsiMeetJS.isDesktopSharingEnabled(); + if(this.isDesktopSharingEnabled) + APP.API.addPostisMessageListener('toggle-share-screen', + () => this.toggleScreenSharing()); // if user didn't give access to mic or camera or doesn't have // them at all, we disable corresponding toolbar buttons @@ -851,13 +917,7 @@ export default { /** * Known custom conference commands. */ - defaults: { - CONNECTION_QUALITY: "stats", - EMAIL: "email", - ETHERPAD: "etherpad", - SHARED_VIDEO: "shared-video", - CUSTOM_ROLE: "custom-role" - }, + defaults: commands, /** * Receives notifications from other participants about commands aka * custom events (sent by sendCommand or sendCommandOnce methods). @@ -910,7 +970,11 @@ export default { this._room = room; // FIXME do not use this let email = APP.settings.getEmail(); - email && sendEmail(this.commands.defaults.EMAIL, email); + email && sendData(this.commands.defaults.EMAIL, email); + + let avatarUrl = APP.settings.getAvatarUrl(); + avatarUrl && sendData(this.commands.defaults.AVATAR_URL, + avatarUrl); let nick = APP.settings.getDisplayName(); if (config.useNicks && !nick) { @@ -1093,6 +1157,10 @@ export default { // add local streams when joined to the conference room.on(ConferenceEvents.CONFERENCE_JOINED, () => { APP.UI.mucJoined(); + APP.API.sendPostisMessage({ + method: 'video-conference-joined', + params: {roomName: APP.conference.roomName} + }); }); room.on( @@ -1297,33 +1365,20 @@ export default { APP.UI.initEtherpad(value); }); - APP.UI.addListener(UIEvents.EMAIL_CHANGED, (email = '') => { - email = email.trim(); - - if (email === APP.settings.getEmail()) { - return; - } - - APP.settings.setEmail(email); - APP.UI.setUserAvatar(room.myUserId(), email); - sendEmail(this.commands.defaults.EMAIL, email); - }); - room.addCommandListener(this.commands.defaults.EMAIL, (data) => { - APP.UI.setUserAvatar(data.attributes.id, data.value); + APP.UI.addListener(UIEvents.EMAIL_CHANGED, changeLocalEmail); + room.addCommandListener(this.commands.defaults.EMAIL, (data, from) => { + APP.UI.setUserEmail(from, data.value); }); - APP.UI.addListener(UIEvents.NICKNAME_CHANGED, (nickname = '') => { - nickname = nickname.trim(); + APP.UI.addListener(UIEvents.AVATAR_URL_CHANGED, changeLocalAvatarUrl); - if (nickname === APP.settings.getDisplayName()) { - return; - } - - APP.settings.setDisplayName(nickname); - room.setDisplayName(nickname); - APP.UI.changeDisplayName(APP.conference.localId, nickname); + room.addCommandListener(this.commands.defaults.AVATAR_URL, + (data, from) => { + APP.UI.setUserAvatarUrl(from, data.value); }); + APP.UI.addListener(UIEvents.NICKNAME_CHANGED, changeLocalDisplayName); + APP.UI.addListener(UIEvents.START_MUTED_CHANGED, (startAudioMuted, startVideoMuted) => { room.setStartMutedPolicy({ diff --git a/connection_optimization/do_external_connect.js b/connection_optimization/do_external_connect.js index 98014eafb..77b73ece9 100644 --- a/connection_optimization/do_external_connect.js +++ b/connection_optimization/do_external_connect.js @@ -16,12 +16,13 @@ * Executes createConnectionExternally function. */ (function () { - var params = getConfigParamsFromUrl(); - + var hashParams = getConfigParamsFromUrl("hash", true); + var searchParams = getConfigParamsFromUrl("search", true); + //Url params have higher proirity than config params var url = config.externalConnectUrl; - if(params.hasOwnProperty('config.externalConnectUrl')) - url = params["config.externalConnectUrl"]; + if(hashParams.hasOwnProperty('config.externalConnectUrl')) + url = hashParams["config.externalConnectUrl"]; /** * Check if connect from connection.js was executed and executes the handler @@ -57,7 +58,8 @@ url += "?room=" + room_name; - var token = params["config.token"] || config.token; + var token = hashParams["config.token"] || config.token || + searchParams.jwt; if(token) url += "&token=" + token; diff --git a/css/main.css b/css/main.css index 065be9774..750dde54e 100644 --- a/css/main.css +++ b/css/main.css @@ -33,6 +33,10 @@ html, body{ display:none; } +#header_container { + z-index: 1014; +} + .toolbar_span { display: inline-block; position: relative; diff --git a/css/overlay.css b/css/overlay.css new file mode 100644 index 000000000..feb4200c8 --- /dev/null +++ b/css/overlay.css @@ -0,0 +1,51 @@ + +.overlay { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 1013; + background: #000000; /* Old browsers */ + opacity: 0.75; + display: block; +} + +.overlay_container { + width: 100%; + height: 100%; + position: fixed; + z-index: 1013; +} + +.overlay_content { + color: #fff; + font-weight: normal; + font-size: 20px; + text-align: center; + width: 400px; + height: 250px; + top: 50%; + left: 50%; + position:absolute; + margin-top: -125px; + margin-left: -200px; +} + +.overlay_avatar { + width: 200px; + height: 200px; + position: relative; + border-radius: 100px; + z-index: 1013; + float: left; + margin-left: 100px; +} + +.overlay_text { + position: relative; + width: 400px; + z-index: 1013; + margin-top: 20px; + float: left; +} diff --git a/css/popover.css b/css/popover.css index 82dbdabe4..a72f9706a 100644 --- a/css/popover.css +++ b/css/popover.css @@ -2,7 +2,7 @@ position: absolute; top: 0; left: 0; - z-index: 1010; + z-index: 1015; display: none; max-width: 300px; min-width: 100px; @@ -121,4 +121,4 @@ border-right-width: 0; border-left-color: #ffffff; bottom: -10px; -} \ No newline at end of file +} diff --git a/css/toastr.css b/css/toastr.css index d86235a9f..c58653f3a 100644 --- a/css/toastr.css +++ b/css/toastr.css @@ -84,7 +84,7 @@ button.toast-close-button { } #toast-container { position: fixed; - z-index: 999999; + z-index: 1012; /*overrides*/ } diff --git a/css/videolayout_default.css b/css/videolayout_default.css index 4767ec059..9d16b77e2 100644 --- a/css/videolayout_default.css +++ b/css/videolayout_default.css @@ -468,7 +468,7 @@ position: absolute; width: 100%; top:50%; - z-index: 10000; + z-index: 1011; font-weight: 600; font-size: 14px; text-align: center; @@ -488,7 +488,7 @@ background: rgba(0,0,0,.5); padding: 10px; color: rgba(255,255,255,.5); - z-index: 10000; + z-index: 1011; } .centeredVideoLabel { @@ -506,7 +506,7 @@ margin-left: auto; background: rgba(0,0,0,.5); color: #FFF; - z-index: 10000; + z-index: 1011; border-radius: 2px; -webkit-transition: all 2s 2s linear; transition: all 2s 2s linear; @@ -522,4 +522,4 @@ } .hidden { -} \ No newline at end of file +} diff --git a/debian/jitsi-meet-tokens.postinst b/debian/jitsi-meet-tokens.postinst index d298316ab..fe9b555ea 100644 --- a/debian/jitsi-meet-tokens.postinst +++ b/debian/jitsi-meet-tokens.postinst @@ -67,8 +67,8 @@ case "$1" in sed -i 's/ --modules_enabled = { "token_verification" }/ modules_enabled = { "token_verification" }/g' $PROSODY_HOST_CONFIG # Install luajwt - if ! luarocks install luajwt; then - echo "Failed to install luajwt - try installing it manually" + if ! luarocks install jwt; then + echo "Failed to install jwt - try installing it manually" fi if [ -x "/etc/init.d/prosody" ]; then @@ -85,7 +85,7 @@ case "$1" in else echo "Prosody config not found at $PROSODY_HOST_CONFIG - unable to auto-configure token authentication" fi - + ;; abort-upgrade|abort-remove|abort-deconfigure) diff --git a/index.html b/index.html index c6caf01c5..b05cf32a3 100644 --- a/index.html +++ b/index.html @@ -241,6 +241,7 @@
+