From 7819f425d86eb908dc8192d303bef34c74f36779 Mon Sep 17 00:00:00 2001 From: Maxim Khlobystov Date: Mon, 21 Aug 2017 11:42:10 -0400 Subject: [PATCH 01/51] Added Google Dev and Firefox Nightly to the browsers list. --- bigbluebutton-html5/tests/webdriverio/wdio.conf.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/bigbluebutton-html5/tests/webdriverio/wdio.conf.js b/bigbluebutton-html5/tests/webdriverio/wdio.conf.js index df609a1a0a..7022f70108 100644 --- a/bigbluebutton-html5/tests/webdriverio/wdio.conf.js +++ b/bigbluebutton-html5/tests/webdriverio/wdio.conf.js @@ -2,14 +2,28 @@ exports.config = { specs: ['tests/webdriverio/specs/**/*.spec.js'], capabilities: { chromeBrowser: { + desiredCapabilities: { + browserName: 'chrome' + } + }, + chromeDevBrowser: { desiredCapabilities: { browserName: 'chrome', + chromeOptions: { + binary: '/opt/google/chrome-unstable/google-chrome-unstable' + } } }, firefoxBrowser: { desiredCapabilities: { browserName: 'firefox' } + }, + firefoxNightlyBrowser: { + desiredCapabilities: { + browserName: 'firefox', + firefox_binary: '/usr/lib/firefox-trunk/firefox-trunk' + } } }, baseUrl: 'http://localhost:8080', From 0d7072f6c7fc82d4ffd5aa111c279150883914e2 Mon Sep 17 00:00:00 2001 From: Maxim Khlobystov Date: Mon, 21 Aug 2017 14:29:25 -0400 Subject: [PATCH 02/51] Put the logic of typing a username into a separate function, thus avoiding repetition. --- bigbluebutton-html5/tests/webdriverio/specs/login.spec.js | 8 ++++++-- bigbluebutton-html5/tests/webdriverio/utils.js | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/bigbluebutton-html5/tests/webdriverio/specs/login.spec.js b/bigbluebutton-html5/tests/webdriverio/specs/login.spec.js index bff08dfc9c..59656cbd17 100644 --- a/bigbluebutton-html5/tests/webdriverio/specs/login.spec.js +++ b/bigbluebutton-html5/tests/webdriverio/specs/login.spec.js @@ -19,8 +19,12 @@ describe('Landing page', function () { function () { LandingPage.open(); - chromeBrowser.setValue(LandingPage.usernameInputSelector, 'Maxim'); - firefoxBrowser.setValue(LandingPage.usernameInputSelector, 'Anton'); + utils.setUsername(new Map([ + ['chromeBrowser', 'Alex'], + ['chromeDevBrowser', 'Anton'], + ['firefoxBrowser', 'Danny'], + ['firefoxNightlyBrowser', 'Maxim'] + ])); LandingPage.joinWithButtonClick(); LandingPage.loadedHomePageElement.waitForExist(5000); diff --git a/bigbluebutton-html5/tests/webdriverio/utils.js b/bigbluebutton-html5/tests/webdriverio/utils.js index 209bdc6fe8..edfa3dfd52 100644 --- a/bigbluebutton-html5/tests/webdriverio/utils.js +++ b/bigbluebutton-html5/tests/webdriverio/utils.js @@ -1,6 +1,7 @@ 'use strict'; let chai = require('chai'); +let LandingPage = require('./pageobjects/landing.page'); class Utils { assertTitle(title) { @@ -13,6 +14,9 @@ class Utils { chai.expect(browser.getUrl()[browserName]).to.equal(url); }); } + setUsername(map) { + map.forEach((v, k) => browser.select(k).setValue(LandingPage.usernameInputSelector, v)); + } } module.exports = new Utils(); From 92c9af6d965c8a04be73e1d2e514299694c439a7 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Mon, 28 Aug 2017 07:19:43 -0700 Subject: [PATCH 03/51] add functions to create headers --- .../server/methods/clearPublicChatHistory.js | 10 +---- .../api/2.0/chat/server/methods/sendChat.js | 8 +--- .../2.0/polls/server/methods/publishVote.js | 8 +--- .../2.0/slides/server/methods/switchSlide.js | 4 +- .../2.0/slides/server/modifiers/addSlide.js | 4 +- .../users/server/methods/assignPresenter.js | 8 +--- .../users/server/methods/requestStunTurn.js | 2 +- .../users/server/methods/setEmojiStatus.js | 8 +--- .../api/2.0/users/server/methods/userJoin.js | 8 +--- .../2.0/users/server/methods/userLeaving.js | 8 +--- .../users/server/methods/validateAuthToken.js | 8 +--- .../voice-users/server/methods/muteToggle.js | 8 +--- .../imports/startup/server/redis2x.js | 42 +++++++++++++++++++ 13 files changed, 55 insertions(+), 71 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js index 1cff839e8e..5a78036fba 100644 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js @@ -13,13 +13,7 @@ export default function clearPublicChatHistory(credentials) { const eventName = 'ClearPublicChatHistoryPubMsg'; - const header = { - meetingId, - name: eventName, - userId: requesterUserId, - }; + const payload = {}; - const body = {}; - - return RedisPubSub.publish(CHANNEL, eventName, meetingId, body, header); + return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js index c8c5bfd825..40b12c3166 100755 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js @@ -50,11 +50,5 @@ export default function sendChat(credentials, message) { eventName = 'SendPublicMessagePubMsg'; } - const header = { - meetingId, - name: eventName, - userId: requesterUserId, - }; - - return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, header); + return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, { message: parsedMessage }); } diff --git a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js index 35706f7245..03617522af 100644 --- a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js +++ b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js @@ -29,12 +29,6 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis answerId: pollAnswerId, }; - const header = { - meetingId, - name: EVENT_NAME, - userId: requesterUserId, - }; - const selector = { users: requesterUserId, meetingId, @@ -57,5 +51,5 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis }; Polls.update(selector, modifier, cb); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js index 9805bb8c40..a33fdc3e28 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js @@ -40,12 +40,10 @@ export default function switchSlide(credentials, slideNumber) { 'slide-not-found', `Slide number ${slideNumber} not found in the current presentation`); } - const header = { name: EVENT_NAME, meetingId, userId: requesterUserId }; - const payload = { pageId: Slide.id, presentationId: Presentation.id, }; - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js index 702b2640ad..6e18e339c6 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js @@ -12,13 +12,11 @@ const requestWhiteboardHistory = (meetingId, slideId) => { const CHANNEL = REDIS_CONFIG.channels.toAkkaApps; const EVENT_NAME = 'GetWhiteboardAnnotationsReqMsg'; - const header = { name: EVENT_NAME, meetingId, userId: 'nodeJSapp' }; - const payload = { whiteboardId: slideId, }; - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, { userId: 'nodeJSapp' }, payload); }; const SUPPORTED_TYPES = [SVG, PNG]; diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js index e56361cf49..7f005e9cbf 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js @@ -25,12 +25,6 @@ export default function assignPresenter(credentials, userId) { 'user-not-found', 'You need a valid user to be able to set presenter'); } - const header = { - name: EVENT_NAME, - meetingId, - userId, - }; - const payload = { newPresenterId: userId, newPresenterName: User.name, @@ -41,5 +35,5 @@ export default function assignPresenter(credentials, userId) { Logger.verbose(`User '${userId}' setted as presenter by '${ requesterUserId}' from meeting '${meetingId}'`); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, User.userId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js index f12af05865..638072d133 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js @@ -18,5 +18,5 @@ export default function requestStunTurn(meetingId, requesterUserId) { Logger.verbose(`User '${requesterUserId}' requested stun/turn from meeting '${meetingId}'`); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload); + return RedisPubSub.publishMeetingMessage(CHANNEL, EVENT_NAME, meetingId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js index 193bad74a3..544316450a 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js @@ -19,14 +19,8 @@ export default function setEmojiStatus(credentials, userId, status) { userId, }; - const header = { - meetingId, - name: EVENT_NAME, - userId: requesterUserId, - }; - Logger.verbose(`User '${userId}' emoji status updated to '${status}' by '${ requesterUserId}' from meeting '${meetingId}'`); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js index 2fdac789db..f705681241 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js @@ -17,13 +17,7 @@ export default function userJoin(meetingId, userId, authToken) { authToken, }; - const header = { - name: EVENT_NAME, - meetingId, - userId, - }; - Logger.info(`User '${userId}' is joining meeting '${meetingId}'`); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, userId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js index 37ace7421f..783741dcc3 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js @@ -50,12 +50,6 @@ export default function userLeaving(credentials, userId) { Users.update(selector, modifier, cb); } - const header = { - name: EVENT_NAME, - meetingId, - userId: requesterUserId, - }; - const payload = { userId, sessionId: meetingId, @@ -63,5 +57,5 @@ export default function userLeaving(credentials, userId) { Logger.verbose(`User '${requesterUserId}' left meeting '${meetingId}'`); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js index 358d30389d..a2dd8fc52f 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js @@ -36,15 +36,9 @@ export default function validateAuthToken(credentials) { authToken: requesterToken, }; - const header = { - name: EVENT_NAME, - meetingId, - userId: requesterUserId, - }; - Logger.info(`User '${ requesterUserId }' is trying to validate auth tokenfor meeting '${meetingId}'`); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js index f3cafb2868..c4d6e8f1cc 100644 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js @@ -12,16 +12,10 @@ export default function muteToggle(credentials, userId) { check(meetingId, String); check(requesterUserId, String); - const header = { - name: EVENT_NAME, - meetingId, - userId, - }; - const payload = { userId, mutedBy: requesterUserId, }; - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, userId, payload); } diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index 9da68ce7b1..47d5281cad 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -40,6 +40,48 @@ class RedisPubSub2x { return this.emitter.on(...args); } + publishUserMessage(channel, eventName, meetingId, userId, payload) { + const header = { + name: eventName, + meetingId: meetingId, + userId: userId + } + + return this.publishMessage(channel, eventName, header, payload); + } + + publishMeetingMessage(channel, eventName, meetingId, payload) { + const header = { + name: eventName, + meetingId: meetingId + } + + return thtis.publishMessage(channel, eventName, header, payload); + } + + publishMessage(channel, eventName, header, payload) { + const envelope = { + envelope: { + name: eventName, + routing: { + sender: 'bbb-apps-akka', + // sender: 'html5-server', // TODO + }, + }, + core: { + header: header, + body: payload, + }, + }; + + Logger.warn(`<<<<< { + if (err) { + Logger.error('Tried to publish to %s', channel, envelope); + } + }); + } + publish(channel, eventName, meetingId, payload = {}, header = {}) { const header2x = { name: eventName, From 9a8a4a2a5edf232c7df42ce417557fda86d67cc5 Mon Sep 17 00:00:00 2001 From: Maxim Khlobystov Date: Mon, 28 Aug 2017 11:52:15 -0400 Subject: [PATCH 04/51] Added an instance of the mobile Chrome (iPhone 6). --- .../tests/webdriverio/specs/login.spec.js | 3 ++- bigbluebutton-html5/tests/webdriverio/wdio.conf.js | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-html5/tests/webdriverio/specs/login.spec.js b/bigbluebutton-html5/tests/webdriverio/specs/login.spec.js index 59656cbd17..4de91df66e 100644 --- a/bigbluebutton-html5/tests/webdriverio/specs/login.spec.js +++ b/bigbluebutton-html5/tests/webdriverio/specs/login.spec.js @@ -23,7 +23,8 @@ describe('Landing page', function () { ['chromeBrowser', 'Alex'], ['chromeDevBrowser', 'Anton'], ['firefoxBrowser', 'Danny'], - ['firefoxNightlyBrowser', 'Maxim'] + ['firefoxNightlyBrowser', 'Maxim'], + ['chromeMobileBrowser', 'Oswaldo'] ])); LandingPage.joinWithButtonClick(); diff --git a/bigbluebutton-html5/tests/webdriverio/wdio.conf.js b/bigbluebutton-html5/tests/webdriverio/wdio.conf.js index 7022f70108..87c77380d8 100644 --- a/bigbluebutton-html5/tests/webdriverio/wdio.conf.js +++ b/bigbluebutton-html5/tests/webdriverio/wdio.conf.js @@ -24,6 +24,16 @@ exports.config = { browserName: 'firefox', firefox_binary: '/usr/lib/firefox-trunk/firefox-trunk' } + }, + chromeMobileBrowser: { + desiredCapabilities: { + browserName: 'chrome', + chromeOptions: { + mobileEmulation: { + deviceName: 'Apple iPhone 6' + } + } + } } }, baseUrl: 'http://localhost:8080', From 54e74d213dce77cd70ba809c49fc0dbb6a97134c Mon Sep 17 00:00:00 2001 From: Maxim Khlobystov Date: Mon, 28 Aug 2017 14:45:38 -0400 Subject: [PATCH 05/51] Added test command to the precommit git hook. --- bigbluebutton-html5/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-html5/package.json b/bigbluebutton-html5/package.json index 1175fb07a0..bc5ba6c8c5 100644 --- a/bigbluebutton-html5/package.json +++ b/bigbluebutton-html5/package.json @@ -7,7 +7,7 @@ "start:dev": "ROOT_URL=http://127.0.0.1/html5client NODE_ENV=development meteor", "test": "wdio ./tests/webdriverio/wdio.conf.js", "lint": "eslint . --ext .jsx,.js", - "precommit": "lint-staged" + "precommit": "lint-staged && npm test" }, "lint-staged": { "gitDir": "../", From 82de509c5528428c74db76cc1147119faa617b28 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Tue, 29 Aug 2017 07:00:41 -0700 Subject: [PATCH 06/51] fix typo --- bigbluebutton-html5/imports/startup/server/redis2x.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index 47d5281cad..ad146f195b 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -56,7 +56,7 @@ class RedisPubSub2x { meetingId: meetingId } - return thtis.publishMessage(channel, eventName, header, payload); + return this.publishMessage(channel, eventName, header, payload); } publishMessage(channel, eventName, header, payload) { From a8137c3054bfcbc09ac7103c08c7fd18877b9ca2 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 30 Aug 2017 07:58:46 -0700 Subject: [PATCH 07/51] switch to one function to create headers --- .../server/methods/clearPublicChatHistory.js | 2 +- .../api/2.0/chat/server/methods/sendChat.js | 2 +- .../2.0/polls/server/methods/publishVote.js | 2 +- .../2.0/slides/server/methods/switchSlide.js | 2 +- .../2.0/slides/server/modifiers/addSlide.js | 2 +- .../users/server/methods/assignPresenter.js | 2 +- .../users/server/methods/requestStunTurn.js | 2 +- .../users/server/methods/setEmojiStatus.js | 2 +- .../api/2.0/users/server/methods/userJoin.js | 2 +- .../2.0/users/server/methods/userLeaving.js | 2 +- .../users/server/methods/validateAuthToken.js | 2 +- .../voice-users/server/methods/muteToggle.js | 2 +- .../imports/startup/server/redis2x.js | 28 +++++++++---------- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js index 5a78036fba..16284acd4b 100644 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js @@ -15,5 +15,5 @@ export default function clearPublicChatHistory(credentials) { const payload = {}; - return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, eventName, meetingId, payload, requesterUserId); } diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js index 40b12c3166..dc0c64bc4d 100755 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js @@ -50,5 +50,5 @@ export default function sendChat(credentials, message) { eventName = 'SendPublicMessagePubMsg'; } - return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, { message: parsedMessage }); + return RedisPubSub.buildMessageheader(CHANNEL, eventName, meetingId, { message: parsedMessage }, requesterUserId); } diff --git a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js index 03617522af..082d514ec2 100644 --- a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js +++ b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js @@ -51,5 +51,5 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis }; Polls.update(selector, modifier, cb); - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); } diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js index a33fdc3e28..52800dd2bf 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js @@ -45,5 +45,5 @@ export default function switchSlide(credentials, slideNumber) { presentationId: Presentation.id, }; - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); } diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js index 6e18e339c6..a654bc1fd1 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js @@ -16,7 +16,7 @@ const requestWhiteboardHistory = (meetingId, slideId) => { whiteboardId: slideId, }; - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, { userId: 'nodeJSapp' }, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, { userId: 'nodeJSapp' }); }; const SUPPORTED_TYPES = [SVG, PNG]; diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js index 7f005e9cbf..3d9a72da48 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js @@ -35,5 +35,5 @@ export default function assignPresenter(credentials, userId) { Logger.verbose(`User '${userId}' setted as presenter by '${ requesterUserId}' from meeting '${meetingId}'`); - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, User.userId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, paload, User.userId); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js index 638072d133..01e19bc5cd 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js @@ -18,5 +18,5 @@ export default function requestStunTurn(meetingId, requesterUserId) { Logger.verbose(`User '${requesterUserId}' requested stun/turn from meeting '${meetingId}'`); - return RedisPubSub.publishMeetingMessage(CHANNEL, EVENT_NAME, meetingId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js index 544316450a..61331839d0 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js @@ -22,5 +22,5 @@ export default function setEmojiStatus(credentials, userId, status) { Logger.verbose(`User '${userId}' emoji status updated to '${status}' by '${ requesterUserId}' from meeting '${meetingId}'`); - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js index f705681241..11f3f51f3d 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js @@ -19,5 +19,5 @@ export default function userJoin(meetingId, userId, authToken) { Logger.info(`User '${userId}' is joining meeting '${meetingId}'`); - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, userId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, userId); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js index 783741dcc3..62559ac83b 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js @@ -57,5 +57,5 @@ export default function userLeaving(credentials, userId) { Logger.verbose(`User '${requesterUserId}' left meeting '${meetingId}'`); - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js index a2dd8fc52f..c55fa0ba07 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js @@ -40,5 +40,5 @@ export default function validateAuthToken(credentials) { requesterUserId }' is trying to validate auth tokenfor meeting '${meetingId}'`); - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); } diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js index c4d6e8f1cc..d4e85e2d29 100644 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js @@ -17,5 +17,5 @@ export default function muteToggle(credentials, userId) { mutedBy: requesterUserId, }; - return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, userId, payload); + return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, userId); } diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index ad146f195b..2e994b81da 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -40,20 +40,20 @@ class RedisPubSub2x { return this.emitter.on(...args); } - publishUserMessage(channel, eventName, meetingId, userId, payload) { - const header = { - name: eventName, - meetingId: meetingId, - userId: userId - } - - return this.publishMessage(channel, eventName, header, payload); - } - - publishMeetingMessage(channel, eventName, meetingId, payload) { - const header = { - name: eventName, - meetingId: meetingId + buildMessageheader( channel, eventName, meetingId, payload, userId = {} ) { + let header; + + if (userId.length > 0) { + header = { + name: eventName, + meetingId: meetingId, + userId: userId + } + } else if (userid.length == 0){ + header = { + name: eventName, + meetingId: meetingId + } } return this.publishMessage(channel, eventName, header, payload); From 14696a3cff8460ee44675a2556c30243bd8bdf4a Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 30 Aug 2017 08:03:19 -0700 Subject: [PATCH 08/51] fix lint issue --- .../imports/startup/server/redis2x.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index 2e994b81da..fef9b28c5e 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -40,19 +40,19 @@ class RedisPubSub2x { return this.emitter.on(...args); } - buildMessageheader( channel, eventName, meetingId, payload, userId = {} ) { + buildMessageheader(channel, eventName, meetingId, payload, userId = {}) { let header; if (userId.length > 0) { header = { name: eventName, - meetingId: meetingId, - userId: userId + meetingId, + userId } - } else if (userid.length == 0){ + } else if (userid.length == 0) { header = { name: eventName, - meetingId: meetingId + meetingId } } @@ -69,7 +69,7 @@ class RedisPubSub2x { }, }, core: { - header: header, + header, body: payload, }, }; From f31a2df1337f9d9ce75bae8dda0a2a87d29ab34c Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 30 Aug 2017 09:31:08 -0700 Subject: [PATCH 09/51] implement suggested changes --- .../server/methods/clearPublicChatHistory.js | 5 ++- .../api/2.0/chat/server/methods/sendChat.js | 5 ++- .../2.0/polls/server/methods/publishVote.js | 6 ++- .../2.0/slides/server/methods/switchSlide.js | 5 ++- .../2.0/slides/server/modifiers/addSlide.js | 5 ++- .../users/server/methods/assignPresenter.js | 5 ++- .../users/server/methods/requestStunTurn.js | 5 ++- .../users/server/methods/setEmojiStatus.js | 5 ++- .../api/2.0/users/server/methods/userJoin.js | 5 ++- .../2.0/users/server/methods/userLeaving.js | 5 ++- .../users/server/methods/validateAuthToken.js | 6 ++- .../voice-users/server/methods/muteToggle.js | 5 ++- .../imports/api/common/server/helpers.js | 19 +++++++++ .../imports/startup/server/redis2x.js | 42 ------------------- 14 files changed, 68 insertions(+), 55 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js index 16284acd4b..c472aec136 100644 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function clearPublicChatHistory(credentials) { const REDIS_CONFIG = Meteor.settings.redis; @@ -15,5 +16,7 @@ export default function clearPublicChatHistory(credentials) { const payload = {}; - return RedisPubSub.buildMessageheader(CHANNEL, eventName, meetingId, payload, requesterUserId); + const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + + return RedisPubSub.publish(CHANNEL, eventName, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js index dc0c64bc4d..3cda1b20cb 100755 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import RegexWebUrl from '/imports/utils/regex-weburl'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; const HTML_SAFE_MAP = { '<': '<', @@ -50,5 +51,7 @@ export default function sendChat(credentials, message) { eventName = 'SendPublicMessagePubMsg'; } - return RedisPubSub.buildMessageheader(CHANNEL, eventName, meetingId, { message: parsedMessage }, requesterUserId); + const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + + return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js index 082d514ec2..e3f6d023ec 100644 --- a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js +++ b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js @@ -2,6 +2,7 @@ import RedisPubSub from '/imports/startup/server/redis2x'; import { check } from 'meteor/check'; import Polls from '/imports/api/2.0/polls'; import Logger from '/imports/startup/server/logger'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function publishVote(credentials, id, pollAnswerId) { // TODO discuss location const REDIS_CONFIG = Meteor.settings.redis; @@ -51,5 +52,8 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis }; Polls.update(selector, modifier, cb); - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); + + const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js index 52800dd2bf..78d9da8da7 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js @@ -3,6 +3,7 @@ import Slides from '/imports/api/2.0/slides'; import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function switchSlide(credentials, slideNumber) { const REDIS_CONFIG = Meteor.settings.redis; @@ -45,5 +46,7 @@ export default function switchSlide(credentials, slideNumber) { presentationId: Presentation.id, }; - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); + const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js index a654bc1fd1..1dd438ad15 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js @@ -6,6 +6,7 @@ import RedisPubSub from '/imports/startup/server/redis2x'; import Slides from '/imports/api/2.0/slides'; import Logger from '/imports/startup/server/logger'; import { SVG, PNG } from '/imports/utils/mimeTypes'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; const requestWhiteboardHistory = (meetingId, slideId) => { const REDIS_CONFIG = Meteor.settings.redis; @@ -16,7 +17,9 @@ const requestWhiteboardHistory = (meetingId, slideId) => { whiteboardId: slideId, }; - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, { userId: 'nodeJSapp' }); + const header = buildMessageHeader(EVENT_NAME, meetingId, { userId: 'nodeJSapp' }); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); }; const SUPPORTED_TYPES = [SVG, PNG]; diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js index 3d9a72da48..c9106fd6d1 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js @@ -3,6 +3,7 @@ import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; import Users from '/imports/api/2.0/users'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function assignPresenter(credentials, userId) { const REDIS_CONFIG = Meteor.settings.redis; @@ -35,5 +36,7 @@ export default function assignPresenter(credentials, userId) { Logger.verbose(`User '${userId}' setted as presenter by '${ requesterUserId}' from meeting '${meetingId}'`); - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, paload, User.userId); + const header = buildMessageHeader(EVENT_NAME, meetingId, User.userId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, paload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js index 01e19bc5cd..228481fbd6 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function requestStunTurn(meetingId, requesterUserId) { const REDIS_CONFIG = Meteor.settings.redis; @@ -18,5 +19,7 @@ export default function requestStunTurn(meetingId, requesterUserId) { Logger.verbose(`User '${requesterUserId}' requested stun/turn from meeting '${meetingId}'`); - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload); + const header = buildMessageHeader(EVENT_NAME, meetingId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js index 61331839d0..e0e4397100 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function setEmojiStatus(credentials, userId, status) { const REDIS_CONFIG = Meteor.settings.redis; @@ -22,5 +23,7 @@ export default function setEmojiStatus(credentials, userId, status) { Logger.verbose(`User '${userId}' emoji status updated to '${status}' by '${ requesterUserId}' from meeting '${meetingId}'`); - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); + const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js index 11f3f51f3d..189462aaa1 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function userJoin(meetingId, userId, authToken) { const REDIS_CONFIG = Meteor.settings.redis; @@ -19,5 +20,7 @@ export default function userJoin(meetingId, userId, authToken) { Logger.info(`User '${userId}' is joining meeting '${meetingId}'`); - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, userId); + const header = buildMessageHeader(EVENT_NAME, meetingId, userId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js index 62559ac83b..e1e131ef76 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js @@ -3,6 +3,7 @@ import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; import Users from '/imports/api/2.0/users'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; const OFFLINE_CONNECTION_STATUS = 'offline'; @@ -57,5 +58,7 @@ export default function userLeaving(credentials, userId) { Logger.verbose(`User '${requesterUserId}' left meeting '${meetingId}'`); - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); + const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js index c55fa0ba07..a3118d5b87 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js @@ -3,7 +3,7 @@ import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; import Users from '/imports/api/2.0/users'; - +import { buildMessageHeader } from '/imports/api/common/server/helpers'; import createDummyUser2x from '../modifiers/createDummyUser'; import setConnectionStatus from '../modifiers/setConnectionStatus'; @@ -40,5 +40,7 @@ export default function validateAuthToken(credentials) { requesterUserId }' is trying to validate auth tokenfor meeting '${meetingId}'`); - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, requesterUserId); + const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js index d4e85e2d29..01f5af08ec 100644 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; +import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function muteToggle(credentials, userId) { const REDIS_CONFIG = Meteor.settings.redis; @@ -17,5 +18,7 @@ export default function muteToggle(credentials, userId) { mutedBy: requesterUserId, }; - return RedisPubSub.buildMessageheader(CHANNEL, EVENT_NAME, meetingId, payload, userId); + const header = buildMessageHeader(EVENT_NAME, meetingId, userId); + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/common/server/helpers.js b/bigbluebutton-html5/imports/api/common/server/helpers.js index 9d65f301a6..0abfc28bcc 100755 --- a/bigbluebutton-html5/imports/api/common/server/helpers.js +++ b/bigbluebutton-html5/imports/api/common/server/helpers.js @@ -12,6 +12,25 @@ export function appendMessageHeader(eventName, messageObj) { return messageObj; } +export function buildMessageHeader(eventName, meetingId, userId = {}) { + let header; + + if (userId.length > 0) { + header = { + name: eventName, + meetingId, + userId + } + } else if (userid.length == 0) { + header = { + name: eventName, + meetingId + } + } + + return header; +} + export const indexOf = [].indexOf || function (item) { for (let i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) { diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index fef9b28c5e..9da68ce7b1 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -40,48 +40,6 @@ class RedisPubSub2x { return this.emitter.on(...args); } - buildMessageheader(channel, eventName, meetingId, payload, userId = {}) { - let header; - - if (userId.length > 0) { - header = { - name: eventName, - meetingId, - userId - } - } else if (userid.length == 0) { - header = { - name: eventName, - meetingId - } - } - - return this.publishMessage(channel, eventName, header, payload); - } - - publishMessage(channel, eventName, header, payload) { - const envelope = { - envelope: { - name: eventName, - routing: { - sender: 'bbb-apps-akka', - // sender: 'html5-server', // TODO - }, - }, - core: { - header, - body: payload, - }, - }; - - Logger.warn(`<<<<< { - if (err) { - Logger.error('Tried to publish to %s', channel, envelope); - } - }); - } - publish(channel, eventName, meetingId, payload = {}, header = {}) { const header2x = { name: eventName, From 7cdf031a22b854a22542f154cb3b968fac08bbe7 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 30 Aug 2017 09:33:18 -0700 Subject: [PATCH 10/51] fix typo --- .../imports/api/2.0/users/server/methods/assignPresenter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js index c9106fd6d1..cc4fa7113f 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js @@ -38,5 +38,5 @@ export default function assignPresenter(credentials, userId) { const header = buildMessageHeader(EVENT_NAME, meetingId, User.userId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, paload, header); + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); } From a01451f9fd6d069e67ea735a1c8bed6d9c6b9510 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 30 Aug 2017 11:00:56 -0700 Subject: [PATCH 11/51] handle LockSettingsInMeetingChangedEvtMsg and fix userlistitem lock notification --- .../api/2.0/meetings/server/eventHandlers.js | 2 ++ .../server/handlers/meetingLockChange.js | 8 ++++++ .../server/modifiers/changeLockSettings.js | 26 +++++++++++++++++++ .../ui/components/user-list/container.jsx | 2 +- .../user-list/user-list-item/component.jsx | 8 +++++- 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js create mode 100644 bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js index cea124d555..717d326ab9 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js @@ -2,7 +2,9 @@ import RedisPubSub from '/imports/startup/server/redis2x'; import handleMeetingCreation from './handlers/meetingCreation'; import handleGetAllMeetings from './handlers/getAllMeetings'; import handleMeetingEnd from './handlers/meetingEnd'; +import handleMeetingLocksChange from './handlers/meetingLockChange'; RedisPubSub.on('MeetingCreatedEvtMsg', handleMeetingCreation); RedisPubSub.on('SyncGetMeetingInfoRespMsg', handleGetAllMeetings); RedisPubSub.on('MeetingEndingEvtMsg', handleMeetingEnd); +RedisPubSub.on('LockSettingsInMeetingChangedEvtMsg', handleMeetingLocksChange); \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js new file mode 100644 index 0000000000..c07d5dfa1a --- /dev/null +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js @@ -0,0 +1,8 @@ +import { check } from 'meteor/check'; +import ChangeLockSettings from '../modifiers/changeLockSettings'; + +export default function handleLockSettingsInMeeting({ body }, meetingId) { + check(meetingId, String); + + return ChangeLockSettings(meetingId, body); +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js new file mode 100644 index 0000000000..ddc9151031 --- /dev/null +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js @@ -0,0 +1,26 @@ +import Logger from '/imports/startup/server/logger'; +import Meetings from '/imports/api/2.0/meetings'; + +export default function ChangeLockSettings(meetingId, payload) { + + const selector = { + meetingId + }; + + const modifier = { + $set: { + body: payload, + }, + }; + + Meetings.upsert(selector, modifier, cb); + + const cb = (err) => { + if (err) { + return Logger.error(`Removing user from collection: ${err}`); + } + }; + + const settings = JSON.stringify(body); + return Logger.info(`updated lock settings=${settings} for meeting=${meetingId} `);; +}; \ No newline at end of file diff --git a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx index 3667e55d92..eea97148b7 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { createContainer } from 'meteor/react-meteor-data'; import { meetingIsBreakout } from '/imports/ui/components/app/service'; import { makeCall } from '/imports/ui/services/api'; -import Meetings from '/imports/api/1.1/meetings'; +import Meetings from '/imports/api/2.0/meetings'; import Service from './service'; import UserList from './component'; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx index 71a705ff86..8e8e47dd16 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx @@ -239,6 +239,7 @@ class UserListItem extends Component { user, intl, compact, + meeting, } = this.props; if (compact) { @@ -246,8 +247,13 @@ class UserListItem extends Component { } const userNameSub = []; + const lockSettings = meeting.body; + + if ((lockSettings.disableCam + || lockSettings.disableMic + || lockSettings.disablePrivChat + || lockSettings.disablePubChat) && !user.isPresenter && !user.isModerator) { - if (user.isLocked) { userNameSub.push( {intl.formatMessage(messages.locked)} From c244ef91ec1a1d9e31d6ddf7ef1a7a9911cc0c9e Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 30 Aug 2017 11:35:40 -0700 Subject: [PATCH 12/51] fix line endings --- .../imports/api/2.0/meetings/server/eventHandlers.js | 2 +- .../api/2.0/meetings/server/handlers/meetingLockChange.js | 2 +- .../api/2.0/meetings/server/modifiers/changeLockSettings.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js index 717d326ab9..7181bc6e21 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js @@ -7,4 +7,4 @@ import handleMeetingLocksChange from './handlers/meetingLockChange'; RedisPubSub.on('MeetingCreatedEvtMsg', handleMeetingCreation); RedisPubSub.on('SyncGetMeetingInfoRespMsg', handleGetAllMeetings); RedisPubSub.on('MeetingEndingEvtMsg', handleMeetingEnd); -RedisPubSub.on('LockSettingsInMeetingChangedEvtMsg', handleMeetingLocksChange); \ No newline at end of file +RedisPubSub.on('LockSettingsInMeetingChangedEvtMsg', handleMeetingLocksChange); diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js index c07d5dfa1a..04834102e9 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js @@ -5,4 +5,4 @@ export default function handleLockSettingsInMeeting({ body }, meetingId) { check(meetingId, String); return ChangeLockSettings(meetingId, body); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js index ddc9151031..c156773aa0 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js @@ -22,5 +22,5 @@ export default function ChangeLockSettings(meetingId, payload) { }; const settings = JSON.stringify(body); - return Logger.info(`updated lock settings=${settings} for meeting=${meetingId} `);; -}; \ No newline at end of file + return Logger.info(`updated lock settings=${settings} for meeting=${meetingId} `); +}; From 2f9d4bcc0e2522c72d975f8a32e388d3921a4457 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 31 Aug 2017 11:12:53 -0700 Subject: [PATCH 13/51] move isMeetingLocked condition check to userlist service --- .../server/handlers/meetingLockChange.js | 5 +++-- .../server/modifiers/changeLockSettings.js | 9 +++------ .../ui/components/user-list/component.jsx | 2 ++ .../ui/components/user-list/container.jsx | 3 +++ .../imports/ui/components/user-list/service.js | 16 ++++++++++++++++ .../user-list/user-list-item/component.jsx | 8 ++------ 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js index 04834102e9..dc5bfeebc8 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js @@ -1,8 +1,9 @@ import { check } from 'meteor/check'; -import ChangeLockSettings from '../modifiers/changeLockSettings'; +import changeLockSettings from '../modifiers/changeLockSettings'; export default function handleLockSettingsInMeeting({ body }, meetingId) { check(meetingId, String); + check(body, Object); - return ChangeLockSettings(meetingId, body); + return changeLockSettings(meetingId, body); } diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js index c156773aa0..0da02c6fe1 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js @@ -1,7 +1,7 @@ import Logger from '/imports/startup/server/logger'; import Meetings from '/imports/api/2.0/meetings'; -export default function ChangeLockSettings(meetingId, payload) { +export default function changeLockSettings(meetingId, payload) { const selector = { meetingId @@ -9,18 +9,15 @@ export default function ChangeLockSettings(meetingId, payload) { const modifier = { $set: { - body: payload, + lockSettingsProp: payload, }, }; - Meetings.upsert(selector, modifier, cb); - const cb = (err) => { if (err) { return Logger.error(`Removing user from collection: ${err}`); } }; - const settings = JSON.stringify(body); - return Logger.info(`updated lock settings=${settings} for meeting=${meetingId} `); + return Meetings.upsert(selector, modifier, cb); }; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx index ea5762df85..81c8781c5c 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx @@ -255,6 +255,7 @@ class UserList extends Component { intl, makeCall, meeting, + isMeetingLocked, } = this.props; const userActions = { @@ -326,6 +327,7 @@ class UserList extends Component { currentUser={currentUser} userActions={userActions} meeting={meeting} + isMeetingLocked={isMeetingLocked} /> )) } diff --git a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx index eea97148b7..b59299c7bb 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx @@ -16,6 +16,7 @@ const UserListContainer = (props) => { isBreakoutRoom, children, meeting, + isMeetingLocked, } = props; return ( @@ -28,6 +29,7 @@ const UserListContainer = (props) => { isBreakoutRoom={isBreakoutRoom} makeCall={makeCall} userActions={userActions} + isMeetingLocked={isMeetingLocked} > {children} @@ -42,4 +44,5 @@ export default createContainer(({ params }) => ({ openChat: params.chatID, userActions: Service.userActions, isBreakoutRoom: meetingIsBreakout(), + isMeetingLocked: Service.isMeetingLocked(), }), UserListContainer); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 071ccd5546..48dcf05084 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -1,5 +1,6 @@ import Users from '/imports/api/2.0/users'; import Chat from '/imports/api/2.0/chat'; +import Meetings from '/imports/api/2.0/meetings'; import Auth from '/imports/ui/services/auth'; import UnreadMessages from '/imports/ui/services/unread-messages'; import Storage from '/imports/ui/services/storage/session'; @@ -210,8 +211,23 @@ const getCurrentUser = () => { return (currentUser) ? mapUser(currentUser) : null; }; +const isMeetingLocked = () => { + const meeting = Meetings.findOne({}); + const lockSettings = meeting.lockSettingsProp; + + if ( lockSettings.disableCam + || lockSettings.disableMic + || lockSettings.disablePrivChat + || lockSettings.disablePubChat ) { + return true; + } + + return false; +} + export default { getUsers, getOpenChats, getCurrentUser, + isMeetingLocked }; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx index 8e8e47dd16..ac97443dd2 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx @@ -240,6 +240,7 @@ class UserListItem extends Component { intl, compact, meeting, + isMeetingLocked, } = this.props; if (compact) { @@ -247,13 +248,8 @@ class UserListItem extends Component { } const userNameSub = []; - const lockSettings = meeting.body; - - if ((lockSettings.disableCam - || lockSettings.disableMic - || lockSettings.disablePrivChat - || lockSettings.disablePubChat) && !user.isPresenter && !user.isModerator) { + if ( isMeetingLocked && !user.isPresenter && !user.isModerator) { userNameSub.push( {intl.formatMessage(messages.locked)} From a404cc14d1a73ab679f03997d52ef106f1367463 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 31 Aug 2017 13:47:06 -0700 Subject: [PATCH 14/51] remove space typo --- .../ui/components/user-list/user-list-item/component.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx index ac97443dd2..316d297e64 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx @@ -249,7 +249,7 @@ class UserListItem extends Component { const userNameSub = []; - if ( isMeetingLocked && !user.isPresenter && !user.isModerator) { + if (isMeetingLocked && !user.isPresenter && !user.isModerator) { userNameSub.push( {intl.formatMessage(messages.locked)} From 94e44d6a232654743d68dbd59a88dd7932d95291 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 31 Aug 2017 13:50:20 -0700 Subject: [PATCH 15/51] remove unused prop --- .../imports/ui/components/user-list/user-list-item/component.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx index 316d297e64..f34721ffa1 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx @@ -239,7 +239,6 @@ class UserListItem extends Component { user, intl, compact, - meeting, isMeetingLocked, } = this.props; From 7a9cb7d04f5969bb70b837ba642c5bacab4fed65 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 31 Aug 2017 14:29:18 -0700 Subject: [PATCH 16/51] fix the disabling of chat when locked --- .../imports/ui/components/chat/service.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index 1991157209..b863cb6c7d 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -1,5 +1,6 @@ import Chats from '/imports/api/2.0/chat'; import Users from '/imports/api/2.0/users'; +import Meetings from '/imports/api/2.0/meetings'; import Auth from '/imports/ui/services/auth'; import UnreadMessages from '/imports/ui/services/unread-messages'; import Storage from '/imports/ui/services/storage/session'; @@ -102,21 +103,12 @@ const getPrivateMessages = (userID) => { const isChatLocked = (receiverID) => { const isPublic = receiverID === PUBLIC_CHAT_ID; - const currentUser = getUser(Auth.userID); - const lockSettings = false; + const meeting = Meetings.findOne({}); + const isPubChatLocked = meeting.lockSettingsProp.disablePubChat; + const isPrivChatLocked = meeting.lockSettingsProp.disablePrivChat; - // FIX ME - /* meeting.roomLockSettings || { - disablePublicChat: false, - disablePrivateChat: false, - }; */ - - if (!currentUser.isLocked || currentUser.isPresenter) { - return false; - } - - return isPublic ? lockSettings.disablePublicChat : lockSettings.disablePrivateChat; + return ((isPublic && isPubChatLocked) || (!isPublic && isPrivChatLocked)) ? true : false; }; const hasUnreadMessages = (receiverID) => { From b20859d1c9e6ce209e4daf06bc1a7598182b31b4 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 31 Aug 2017 14:49:13 -0700 Subject: [PATCH 17/51] fix chat being locked for moderators --- bigbluebutton-html5/imports/ui/components/chat/service.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index b863cb6c7d..12d6a634d3 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -108,7 +108,11 @@ const isChatLocked = (receiverID) => { const isPubChatLocked = meeting.lockSettingsProp.disablePubChat; const isPrivChatLocked = meeting.lockSettingsProp.disablePrivChat; - return ((isPublic && isPubChatLocked) || (!isPublic && isPrivChatLocked)) ? true : false; + const user = Users.findOne({}); + const isViewer = user.role === "VIEWER"; + + return ((isPublic && isPubChatLocked && isViewer) || (!isPublic && isPrivChatLocked && isViewer)) + ? true : false; }; const hasUnreadMessages = (receiverID) => { From c14e779bb453708de241b078d760f347ab7cfa71 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Tue, 5 Sep 2017 08:53:02 -0700 Subject: [PATCH 18/51] add check to payload --- .../api/2.0/meetings/server/modifiers/changeLockSettings.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js index 0da02c6fe1..18cd751f53 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js @@ -1,7 +1,10 @@ import Logger from '/imports/startup/server/logger'; import Meetings from '/imports/api/2.0/meetings'; +import { check } from 'meteor/check'; export default function changeLockSettings(meetingId, payload) { + check(meetingId, String); + check(payload, Object) const selector = { meetingId From 1379b533fda1ca698a61febc0310f9c30cc4a23d Mon Sep 17 00:00:00 2001 From: Maxim Khlobystov Date: Tue, 5 Sep 2017 13:51:41 -0400 Subject: [PATCH 19/51] Removed the test command from the git precommit hook. --- bigbluebutton-html5/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-html5/package.json b/bigbluebutton-html5/package.json index bc5ba6c8c5..1175fb07a0 100644 --- a/bigbluebutton-html5/package.json +++ b/bigbluebutton-html5/package.json @@ -7,7 +7,7 @@ "start:dev": "ROOT_URL=http://127.0.0.1/html5client NODE_ENV=development meteor", "test": "wdio ./tests/webdriverio/wdio.conf.js", "lint": "eslint . --ext .jsx,.js", - "precommit": "lint-staged && npm test" + "precommit": "lint-staged" }, "lint-staged": { "gitDir": "../", From 67ab2d53790f440489485597390746891b12a573 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 6 Sep 2017 07:17:46 -0700 Subject: [PATCH 20/51] alternate solution test --- .../server/methods/clearPublicChatHistory.js | 4 +-- .../api/2.0/chat/server/methods/sendChat.js | 4 +-- .../2.0/polls/server/methods/publishVote.js | 4 +-- .../2.0/slides/server/methods/switchSlide.js | 4 +-- .../2.0/slides/server/modifiers/addSlide.js | 4 +-- .../users/server/methods/assignPresenter.js | 4 +-- .../users/server/methods/requestStunTurn.js | 4 +-- .../users/server/methods/setEmojiStatus.js | 4 +-- .../api/2.0/users/server/methods/userJoin.js | 2 +- .../users/server/methods/validateAuthToken.js | 2 +- .../server/methods/listenOnlyToggle.js | 2 +- .../voice-users/server/methods/muteToggle.js | 2 +- .../imports/startup/server/redis2x.js | 29 ++++++++++++++++++- 13 files changed, 48 insertions(+), 21 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js index c472aec136..26c19ef540 100644 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js @@ -16,7 +16,7 @@ export default function clearPublicChatHistory(credentials) { const payload = {}; - const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, eventName, meetingId, payload, header); + return RedisPubSub.publish(CHANNEL, eventName, meetingId, payload, { userId: requesterUserId }); } diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js index 3cda1b20cb..adc6b80536 100755 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js @@ -51,7 +51,7 @@ export default function sendChat(credentials, message) { eventName = 'SendPublicMessagePubMsg'; } - const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, header); + return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, { userId: requesterUserId }); } diff --git a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js index e3f6d023ec..59d2f34c03 100644 --- a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js +++ b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js @@ -53,7 +53,7 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis Polls.update(selector, modifier, cb); - const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); } diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js index 78d9da8da7..d5eae2b008 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js @@ -46,7 +46,7 @@ export default function switchSlide(credentials, slideNumber) { presentationId: Presentation.id, }; - const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); } diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js index 1dd438ad15..74c385f2e6 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js @@ -17,9 +17,9 @@ const requestWhiteboardHistory = (meetingId, slideId) => { whiteboardId: slideId, }; - const header = buildMessageHeader(EVENT_NAME, meetingId, { userId: 'nodeJSapp' }); + //const header = buildMessageHeader(EVENT_NAME, meetingId, { userId: 'nodeJSapp' }); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: 'nodeJSapp' }); }; const SUPPORTED_TYPES = [SVG, PNG]; diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js index cc4fa7113f..a07a67224d 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js @@ -36,7 +36,7 @@ export default function assignPresenter(credentials, userId) { Logger.verbose(`User '${userId}' setted as presenter by '${ requesterUserId}' from meeting '${meetingId}'`); - const header = buildMessageHeader(EVENT_NAME, meetingId, User.userId); + //const header = buildMessageHeader(EVENT_NAME, meetingId, User.userId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: User.userId }); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js index 228481fbd6..3871a8739e 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js @@ -19,7 +19,7 @@ export default function requestStunTurn(meetingId, requesterUserId) { Logger.verbose(`User '${requesterUserId}' requested stun/turn from meeting '${meetingId}'`); - const header = buildMessageHeader(EVENT_NAME, meetingId); + //const header = buildMessageHeader(EVENT_NAME, meetingId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js index e0e4397100..12d5848843 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js @@ -23,7 +23,7 @@ export default function setEmojiStatus(credentials, userId, status) { Logger.verbose(`User '${userId}' emoji status updated to '${status}' by '${ requesterUserId}' from meeting '${meetingId}'`); - const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); + //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js index 189462aaa1..f52596753f 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js @@ -22,5 +22,5 @@ export default function userJoin(meetingId, userId, authToken) { const header = buildMessageHeader(EVENT_NAME, meetingId, userId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publ(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js index a3118d5b87..7941420b9c 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js @@ -42,5 +42,5 @@ export default function validateAuthToken(credentials) { const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publ(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js index 8ec928b7e9..acbdb1ccc7 100755 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js @@ -49,5 +49,5 @@ export default function listenOnlyToggle(credentials, isJoining = true) { Logger.verbose(`VoiceUser '${requesterUserId}' ${isJoining ? 'joined' : 'left'} global audio from meeting '${meetingId}'`); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publ(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js index 01f5af08ec..f0e25e0786 100644 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js @@ -20,5 +20,5 @@ export default function muteToggle(credentials, userId) { const header = buildMessageHeader(EVENT_NAME, meetingId, userId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); + return RedisPubSub.publ(CHANNEL, EVENT_NAME, meetingId, payload, header); } diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index 9da68ce7b1..8699e9d2ce 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -40,7 +40,34 @@ class RedisPubSub2x { return this.emitter.on(...args); } - publish(channel, eventName, meetingId, payload = {}, header = {}) { + publish(channel, eventName, meetingId, payload = {}, userId = {}) { + const envelope = { + envelope: { + name: eventName, + routing: { + sender: 'bbb-apps-akka', + // sender: 'html5-server', // TODO + } + }, + core: { + header: Object.assign({ + name: eventName, + timestamp: new Date().getTime(), + meetingId, + }, userId), + body: payload, + } + }; + + Logger.warn(`<<<<< { + if (err) { + Logger.error('Tried to publish to %s', channel, envelope); + } + }); + } + + publ(channel, eventName, meetingId, payload = {}, header = {}) { const header2x = { name: eventName, meetingId, From 572bb0b8d300be9c273305cd7d9714752d3049e5 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 6 Sep 2017 09:08:26 -0700 Subject: [PATCH 21/51] remove ternary operation --- bigbluebutton-html5/imports/ui/components/chat/service.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index 12d6a634d3..8dc91e8996 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -111,8 +111,7 @@ const isChatLocked = (receiverID) => { const user = Users.findOne({}); const isViewer = user.role === "VIEWER"; - return ((isPublic && isPubChatLocked && isViewer) || (!isPublic && isPrivChatLocked && isViewer)) - ? true : false; + return ((isPublic && isPubChatLocked && isViewer) || (!isPublic && isPrivChatLocked && isViewer)); }; const hasUnreadMessages = (receiverID) => { From d34f138b568cb0e5b806f1197e3a23bcc6a24d25 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 6 Sep 2017 10:50:48 -0700 Subject: [PATCH 22/51] check if lock settings are undefined --- .../imports/ui/components/chat/service.js | 10 ++++++--- .../ui/components/user-list/service.js | 22 ++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index 8dc91e8996..041937d7df 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -105,10 +105,14 @@ const isChatLocked = (receiverID) => { const isPublic = receiverID === PUBLIC_CHAT_ID; const meeting = Meetings.findOne({}); + const user = Users.findOne({}); + + if (typeof meeting.lockSettingsProp === 'undefined'){ + return false; + } + const isPubChatLocked = meeting.lockSettingsProp.disablePubChat; const isPrivChatLocked = meeting.lockSettingsProp.disablePrivChat; - - const user = Users.findOne({}); const isViewer = user.role === "VIEWER"; return ((isPublic && isPubChatLocked && isViewer) || (!isPublic && isPrivChatLocked && isViewer)); @@ -226,4 +230,4 @@ export default { closePrivateChat, exportChat, clearPublicChatHistory, -}; +}; \ No newline at end of file diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 48dcf05084..2bf44fb558 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -213,16 +213,22 @@ const getCurrentUser = () => { const isMeetingLocked = () => { const meeting = Meetings.findOne({}); + let isLocked = false; + + if (typeof meeting.lockSettingsProp === 'undefined'){ + return isLocked; + } + const lockSettings = meeting.lockSettingsProp; - if ( lockSettings.disableCam - || lockSettings.disableMic - || lockSettings.disablePrivChat - || lockSettings.disablePubChat ) { - return true; + if (lockSettings.disableCam + || lockSettings.disableMic + || lockSettings.disablePrivChat + || lockSettings.disablePubChat ) { + isLocked = true; } - - return false; + + return isLocked; } export default { @@ -230,4 +236,4 @@ export default { getOpenChats, getCurrentUser, isMeetingLocked -}; +}; \ No newline at end of file From fd9a4cd98e63e7529a29f90eb5948d4b82c2b32f Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 6 Sep 2017 11:13:24 -0700 Subject: [PATCH 23/51] fix bug in undefined check --- bigbluebutton-html5/imports/ui/components/chat/service.js | 2 +- .../imports/ui/components/user-list/service.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index 041937d7df..8993d80e11 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -107,7 +107,7 @@ const isChatLocked = (receiverID) => { const meeting = Meetings.findOne({}); const user = Users.findOne({}); - if (typeof meeting.lockSettingsProp === 'undefined'){ + if (meeting.lockSettingsProp === 'undefined'){ return false; } diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 2bf44fb558..47b2ee3226 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -212,10 +212,10 @@ const getCurrentUser = () => { }; const isMeetingLocked = () => { - const meeting = Meetings.findOne({}); + const meeting = Meetings.findOne({ }); let isLocked = false; - if (typeof meeting.lockSettingsProp === 'undefined'){ + if (meeting.lockSettingsProp === 'undefined'){ return isLocked; } From 31cf7aea427dca81bc220b15321754c24e0edaa7 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 6 Sep 2017 11:32:29 -0700 Subject: [PATCH 24/51] check for specific meeting id --- .../imports/ui/components/user-list/container.jsx | 4 ++-- .../imports/ui/components/user-list/service.js | 4 ++-- .../ui/components/user-list/user-list-item/component.jsx | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx index b59299c7bb..8267209bfb 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx @@ -44,5 +44,5 @@ export default createContainer(({ params }) => ({ openChat: params.chatID, userActions: Service.userActions, isBreakoutRoom: meetingIsBreakout(), - isMeetingLocked: Service.isMeetingLocked(), -}), UserListContainer); + isMeetingLocked: Service.isMeetingLocked, +}), UserListContainer); \ No newline at end of file diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 47b2ee3226..9f2af3bff4 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -211,8 +211,8 @@ const getCurrentUser = () => { return (currentUser) ? mapUser(currentUser) : null; }; -const isMeetingLocked = () => { - const meeting = Meetings.findOne({ }); +const isMeetingLocked = (id) => { + const meeting = Meetings.findOne({ meetingId: id }); let isLocked = false; if (meeting.lockSettingsProp === 'undefined'){ diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx index f34721ffa1..6032d63ee2 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx @@ -240,6 +240,7 @@ class UserListItem extends Component { intl, compact, isMeetingLocked, + meeting, } = this.props; if (compact) { @@ -247,8 +248,9 @@ class UserListItem extends Component { } const userNameSub = []; + const isViewer = (!user.isPresenter || !user.isModerator) ? true : false; - if (isMeetingLocked && !user.isPresenter && !user.isModerator) { + if (isMeetingLocked(meeting.meetingId) && isViewer) { userNameSub.push( {intl.formatMessage(messages.locked)} @@ -430,4 +432,4 @@ class UserListItem extends Component { UserListItem.propTypes = propTypes; UserListItem.defaultProps = defaultProps; -export default withRouter(injectIntl(UserListItem)); +export default withRouter(injectIntl(UserListItem)); \ No newline at end of file From 9193ae8849236065afca334be04879d3640a1994 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 6 Sep 2017 12:53:07 -0700 Subject: [PATCH 25/51] handle UserLockedInMeetingEvtMsg --- .../api/2.0/meetings/server/eventHandlers.js | 2 ++ .../server/handlers/userLockChange.js | 9 +++++++ .../server/modifiers/changeUserLock.js | 26 +++++++++++++++++++ .../imports/ui/components/chat/service.js | 2 +- .../user-list/user-list-item/component.jsx | 4 +-- 5 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js create mode 100644 bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js index 7181bc6e21..dcd1f125db 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js @@ -3,8 +3,10 @@ import handleMeetingCreation from './handlers/meetingCreation'; import handleGetAllMeetings from './handlers/getAllMeetings'; import handleMeetingEnd from './handlers/meetingEnd'; import handleMeetingLocksChange from './handlers/meetingLockChange'; +import handleUserLockChange from './handlers/userLockChange'; RedisPubSub.on('MeetingCreatedEvtMsg', handleMeetingCreation); RedisPubSub.on('SyncGetMeetingInfoRespMsg', handleGetAllMeetings); RedisPubSub.on('MeetingEndingEvtMsg', handleMeetingEnd); RedisPubSub.on('LockSettingsInMeetingChangedEvtMsg', handleMeetingLocksChange); +RedisPubSub.on('UserLockedInMeetingEvtMsg', handleUserLockChange); \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js new file mode 100644 index 0000000000..becde61783 --- /dev/null +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js @@ -0,0 +1,9 @@ +import { check } from 'meteor/check'; +import changeUserLock from '../modifiers/changeUserLock'; + +export default function handleLockSettingsInMeeting({ body }, meetingId) { + check(meetingId, String); + check(body, Object); + + return changeUserLock(meetingId, body); +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js new file mode 100644 index 0000000000..b3a1c56fd1 --- /dev/null +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js @@ -0,0 +1,26 @@ +import Logger from '/imports/startup/server/logger'; +import Users from '/imports/api/2.0/users'; +import { check } from 'meteor/check'; + +export default function changeUserLock(meetingId, payload) { + check(meetingId, String); + check(payload, Object) + + const selector = { + userId: payload.userId, + }; + + const modifier = { + $set: { + locked: payload.locked, + }, + }; + + const cb = (err) => { + if (err) { + return Logger.error(`Changing user lock setting: ${err}`); + } + }; + + return Users.upsert(selector, modifier, cb); +}; \ No newline at end of file diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index 8993d80e11..e2f2c84cc6 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -115,7 +115,7 @@ const isChatLocked = (receiverID) => { const isPrivChatLocked = meeting.lockSettingsProp.disablePrivChat; const isViewer = user.role === "VIEWER"; - return ((isPublic && isPubChatLocked && isViewer) || (!isPublic && isPrivChatLocked && isViewer)); + return ((isPublic && isPubChatLocked && isViewer && user.locked) || (!isPublic && isPrivChatLocked && isViewer && user.locked)); }; const hasUnreadMessages = (receiverID) => { diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx index 6032d63ee2..d056c04a1b 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx @@ -248,9 +248,9 @@ class UserListItem extends Component { } const userNameSub = []; - const isViewer = (!user.isPresenter || !user.isModerator) ? true : false; + const isViewer = (!user.isPresenter && !user.isModerator) ? true : false; - if (isMeetingLocked(meeting.meetingId) && isViewer) { + if (isMeetingLocked(meeting.meetingId) && isViewer && user.isLocked) { userNameSub.push( {intl.formatMessage(messages.locked)} From 5a6183dc34c292219d0e7d89f47a3e52b3678f42 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Wed, 6 Sep 2017 12:57:24 -0700 Subject: [PATCH 26/51] fix undefined check --- .../imports/ui/components/chat/service.js | 14 ++++++------- .../ui/components/user-list/service.js | 20 +++++++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index e2f2c84cc6..1554529e0b 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -107,15 +107,15 @@ const isChatLocked = (receiverID) => { const meeting = Meetings.findOne({}); const user = Users.findOne({}); - if (meeting.lockSettingsProp === 'undefined'){ - return false; + if (meeting.lockSettingsProp !== 'undefined'){ + const isPubChatLocked = meeting.lockSettingsProp.disablePubChat; + const isPrivChatLocked = meeting.lockSettingsProp.disablePrivChat; + const isViewer = user.role === "VIEWER"; + + return ((isPublic && isPubChatLocked && isViewer && user.locked) || (!isPublic && isPrivChatLocked && isViewer && user.locked)); } - const isPubChatLocked = meeting.lockSettingsProp.disablePubChat; - const isPrivChatLocked = meeting.lockSettingsProp.disablePrivChat; - const isViewer = user.role === "VIEWER"; - - return ((isPublic && isPubChatLocked && isViewer && user.locked) || (!isPublic && isPrivChatLocked && isViewer && user.locked)); + return false; }; const hasUnreadMessages = (receiverID) => { diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 9f2af3bff4..1c1a75cd28 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -215,17 +215,15 @@ const isMeetingLocked = (id) => { const meeting = Meetings.findOne({ meetingId: id }); let isLocked = false; - if (meeting.lockSettingsProp === 'undefined'){ - return isLocked; - } - - const lockSettings = meeting.lockSettingsProp; - - if (lockSettings.disableCam - || lockSettings.disableMic - || lockSettings.disablePrivChat - || lockSettings.disablePubChat ) { - isLocked = true; + if (meeting.lockSettingsProp !== 'undefined'){ + const lockSettings = meeting.lockSettingsProp; + + if (lockSettings.disableCam + || lockSettings.disableMic + || lockSettings.disablePrivChat + || lockSettings.disablePubChat ) { + isLocked = true; + } } return isLocked; From 00ddba6de933c14841cca2809acd0ac4e9077d17 Mon Sep 17 00:00:00 2001 From: Chad Pilkey Date: Wed, 6 Sep 2017 19:31:50 -0400 Subject: [PATCH 27/51] accessible close for TitleWindows --- .../branding/default/style/css/V2Theme.css | 16 +++++++---- .../locale/en_US/bbbResources.properties | 9 ++++-- .../main/views/AudioSelectionWindow.mxml | 28 ++++++++----------- .../polling/views/PollChoicesModal.mxml | 8 ++++-- .../present/ui/views/FileDownloadWindow.mxml | 22 ++++++++++----- .../present/ui/views/FileUploadWindow.mxml | 23 +++++++++------ .../present/ui/views/PresentationWindow.mxml | 2 +- .../users/views/JoinBreakoutRoomWindow.mxml | 24 ++++++++++------ 8 files changed, 81 insertions(+), 51 deletions(-) mode change 100644 => 100755 bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollChoicesModal.mxml mode change 100644 => 100755 bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml diff --git a/bigbluebutton-client/branding/default/style/css/V2Theme.css b/bigbluebutton-client/branding/default/style/css/V2Theme.css index 8939454e3f..af6ab60247 100755 --- a/bigbluebutton-client/branding/default/style/css/V2Theme.css +++ b/bigbluebutton-client/branding/default/style/css/V2Theme.css @@ -432,7 +432,7 @@ users|JoinBreakoutRoomWindow { horizontalAlign : center; iconRooms : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Join_Room"); paddingBottom : 24; - paddingTop : 0; + paddingTop : 24; verticalGap : 18; } @@ -1361,17 +1361,14 @@ mx|Tab, .defaultTabStyle { */ mx|TitleWindow { - closeButtonDisabledSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Disabled"); - closeButtonDownSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Down"); - closeButtonOverSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Over"); - closeButtonUpSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Up"); borderColor : #FFFFFF; cornerRadius : 4; roundedBottomCorners : true; dropShadowEnabled : true; shadowDistance : 0; borderThickness : 1; - paddingTop : 5; + paddingTop : 10; + headerHeight : 0; } .titleWindowStyle { @@ -1381,6 +1378,13 @@ mx|TitleWindow { paddingBottom : 8; } +.titleWindowCloseButton { + disabledSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Disabled"); + downSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Down"); + overSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Over"); + upSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Up"); +} + /* //------------------------------ // ToolTip diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties index dc1279ed65..0ae4b7a88f 100755 --- a/bigbluebutton-client/locale/en_US/bbbResources.properties +++ b/bigbluebutton-client/locale/en_US/bbbResources.properties @@ -273,14 +273,16 @@ bbb.fileupload.uploadBtn.toolTip = Upload the selected file bbb.fileupload.deleteBtn.toolTip = Delete Presentation bbb.fileupload.showBtn = Show bbb.fileupload.showBtn.toolTip = Show Presentation -bbb.fileupload.okCancelBtn = Close -bbb.fileupload.okCancelBtn.toolTip = Close the File Upload dialog box +bbb.fileupload.close.tooltip = Close +bbb.fileupload.close.accessibilityName = Close the File Upload window bbb.fileupload.genThumbText = Generating thumbnails.. bbb.fileupload.progBarLbl = Progress: bbb.fileupload.fileFormatHint = Upload any office document or Portable Document Format (PDF) file. For best results upload PDF. bbb.fileupload.letUserDownload = Enable download of presentation bbb.fileupload.letUserDownload.tooltip = Check here if you want the other users to download your presentation bbb.filedownload.title = Download the Presentations +bbb.filedownload.close.tooltip = Close +bbb.filedownload.close.accessibilityName = Close file download window bbb.filedownload.fileLbl = Choose File to Download: bbb.filedownload.downloadBtn = Download bbb.filedownload.downloadBtn.toolTip = Download Presentation @@ -817,6 +819,9 @@ bbb.users.breakout.confirm = Join A Breakout Room bbb.users.breakout.invited = You have been invited to join Breakout Room bbb.users.breakout.accept = By accepting, you will automatically leave the audio and the video confrences. bbb.users.breakout.joinSession = Join Session +bbb.users.breakout.joinSession.accessibilityName = Join Breakout Room Session +bbb.users.breakout.joinSession.close.tooltip = Close +bbb.users.breakout.joinSession.close.accessibilityName = Close Join Breakout Room Window bbb.users.breakout.youareinroom = You are in Breakout Room {0} bbb.users.roomsGrid.room = Room bbb.users.roomsGrid.users = Users diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml index e49c52efb6..3a6612c8a6 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml @@ -24,11 +24,10 @@ with BigBlueButton; if not, see . xmlns:mate="http://mate.asfusion.com/" xmlns:common="org.bigbluebutton.common.*" initialize="init()" - creationComplete="creationCompleteHandler(event)" close="onCancelClicked()" verticalScrollPolicy="off" horizontalScrollPolicy="off" - showCloseButton="true"> + showCloseButton="false"> . } } - private function creationCompleteHandler(event:FlexEvent):void - { - this.mx_internal::closeButton.toolTip = ResourceUtil.getInstance().getString('bbb.micSettings.cancel'); - this.mx_internal::closeButton.accessibilityName = ResourceUtil.getInstance().getString('bbb.micSettings.cancel.toolTip'); - - tabIndexer.tabIndices.unshift(this.mx_internal::closeButton); - } - private function onMicClick():void { LOGGER.debug("AudioSelectionWindow - Share Microphone Clicked"); var dispatcher:Dispatcher = new Dispatcher(); @@ -127,14 +118,19 @@ with BigBlueButton; if not, see . - + - - + + + + + . xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="350" layout="vertical" - showCloseButton="true" - close="PopUpUtil.removePopUp(this)" + close="onCloseClicked()" show="{focusManager.setFocus(choiceFirst)}" xmlns:common="org.bigbluebutton.common.*"> . return result; } + private function onCloseClicked():void { + PopUpUtil.removePopUp(this); + } ]]> @@ -88,6 +90,8 @@ with BigBlueButton; if not, see . + diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml index fc19f3faa0..be5d8af413 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml @@ -24,11 +24,9 @@ with BigBlueButton; if not, see . xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mate="http://mate.asfusion.com/" xmlns:common="org.bigbluebutton.common.*" - layout="absolute" width="580" height="410" - showCloseButton="true" - close="{globalDispatch.dispatchEvent(new DownloadEvent(DownloadEvent.CLOSE_DOWNLOAD_WINDOW))}" + close="onCancelClicked()" initialize="initData();" > @@ -38,7 +36,8 @@ with BigBlueButton; if not, see . . private function initData():void { downloadablePresentations = PresentationModel.getInstance().getDownloadablePresentations(); } + + private function onCancelClicked():void { + globalDispatch.dispatchEvent(new DownloadEvent(DownloadEvent.CLOSE_DOWNLOAD_WINDOW)); + } ]]> @@ -60,9 +63,14 @@ with BigBlueButton; if not, see . - + + + + . @@ -112,8 +110,6 @@ with BigBlueButton; if not, see . protected function onCreationComplete(event:FlexEvent):void { dispatcher = new Dispatcher(); - - this.mx_internal::closeButton.toolTip = ResourceUtil.getInstance().getString('bbb.fileupload.okCancelBtn.toolTip'); } private function initData():void { @@ -311,11 +307,11 @@ with BigBlueButton; if not, see . } private function disableClosing():void { - this.closeButton.enabled = false; + this.closeButton2.enabled = false; } private function enableClosing():void { - this.closeButton.enabled = true; + this.closeButton2.enabled = true; } private function handlePresentationRemoved(e:RemovePresentationEvent):void { @@ -341,14 +337,23 @@ with BigBlueButton; if not, see . dispatcher.dispatchEvent(rollEvent); } + private function onCancelClicked():void { + globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW)); + } + ]]> - + + width="100%" /> + + diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml index a353914d6a..e5f4f4476b 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml @@ -792,7 +792,7 @@ with BigBlueButton; if not, see . + tabIndices="{[minimizeBtn, maximizeRestoreBtn, closeBtn, slideView.slideLoader, uploadPres, pollStartBtn, quickPollBtn, backButton, btnSlideNum, forwardButton, zoomSlider, btnFitToWidth, btnFitToPage]}"/> diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml old mode 100644 new mode 100755 index c57c483692..0e5ff8a612 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml @@ -23,10 +23,8 @@ with BigBlueButton; if not, see . + close="onCloseClick()" + width="600" xmlns:common="org.bigbluebutton.common.*"> . navigateToURL(new URLRequest(this.joinUrl), "_blank"); PopUpUtil.removePopUp(this); } + + private function onCloseClick():void { + PopUpUtil.removePopUp(this); + } ]]> - + + + + @@ -72,9 +79,10 @@ with BigBlueButton; if not, see . horizontalCenter="0" /> - + From 13e6357b19b6a6a291ab4ecdc2f529dd6f5109d1 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 7 Sep 2017 07:31:19 -0700 Subject: [PATCH 28/51] fix line endings --- .../imports/api/2.0/meetings/server/eventHandlers.js | 2 +- .../imports/api/2.0/meetings/server/handlers/userLockChange.js | 2 +- .../imports/api/2.0/meetings/server/modifiers/changeUserLock.js | 2 +- bigbluebutton-html5/imports/ui/components/chat/service.js | 2 +- .../imports/ui/components/user-list/container.jsx | 2 +- bigbluebutton-html5/imports/ui/components/user-list/service.js | 2 +- .../ui/components/user-list/user-list-item/component.jsx | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js index dcd1f125db..4ce1d21764 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/eventHandlers.js @@ -9,4 +9,4 @@ RedisPubSub.on('MeetingCreatedEvtMsg', handleMeetingCreation); RedisPubSub.on('SyncGetMeetingInfoRespMsg', handleGetAllMeetings); RedisPubSub.on('MeetingEndingEvtMsg', handleMeetingEnd); RedisPubSub.on('LockSettingsInMeetingChangedEvtMsg', handleMeetingLocksChange); -RedisPubSub.on('UserLockedInMeetingEvtMsg', handleUserLockChange); \ No newline at end of file +RedisPubSub.on('UserLockedInMeetingEvtMsg', handleUserLockChange); diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js index becde61783..cf7719c3e1 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js @@ -6,4 +6,4 @@ export default function handleLockSettingsInMeeting({ body }, meetingId) { check(body, Object); return changeUserLock(meetingId, body); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js index b3a1c56fd1..c7a7ed86f3 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js @@ -23,4 +23,4 @@ export default function changeUserLock(meetingId, payload) { }; return Users.upsert(selector, modifier, cb); -}; \ No newline at end of file +}; diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index 1554529e0b..a129234b83 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -230,4 +230,4 @@ export default { closePrivateChat, exportChat, clearPublicChatHistory, -}; \ No newline at end of file +}; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx index 8267209bfb..77650a62db 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx @@ -45,4 +45,4 @@ export default createContainer(({ params }) => ({ userActions: Service.userActions, isBreakoutRoom: meetingIsBreakout(), isMeetingLocked: Service.isMeetingLocked, -}), UserListContainer); \ No newline at end of file +}), UserListContainer); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 1c1a75cd28..7771a138da 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -234,4 +234,4 @@ export default { getOpenChats, getCurrentUser, isMeetingLocked -}; \ No newline at end of file +}; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx index d056c04a1b..4bfc35320b 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-item/component.jsx @@ -432,4 +432,4 @@ class UserListItem extends Component { UserListItem.propTypes = propTypes; UserListItem.defaultProps = defaultProps; -export default withRouter(injectIntl(UserListItem)); \ No newline at end of file +export default withRouter(injectIntl(UserListItem)); From 21c5ffee8fd04fe889276b54fef24293af4cce13 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 7 Sep 2017 09:37:13 -0700 Subject: [PATCH 29/51] remove need for separate headerBuilder function --- .../server/methods/clearPublicChatHistory.js | 5 +-- .../api/2.0/chat/server/methods/sendChat.js | 5 +-- .../2.0/polls/server/methods/publishVote.js | 5 +-- .../2.0/slides/server/methods/switchSlide.js | 5 +-- .../2.0/slides/server/modifiers/addSlide.js | 5 +-- .../users/server/methods/assignPresenter.js | 5 +-- .../users/server/methods/requestStunTurn.js | 5 +-- .../users/server/methods/setEmojiStatus.js | 5 +-- .../api/2.0/users/server/methods/userJoin.js | 7 ++-- .../2.0/users/server/methods/userLeaving.js | 7 ++-- .../users/server/methods/validateAuthToken.js | 7 ++-- .../server/methods/listenOnlyToggle.js | 9 ++--- .../voice-users/server/methods/muteToggle.js | 7 ++-- .../imports/api/common/server/helpers.js | 21 +---------- .../imports/startup/server/redis2x.js | 35 ++----------------- 15 files changed, 21 insertions(+), 112 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js index 26c19ef540..e988a54087 100644 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js @@ -1,7 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function clearPublicChatHistory(credentials) { const REDIS_CONFIG = Meteor.settings.redis; @@ -16,7 +15,5 @@ export default function clearPublicChatHistory(credentials) { const payload = {}; - //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, eventName, meetingId, payload, { userId: requesterUserId }); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js index adc6b80536..273567f2a0 100755 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js @@ -2,7 +2,6 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import RegexWebUrl from '/imports/utils/regex-weburl'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; const HTML_SAFE_MAP = { '<': '<', @@ -51,7 +50,5 @@ export default function sendChat(credentials, message) { eventName = 'SendPublicMessagePubMsg'; } - //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, { userId: requesterUserId }); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js index 59d2f34c03..c3a32d48a0 100644 --- a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js +++ b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js @@ -2,7 +2,6 @@ import RedisPubSub from '/imports/startup/server/redis2x'; import { check } from 'meteor/check'; import Polls from '/imports/api/2.0/polls'; import Logger from '/imports/startup/server/logger'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function publishVote(credentials, id, pollAnswerId) { // TODO discuss location const REDIS_CONFIG = Meteor.settings.redis; @@ -53,7 +52,5 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis Polls.update(selector, modifier, cb); - //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js index d5eae2b008..421970b4e7 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js @@ -3,7 +3,6 @@ import Slides from '/imports/api/2.0/slides'; import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function switchSlide(credentials, slideNumber) { const REDIS_CONFIG = Meteor.settings.redis; @@ -46,7 +45,5 @@ export default function switchSlide(credentials, slideNumber) { presentationId: Presentation.id, }; - //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js index 74c385f2e6..9c723fa665 100755 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js @@ -6,7 +6,6 @@ import RedisPubSub from '/imports/startup/server/redis2x'; import Slides from '/imports/api/2.0/slides'; import Logger from '/imports/startup/server/logger'; import { SVG, PNG } from '/imports/utils/mimeTypes'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; const requestWhiteboardHistory = (meetingId, slideId) => { const REDIS_CONFIG = Meteor.settings.redis; @@ -17,8 +16,6 @@ const requestWhiteboardHistory = (meetingId, slideId) => { whiteboardId: slideId, }; - //const header = buildMessageHeader(EVENT_NAME, meetingId, { userId: 'nodeJSapp' }); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: 'nodeJSapp' }); }; @@ -99,4 +96,4 @@ export default function addSlide(meetingId, presentationId, slide) { }) .catch(reason => Logger.error(`Error parsing image size. ${reason}. slide=${slide.id} uri=${imageUri}`)); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js index a07a67224d..c3fec76ba1 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js @@ -3,7 +3,6 @@ import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; import Users from '/imports/api/2.0/users'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function assignPresenter(credentials, userId) { const REDIS_CONFIG = Meteor.settings.redis; @@ -36,7 +35,5 @@ export default function assignPresenter(credentials, userId) { Logger.verbose(`User '${userId}' setted as presenter by '${ requesterUserId}' from meeting '${meetingId}'`); - //const header = buildMessageHeader(EVENT_NAME, meetingId, User.userId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: User.userId }); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js index 3871a8739e..9315a720e9 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js @@ -2,7 +2,6 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function requestStunTurn(meetingId, requesterUserId) { const REDIS_CONFIG = Meteor.settings.redis; @@ -19,7 +18,5 @@ export default function requestStunTurn(meetingId, requesterUserId) { Logger.verbose(`User '${requesterUserId}' requested stun/turn from meeting '${meetingId}'`); - //const header = buildMessageHeader(EVENT_NAME, meetingId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js index 12d5848843..fb59b40248 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js @@ -2,7 +2,6 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function setEmojiStatus(credentials, userId, status) { const REDIS_CONFIG = Meteor.settings.redis; @@ -23,7 +22,5 @@ export default function setEmojiStatus(credentials, userId, status) { Logger.verbose(`User '${userId}' emoji status updated to '${status}' by '${ requesterUserId}' from meeting '${meetingId}'`); - //const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js index f52596753f..f0311a383f 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js @@ -2,7 +2,6 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function userJoin(meetingId, userId, authToken) { const REDIS_CONFIG = Meteor.settings.redis; @@ -20,7 +19,5 @@ export default function userJoin(meetingId, userId, authToken) { Logger.info(`User '${userId}' is joining meeting '${meetingId}'`); - const header = buildMessageHeader(EVENT_NAME, meetingId, userId); - - return RedisPubSub.publ(CHANNEL, EVENT_NAME, meetingId, payload, header); -} + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId }); +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js index e1e131ef76..b25a1ce605 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js @@ -3,7 +3,6 @@ import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; import Users from '/imports/api/2.0/users'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; const OFFLINE_CONNECTION_STATUS = 'offline'; @@ -58,7 +57,5 @@ export default function userLeaving(credentials, userId) { Logger.verbose(`User '${requesterUserId}' left meeting '${meetingId}'`); - const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header); -} + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js index 7941420b9c..871d8fa036 100755 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js @@ -3,7 +3,6 @@ import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; import Logger from '/imports/startup/server/logger'; import Users from '/imports/api/2.0/users'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; import createDummyUser2x from '../modifiers/createDummyUser'; import setConnectionStatus from '../modifiers/setConnectionStatus'; @@ -40,7 +39,5 @@ export default function validateAuthToken(credentials) { requesterUserId }' is trying to validate auth tokenfor meeting '${meetingId}'`); - const header = buildMessageHeader(EVENT_NAME, meetingId, requesterUserId); - - return RedisPubSub.publ(CHANNEL, EVENT_NAME, meetingId, payload, header); -} + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js index acbdb1ccc7..ff60ce5c89 100755 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js @@ -36,11 +36,6 @@ export default function listenOnlyToggle(credentials, isJoining = true) { // check(User.user.name, String); - const header = { - name: EVENT_NAME, - voiceConf: Meeting.voiceProp.voiceConf, - }; - const payload = { userId: requesterUserId, name: VoiceUser.callerName, @@ -49,5 +44,5 @@ export default function listenOnlyToggle(credentials, isJoining = true) { Logger.verbose(`VoiceUser '${requesterUserId}' ${isJoining ? 'joined' : 'left'} global audio from meeting '${meetingId}'`); - return RedisPubSub.publ(CHANNEL, EVENT_NAME, meetingId, payload, header); -} + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: Meeting.voiceProp.voiceConf }); +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js index f0e25e0786..1eda165287 100644 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js @@ -1,7 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import RedisPubSub from '/imports/startup/server/redis2x'; -import { buildMessageHeader } from '/imports/api/common/server/helpers'; export default function muteToggle(credentials, userId) { const REDIS_CONFIG = Meteor.settings.redis; @@ -18,7 +17,5 @@ export default function muteToggle(credentials, userId) { mutedBy: requesterUserId, }; - const header = buildMessageHeader(EVENT_NAME, meetingId, userId); - - return RedisPubSub.publ(CHANNEL, EVENT_NAME, meetingId, payload, header); -} + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId }); +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/common/server/helpers.js b/bigbluebutton-html5/imports/api/common/server/helpers.js index 0abfc28bcc..29e2732730 100755 --- a/bigbluebutton-html5/imports/api/common/server/helpers.js +++ b/bigbluebutton-html5/imports/api/common/server/helpers.js @@ -12,25 +12,6 @@ export function appendMessageHeader(eventName, messageObj) { return messageObj; } -export function buildMessageHeader(eventName, meetingId, userId = {}) { - let header; - - if (userId.length > 0) { - header = { - name: eventName, - meetingId, - userId - } - } else if (userid.length == 0) { - header = { - name: eventName, - meetingId - } - } - - return header; -} - export const indexOf = [].indexOf || function (item) { for (let i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) { @@ -56,4 +37,4 @@ export const translateHTML5ToFlash = function (message) { export const inReplyToHTML5Client = function (arg) { return arg.routing.userId === 'nodeJSapp'; -}; +}; \ No newline at end of file diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index 8699e9d2ce..42ff0a9200 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -51,8 +51,7 @@ class RedisPubSub2x { }, core: { header: Object.assign({ - name: eventName, - timestamp: new Date().getTime(), + name: eventName, meetingId, }, userId), body: payload, @@ -67,36 +66,6 @@ class RedisPubSub2x { }); } - publ(channel, eventName, meetingId, payload = {}, header = {}) { - const header2x = { - name: eventName, - meetingId, - }; - - const msgHeader = header === {} ? header2x : header; - - const envelope = { - envelope: { - name: eventName, - routing: { - sender: 'bbb-apps-akka', - // sender: 'html5-server', // TODO - }, - }, - core: { - header: msgHeader, - body: payload, - }, - }; - - Logger.warn(`<<<<< { - if (err) { - Logger.error('Tried to publish to %s', channel, envelope); - } - }); - } - handleSubscribe() { if (this.didSendRequestEvent) return; @@ -190,4 +159,4 @@ Meteor.startup(() => { RedisPubSubSingleton.init(); }); -export default RedisPubSubSingleton; +export default RedisPubSubSingleton; \ No newline at end of file From bc8718e2631e4f314f89e5ae2c86f35cd8ec9654 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 7 Sep 2017 09:47:20 -0700 Subject: [PATCH 30/51] fix line endidngs --- .../api/2.0/chat/server/methods/clearPublicChatHistory.js | 2 +- .../imports/api/2.0/chat/server/methods/sendChat.js | 2 +- .../imports/api/2.0/polls/server/methods/publishVote.js | 2 +- .../imports/api/2.0/slides/server/methods/switchSlide.js | 2 +- .../imports/api/2.0/slides/server/modifiers/addSlide.js | 2 +- .../imports/api/2.0/users/server/methods/assignPresenter.js | 2 +- .../imports/api/2.0/users/server/methods/requestStunTurn.js | 2 +- .../imports/api/2.0/users/server/methods/setEmojiStatus.js | 2 +- .../imports/api/2.0/users/server/methods/userJoin.js | 2 +- .../imports/api/2.0/users/server/methods/userLeaving.js | 2 +- .../imports/api/2.0/users/server/methods/validateAuthToken.js | 2 +- .../api/2.0/voice-users/server/methods/listenOnlyToggle.js | 2 +- .../imports/api/2.0/voice-users/server/methods/muteToggle.js | 2 +- bigbluebutton-html5/imports/api/common/server/helpers.js | 2 +- bigbluebutton-html5/imports/startup/server/redis2x.js | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) mode change 100755 => 100644 bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js mode change 100755 => 100644 bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js mode change 100755 => 100644 bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js mode change 100755 => 100644 bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js mode change 100755 => 100644 bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js mode change 100755 => 100644 bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js mode change 100755 => 100644 bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js mode change 100755 => 100644 bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js mode change 100755 => 100644 bigbluebutton-html5/imports/api/common/server/helpers.js diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js index e988a54087..58db153e09 100644 --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/clearPublicChatHistory.js @@ -16,4 +16,4 @@ export default function clearPublicChatHistory(credentials) { const payload = {}; return RedisPubSub.publish(CHANNEL, eventName, meetingId, payload, { userId: requesterUserId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js old mode 100755 new mode 100644 index 273567f2a0..7d08e015dc --- a/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js +++ b/bigbluebutton-html5/imports/api/2.0/chat/server/methods/sendChat.js @@ -51,4 +51,4 @@ export default function sendChat(credentials, message) { } return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, { userId: requesterUserId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js index c3a32d48a0..489bb58685 100644 --- a/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js +++ b/bigbluebutton-html5/imports/api/2.0/polls/server/methods/publishVote.js @@ -53,4 +53,4 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis Polls.update(selector, modifier, cb); return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js old mode 100755 new mode 100644 index 421970b4e7..14e8338dd6 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/methods/switchSlide.js @@ -46,4 +46,4 @@ export default function switchSlide(credentials, slideNumber) { }; return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js old mode 100755 new mode 100644 index 9c723fa665..83238377b1 --- a/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js +++ b/bigbluebutton-html5/imports/api/2.0/slides/server/modifiers/addSlide.js @@ -96,4 +96,4 @@ export default function addSlide(meetingId, presentationId, slide) { }) .catch(reason => Logger.error(`Error parsing image size. ${reason}. slide=${slide.id} uri=${imageUri}`)); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js old mode 100755 new mode 100644 index c3fec76ba1..e332c42d94 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/assignPresenter.js @@ -36,4 +36,4 @@ export default function assignPresenter(credentials, userId) { requesterUserId}' from meeting '${meetingId}'`); return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: User.userId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js index 9315a720e9..93b5f3649a 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/requestStunTurn.js @@ -19,4 +19,4 @@ export default function requestStunTurn(meetingId, requesterUserId) { Logger.verbose(`User '${requesterUserId}' requested stun/turn from meeting '${meetingId}'`); return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js old mode 100755 new mode 100644 index fb59b40248..6363e5174e --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/setEmojiStatus.js @@ -23,4 +23,4 @@ export default function setEmojiStatus(credentials, userId, status) { requesterUserId}' from meeting '${meetingId}'`); return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js index f0311a383f..437b322f7e 100644 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userJoin.js @@ -20,4 +20,4 @@ export default function userJoin(meetingId, userId, authToken) { Logger.info(`User '${userId}' is joining meeting '${meetingId}'`); return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js old mode 100755 new mode 100644 index b25a1ce605..6c6f992c81 --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/userLeaving.js @@ -58,4 +58,4 @@ export default function userLeaving(credentials, userId) { Logger.verbose(`User '${requesterUserId}' left meeting '${meetingId}'`); return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js old mode 100755 new mode 100644 index 871d8fa036..2a4b13bc5d --- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js +++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/validateAuthToken.js @@ -40,4 +40,4 @@ export default function validateAuthToken(credentials) { }' is trying to validate auth tokenfor meeting '${meetingId}'`); return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js old mode 100755 new mode 100644 index ff60ce5c89..0a5a699432 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js @@ -45,4 +45,4 @@ export default function listenOnlyToggle(credentials, isJoining = true) { ? 'joined' : 'left'} global audio from meeting '${meetingId}'`); return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: Meeting.voiceProp.voiceConf }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js index 1eda165287..4e131d6af8 100644 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/muteToggle.js @@ -18,4 +18,4 @@ export default function muteToggle(credentials, userId) { }; return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId }); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/common/server/helpers.js b/bigbluebutton-html5/imports/api/common/server/helpers.js old mode 100755 new mode 100644 index 29e2732730..9d65f301a6 --- a/bigbluebutton-html5/imports/api/common/server/helpers.js +++ b/bigbluebutton-html5/imports/api/common/server/helpers.js @@ -37,4 +37,4 @@ export const translateHTML5ToFlash = function (message) { export const inReplyToHTML5Client = function (arg) { return arg.routing.userId === 'nodeJSapp'; -}; \ No newline at end of file +}; diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index 42ff0a9200..a7bfd0c6b3 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -159,4 +159,4 @@ Meteor.startup(() => { RedisPubSubSingleton.init(); }); -export default RedisPubSubSingleton; \ No newline at end of file +export default RedisPubSubSingleton; From b2b36254abee1506815cb84b467b9a515d690b19 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 7 Sep 2017 10:33:23 -0700 Subject: [PATCH 31/51] remove check from handler add exhaustive check to modifier --- .../meetings/server/handlers/meetingLockChange.js | 4 +--- .../2.0/meetings/server/handlers/userLockChange.js | 4 +--- .../meetings/server/modifiers/changeLockSettings.js | 13 +++++++++++-- .../2.0/meetings/server/modifiers/changeUserLock.js | 8 ++++++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js index dc5bfeebc8..19aea87dd7 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js @@ -2,8 +2,6 @@ import { check } from 'meteor/check'; import changeLockSettings from '../modifiers/changeLockSettings'; export default function handleLockSettingsInMeeting({ body }, meetingId) { - check(meetingId, String); - check(body, Object); return changeLockSettings(meetingId, body); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js index cf7719c3e1..53e1561dc0 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js @@ -2,8 +2,6 @@ import { check } from 'meteor/check'; import changeUserLock from '../modifiers/changeUserLock'; export default function handleLockSettingsInMeeting({ body }, meetingId) { - check(meetingId, String); - check(body, Object); return changeUserLock(meetingId, body); -} +} \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js index 18cd751f53..33abce85ef 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js @@ -4,7 +4,16 @@ import { check } from 'meteor/check'; export default function changeLockSettings(meetingId, payload) { check(meetingId, String); - check(payload, Object) + check(payload, { + disableCam: Boolean, + disableMic: Boolean, + disablePrivChat: Boolean, + disablePubChat: Boolean, + lockedLayout: Boolean, + lockOnJoin: Boolean, + lockOnJoinConfigurable: Boolean, + setBy: String, + }); const selector = { meetingId @@ -23,4 +32,4 @@ export default function changeLockSettings(meetingId, payload) { }; return Meetings.upsert(selector, modifier, cb); -}; +}; \ No newline at end of file diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js index c7a7ed86f3..44ec2811ca 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js @@ -4,7 +4,11 @@ import { check } from 'meteor/check'; export default function changeUserLock(meetingId, payload) { check(meetingId, String); - check(payload, Object) + check(payload, { + userId: String, + locked: Boolean, + lockedBy: String, + }); const selector = { userId: payload.userId, @@ -23,4 +27,4 @@ export default function changeUserLock(meetingId, payload) { }; return Users.upsert(selector, modifier, cb); -}; +}; \ No newline at end of file From 876097a0f4105a562198cb7b20199a699ac2427c Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 7 Sep 2017 10:38:00 -0700 Subject: [PATCH 32/51] fix line endings --- .../api/2.0/meetings/server/handlers/meetingLockChange.js | 2 +- .../imports/api/2.0/meetings/server/handlers/userLockChange.js | 2 +- .../api/2.0/meetings/server/modifiers/changeLockSettings.js | 2 +- .../imports/api/2.0/meetings/server/modifiers/changeUserLock.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js index 19aea87dd7..1f8c14d632 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js @@ -4,4 +4,4 @@ import changeLockSettings from '../modifiers/changeLockSettings'; export default function handleLockSettingsInMeeting({ body }, meetingId) { return changeLockSettings(meetingId, body); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js index 53e1561dc0..bc0331d79f 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js @@ -4,4 +4,4 @@ import changeUserLock from '../modifiers/changeUserLock'; export default function handleLockSettingsInMeeting({ body }, meetingId) { return changeUserLock(meetingId, body); -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js index 33abce85ef..f962c8add2 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js @@ -32,4 +32,4 @@ export default function changeLockSettings(meetingId, payload) { }; return Meetings.upsert(selector, modifier, cb); -}; \ No newline at end of file +}; diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js index 44ec2811ca..a17f14c2ed 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeUserLock.js @@ -27,4 +27,4 @@ export default function changeUserLock(meetingId, payload) { }; return Users.upsert(selector, modifier, cb); -}; \ No newline at end of file +}; From b0f3ca7a1a43890543b3a09b5dc4da2cc1ceb3b0 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 7 Sep 2017 10:41:26 -0700 Subject: [PATCH 33/51] remove unused import --- .../api/2.0/meetings/server/handlers/meetingLockChange.js | 1 - .../imports/api/2.0/meetings/server/handlers/userLockChange.js | 1 - 2 files changed, 2 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js index 1f8c14d632..813820aaca 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/meetingLockChange.js @@ -1,4 +1,3 @@ -import { check } from 'meteor/check'; import changeLockSettings from '../modifiers/changeLockSettings'; export default function handleLockSettingsInMeeting({ body }, meetingId) { diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js index bc0331d79f..c1d25b68f0 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/handlers/userLockChange.js @@ -1,4 +1,3 @@ -import { check } from 'meteor/check'; import changeUserLock from '../modifiers/changeUserLock'; export default function handleLockSettingsInMeeting({ body }, meetingId) { From ef6d3059a7e7664f4348d8b5888f35fb524fcb2f Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Thu, 7 Sep 2017 12:06:48 -0700 Subject: [PATCH 34/51] fix lint issue --- bigbluebutton-html5/imports/ui/components/chat/service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index a129234b83..f747d5ebd4 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -107,7 +107,7 @@ const isChatLocked = (receiverID) => { const meeting = Meetings.findOne({}); const user = Users.findOne({}); - if (meeting.lockSettingsProp !== 'undefined'){ + if (meeting.lockSettingsProp !== 'undefined') { const isPubChatLocked = meeting.lockSettingsProp.disablePubChat; const isPrivChatLocked = meeting.lockSettingsProp.disablePrivChat; const isViewer = user.role === "VIEWER"; From 8b6d903c87ba9dad41ca9f63d23274cc4520c9f7 Mon Sep 17 00:00:00 2001 From: Chad Pilkey Date: Thu, 7 Sep 2017 15:44:10 -0400 Subject: [PATCH 35/51] fix some tab order issues in the Flash client --- .../src/org/bigbluebutton/main/views/MainApplicationShell.mxml | 2 +- .../src/org/bigbluebutton/modules/chat/views/AddChatTabBox.mxml | 2 +- .../modules/present/ui/views/PresentationWindow.mxml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml index 1657777be8..9626976ab8 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml @@ -1032,7 +1032,7 @@ with BigBlueButton; if not, see . + tabIndices="{[warningBtn, langSelector, logBtn, fullScreenBtn]}"/> . - + . + tabIndices="{[minimizeBtn, maximizeRestoreBtn, closeBtn, slideView.slideLoader, uploadPres, pollStartBtn, quickPollBtn, downloadPres, backButton, btnSlideNum, forwardButton, zoomSlider, btnFitToWidth, btnFitToPage]}"/> From b346eb6479de5145b5569943bb7576254a92fd7a Mon Sep 17 00:00:00 2001 From: Chad Pilkey Date: Thu, 7 Sep 2017 17:48:13 -0400 Subject: [PATCH 36/51] SharedNotesNameWindow accessible close --- .../locale/en_US/bbbResources.properties | 4 +++- .../sharednotes/views/SharedNotesNameWindow.mxml | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties index 9976fdf479..6075522a43 100755 --- a/bigbluebutton-client/locale/en_US/bbbResources.properties +++ b/bigbluebutton-client/locale/en_US/bbbResources.properties @@ -519,7 +519,9 @@ bbb.notes.saveBtn = Save bbb.notes.saveBtn.toolTip = Save Note bbb.sharedNotes.title = Shared notes bbb.sharedNotes.quickLink.label = Shared notes Window -bbb.sharedNotes.name = Note name +bbb.sharedNotes.createNoteWindow.label = Note name +bbb.sharedNotes.createNoteWindow.close.tooltip = Close +bbb.sharedNotes.createNoteWindow.close.accessibilityName = Close create new note window bbb.sharedNotes.typing.single = {0} is typing... bbb.sharedNotes.typing.double = {0} and {1} are typing... bbb.sharedNotes.typing.multiple = Several people are typing... diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml index d30107263d..bb7af42195 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml @@ -26,12 +26,10 @@ with BigBlueButton; if not, see . verticalScrollPolicy="off" horizontalScrollPolicy="off" horizontalAlign="center" - showCloseButton="true" close="onCancelClicked()" creationComplete="onCreationComplete()" keyUp="keyUpHandler(event)" - width="250" - title="{ResourceUtil.getInstance().getString('bbb.sharedNotes.name')}"> + width="250" xmlns:common="org.bigbluebutton.common.*"> . ]]> + + + + Date: Mon, 11 Sep 2017 00:45:39 -0400 Subject: [PATCH 37/51] tab order fixes --- .../org/bigbluebutton/main/views/MainApplicationShell.mxml | 6 +++++- .../src/org/bigbluebutton/main/views/MainToolbar.mxml | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml index 0701165774..d814efa744 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml @@ -765,9 +765,13 @@ with BigBlueButton; if not, see . private function handleAddToolbarComponent(event:ToolbarButtonEvent):void { if (event.location == ToolbarButtonEvent.BOTTOM_TOOLBAR) { - (event.button as UIComponent).tabIndex = tabIndexer.startIndex + addedBtns.numChildren + 10; + var newComponentTabIndex:int = tabIndexer.startIndex + addedBtns.numChildren + 10; + (event.button as UIComponent).tabIndex = newComponentTabIndex; addedBtns.addChild(event.button as UIComponent); //realignButtons(); + + //need to force the fullscreen button to be after it + fullScreenBtn.tabIndex = newComponentTabIndex + 1; } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml index d01abbbcfc..7a2d3d72ea 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml @@ -365,7 +365,7 @@ with BigBlueButton; if not, see . } numButtons++; - (event.button as UIComponent).tabIndex = quickLinksIndexer.startIndex + 5; + (event.button as UIComponent).tabIndex = quickLinksIndexer.startIndex + 6; } } @@ -508,7 +508,7 @@ with BigBlueButton; if not, see . - + From 0a6f5880042fc0476e924206029af98e05a6b9bf Mon Sep 17 00:00:00 2001 From: Chad Pilkey Date: Mon, 11 Sep 2017 00:46:18 -0400 Subject: [PATCH 38/51] set the label correctly on the audible chat notification --- .../src/org/bigbluebutton/modules/chat/views/AddChatTabBox.mxml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/AddChatTabBox.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/AddChatTabBox.mxml index fea9726a97..7887fc9f9e 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/AddChatTabBox.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/AddChatTabBox.mxml @@ -220,7 +220,7 @@ with BigBlueButton; if not, see . - + Date: Mon, 11 Sep 2017 00:47:25 -0400 Subject: [PATCH 39/51] refix the presentation back/forward enable state for a third time --- .../branding/default/style/css/V2Theme.css | 8 +++++ .../present/ui/views/PresentationWindow.mxml | 32 ++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/bigbluebutton-client/branding/default/style/css/V2Theme.css b/bigbluebutton-client/branding/default/style/css/V2Theme.css index f684a0cfd3..df6cde1c14 100755 --- a/bigbluebutton-client/branding/default/style/css/V2Theme.css +++ b/bigbluebutton-client/branding/default/style/css/V2Theme.css @@ -1107,11 +1107,19 @@ mx|Panel { disabledIcon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Left_Disabled"); } +.presentationBackButtonDisabledStyle { + icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Left_Disabled"); +} + .presentationForwardButtonStyle { icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Right"); disabledIcon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Right_Disabled"); } +.presentationForwardButtonDisabledStyle { + icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Right_Disabled"); +} + .presentationFitToWidthButtonStyle { icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Fit_To_Width"); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml index e539a6e4cd..8102a86e21 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml @@ -393,11 +393,23 @@ with BigBlueButton; if not, see . } private function disableSlideNavigationButtons(pageNumber:int):void { - backButton.mouseEnabled = pageNumber != 1; - forwardButton.mouseEnabled = pageNumber < PresentationModel.getInstance().getNumberOfPages(); + // We use mouseEnabled here instead of enabled because the tab position gets lost when going through + //the pages. Please don't change this if you don't know why this is. + if (pageNumber != 1) { + backButton.mouseEnabled = true; + backButton.styleName = "presentationBackButtonStyle"; + } else { + backButton.mouseEnabled = false; + backButton.styleName = "presentationBackButtonDisabledStyle"; + } - backButton.enabled = pageNumber != 1; - forwardButton.enabled = pageNumber < PresentationModel.getInstance().getNumberOfPages(); + if (pageNumber < PresentationModel.getInstance().getNumberOfPages()) { + forwardButton.mouseEnabled = true; + forwardButton.styleName = "presentationForwardButtonStyle"; + } else { + forwardButton.mouseEnabled = false; + forwardButton.styleName = "presentationForwardButtonDisabledStyle"; + } } private function displaySlideNumber(currentSlide:int):void { @@ -428,11 +440,15 @@ with BigBlueButton; if not, see . } private function goToPreviousSlide():void { - dispatchEvent(new GoToPrevPageCommand()); + if (PresentationModel.getInstance().getCurrentPage().num > 1) { + dispatchEvent(new GoToPrevPageCommand()); + } } private function goToNextSlide():void { - dispatchEvent(new GoToNextPageCommand()); + if (PresentationModel.getInstance().getCurrentPage().num < PresentationModel.getInstance().getNumberOfPages()) { + dispatchEvent(new GoToNextPageCommand()); + } } private function showPercentageInDataTip(val:String):String { @@ -502,7 +518,7 @@ with BigBlueButton; if not, see . } private function remotePrevious(e:ShortcutEvent):void{ - if (backButton.visible && backButton.enabled){ + if (backButton.visible){ //backButton.setFocus(); goToPreviousSlide(); } @@ -516,7 +532,7 @@ with BigBlueButton; if not, see . } private function remoteNext(e:ShortcutEvent):void{ - if (forwardButton.visible && forwardButton.enabled){ + if (forwardButton.visible){ //forwardButton.setFocus(); goToNextSlide(); } From eeb878649a28ba04137347da8a29641a2bfc3685 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Mon, 11 Sep 2017 06:42:56 -0700 Subject: [PATCH 40/51] remove single quotes from variable --- bigbluebutton-html5/imports/ui/components/user-list/service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 7771a138da..b34fc9521d 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -215,7 +215,7 @@ const isMeetingLocked = (id) => { const meeting = Meetings.findOne({ meetingId: id }); let isLocked = false; - if (meeting.lockSettingsProp !== 'undefined'){ + if (meeting.lockSettingsProp !== undefined) { const lockSettings = meeting.lockSettingsProp; if (lockSettings.disableCam From 467ffaba498ff93fc0715e0579930b3709b3820f Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Mon, 11 Sep 2017 06:46:19 -0700 Subject: [PATCH 41/51] change log message --- .../api/2.0/meetings/server/modifiers/changeLockSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js index f962c8add2..bb8bf47ef4 100644 --- a/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js +++ b/bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/changeLockSettings.js @@ -27,7 +27,7 @@ export default function changeLockSettings(meetingId, payload) { const cb = (err) => { if (err) { - return Logger.error(`Removing user from collection: ${err}`); + return Logger.error(`Changing meeting={${meetingId}} lock settings: ${err}`); } }; From 89de2f771befb150c7c1bcb74d6c4bf80ad1cf28 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Mon, 11 Sep 2017 10:19:06 -0700 Subject: [PATCH 42/51] change parameter name to header --- .../api/2.0/voice-users/server/methods/listenOnlyToggle.js | 2 +- bigbluebutton-html5/imports/startup/server/redis2x.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js index 0a5a699432..66951cf673 100644 --- a/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js +++ b/bigbluebutton-html5/imports/api/2.0/voice-users/server/methods/listenOnlyToggle.js @@ -44,5 +44,5 @@ export default function listenOnlyToggle(credentials, isJoining = true) { Logger.verbose(`VoiceUser '${requesterUserId}' ${isJoining ? 'joined' : 'left'} global audio from meeting '${meetingId}'`); - return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: Meeting.voiceProp.voiceConf }); + return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { voiceConf: Meeting.voiceProp.voiceConf }); } diff --git a/bigbluebutton-html5/imports/startup/server/redis2x.js b/bigbluebutton-html5/imports/startup/server/redis2x.js index a7bfd0c6b3..ba4625439e 100644 --- a/bigbluebutton-html5/imports/startup/server/redis2x.js +++ b/bigbluebutton-html5/imports/startup/server/redis2x.js @@ -40,7 +40,7 @@ class RedisPubSub2x { return this.emitter.on(...args); } - publish(channel, eventName, meetingId, payload = {}, userId = {}) { + publish(channel, eventName, meetingId, payload = {}, header = {}) { const envelope = { envelope: { name: eventName, @@ -53,7 +53,7 @@ class RedisPubSub2x { header: Object.assign({ name: eventName, meetingId, - }, userId), + }, header), body: payload, } }; From d8e0e16e54b35785fc2067ac446e563bc993f8ed Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Mon, 11 Sep 2017 21:40:01 +0100 Subject: [PATCH 43/51] Make possible to upload a new file after an error and update the file upload progress bar. --- .../branding/default/style/css/V2Theme.css | 29 +- .../present/ui/views/FileUploadWindow.mxml | 798 +++++++++--------- 2 files changed, 426 insertions(+), 401 deletions(-) diff --git a/bigbluebutton-client/branding/default/style/css/V2Theme.css b/bigbluebutton-client/branding/default/style/css/V2Theme.css index d9f4426941..e11772fe61 100755 --- a/bigbluebutton-client/branding/default/style/css/V2Theme.css +++ b/bigbluebutton-client/branding/default/style/css/V2Theme.css @@ -304,7 +304,7 @@ phonecomponents|MuteMeButton { } .recordButtonStyleStart { - icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Record_On"); + icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Record_On"); } .recordButtonStyleStop { @@ -495,7 +495,7 @@ users|RoomActionsRenderer { textAlign : center; } -.joinBreakoutRoomButton { +.joinBreakoutRoomButton, .retryUploadButton { fillColorUp : #1070D7; fillColorOver : #0A5EAC; fillColorDown : #1070D7; @@ -1103,6 +1103,10 @@ mx|Panel { icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Trash"); } +.presentationUploadProgressBar { + trackHeight : 12; +} + .presentationUploadButtonStyle { icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Upload"); } @@ -1193,6 +1197,11 @@ mx|Panel { color : #2A2D33; } +.progressErrorLblStyle { + color : #DE2721; + fontSize : 16; +} + .presentationDownloadShowButtonStyle { /* Normal state */ borderStyle : none; @@ -1386,14 +1395,14 @@ mx|Tab, .defaultTabStyle { */ mx|TitleWindow { - borderColor : #FFFFFF; - cornerRadius : 4; - roundedBottomCorners : true; - dropShadowEnabled : true; - shadowDistance : 0; - borderThickness : 1; - paddingTop : 10; - headerHeight : 0; + borderColor : #FFFFFF; + cornerRadius : 4; + roundedBottomCorners : true; + dropShadowEnabled : true; + shadowDistance : 0; + borderThickness : 1; + paddingTop : 10; + headerHeight : 0; } .titleWindowStyle { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml index caf7c1a9fb..6102313273 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml @@ -1,391 +1,407 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - maxFileSizeBytes) { - // Hardcode for now to 30M limit. - // This should be configurable to match what's allowed in nginx. (ralam feb 23, 2010) - var logData:Object = UsersUtil.initLogData(); - logData.tags = ["presentation"]; - logData.message = "File exceeds max limit."; - logData.fileSizeBytes = fileSize; - logData.maxFileSizeBytes = maxFileSizeBytes; - LOGGER.error(JSON.stringify(logData)); - - enableControls(); - displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.maxUploadFileExceededAlert')); - } else { - var presentationName:String = StringUtil.trim(fileToUpload.name); - - progBarLbl.visible = true; - lblFileName.enabled = false; - - var isDownloadable:Boolean = new Boolean(letUserDownload.selected); - - var uploadCmd:UploadFileCommand = new UploadFileCommand(); - uploadCmd.filename = presentationName; - uploadCmd.file = fileToUpload; - uploadCmd.isDownloadable = isDownloadable; - globalDispatch.dispatchEvent(uploadCmd); - letUserDownload.visible = false; - } - } - - private function handleUploadProgressUpdate(e:UploadProgressEvent):void{ - var progress:Number = e.percentUploaded; - progressBar.label = progress + "% " + ResourceUtil.getInstance().getString('bbb.presentation.uploaded'); - progressBar.setProgress(progress, 100); - progressBar.validateNow(); - } - - private function handleUploadCompletedEvent(e:UploadCompletedEvent):void{ - progressBar.label = ResourceUtil.getInstance().getString('bbb.presentation.uploadcomplete'); - progressBar.setProgress(0, 100); - progressBar.validateNow(); - - selectBtn.visible = false; - uploadBtn.visible = false; - selectBtn.enabled = false; - uploadBtn.enabled = false; - lblFileName.visible = false; - } - - private function handleOfficeDocumentConversionFailed(e:OfficeDocConvertFailedEvent):void { - enableControls(); - displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.document.convert.failed')); - } - - private function handleOfficeDocumentConversionInvalid(e:OfficeDocConvertInvalidEvent):void { - enableControls(); - displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.document.convert.invalid')); - } - - private function handleOfficeDocumentConversionSuccess(e:OfficeDocConvertSuccessEvent):void { - progressBar.label = ResourceUtil.getInstance().getString('bbb.presentation.document.converted'); - progressBar.setProgress(0, 100); - progressBar.validateNow(); - } - - private function handleSupportedDocument(e:ConversionSupportedDocEvent):void { - LOGGER.debug("handleSupportedDocument"); - progressBar.label = ResourceUtil.getInstance().getString('bbb.presentation.document.supported'); - progressBar.setProgress(0, 100); - progressBar.validateNow(); - } - - private function handleUnsupportedDocument(e:ConversionUnsupportedDocEvent):void { - enableControls(); - displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.notsupported')); - } - - private function handlePageCountFailed(e:ConversionPageCountError):void { - enableControls(); - displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.nbpage')); - } - - private function handlePageCountExceeded(e:ConversionPageCountMaxed):void { - LOGGER.debug("handlePageCountExceeded"); - enableControls(); - var message:String = " Maximum supported is " + e.maxPages; - displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.maxnbpagereach'), message); - } - - private function handleUploadIoError(e:UploadIoErrorEvent):void{ - enableControls(); - displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.io')); - } - - private function handleUploadSecurityError(e:UploadSecurityErrorEvent):void{ - enableControls(); - displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.security')); - } - - private function displayAlert(error:String, message:String = null):void { - progressBar.setStyle("color", 0xFF0000); - progressBar.label = error; - if (!StringUtils.isEmpty(message)) { - progressBar.label += message; - } - } - - private function enableControls():void { - enableClosing(); - selectBtn.enabled = true; - uploadBtn.enabled = true; - lblFileName.enabled = true; - letUserDownload.visible = true; - } - - private function handleConvertUpdate(e:ConversionUpdateEvent):void{ - progressBar.label = ResourceUtil.getInstance().getString('bbb.presentation.converted',[e.numPagesDone, e.totalPages]); - progressBar.setProgress(e.numPagesDone, e.totalPages); - progressBar.validateNow(); - } - - private function handleConversionCompleted(e:ConversionCompletedEvent):void{ - enableClosing(); - globalDispatch.dispatchEvent(new ChangePresentationCommand(e.presId)); - globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW)); - } - - private function disableClosing():void { - this.closeButton2.enabled = false; - } - - private function enableClosing():void { - this.closeButton2.enabled = true; - } - - private function handlePresentationRemoved(e:RemovePresentationEvent):void { - for(var i:int = 0; i < presentationNamesAC.length; i++) { - if(e.presentationName == presentationNamesAC.getItemAt(i).id) { - presentationNamesAC.removeItemAt(i); - return; - } - } - } - - private function onItemRollOver(event:ListEvent):void { - var item:IListItemRenderer = event.itemRenderer; - var presentation:Presentation = item.data as Presentation; - var rollEvent:PresentationRollEvent = new PresentationRollEvent(PresentationRollEvent.PRESENTATION_ROLL_OVER, presentation.id); - dispatcher.dispatchEvent(rollEvent); - } - - private function onItemRollOut(event:ListEvent):void { - var item:IListItemRenderer = event.itemRenderer; - var presentation:Presentation = item.data as Presentation; - var rollEvent:PresentationRollEvent = new PresentationRollEvent(PresentationRollEvent.PRESENTATION_ROLL_OUT, presentation.id); - dispatcher.dispatchEvent(rollEvent); - } - - private function onCancelClicked():void { - globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW)); - } - - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + maxFileSizeBytes) { + // Hardcode for now to 30M limit. + // This should be configurable to match what's allowed in nginx. (ralam feb 23, 2010) + var logData:Object = UsersUtil.initLogData(); + logData.tags = ["presentation"]; + logData.message = "File exceeds max limit."; + logData.fileSizeBytes = fileSize; + logData.maxFileSizeBytes = maxFileSizeBytes; + LOGGER.error(JSON.stringify(logData)); + + enableClosing(); + displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.maxUploadFileExceededAlert')); + } else { + var presentationName:String = StringUtil.trim(fileToUpload.name); + + lblFileName.enabled = false; + + var isDownloadable:Boolean = new Boolean(letUserDownload.selected); + + var uploadCmd:UploadFileCommand = new UploadFileCommand(); + uploadCmd.filename = presentationName; + uploadCmd.file = fileToUpload; + uploadCmd.isDownloadable = isDownloadable; + globalDispatch.dispatchEvent(uploadCmd); + letUserDownload.visible = false; + } + } + + private function handleUploadProgressUpdate(e:UploadProgressEvent):void{ + var progress:Number = e.percentUploaded; + buildProgressLabel(progress + "% " + ResourceUtil.getInstance().getString('bbb.presentation.uploaded')); + progressBar.setProgress(progress, 100); + progressBar.validateNow(); + } + + private function handleUploadCompletedEvent(e:UploadCompletedEvent):void{ + buildProgressLabel(ResourceUtil.getInstance().getString('bbb.presentation.uploadcomplete')); + progressBar.setProgress(0, 100); + progressBar.validateNow(); + + selectBtn.visible = false; + uploadBtn.visible = false; + selectBtn.enabled = false; + uploadBtn.enabled = false; + lblFileName.visible = false; + } + + private function handleOfficeDocumentConversionFailed(e:OfficeDocConvertFailedEvent):void { + enableClosing(); + displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.document.convert.failed')); + } + + private function handleOfficeDocumentConversionInvalid(e:OfficeDocConvertInvalidEvent):void { + enableClosing(); + displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.document.convert.invalid')); + } + + private function handleOfficeDocumentConversionSuccess(e:OfficeDocConvertSuccessEvent):void { + buildProgressLabel(ResourceUtil.getInstance().getString('bbb.presentation.document.converted')); + progressBar.setProgress(0, 100); + progressBar.validateNow(); + } + + private function handleSupportedDocument(e:ConversionSupportedDocEvent):void { + LOGGER.debug("handleSupportedDocument"); + buildProgressLabel(ResourceUtil.getInstance().getString('bbb.presentation.document.supported')); + progressBar.setProgress(0, 100); + progressBar.validateNow(); + } + + private function handleUnsupportedDocument(e:ConversionUnsupportedDocEvent):void { + enableClosing(); + displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.notsupported')); + } + + private function handlePageCountFailed(e:ConversionPageCountError):void { + enableClosing(); + displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.nbpage')); + } + + private function handlePageCountExceeded(e:ConversionPageCountMaxed):void { + LOGGER.debug("handlePageCountExceeded"); + enableClosing(); + var message:String = " Maximum supported is " + e.maxPages; + displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.maxnbpagereach'), message); + } + + private function handleUploadIoError(e:UploadIoErrorEvent):void{ + enableClosing(); + displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.io')); + } + + private function handleUploadSecurityError(e:UploadSecurityErrorEvent):void{ + enableClosing(); + displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.security')); + } + + private function displayAlert(error:String, message:String = null):void { + currentState = "error"; + progressErrorLbl.text = error; + if (!StringUtils.isEmpty(message)) { + progressErrorLbl.text += message; + } + } + + private function handleConvertUpdate(e:ConversionUpdateEvent):void{ + buildProgressLabel(ResourceUtil.getInstance().getString('bbb.presentation.converted',[e.numPagesDone, e.totalPages])); + progressBar.setProgress(e.numPagesDone, e.totalPages); + progressBar.validateNow(); + } + + private function buildProgressLabel(value:String) : void { + progressBar.label = ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl') + " " + value; + } + + private function handleConversionCompleted(e:ConversionCompletedEvent):void{ + enableClosing(); + globalDispatch.dispatchEvent(new ChangePresentationCommand(e.presId)); + globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW)); + } + + private function disableClosing():void { + this.closeButton2.enabled = false; + } + + private function enableClosing():void { + this.closeButton2.enabled = true; + } + + private function handlePresentationRemoved(e:RemovePresentationEvent):void { + for(var i:int = 0; i < presentationNamesAC.length; i++) { + if(e.presentationName == presentationNamesAC.getItemAt(i).id) { + presentationNamesAC.removeItemAt(i); + return; + } + } + } + + private function onItemRollOver(event:ListEvent):void { + var item:IListItemRenderer = event.itemRenderer; + var presentation:Presentation = item.data as Presentation; + var rollEvent:PresentationRollEvent = new PresentationRollEvent(PresentationRollEvent.PRESENTATION_ROLL_OVER, presentation.id); + dispatcher.dispatchEvent(rollEvent); + } + + private function onItemRollOut(event:ListEvent):void { + var item:IListItemRenderer = event.itemRenderer; + var presentation:Presentation = item.data as Presentation; + var rollEvent:PresentationRollEvent = new PresentationRollEvent(PresentationRollEvent.PRESENTATION_ROLL_OUT, presentation.id); + dispatcher.dispatchEvent(rollEvent); + } + + private function onCancelClicked():void { + globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW)); + } + + private function retryButtonClikcHandler(event:MouseEvent):void { + globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW)) + setTimeout(function():void { + globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.OPEN_UPLOAD_WINDOW)) + }, 100); + } + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 9e906bd67137409d288d23e0333ea6fa1c9ce483 Mon Sep 17 00:00:00 2001 From: Richard Alam Date: Mon, 11 Sep 2017 14:38:09 -0700 Subject: [PATCH 44/51] - fix passive xss --- bigbluebutton-config/web/js/bigbluebutton.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bigbluebutton-config/web/js/bigbluebutton.js b/bigbluebutton-config/web/js/bigbluebutton.js index 62c8b447e2..ccba3f4080 100644 --- a/bigbluebutton-config/web/js/bigbluebutton.js +++ b/bigbluebutton-config/web/js/bigbluebutton.js @@ -13,6 +13,16 @@ function AutoClose() { window.close(); } +function escapeHTML(text) { + if (text != null) { + return text.replace(/&/g, ''). + replace(/×Error: "+error.message+""); }); $('#messages').removeClass('hidden'); From 73d394bf316ecacaee9c9adf34cc82e82a9fb622 Mon Sep 17 00:00:00 2001 From: Chad Pilkey Date: Mon, 11 Sep 2017 20:49:04 -0400 Subject: [PATCH 45/51] updated sipjs to the latest release 0.7.8 --- .../prod/lib/bbb_webrtc_bridge_sip.js | 8 +- .../resources/prod/lib/sip.js | 1656 +++++++++-------- 2 files changed, 852 insertions(+), 812 deletions(-) mode change 100644 => 100755 bigbluebutton-client/resources/prod/lib/sip.js diff --git a/bigbluebutton-client/resources/prod/lib/bbb_webrtc_bridge_sip.js b/bigbluebutton-client/resources/prod/lib/bbb_webrtc_bridge_sip.js index 1cbcfa6e33..c73a340339 100755 --- a/bigbluebutton-client/resources/prod/lib/bbb_webrtc_bridge_sip.js +++ b/bigbluebutton-client/resources/prod/lib/bbb_webrtc_bridge_sip.js @@ -183,9 +183,9 @@ function createUA(username, server, callback, makeCallFunc) { 'password': data['password'] }; }) : [] ); - stunsConfig['remoteIceCandidates'] = ( data['remoteIceCandidates'] ? data['remoteIceCandidates'].map(function(data) { - return data['ip']; - }) : [] ); + //stunsConfig['remoteIceCandidates'] = ( data['remoteIceCandidates'] ? data['remoteIceCandidates'].map(function(data) { + // return data['ip']; + //}) : [] ); createUAWithStuns(username, server, callback, stunsConfig, makeCallFunc); }).fail(function(data, textStatus, errorThrown) { BBBLog.error("Could not fetch stun/turn servers", {error: textStatus, user: callerIdName, voiceBridge: conferenceVoiceBridge}); @@ -211,7 +211,7 @@ function createUAWithStuns(username, server, callback, stunsConfig, makeCallFunc userAgentString: "BigBlueButton", stunServers: stunsConfig['stunServers'], turnServers: stunsConfig['turnServers'], - artificialRemoteIceCandidates: stunsConfig['remoteIceCandidates'] + //artificialRemoteIceCandidates: stunsConfig['remoteIceCandidates'] }; uaConnected = false; diff --git a/bigbluebutton-client/resources/prod/lib/sip.js b/bigbluebutton-client/resources/prod/lib/sip.js old mode 100644 new mode 100755 index 06e964c68a..e57c90c2bc --- a/bigbluebutton-client/resources/prod/lib/sip.js +++ b/bigbluebutton-client/resources/prod/lib/sip.js @@ -1,13 +1,13 @@ /* - * SIP version 0.7.5 - * Copyright (c) 2014-2016 Junction Networks, Inc + * SIP version 0.7.8 + * Copyright (c) 2014-2017 Junction Networks, Inc * Homepage: http://sipjs.com * License: http://sipjs.com/license/ * * * ~~~SIP.js contains substantial portions of JsSIP under the following license~~~ * Homepage: http://jssip.net - * Copyright (c) 2012-2013 José Luis Millán - Versatica + * Copyright (c) 2012-2013 José Luis Millán - Versatica * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -340,7 +340,7 @@ module.exports={ "name": "sip.js", "title": "SIP.js", "description": "A simple, intuitive, and powerful JavaScript signaling library", - "version": "0.7.5", + "version": "0.7.8", "main": "src/index.js", "browser": { "./src/environment.js": "./src/environment_browser.js" @@ -370,7 +370,7 @@ module.exports={ "grunt-browserify": "^4.0.1", "grunt-cli": "~0.1.6", "grunt-contrib-copy": "^0.5.0", - "grunt-contrib-jasmine": "^0.9.2", + "grunt-contrib-jasmine": "^1.0.3", "grunt-contrib-jshint": ">0.5.0", "grunt-contrib-uglify": "~0.2.0", "grunt-peg": "~1.3.1", @@ -378,7 +378,7 @@ module.exports={ "pegjs": "^0.8.0" }, "engines": { - "node": ">=0.8" + "node": ">=0.12" }, "license": "MIT", "scripts": { @@ -388,7 +388,7 @@ module.exports={ "test": "grunt travis --verbose" }, "dependencies": { - "ws": "^0.6.4" + "ws": "^1.0.1" }, "optionalDependencies": { "promiscuous": "^0.6.0" @@ -425,11 +425,6 @@ ClientContext = function (ua, method, target, options) { options = Object.create(options || Object.prototype); options.extraHeaders = (options.extraHeaders || []).slice(); - if (options.contentType) { - this.contentType = options.contentType; - options.extraHeaders.push('Content-Type: ' + this.contentType); - } - // Build the request this.request = new SIP.OutgoingRequest(this.method, target, @@ -437,7 +432,11 @@ ClientContext = function (ua, method, target, options) { options.params, options.extraHeaders); if (options.body) { - this.body = options.body; + this.body = {}; + this.body.body = options.body; + if (options.contentType) { + this.body.contentType = options.contentType; + } this.request.body = this.body; } @@ -457,8 +456,10 @@ ClientContext.prototype.send = function () { ClientContext.prototype.cancel = function (options) { options = options || {}; + options.extraHeaders = (options.extraHeaders || []).slice(); + var cancel_reason = SIP.Utils.getCancelReason(options.status_code, options.reason_phrase); - this.request.cancel(cancel_reason); + this.request.cancel(cancel_reason, options.extraHeaders); this.emit('cancel'); }; @@ -1030,10 +1031,22 @@ Dialog.prototype = { sendRequest: function(applicant, method, options) { options = options || {}; - var - extraHeaders = (options.extraHeaders || []).slice(), - body = options.body || null, - request = this.createRequest(method, extraHeaders, body), + var extraHeaders = (options.extraHeaders || []).slice(); + + var body = null; + if (options.body) { + if (options.body.body) { + body = options.body; + } else { + body = {}; + body.body = options.body; + if (options.contentType) { + body.contentType = options.contentType; + } + } + } + + var request = this.createRequest(method, extraHeaders, body), request_sender = new RequestSender(this, applicant, request); request_sender.send(); @@ -2712,10 +2725,11 @@ SIP = SIP; var Hacks = { AllBrowsers: { - maskDtls: function (message) { - if (message.body) { - message.body = message.body.replace(/ UDP\/TLS\/RTP\/SAVP/gmi, " RTP/SAVP"); + maskDtls: function (sdp) { + if (sdp) { + sdp = sdp.replace(/ UDP\/TLS\/RTP\/SAVP/gmi, " RTP/SAVP"); } + return sdp; }, unmaskDtls: function (sdp) { /** @@ -2730,72 +2744,6 @@ var Hacks = { * **/ return sdp.replace(/ RTP\/SAVP/gmi, " UDP/TLS/RTP/SAVP"); - }, - addArtificialRemoteIceCandidates: function (response, artificialRemoteIceCandidates) { - /* - For those SIP endpoints that don't add all it's possible candidates, - we can manually add it to successfully complete ICE. - */ - function findACandidate(sdpArray) { - for (i=0; i < sdpArray.length; i++) { - if (sdpArray[i].trim().match("^a=candidate:.*")) { - return sdpArray[i]; - } - } - return null; - } - - function findEndOfCandidatesIndex(sdpArray) { - var lastCandidateNeighborIndex = -1; - for (i=0; i < sdpArray.length; i++) { - if (sdpArray[i].trim().match("^a=end-of-candidates$")) { - return i; - } else if (sdpArray[i].trim().match("^a=candidate:.*")) { - lastCandidateNeighborIndex = i + 1; - } - } - return lastCandidateNeighborIndex; - } - - function findCandidatePriority(candidate) { - var result = candidate.match(/.* (udp|tcp) (\d+) .*/); - return result[2]; - } - - var sdp = response.body; - if (sdp == null || sdp.length == 0) { - console.log("Empty SDP"); - return response; - } - var sdpArray = sdp.split("\n"); - if (sdpArray.length == 0) { - console.log("Can't split SDP properly"); - return response; - } - var a_candidate = findACandidate(sdpArray); - if (a_candidate == null) { - console.log("No candidate found"); - return response; - } - var index = findEndOfCandidatesIndex(sdpArray); - if (index == -1) { - console.log("end-of-candidates not found"); - return response; - } - - for (var i=0; i < artificialRemoteIceCandidates.length; i++) { - var ipAddress = artificialRemoteIceCandidates[i]; - console.log("Processing artificialRemoteIceCandidate " + ipAddress); - // we set the new candidates to a lower priority - // https://webrtchacks.com/sdp-anatomy/ - var priority = findCandidatePriority(a_candidate) - 256; - var new_candidate = a_candidate.replace(/\d+ \d+\.\d+\.\d+\.\d+/g, priority + " " + ipAddress); - sdpArray.splice(index, 0, new_candidate); - } - sdp = sdpArray.join("\n"); - console.log("SDP with the new candidates:\r\n" + sdp); - response.body = sdp; - return response; } }, Firefox: { @@ -2804,10 +2752,11 @@ var Hacks = { return typeof mozRTCPeerConnection !== 'undefined'; }, - cannotHandleExtraWhitespace: function (message) { - if (this.isFirefox() && message.body) { - message.body = message.body.replace(/ \r\n/g, "\r\n"); + cannotHandleExtraWhitespace: function (sdp) { + if (this.isFirefox() && sdp) { + sdp = sdp.replace(/ \r\n/g, "\r\n"); } + return sdp; }, hasMissingCLineInSDP: function (sdp) { @@ -2875,6 +2824,7 @@ var Hacks = { }; return Hacks; }; + },{}],13:[function(require,module,exports){ "use strict"; var levels = { @@ -3023,13 +2973,23 @@ MediaHandler.prototype = Object.create(EventEmitter.prototype, { }}, /** - * Message reception. - * @param {String} type - * @param {String} description - */ - setDescription: {value: function setDescription (description) { + * Check if a SIP message contains a session description. + * @param {SIP.SIPMessage} message + * @returns {boolean} + */ + hasDescription: {value: function hasDescription (message) { // keep jshint happy - description = description; + message = message; + }}, + + /** + * Set the session description contained in a SIP message. + * @param {SIP.SIPMessage} message + * @returns {Promise} + */ + setDescription: {value: function setDescription (message) { + // keep jshint happy + message = message; }} }); @@ -3838,14 +3798,16 @@ SIP.RequestSender = RequestSender; module.exports = function (environment) { -var pkg = require('../package.json'); +var pkg = require('../package.json'), + version = pkg.version, + title = pkg.title; var SIP = Object.defineProperties({}, { version: { - get: function(){ return pkg.version; } + get: function(){ return version; } }, name: { - get: function(){ return pkg.title; } + get: function(){ return title; } } }); @@ -4121,12 +4083,23 @@ OutgoingRequest.prototype = { msg += getSupportedHeader(this); msg += 'User-Agent: ' + this.ua.configuration.userAgentString +'\r\n'; - if(this.body) { - length = SIP.Utils.str_utf8_length(this.body); - msg += 'Content-Length: ' + length + '\r\n\r\n'; - msg += this.body; + if (this.body) { + if (typeof this.body === 'string') { + length = SIP.Utils.str_utf8_length(this.body); + msg += 'Content-Length: ' + length + '\r\n\r\n'; + msg += this.body; + } else { + if (this.body.body && this.body.contentType) { + length = SIP.Utils.str_utf8_length(this.body.body); + msg += 'Content-Type: ' + this.body.contentType + '\r\n'; + msg += 'Content-Length: ' + length + '\r\n\r\n'; + msg += this.body.body; + } else { + msg += 'Content-Length: ' + 0 + '\r\n\r\n'; + } + } } else { - msg += 'Content-Length: 0\r\n\r\n'; + msg += 'Content-Length: ' + 0 + '\r\n\r\n'; } return msg; @@ -4355,11 +4328,22 @@ IncomingRequest.prototype.reply = function(code, reason, extraHeaders, body, onS response += getSupportedHeader(this); response += 'User-Agent: ' + this.ua.configuration.userAgentString +'\r\n'; - if(body) { - length = SIP.Utils.str_utf8_length(body); - response += 'Content-Type: application/sdp\r\n'; - response += 'Content-Length: ' + length + '\r\n\r\n'; - response += body; + if (body) { + if (typeof body === 'string') { + length = SIP.Utils.str_utf8_length(body); + response += 'Content-Type: application/sdp\r\n'; + response += 'Content-Length: ' + length + '\r\n\r\n'; + response += body; + } else { + if (body.body && body.contentType) { + length = SIP.Utils.str_utf8_length(body.body); + response += 'Content-Type: ' + body.contentType + '\r\n'; + response += 'Content-Length: ' + length + '\r\n\r\n'; + response += body.body; + } else { + response += 'Content-Length: ' + 0 + '\r\n\r\n'; + } + } } else { response += 'Content-Length: ' + 0 + '\r\n\r\n'; } @@ -4439,14 +4423,12 @@ SIP.IncomingResponse = IncomingResponse; */ module.exports = function (SIP) { var sanityCheck, - logger, - message, ua, transport, requests = [], responses = [], all = []; // Reply -function reply(status_code) { +function reply(status_code, message, transport) { var to, response = SIP.Utils.buildStatusLine(status_code), vias = message.getHeaders('via'), @@ -4493,33 +4475,33 @@ function reply(status_code) { */ // Sanity Check functions for requests -function rfc3261_8_2_2_1() { +function rfc3261_8_2_2_1(message, ua, transport) { if(!message.ruri || message.ruri.scheme !== 'sip') { - reply(416); + reply(416, message, transport); return false; } } -function rfc3261_16_3_4() { +function rfc3261_16_3_4(message, ua, transport) { if(!message.to_tag) { if(message.call_id.substr(0, 5) === ua.configuration.sipjsId) { - reply(482); + reply(482, message, transport); return false; } } } -function rfc3261_18_3_request() { +function rfc3261_18_3_request(message, ua, transport) { var len = SIP.Utils.str_utf8_length(message.body), contentLength = message.getHeader('content-length'); if(len < contentLength) { - reply(400); + reply(400, message, transport); return false; } } -function rfc3261_8_2_2_2() { +function rfc3261_8_2_2_2(message, ua, transport) { var tr, idx, fromTag = message.from_tag, call_id = message.call_id, @@ -4534,7 +4516,7 @@ function rfc3261_8_2_2_2() { for(idx in ua.transactions.ist) { tr = ua.transactions.ist[idx]; if(tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) { - reply(482); + reply(482, message, transport); return false; } } @@ -4547,7 +4529,7 @@ function rfc3261_8_2_2_2() { for(idx in ua.transactions.nist) { tr = ua.transactions.nist[idx]; if(tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) { - reply(482); + reply(482, message, transport); return false; } } @@ -4557,41 +4539,41 @@ function rfc3261_8_2_2_2() { } // Sanity Check functions for responses -function rfc3261_8_1_3_3() { +function rfc3261_8_1_3_3(message, ua) { if(message.getHeaders('via').length > 1) { - logger.warn('More than one Via header field present in the response. Dropping the response'); + ua.getLogger('sip.sanitycheck').warn('More than one Via header field present in the response. Dropping the response'); return false; } } -function rfc3261_18_1_2() { +function rfc3261_18_1_2(message, ua) { var viaHost = ua.configuration.viaHost; if(message.via.host !== viaHost || message.via.port !== undefined) { - logger.warn('Via sent-by in the response does not match UA Via host value. Dropping the response'); + ua.getLogger('sip.sanitycheck').warn('Via sent-by in the response does not match UA Via host value. Dropping the response'); return false; } } -function rfc3261_18_3_response() { +function rfc3261_18_3_response(message, ua) { var len = SIP.Utils.str_utf8_length(message.body), contentLength = message.getHeader('content-length'); if(len < contentLength) { - logger.warn('Message body length is lower than the value in Content-Length header field. Dropping the response'); + ua.getLogger('sip.sanitycheck').warn('Message body length is lower than the value in Content-Length header field. Dropping the response'); return false; } } // Sanity Check functions for requests and responses -function minimumHeaders() { +function minimumHeaders(message, ua) { var mandatoryHeaders = ['from', 'to', 'call_id', 'cseq', 'via'], idx = mandatoryHeaders.length; while(idx--) { if(!message.hasHeader(mandatoryHeaders[idx])) { - logger.warn('Missing mandatory header field : '+ mandatoryHeaders[idx] +'. Dropping the response'); + ua.getLogger('sip.sanitycheck').warn('Missing mandatory header field : '+ mandatoryHeaders[idx] +'. Dropping the response'); return false; } } @@ -4608,18 +4590,12 @@ responses.push(rfc3261_18_3_response); all.push(minimumHeaders); -sanityCheck = function(m, u, t) { +sanityCheck = function(message, ua, transport) { var len, pass; - message = m; - ua = u; - transport = t; - - logger = ua.getLogger('sip.sanitycheck'); - len = all.length; while(len--) { - pass = all[len](message); + pass = all[len](message, ua, transport); if(pass === false) { return false; } @@ -4628,7 +4604,7 @@ sanityCheck = function(m, u, t) { if(message instanceof SIP.IncomingRequest) { len = requests.length; while(len--) { - pass = requests[len](message); + pass = requests[len](message, ua, transport); if(pass === false) { return false; } @@ -4638,7 +4614,7 @@ sanityCheck = function(m, u, t) { else if(message instanceof SIP.IncomingResponse) { len = responses.length; while(len--) { - pass = responses[len](message); + pass = responses[len](message, ua, transport); if(pass === false) { return false; } @@ -5244,21 +5220,6 @@ Session.prototype = { this.onhold('local'); - options = options || {}; - options.mangle = function(body){ - - // Don't receive media - // TODO - This will break for media streams with different directions. - if (!(/a=(sendrecv|sendonly|recvonly|inactive)/).test(body)) { - body = body.replace(/(m=[^\r]*\r\n)/g, '$1a=sendonly\r\n'); - } else { - body = body.replace(/a=sendrecv\r\n/g, 'a=sendonly\r\n'); - body = body.replace(/a=recvonly\r\n/g, 'a=inactive\r\n'); - } - - return body; - }; - this.sendReinvite(options); }, @@ -5310,31 +5271,25 @@ Session.prototype = { receiveReinvite: function(request) { var self = this; - if (!request.body) { - return; - } - - if (request.getHeader('Content-Type') !== 'application/sdp') { + if (!this.mediaHandler.hasDescription(request)) { this.logger.warn('invalid Content-Type'); request.reply(415); return; } - this.mediaHandler.setDescription(request.body) + this.mediaHandler.setDescription(request) .then(this.mediaHandler.getDescription.bind(this.mediaHandler, this.mediaHint)) - .then(function(body) { - request.reply(200, null, ['Contact: ' + self.contact], body, + .then(function(description) { + var extraHeaders = ['Contact: ' + self.contact]; + request.reply(200, null, extraHeaders, description, function() { self.status = C.STATUS_WAITING_FOR_ACK; - self.setInvite2xxTimer(request, body); + self.setInvite2xxTimer(request, description); self.setACKTimer(); - // Are we holding? - var hold = (/a=(sendonly|inactive)/).test(request.body); - - if (self.remote_hold && !hold) { + if (self.remote_hold && !self.mediaHandler.remote_hold) { self.onunhold('remote'); - } else if (!self.remote_hold && hold) { + } else if (!self.remote_hold && self.mediaHandler.remote_hold) { self.onhold('remote'); } }); @@ -5356,10 +5311,9 @@ Session.prototype = { var self = this, - extraHeaders = (options.extraHeaders || []).slice(), - eventHandlers = options.eventHandlers || {}, - mangle = options.mangle || null, - succeeded; + extraHeaders = (options.extraHeaders || []).slice(), + eventHandlers = options.eventHandlers || {}, + succeeded; if (eventHandlers.succeeded) { succeeded = eventHandlers.succeeded; @@ -5378,17 +5332,15 @@ Session.prototype = { extraHeaders.push('Contact: ' + this.contact); extraHeaders.push('Allow: '+ SIP.UA.C.ALLOWED_METHODS.toString()); - extraHeaders.push('Content-Type: application/sdp'); this.receiveResponse = this.receiveReinviteResponse; //REVISIT this.mediaHandler.getDescription(self.mediaHint) - .then(mangle) .then( - function(body){ + function(description){ self.dialog.sendRequest(self, SIP.C.INVITE, { extraHeaders: extraHeaders, - body: body + body: description }); }, function() { @@ -5417,6 +5369,10 @@ Session.prototype = { break; case SIP.C.INFO: if(this.status === C.STATUS_CONFIRMED || this.status === C.STATUS_WAITING_FOR_ACK) { + if (this.onInfo) { + return this.onInfo(request); + } + var body, tone, duration, contentType = request.getHeader('content-type'), reg_tone = /^(Signal\s*?=\s*?)([0-9A-D#*]{1})(\s)?.*/, @@ -5482,8 +5438,7 @@ Session.prototype = { * @private */ receiveReinviteResponse: function(response) { - var self = this, - contentType = response.getHeader('Content-Type'); + var self = this; if (this.status === C.STATUS_TERMINATED) { return; @@ -5497,16 +5452,13 @@ Session.prototype = { this.sendRequest(SIP.C.ACK,{cseq:response.cseq}); - if(!response.body) { - this.reinviteFailed(); - break; - } else if (contentType !== 'application/sdp') { + if (!this.mediaHandler.hasDescription(response)) { this.reinviteFailed(); break; } //REVISIT - this.mediaHandler.setDescription(response.body) + this.mediaHandler.setDescription(response) .then( function onSuccess () { self.reinviteSucceeded(); @@ -5544,7 +5496,7 @@ Session.prototype = { * Response retransmissions cannot be accomplished by transaction layer * since it is destroyed when receiving the first 2xx answer */ - setInvite2xxTimer: function(request, body) { + setInvite2xxTimer: function(request, description) { var self = this, timeout = SIP.Timers.T1; @@ -5555,7 +5507,9 @@ Session.prototype = { self.logger.log('no ACK received, attempting to retransmit OK'); - request.reply(200, null, ['Contact: ' + self.contact], body); + var extraHeaders = ['Contact: ' + self.contact]; + + request.reply(200, null, extraHeaders, description); timeout = Math.min(timeout * 2, SIP.Timers.T2); @@ -5737,23 +5691,24 @@ InviteServerContext = function(ua, request) { contentType = request.getHeader('Content-Type'), contentDisp = request.parseHeader('Content-Disposition'); + SIP.Utils.augment(this, SIP.ServerContext, [ua, request]); + SIP.Utils.augment(this, SIP.Session, [ua.configuration.mediaHandlerFactory]); + + //Initialize Media Session + this.mediaHandler = this.mediaHandlerFactory(this, { + RTCConstraints: {"optional": [{'DtlsSrtpKeyAgreement': 'true'}]} + }); + // Check body and content type - if ((!contentDisp && contentType !== 'application/sdp') || (contentDisp && contentDisp.type === 'render')) { + if ((!contentDisp && !this.mediaHandler.hasDescription(request)) || (contentDisp && contentDisp.type === 'render')) { this.renderbody = request.body; this.rendertype = contentType; - } else if (contentType !== 'application/sdp' && (contentDisp && contentDisp.type === 'session')) { + } else if (!this.mediaHandler.hasDescription(request) && (contentDisp && contentDisp.type === 'session')) { request.reply(415); //TODO: instead of 415, pass off to the media handler, who can then decide if we can use it return; } - //TODO: move this into media handler - SIP.Hacks.Firefox.cannotHandleExtraWhitespace(request); - SIP.Hacks.AllBrowsers.maskDtls(request); - - SIP.Utils.augment(this, SIP.ServerContext, [ua, request]); - SIP.Utils.augment(this, SIP.Session, [ua.configuration.mediaHandlerFactory]); - this.status = C.STATUS_INVITE_RECEIVED; this.from_tag = request.from_tag; this.id = request.call_id + this.from_tag; @@ -5792,11 +5747,6 @@ InviteServerContext = function(ua, request) { return; } - //Initialize Media Session - this.mediaHandler = this.mediaHandlerFactory(this, { - RTCConstraints: {"optional": [{'DtlsSrtpKeyAgreement': 'true'}]} - }); - if (this.mediaHandler && this.mediaHandler.getRemoteStreams) { this.getRemoteStreams = this.mediaHandler.getRemoteStreams.bind(this.mediaHandler); this.getLocalStreams = this.mediaHandler.getLocalStreams.bind(this.mediaHandler); @@ -5833,15 +5783,15 @@ InviteServerContext = function(ua, request) { self.emit('invite',request); } - if (!request.body || this.renderbody) { + if (!this.mediaHandler.hasDescription(request) || this.renderbody) { SIP.Timers.setTimeout(fireNewSession, 0); } else { this.hasOffer = true; - this.mediaHandler.setDescription(request.body) + this.mediaHandler.setDescription(request) .then( fireNewSession, function onFailure (e) { - self.logger.warn('invalid SDP'); + self.logger.warn('invalid description'); self.logger.warn(e); request.reply(488); } @@ -5877,7 +5827,7 @@ InviteServerContext.prototype = { this.receiveRequest = function(request) { if (request.method === SIP.C.ACK) { - this.request(SIP.C.BYE, { + this.sendRequest(SIP.C.BYE, { extraHeaders: extraHeaders, body: body }); @@ -5886,7 +5836,7 @@ InviteServerContext.prototype = { }; this.request.server_transaction.on('stateChanged', function(){ - if (this.state === SIP.Transactions.C.STATUS_TERMINATED) { + if (this.state === SIP.Transactions.C.STATUS_TERMINATED && this.dialog) { this.request = new SIP.OutgoingRequest( SIP.C.BYE, this.dialog.remote_target, @@ -5953,7 +5903,6 @@ InviteServerContext.prototype = { iceServers, stunServers = options.stunServers || null, turnServers = options.turnServers || null, - artificialRemoteIceCandidates = options.artificialRemoteIceCandidates || null, body = options.body, response; @@ -5967,7 +5916,7 @@ InviteServerContext.prototype = { if (stunServers || turnServers) { if (stunServers) { - iceServers = SIP.UA.configuration_check.optional['stunServers'](stunServers); + iceServers = this.ua.getConfigurationCheck().optional['stunServers'](stunServers); if (!iceServers) { throw new TypeError('Invalid stunServers: '+ stunServers); } else { @@ -5976,7 +5925,7 @@ InviteServerContext.prototype = { } if (turnServers) { - iceServers = SIP.UA.configuration_check.optional['turnServers'](turnServers); + iceServers = this.ua.getConfigurationCheck().optional['turnServers'](turnServers); if (!iceServers) { throw new TypeError('Invalid turnServers: '+ turnServers); } else { @@ -6006,18 +5955,18 @@ InviteServerContext.prototype = { // Get the session description to add to preaccept with this.mediaHandler.getDescription(options.media) .then( - function onSuccess (body) { + function onSuccess (description) { if (this.isCanceled || this.status === C.STATUS_TERMINATED) { return; } - this.early_sdp = body; + this.early_sdp = description.body; this[this.hasOffer ? 'hasAnswer' : 'hasOffer'] = true; // Retransmit until we get a response or we time out (see prackTimer below) var timeout = SIP.Timers.T1; this.timers.rel1xxTimer = SIP.Timers.setTimeout(function rel1xxRetransmission() { - this.request.reply(statusCode, null, extraHeaders, body); + this.request.reply(statusCode, null, extraHeaders, description); timeout *= 2; this.timers.rel1xxTimer = SIP.Timers.setTimeout(rel1xxRetransmission.bind(this), timeout); }.bind(this), timeout); @@ -6035,7 +5984,7 @@ InviteServerContext.prototype = { }.bind(this), SIP.Timers.T1 * 64); // Send the initial response - response = this.request.reply(statusCode, reasonPhrase, extraHeaders, body); + response = this.request.reply(statusCode, reasonPhrase, extraHeaders, description); this.emit('progress', response, reasonPhrase); }.bind(this), @@ -6072,6 +6021,8 @@ InviteServerContext.prototype = { SIP.Utils.optionsOverride(options, 'media', 'mediaConstraints', true, this.logger, this.ua.configuration.media); this.mediaHint = options.media; + this.onInfo = options.onInfo; + // commented out now-unused hold-related variables for jshint. See below. JMF 2014-1-21 var //idx, length, hasAudio, hasVideo, @@ -6082,15 +6033,14 @@ InviteServerContext.prototype = { iceServers, stunServers = options.stunServers || null, turnServers = options.turnServers || null, - artificialRemoteIceCandidates = options.artificialRemoteIceCandidates || null, - sdpCreationSucceeded = function(body) { + descriptionCreationSucceeded = function(description) { var response, // run for reply success callback replySucceeded = function() { self.status = C.STATUS_WAITING_FOR_ACK; - self.setInvite2xxTimer(request, body); + self.setInvite2xxTimer(request, description); self.setACKTimer(); }, @@ -6117,7 +6067,7 @@ InviteServerContext.prototype = { self.hasAnswer = true; } response = request.reply(200, null, extraHeaders, - body, + description, replySucceeded, replyFailed ); @@ -6126,7 +6076,7 @@ InviteServerContext.prototype = { } }, - sdpCreationFailed = function() { + descriptionCreationFailed = function() { if (self.status === C.STATUS_TERMINATED) { return; } @@ -6150,7 +6100,7 @@ InviteServerContext.prototype = { if ((stunServers || turnServers) && (this.status !== C.STATUS_EARLY_MEDIA && this.status !== C.STATUS_ANSWERED_WAITING_FOR_PRACK)) { if (stunServers) { - iceServers = SIP.UA.configuration_check.optional['stunServers'](stunServers); + iceServers = this.ua.getConfigurationCheck().optional['stunServers'](stunServers); if (!iceServers) { throw new TypeError('Invalid stunServers: '+ stunServers); } else { @@ -6159,7 +6109,7 @@ InviteServerContext.prototype = { } if (turnServers) { - iceServers = SIP.UA.configuration_check.optional['turnServers'](turnServers); + iceServers = this.ua.getConfigurationCheck().optional['turnServers'](turnServers); if (!iceServers) { throw new TypeError('Invalid turnServers: '+ turnServers); } else { @@ -6216,12 +6166,12 @@ InviteServerContext.prototype = { */ if (this.status === C.STATUS_EARLY_MEDIA) { - sdpCreationSucceeded(); + descriptionCreationSucceeded({}); } else { this.mediaHandler.getDescription(self.mediaHint) .then( - sdpCreationSucceeded, - sdpCreationFailed + descriptionCreationSucceeded, + descriptionCreationFailed ); } @@ -6243,10 +6193,12 @@ InviteServerContext.prototype = { // TODO - this logic assumes Content-Disposition defaults contentType = request.getHeader('Content-Type'); - if (contentType !== 'application/sdp') { + if (!this.mediaHandler.hasDescription(request)) { this.renderbody = request.body; this.rendertype = contentType; } + + this.emit('confirmed', request); } switch(request.method) { @@ -6279,13 +6231,10 @@ InviteServerContext.prototype = { case SIP.C.ACK: if(this.status === C.STATUS_WAITING_FOR_ACK) { if (!this.hasAnswer) { - if(request.body && request.getHeader('content-type') === 'application/sdp') { + if(this.mediaHandler.hasDescription(request)) { // ACK contains answer to an INVITE w/o SDP negotiation - SIP.Hacks.Firefox.cannotHandleExtraWhitespace(request); - SIP.Hacks.AllBrowsers.maskDtls(request); - this.hasAnswer = true; - this.mediaHandler.setDescription(request.body) + this.mediaHandler.setDescription(request) .then( confirmSession.bind(this), function onFailure (e) { @@ -6314,9 +6263,9 @@ InviteServerContext.prototype = { if (this.status === C.STATUS_WAITING_FOR_PRACK || this.status === C.STATUS_ANSWERED_WAITING_FOR_PRACK) { //localMedia = session.mediaHandler.localMedia; if(!this.hasAnswer) { - if(request.body && request.getHeader('content-type') === 'application/sdp') { + if(this.mediaHandler.hasDescription(request)) { this.hasAnswer = true; - this.mediaHandler.setDescription(request.body) + this.mediaHandler.setDescription(request) .then( function onSuccess () { SIP.Timers.clearTimeout(this.timers.rel1xxTimer); @@ -6399,7 +6348,6 @@ InviteClientContext = function(ua, target, options) { extraHeaders = (options.extraHeaders || []).slice(), stunServers = options.stunServers || null, turnServers = options.turnServers || null, - artificialRemoteIceCandidates = options.artificialRemoteIceCandidates || null, mediaHandlerFactory = options.mediaHandlerFactory || ua.configuration.mediaHandlerFactory, isMediaSupported = mediaHandlerFactory.isSupported; @@ -6437,9 +6385,7 @@ InviteClientContext = function(ua, target, options) { } extraHeaders.push('Contact: '+ this.contact); extraHeaders.push('Allow: '+ SIP.UA.C.ALLOWED_METHODS.toString()); - if (!this.inviteWithoutSdp) { - extraHeaders.push('Content-Type: application/sdp'); - } else if (this.renderbody) { + if (this.inviteWithoutSdp && this.renderbody) { extraHeaders.push('Content-Type: ' + this.rendertype); extraHeaders.push('Content-Disposition: render;handling=optional'); } @@ -6476,7 +6422,7 @@ InviteClientContext = function(ua, target, options) { this.logger = ua.getLogger('sip.inviteclientcontext'); if (stunServers) { - iceServers = SIP.UA.configuration_check.optional['stunServers'](stunServers); + iceServers = this.ua.getConfigurationCheck().optional['stunServers'](stunServers); if (!iceServers) { throw new TypeError('Invalid stunServers: '+ stunServers); } else { @@ -6485,7 +6431,7 @@ InviteClientContext = function(ua, target, options) { } if (turnServers) { - iceServers = SIP.UA.configuration_check.optional['turnServers'](turnServers); + iceServers = this.ua.getConfigurationCheck().optional['turnServers'](turnServers); if (!iceServers) { throw new TypeError('Invalid turnServers: '+ turnServers); } else { @@ -6493,15 +6439,6 @@ InviteClientContext = function(ua, target, options) { } } - if (artificialRemoteIceCandidates) { - iceServers = SIP.UA.configuration_check.optional['artificialRemoteIceCandidates'](artificialRemoteIceCandidates); - if (!iceServers) { - throw new TypeError('Invalid artificialRemoteIceCandidates: '+ artificialRemoteIceCandidates); - } else { - this.artificialRemoteIceCandidates = iceServers; - } - } - ua.applicants[this] = this; this.id = this.request.call_id + this.from_tag; @@ -6520,6 +6457,8 @@ InviteClientContext = function(ua, target, options) { SIP.Utils.optionsOverride(options, 'media', 'mediaConstraints', true, this.logger, this.ua.configuration.media); this.mediaHint = options.media; + + this.onInfo = options.onInfo; }; InviteClientContext.prototype = { @@ -6540,12 +6479,12 @@ InviteClientContext.prototype = { } else { this.mediaHandler.getDescription(self.mediaHint) .then( - function onSuccess(offer) { + function onSuccess(description) { if (self.isCanceled || self.status === C.STATUS_TERMINATED) { return; } self.hasOffer = true; - self.request.body = offer; + self.request.body = description; self.status = C.STATUS_INVITE_SENT; self.send(); }, @@ -6638,7 +6577,7 @@ InviteClientContext.prototype = { // Proceed to cancellation if the user requested. if(this.isCanceled) { if(response.status_code >= 100 && response.status_code < 200) { - this.request.cancel(this.cancelReason); + this.request.cancel(this.cancelReason, extraHeaders); this.canceled(null); } else if(response.status_code >= 200 && response.status_code < 299) { this.acceptAndTerminate(response); @@ -6652,8 +6591,6 @@ InviteClientContext.prototype = { return; } - SIP.Hacks.AllBrowsers.addArtificialRemoteIceCandidates(response, this.ua.configuration.artificialRemoteIceCandidates); - switch(true) { case /^100$/.test(response.status_code): this.received_100 = true; @@ -6689,10 +6626,7 @@ InviteClientContext.prototype = { return; } - SIP.Hacks.Firefox.cannotHandleExtraWhitespace(response); - SIP.Hacks.AllBrowsers.maskDtls(response); - - if (!response.body) { + if (!this.mediaHandler.hasDescription(response)) { extraHeaders.push('RAck: ' + response.getHeader('rseq') + ' ' + response.getHeader('cseq')); this.earlyDialogs[id].pracked.push(response.getHeader('rseq')); this.earlyDialogs[id].sendRequest(this, SIP.C.PRACK, { @@ -6707,7 +6641,7 @@ InviteClientContext.prototype = { this.hasAnswer = true; this.dialog.pracked.push(response.getHeader('rseq')); - this.mediaHandler.setDescription(response.body) + this.mediaHandler.setDescription(response) .then( function onSuccess () { extraHeaders.push('RAck: ' + response.getHeader('rseq') + ' ' + response.getHeader('cseq')); @@ -6742,14 +6676,13 @@ InviteClientContext.prototype = { earlyDialog.pracked.push(response.getHeader('rseq')); - earlyMedia.setDescription(response.body) + earlyMedia.setDescription(response) .then(earlyMedia.getDescription.bind(earlyMedia, session.mediaHint)) - .then(function onSuccess(sdp) { - extraHeaders.push('Content-Type: application/sdp'); + .then(function onSuccess(description) { extraHeaders.push('RAck: ' + response.getHeader('rseq') + ' ' + response.getHeader('cseq')); earlyDialog.sendRequest(session, SIP.C.PRACK, { extraHeaders: extraHeaders, - body: sdp + body: description }); session.status = C.STATUS_EARLY_MEDIA; session.emit('progress', response); @@ -6767,7 +6700,7 @@ InviteClientContext.prototype = { } else { earlyDialog.pracked.splice(earlyDialog.pracked.indexOf(response.getHeader('rseq')), 1); // Could not set remote description - session.logger.warn('invalid SDP'); + session.logger.warn('invalid description'); session.logger.warn(e); } }); @@ -6808,9 +6741,6 @@ InviteClientContext.prototype = { break; } - SIP.Hacks.Firefox.cannotHandleExtraWhitespace(response); - SIP.Hacks.AllBrowsers.maskDtls(response); - // This is an invite without sdp if (!this.hasOffer) { if (this.earlyDialogs[id] && this.earlyDialogs[id].mediaHandler.localMedia) { @@ -6835,7 +6765,7 @@ InviteClientContext.prototype = { }*/ this.accepted(response); } else { - if(!response.body) { + if(!this.mediaHandler.hasDescription(response)) { this.acceptAndTerminate(response, 400, 'Missing session description'); this.failed(response, SIP.C.causes.BAD_MEDIA_DESCRIPTION); break; @@ -6844,16 +6774,14 @@ InviteClientContext.prototype = { break; } this.hasOffer = true; - this.mediaHandler.setDescription(response.body) + this.mediaHandler.setDescription(response) .then(this.mediaHandler.getDescription.bind(this.mediaHandler, this.mediaHint)) - .then(function onSuccess(sdp) { + .then(function onSuccess(description) { //var localMedia; if(session.isCanceled || session.status === C.STATUS_TERMINATED) { return; } - sdp = SIP.Hacks.Firefox.hasMissingCLineInSDP(sdp); - session.status = C.STATUS_CONFIRMED; session.hasAnswer = true; @@ -6866,8 +6794,7 @@ InviteClientContext.prototype = { localMedia.getVideoTracks()[0].enabled = true; }*/ session.sendRequest(SIP.C.ACK,{ - body: sdp, - extraHeaders:['Content-Type: application/sdp'], + body: description, cseq:response.cseq }); session.accepted(response); @@ -6877,9 +6804,10 @@ InviteClientContext.prototype = { // TODO do something here session.logger.warn("there was a problem"); } else { - session.logger.warn('invalid SDP'); + session.logger.warn('invalid description'); session.logger.warn(e); - response.reply(488); + session.acceptAndTerminate(response, 488, 'Invalid session description'); + session.failed(response, SIP.C.causes.BAD_MEDIA_DESCRIPTION); } }); } @@ -6891,7 +6819,7 @@ InviteClientContext.prototype = { } this.sendRequest(SIP.C.ACK, options); } else { - if(!response.body) { + if(!this.mediaHandler.hasDescription(response)) { this.acceptAndTerminate(response, 400, 'Missing session description'); this.failed(response, SIP.C.causes.BAD_MEDIA_DESCRIPTION); break; @@ -6900,7 +6828,7 @@ InviteClientContext.prototype = { break; } this.hasAnswer = true; - this.mediaHandler.setDescription(response.body) + this.mediaHandler.setDescription(response) .then( function onSuccess () { var options = {};//,localMedia; @@ -6941,6 +6869,8 @@ InviteClientContext.prototype = { cancel: function(options) { options = options || {}; + options.extraHeaders = (options.extraHeaders || []).slice(); + // Check Session Status if (this.status === C.STATUS_TERMINATED || this.status === C.STATUS_CONFIRMED) { throw new SIP.Exceptions.InvalidStateError(this.status); @@ -6958,7 +6888,7 @@ InviteClientContext.prototype = { } else if (this.status === C.STATUS_INVITE_SENT || this.status === C.STATUS_1XX_RECEIVED || this.status === C.STATUS_EARLY_MEDIA) { - this.request.cancel(cancel_reason); + this.request.cancel(cancel_reason, options.extraHeaders); } return this.canceled(); @@ -7104,7 +7034,8 @@ DTMF.prototype = Object.create(SIP.EventEmitter.prototype); DTMF.prototype.send = function(options) { - var extraHeaders, body; + var extraHeaders, + body = {}; this.direction = 'outgoing'; @@ -7118,10 +7049,10 @@ DTMF.prototype.send = function(options) { options = options || {}; extraHeaders = options.extraHeaders ? options.extraHeaders.slice() : []; - extraHeaders.push('Content-Type: application/dtmf-relay'); + body.contentType = 'application/dtmf-relay'; - body = "Signal= " + this.tone + "\r\n"; - body += "Duration= " + this.duration; + body.body = "Signal= " + this.tone + "\r\n"; + body.body += "Duration= " + this.duration; this.request = this.owner.dialog.sendRequest(this, SIP.C.INFO, { extraHeaders: extraHeaders, @@ -7271,6 +7202,8 @@ SIP.Subscription.prototype = { SIP.Timers.clearTimeout(this.timers.N); this.timers.N = SIP.Timers.setTimeout(sub.timer_fire.bind(sub), SIP.Timers.TIMER_N); + this.ua.earlySubscriptions[this.request.call_id + this.request.from.parameters.tag + this.event] = this; + this.send(); this.state = 'notify_wait'; @@ -7297,15 +7230,11 @@ SIP.Subscription.prototype = { (this.state !== 'notify_wait' && this.errorCodes.indexOf(response.status_code) !== -1)) { this.failed(response, null); } else if (/^2[0-9]{2}$/.test(response.status_code)){ - expires = response.getHeader('Expires'); - SIP.Timers.clearTimeout(this.timers.N); + this.emit('accepted', response, cause); + //As we don't support RFC 5839 or other extensions where the NOTIFY is optional, timer N will not be cleared + //SIP.Timers.clearTimeout(this.timers.N); - if (this.createConfirmedDialog(response,'UAC')) { - this.id = this.dialog.id.toString(); - this.ua.subscriptions[this.id] = this; - this.emit('accepted', response, cause); - // UPDATE ROUTE SET TO BE BACKWARDS COMPATIBLE? - } + expires = response.getHeader('Expires'); if (expires && expires <= this.expires) { // Preserve new expires value for subsequent requests @@ -7320,7 +7249,10 @@ SIP.Subscription.prototype = { this.failed(response, SIP.C.INVALID_EXPIRES_HEADER); } } - } //Used to just ignore provisional responses; now ignores everything except errorCodes and 2xx + } else if (response.statusCode > 300) { + this.emit('failed', response, cause); + this.emit('rejected', response, cause); + } }, unsubscribe: function() { @@ -7357,7 +7289,7 @@ SIP.Subscription.prototype = { SIP.Timers.clearTimeout(this.timers.sub_duration); delete this.ua.subscriptions[this.id]; - } else if (this.state === 'pending' || this.state === 'notify_wait') { + } else if (this.state === 'notify_wait' || this.state === 'pending') { this.close(); } else { this.refresh(); @@ -7368,7 +7300,14 @@ SIP.Subscription.prototype = { * @private */ close: function() { - if(this.state !== 'notify_wait' && this.state !== 'terminated') { + if (this.state === 'notify_wait') { + this.state = 'terminated'; + SIP.Timers.clearTimeout(this.timers.N); + SIP.Timers.clearTimeout(this.timers.sub_duration); + this.receiveResponse = function(){}; + + delete this.ua.earlySubscriptions[this.request.call_id + this.request.from.parameters.tag + this.event]; + } else if (this.state !== 'terminated') { this.unsubscribe(); } }, @@ -7381,6 +7320,8 @@ SIP.Subscription.prototype = { this.terminateDialog(); dialog = new SIP.Dialog(this, message, type); + dialog.invite_seqnum = this.request.cseq; + dialog.local_seqnum = this.request.cseq; if(!dialog.error) { this.dialog = dialog; @@ -7424,6 +7365,15 @@ SIP.Subscription.prototype = { return; } + if (!this.dialog) { + if (this.createConfirmedDialog(request,'UAS')) { + this.id = this.dialog.id.toString(); + delete this.ua.earlySubscriptions[this.request.call_id + this.request.from.parameters.tag + this.event]; + this.ua.subscriptions[this.id] = this; + // UPDATE ROUTE SET TO BE BACKWARDS COMPATIBLE? + } + } + sub_state = request.parseHeader('Subscription-State'); request.reply(200, SIP.C.REASON_200); @@ -7487,6 +7437,7 @@ SIP.Subscription.prototype = { failed: function(response, cause) { this.close(); this.emit('failed', response, cause); + this.emit('rejected', response, cause); return this; }, @@ -7731,8 +7682,15 @@ var InviteClientTransaction = function(request_sender, request, transport) { // Add the cancel property to the request. //Will be called from the request instance, not the transaction itself. - this.request.cancel = function(reason) { - tr.cancel_request(tr, reason); + this.request.cancel = function(reason, extraHeaders) { + extraHeaders = (extraHeaders || []).slice(); + var length = extraHeaders.length; + var extraHeadersString = null; + for (var idx = 0; idx < length; idx++) { + extraHeadersString = (extraHeadersString || '') + extraHeaders[idx].trim() + '\r\n'; + } + + tr.cancel_request(tr, reason, extraHeadersString); }; }; InviteClientTransaction.prototype = Object.create(SIP.EventEmitter.prototype); @@ -7815,7 +7773,7 @@ InviteClientTransaction.prototype.sendACK = function(response) { this.transport.send(this.ack); }; -InviteClientTransaction.prototype.cancel_request = function(tr, reason) { +InviteClientTransaction.prototype.cancel_request = function(tr, reason, extraHeaders) { var request = tr.request; this.cancel = SIP.C.CANCEL + ' ' + request.ruri + ' SIP/2.0\r\n'; @@ -7835,6 +7793,10 @@ InviteClientTransaction.prototype.cancel_request = function(tr, reason) { this.cancel += 'Reason: ' + reason + '\r\n'; } + if (extraHeaders) { + this.cancel += extraHeaders; + } + this.cancel += 'Content-Length: 0\r\n\r\n'; // Send only if a provisional response (>100) has been received. @@ -8220,7 +8182,7 @@ var checkTransaction = function(ua, request) { if(tr.state === C.STATUS_ACCEPTED) { return false; } else if(tr.state === C.STATUS_COMPLETED) { - tr.state = C.STATUS_CONFIRMED; + tr.stateChanged(C.STATUS_CONFIRMED); tr.I = SIP.Timers.setTimeout(tr.timer_I.bind(tr), SIP.Timers.TIMER_I); return true; } @@ -8403,6 +8365,7 @@ Transport.prototype = { this.closed = true; this.logger.log('closing WebSocket ' + this.server.ws_uri); this.ws.close(); + this.ws = null; } if (this.reconnectTimer !== null) { @@ -8429,6 +8392,7 @@ Transport.prototype = { if(this.ws) { this.ws.close(); + this.ws = null; } this.logger.log('connecting to WebSocket ' + this.server.ws_uri); @@ -8449,6 +8413,11 @@ Transport.prototype = { this.ws.onclose = function(e) { transport.onClose(e); + // Always cleanup. Eases GC, prevents potential memory leaks. + this.onopen = null; + this.onclose = null; + this.onmessage = null; + this.onerror = null; }; this.ws.onmessage = function(e) { @@ -8724,6 +8693,7 @@ UA = function(configuration) { this.data = {}; this.sessions = {}; this.subscriptions = {}; + this.earlySubscriptions = {}; this.transport = null; this.contact = null; this.status = C.STATUS_INIT; @@ -8825,14 +8795,6 @@ UA = function(configuration) { if(this.configuration.autostart) { this.start(); } - - if (typeof environment.addEventListener === 'function') { - // Google Chrome Packaged Apps don't allow 'unload' listeners: - // unload is not available in packaged apps - if (!(global.chrome && global.chrome.app && global.chrome.app.runtime)) { - environment.addEventListener('unload', this.stop.bind(this)); - } - } }; UA.prototype = Object.create(SIP.EventEmitter.prototype); @@ -8896,6 +8858,7 @@ UA.prototype.invite = function(target, options) { var context = new SIP.InviteClientContext(this, target, options); this.afterConnected(context.invite.bind(context)); + this.emit('inviteSent', context); return context; }; @@ -8971,12 +8934,18 @@ UA.prototype.stop = function() { this.sessions[session].terminate(); } - //Run _close_ on every Subscription + //Run _close_ on every confirmed Subscription for(subscription in this.subscriptions) { this.logger.log('unsubscribing from subscription ' + subscription); this.subscriptions[subscription].close(); } + //Run _close_ on every early Subscription + for(subscription in this.earlySubscriptions) { + this.logger.log('unsubscribing from early subscription ' + subscription); + this.earlySubscriptions[subscription].close(); + } + // Run _close_ on every applicant for(applicant in this.applicants) { this.applicants[applicant].close(); @@ -8998,6 +8967,14 @@ UA.prototype.stop = function() { this.on('transactionDestroyed', transactionsListener); } + if (typeof environment.removeEventListener === 'function') { + // Google Chrome Packaged Apps don't allow 'unload' listeners: + // unload is not available in packaged apps + if (!(global.chrome && global.chrome.app && global.chrome.app.runtime)) { + environment.removeEventListener('unload', this.environListener); + } + } + return this; }; @@ -9026,6 +9003,15 @@ UA.prototype.start = function() { this.logger.error('Connection is down. Auto-Recovery system is trying to connect'); } + if (this.configuration.autostop && typeof environment.addEventListener === 'function') { + // Google Chrome Packaged Apps don't allow 'unload' listeners: + // unload is not available in packaged apps + if (!(global.chrome && global.chrome.app && global.chrome.app.runtime)) { + this.environListener = this.stop.bind(this); + environment.addEventListener('unload', this.environListener); + } + } + return this; }; @@ -9224,7 +9210,7 @@ UA.prototype.destroyTransaction = function(transaction) { * @param {SIP.IncomingRequest} request. */ UA.prototype.receiveRequest = function(request) { - var dialog, session, message, + var dialog, session, message, earlySubscription, method = request.method, transaction, replaces, @@ -9336,6 +9322,14 @@ UA.prototype.receiveRequest = function(request) { * and without To tag. */ break; + case SIP.C.NOTIFY: + if (this.configuration.allowLegacyNotifications && this.listeners('notify').length > 0) { + request.reply(200, null); + self.emit('notify', {request: request}); + } else { + request.reply(481, 'Subscription does not exist'); + } + break; default: request.reply(405); break; @@ -9352,10 +9346,13 @@ UA.prototype.receiveRequest = function(request) { dialog.receiveRequest(request); } else if (method === SIP.C.NOTIFY) { session = this.findSession(request); + earlySubscription = this.findEarlySubscription(request); if(session) { session.receiveRequest(request); + } else if(earlySubscription) { + earlySubscription.receiveRequest(request); } else { - this.logger.warn('received NOTIFY request for a non existent session'); + this.logger.warn('received NOTIFY request for a non existent session or subscription'); request.reply(481, 'Subscription does not exist'); } } @@ -9400,6 +9397,16 @@ UA.prototype.findDialog = function(request) { null; }; +/** + * Get the subscription which has not been confirmed to which the request belongs to, if any + * @private + * @param {SIP.IncomingRequest} + * @returns {SIP.Subscription|null} + */ +UA.prototype.findEarlySubscription = function(request) { + return this.earlySubscriptions[request.call_id + request.to_tag + request.getHeader('event')] || null; +}; + /** * Retrieve the next server to which connect. * @private @@ -9511,6 +9518,12 @@ UA.prototype.loadConfig = function(configuration) { ws_uri: 'wss://edge.sip.onsip.com' }], + //Custom Configuration Settings + custom: {}, + + //Display name + displayName: '', + // Password password: null, @@ -9540,7 +9553,6 @@ UA.prototype.loadConfig = function(configuration) { noAnswerTimeout: 60, stunServers: ['stun:stun.l.google.com:19302'], turnServers: [], - artificialRemoteIceCandidates: [], // Logging parameters traceSip: false, @@ -9550,12 +9562,15 @@ UA.prototype.loadConfig = function(configuration) { hackIpInContact: false, hackWssInTransport: false, hackAllowUnregisteredOptionTags: false, + hackCleanJitsiSdpImageattr: false, + hackStripTcp: false, contactTransport: 'ws', forceRport: false, //autostarting autostart: true, + autostop: true, //Reliable Provisional Responses rel100: SIP.C.supported.UNSUPPORTED, @@ -9568,7 +9583,9 @@ UA.prototype.loadConfig = function(configuration) { authenticationFactory: checkAuthenticationFactory(function authenticationFactory (ua) { return new SIP.DigestAuthentication(ua); - }) + }), + + allowLegacyNotifications: false }; // Pre-Configuration @@ -9592,14 +9609,16 @@ UA.prototype.loadConfig = function(configuration) { configuration[parameter] = hasParameter ? configuration[parameter] : configuration[underscored]; } + var configCheck = this.getConfigurationCheck(); + // Check Mandatory parameters - for(parameter in UA.configuration_check.mandatory) { + for(parameter in configCheck.mandatory) { aliasUnderscored(parameter, this.logger); if(!configuration.hasOwnProperty(parameter)) { throw new SIP.Exceptions.ConfigurationError(parameter); } else { value = configuration[parameter]; - checked_value = UA.configuration_check.mandatory[parameter](value); + checked_value = configCheck.mandatory[parameter](value); if (checked_value !== undefined) { settings[parameter] = checked_value; } else { @@ -9610,10 +9629,10 @@ UA.prototype.loadConfig = function(configuration) { SIP.Utils.optionsOverride(configuration, 'rel100', 'reliable', true, this.logger, SIP.C.supported.UNSUPPORTED); - var emptyArraysAllowed = ['stunServers', 'turnServers', 'artificialRemoteIceCandidates']; + var emptyArraysAllowed = ['stunServers', 'turnServers']; // Check Optional parameters - for(parameter in UA.configuration_check.optional) { + for(parameter in configCheck.optional) { aliasUnderscored(parameter, this.logger); if(configuration.hasOwnProperty(parameter)) { value = configuration[parameter]; @@ -9627,7 +9646,7 @@ UA.prototype.loadConfig = function(configuration) { // NOTE: JS does not allow "value === NaN", the following does the work: else if(typeof(value) === 'number' && isNaN(value)) { continue; } - checked_value = UA.configuration_check.optional[parameter](value); + checked_value = configCheck.optional[parameter](value); if (checked_value !== undefined) { settings[parameter] = checked_value; } else { @@ -9726,17 +9745,17 @@ UA.prototype.loadConfig = function(configuration) { // media overrides mediaConstraints SIP.Utils.optionsOverride(settings, 'media', 'mediaConstraints', true, this.logger); + var skeleton = {}; // Fill the value of the configuration_skeleton for(parameter in settings) { - UA.configuration_skeleton[parameter].value = settings[parameter]; + skeleton[parameter] = { + value: settings[parameter], + writable: (parameter === 'register' || parameter === 'custom'), + configurable: false + }; } - Object.defineProperties(this.configuration, UA.configuration_skeleton); - - // Clean UA.configuration_skeleton - for(parameter in settings) { - UA.configuration_skeleton[parameter].value = ''; - } + Object.defineProperties(this.configuration, skeleton); this.logger.log('configuration parameters after validation:'); for(parameter in settings) { @@ -9757,500 +9776,461 @@ UA.prototype.loadConfig = function(configuration) { return; }; -/** - * Configuration Object skeleton. - * @private - */ -UA.configuration_skeleton = (function() { - var idx, parameter, - skeleton = {}, - parameters = [ - // Internal parameters - "sipjsId", - "hostportParams", - - // Optional user configurable parameters - "uri", - "wsServers", - "authorizationUser", - "connectionRecoveryMaxInterval", - "connectionRecoveryMinInterval", - "keepAliveInterval", - "extraSupported", - "displayName", - "hackViaTcp", // false. - "hackIpInContact", //false - "hackWssInTransport", //false - "hackAllowUnregisteredOptionTags", //false - "contactTransport", // 'ws' - "forceRport", // false - "iceCheckingTimeout", - "instanceId", - "noAnswerTimeout", // 30 seconds. - "password", - "registerExpires", // 600 seconds. - "registrarServer", - "reliable", - "rel100", - "replaces", - "userAgentString", //SIP.C.USER_AGENT - "autostart", - "stunServers", - "artificialRemoteIceCandidates", - "traceSip", - "turnServers", - "usePreloadedRoute", - "wsServerMaxReconnection", - "wsServerReconnectionTimeout", - "mediaHandlerFactory", - "media", - "mediaConstraints", - "authenticationFactory", - - // Post-configuration generated parameters - "via_core_value", - "viaHost" - ]; - - for(idx in parameters) { - parameter = parameters[idx]; - skeleton[parameter] = { - value: '', - writable: false, - configurable: false - }; - } - - skeleton['register'] = { - value: '', - writable: true, - configurable: false - }; - - return skeleton; -}()); - /** * Configuration checker. * @private * @return {Boolean} */ -UA.configuration_check = { - mandatory: { - }, - - optional: { - - uri: function(uri) { - var parsed; - - if (!(/^sip:/i).test(uri)) { - uri = SIP.C.SIP + ':' + uri; - } - parsed = SIP.URI.parse(uri); - - if(!parsed) { - return; - } else if(!parsed.user) { - return; - } else { - return parsed; - } +UA.prototype.getConfigurationCheck = function () { + return { + mandatory: { }, - //Note: this function used to call 'this.logger.error' but calling 'this' with anything here is invalid - wsServers: function(wsServers) { - var idx, length, url; + optional: { + + uri: function(uri) { + var parsed; + + if (!(/^sip:/i).test(uri)) { + uri = SIP.C.SIP + ':' + uri; + } + parsed = SIP.URI.parse(uri); + + if(!parsed) { + return; + } else if(!parsed.user) { + return; + } else { + return parsed; + } + }, + + //Note: this function used to call 'this.logger.error' but calling 'this' with anything here is invalid + wsServers: function(wsServers) { + var idx, length, url; + + /* Allow defining wsServers parameter as: + * String: "host" + * Array of Strings: ["host1", "host2"] + * Array of Objects: [{ws_uri:"host1", weight:1}, {ws_uri:"host2", weight:0}] + * Array of Objects and Strings: [{ws_uri:"host1"}, "host2"] + */ + if (typeof wsServers === 'string') { + wsServers = [{ws_uri: wsServers}]; + } else if (wsServers instanceof Array) { + length = wsServers.length; + for (idx = 0; idx < length; idx++) { + if (typeof wsServers[idx] === 'string'){ + wsServers[idx] = {ws_uri: wsServers[idx]}; + } + } + } else { + return; + } + + if (wsServers.length === 0) { + return false; + } - /* Allow defining wsServers parameter as: - * String: "host" - * Array of Strings: ["host1", "host2"] - * Array of Objects: [{ws_uri:"host1", weight:1}, {ws_uri:"host2", weight:0}] - * Array of Objects and Strings: [{ws_uri:"host1"}, "host2"] - */ - if (typeof wsServers === 'string') { - wsServers = [{ws_uri: wsServers}]; - } else if (wsServers instanceof Array) { length = wsServers.length; for (idx = 0; idx < length; idx++) { - if (typeof wsServers[idx] === 'string'){ - wsServers[idx] = {ws_uri: wsServers[idx]}; + if (!wsServers[idx].ws_uri) { + return; } - } - } else { - return; - } - - if (wsServers.length === 0) { - return false; - } - - length = wsServers.length; - for (idx = 0; idx < length; idx++) { - if (!wsServers[idx].ws_uri) { - return; - } - if (wsServers[idx].weight && !Number(wsServers[idx].weight)) { - return; - } - - url = SIP.Grammar.parse(wsServers[idx].ws_uri, 'absoluteURI'); - - if(url === -1) { - return; - } else if(['wss', 'ws', 'udp'].indexOf(url.scheme) < 0) { - return; - } else { - wsServers[idx].sip_uri = ''; - - if (!wsServers[idx].weight) { - wsServers[idx].weight = 0; + if (wsServers[idx].weight && !Number(wsServers[idx].weight)) { + return; } - wsServers[idx].status = 0; - wsServers[idx].scheme = url.scheme.toUpperCase(); - } - } - return wsServers; - }, + url = SIP.Grammar.parse(wsServers[idx].ws_uri, 'absoluteURI'); - authorizationUser: function(authorizationUser) { - if(SIP.Grammar.parse('"'+ authorizationUser +'"', 'quoted_string') === -1) { - return; - } else { - return authorizationUser; - } - }, + if(url === -1) { + return; + } else if(['wss', 'ws', 'udp'].indexOf(url.scheme) < 0) { + return; + } else { + wsServers[idx].sip_uri = ''; - connectionRecoveryMaxInterval: function(connectionRecoveryMaxInterval) { - var value; - if(SIP.Utils.isDecimal(connectionRecoveryMaxInterval)) { - value = Number(connectionRecoveryMaxInterval); - if(value > 0) { - return value; - } - } - }, + if (!wsServers[idx].weight) { + wsServers[idx].weight = 0; + } - connectionRecoveryMinInterval: function(connectionRecoveryMinInterval) { - var value; - if(SIP.Utils.isDecimal(connectionRecoveryMinInterval)) { - value = Number(connectionRecoveryMinInterval); - if(value > 0) { - return value; - } - } - }, - - displayName: function(displayName) { - if(SIP.Grammar.parse('"' + displayName + '"', 'displayName') === -1) { - return; - } else { - return displayName; - } - }, - - hackViaTcp: function(hackViaTcp) { - if (typeof hackViaTcp === 'boolean') { - return hackViaTcp; - } - }, - - hackIpInContact: function(hackIpInContact) { - if (typeof hackIpInContact === 'boolean') { - return hackIpInContact; - } - else if (typeof hackIpInContact === 'string' && SIP.Grammar.parse(hackIpInContact, 'host') !== -1) { - return hackIpInContact; - } - }, - - iceCheckingTimeout: function(iceCheckingTimeout) { - if(SIP.Utils.isDecimal(iceCheckingTimeout)) { - return Math.max(500, iceCheckingTimeout); - } - }, - - hackWssInTransport: function(hackWssInTransport) { - if (typeof hackWssInTransport === 'boolean') { - return hackWssInTransport; - } - }, - - hackAllowUnregisteredOptionTags: function(hackAllowUnregisteredOptionTags) { - if (typeof hackAllowUnregisteredOptionTags === 'boolean') { - return hackAllowUnregisteredOptionTags; - } - }, - - contactTransport: function(contactTransport) { - if (typeof contactTransport === 'string') { - return contactTransport; - } - }, - - forceRport: function(forceRport) { - if (typeof forceRport === 'boolean') { - return forceRport; - } - }, - - instanceId: function(instanceId) { - if(typeof instanceId !== 'string') { - return; - } - - if ((/^uuid:/i.test(instanceId))) { - instanceId = instanceId.substr(5); - } - - if(SIP.Grammar.parse(instanceId, 'uuid') === -1) { - return; - } else { - return instanceId; - } - }, - - keepAliveInterval: function(keepAliveInterval) { - var value; - if (SIP.Utils.isDecimal(keepAliveInterval)) { - value = Number(keepAliveInterval); - if (value > 0) { - return value; - } - } - }, - - extraSupported: function(optionTags) { - var idx, length; - - if (!(optionTags instanceof Array)) { - return; - } - - length = optionTags.length; - for (idx = 0; idx < length; idx++) { - if (typeof optionTags[idx] !== 'string') { - return; - } - } - - return optionTags; - }, - - noAnswerTimeout: function(noAnswerTimeout) { - var value; - if (SIP.Utils.isDecimal(noAnswerTimeout)) { - value = Number(noAnswerTimeout); - if (value > 0) { - return value; - } - } - }, - - password: function(password) { - return String(password); - }, - - rel100: function(rel100) { - if(rel100 === SIP.C.supported.REQUIRED) { - return SIP.C.supported.REQUIRED; - } else if (rel100 === SIP.C.supported.SUPPORTED) { - return SIP.C.supported.SUPPORTED; - } else { - return SIP.C.supported.UNSUPPORTED; - } - }, - - replaces: function(replaces) { - if(replaces === SIP.C.supported.REQUIRED) { - return SIP.C.supported.REQUIRED; - } else if (replaces === SIP.C.supported.SUPPORTED) { - return SIP.C.supported.SUPPORTED; - } else { - return SIP.C.supported.UNSUPPORTED; - } - }, - - register: function(register) { - if (typeof register === 'boolean') { - return register; - } - }, - - registerExpires: function(registerExpires) { - var value; - if (SIP.Utils.isDecimal(registerExpires)) { - value = Number(registerExpires); - if (value > 0) { - return value; - } - } - }, - - registrarServer: function(registrarServer) { - var parsed; - - if(typeof registrarServer !== 'string') { - return; - } - - if (!/^sip:/i.test(registrarServer)) { - registrarServer = SIP.C.SIP + ':' + registrarServer; - } - parsed = SIP.URI.parse(registrarServer); - - if(!parsed) { - return; - } else if(parsed.user) { - return; - } else { - return parsed; - } - }, - - stunServers: function(stunServers) { - var idx, length, stun_server; - - if (typeof stunServers === 'string') { - stunServers = [stunServers]; - } else if (!(stunServers instanceof Array)) { - return; - } - - length = stunServers.length; - for (idx = 0; idx < length; idx++) { - stun_server = stunServers[idx]; - if (!(/^stuns?:/.test(stun_server))) { - stun_server = 'stun:' + stun_server; - } - - if(SIP.Grammar.parse(stun_server, 'stun_URI') === -1) { - return; - } else { - stunServers[idx] = stun_server; - } - } - return stunServers; - }, - - artificialRemoteIceCandidates: function(candidates) { - return candidates; - }, - - traceSip: function(traceSip) { - if (typeof traceSip === 'boolean') { - return traceSip; - } - }, - - turnServers: function(turnServers) { - var idx, jdx, length, turn_server, num_turn_server_urls, url; - - if (turnServers instanceof Array) { - // Do nothing - } else { - turnServers = [turnServers]; - } - - length = turnServers.length; - for (idx = 0; idx < length; idx++) { - turn_server = turnServers[idx]; - //Backwards compatibility: Allow defining the turn_server url with the 'server' property. - if (turn_server.server) { - turn_server.urls = [turn_server.server]; - } - - if (!turn_server.urls || !turn_server.username || !turn_server.password) { - return; - } - - if (turn_server.urls instanceof Array) { - num_turn_server_urls = turn_server.urls.length; - } else { - turn_server.urls = [turn_server.urls]; - num_turn_server_urls = 1; - } - - for (jdx = 0; jdx < num_turn_server_urls; jdx++) { - url = turn_server.urls[jdx]; - - if (!(/^turns?:/.test(url))) { - url = 'turn:' + url; + wsServers[idx].status = 0; + wsServers[idx].scheme = url.scheme.toUpperCase(); } + } + return wsServers; + }, - if(SIP.Grammar.parse(url, 'turn_URI') === -1) { + authorizationUser: function(authorizationUser) { + if(SIP.Grammar.parse('"'+ authorizationUser +'"', 'quoted_string') === -1) { + return; + } else { + return authorizationUser; + } + }, + + connectionRecoveryMaxInterval: function(connectionRecoveryMaxInterval) { + var value; + if(SIP.Utils.isDecimal(connectionRecoveryMaxInterval)) { + value = Number(connectionRecoveryMaxInterval); + if(value > 0) { + return value; + } + } + }, + + connectionRecoveryMinInterval: function(connectionRecoveryMinInterval) { + var value; + if(SIP.Utils.isDecimal(connectionRecoveryMinInterval)) { + value = Number(connectionRecoveryMinInterval); + if(value > 0) { + return value; + } + } + }, + + displayName: function(displayName) { + if(SIP.Grammar.parse('"' + displayName + '"', 'displayName') === -1) { + return; + } else { + return displayName; + } + }, + + hackViaTcp: function(hackViaTcp) { + if (typeof hackViaTcp === 'boolean') { + return hackViaTcp; + } + }, + + hackIpInContact: function(hackIpInContact) { + if (typeof hackIpInContact === 'boolean') { + return hackIpInContact; + } + else if (typeof hackIpInContact === 'string' && SIP.Grammar.parse(hackIpInContact, 'host') !== -1) { + return hackIpInContact; + } + }, + + iceCheckingTimeout: function(iceCheckingTimeout) { + if(SIP.Utils.isDecimal(iceCheckingTimeout)) { + return Math.max(500, iceCheckingTimeout); + } + }, + + hackWssInTransport: function(hackWssInTransport) { + if (typeof hackWssInTransport === 'boolean') { + return hackWssInTransport; + } + }, + + hackAllowUnregisteredOptionTags: function(hackAllowUnregisteredOptionTags) { + if (typeof hackAllowUnregisteredOptionTags === 'boolean') { + return hackAllowUnregisteredOptionTags; + } + }, + + hackCleanJitsiSdpImageattr: function(hackCleanJitsiSdpImageattr) { + if (typeof hackCleanJitsiSdpImageattr === 'boolean') { + return hackCleanJitsiSdpImageattr; + } + }, + + hackStripTcp: function(hackStripTcp) { + if (typeof hackStripTcp === 'boolean') { + return hackStripTcp; + } + }, + + contactTransport: function(contactTransport) { + if (typeof contactTransport === 'string') { + return contactTransport; + } + }, + + forceRport: function(forceRport) { + if (typeof forceRport === 'boolean') { + return forceRport; + } + }, + + instanceId: function(instanceId) { + if(typeof instanceId !== 'string') { + return; + } + + if ((/^uuid:/i.test(instanceId))) { + instanceId = instanceId.substr(5); + } + + if(SIP.Grammar.parse(instanceId, 'uuid') === -1) { + return; + } else { + return instanceId; + } + }, + + keepAliveInterval: function(keepAliveInterval) { + var value; + if (SIP.Utils.isDecimal(keepAliveInterval)) { + value = Number(keepAliveInterval); + if (value > 0) { + return value; + } + } + }, + + extraSupported: function(optionTags) { + var idx, length; + + if (!(optionTags instanceof Array)) { + return; + } + + length = optionTags.length; + for (idx = 0; idx < length; idx++) { + if (typeof optionTags[idx] !== 'string') { return; } } - } - return turnServers; - }, - userAgentString: function(userAgentString) { - if (typeof userAgentString === 'string') { - return userAgentString; - } - }, + return optionTags; + }, - usePreloadedRoute: function(usePreloadedRoute) { - if (typeof usePreloadedRoute === 'boolean') { - return usePreloadedRoute; - } - }, - - wsServerMaxReconnection: function(wsServerMaxReconnection) { - var value; - if (SIP.Utils.isDecimal(wsServerMaxReconnection)) { - value = Number(wsServerMaxReconnection); - if (value > 0) { - return value; + noAnswerTimeout: function(noAnswerTimeout) { + var value; + if (SIP.Utils.isDecimal(noAnswerTimeout)) { + value = Number(noAnswerTimeout); + if (value > 0) { + return value; + } } - } - }, + }, - wsServerReconnectionTimeout: function(wsServerReconnectionTimeout) { - var value; - if (SIP.Utils.isDecimal(wsServerReconnectionTimeout)) { - value = Number(wsServerReconnectionTimeout); - if (value > 0) { - return value; + password: function(password) { + return String(password); + }, + + rel100: function(rel100) { + if(rel100 === SIP.C.supported.REQUIRED) { + return SIP.C.supported.REQUIRED; + } else if (rel100 === SIP.C.supported.SUPPORTED) { + return SIP.C.supported.SUPPORTED; + } else { + return SIP.C.supported.UNSUPPORTED; } - } - }, + }, - autostart: function(autostart) { - if (typeof autostart === 'boolean') { - return autostart; - } - }, + replaces: function(replaces) { + if(replaces === SIP.C.supported.REQUIRED) { + return SIP.C.supported.REQUIRED; + } else if (replaces === SIP.C.supported.SUPPORTED) { + return SIP.C.supported.SUPPORTED; + } else { + return SIP.C.supported.UNSUPPORTED; + } + }, - mediaHandlerFactory: function(mediaHandlerFactory) { - if (mediaHandlerFactory instanceof Function) { - var promisifiedFactory = function promisifiedFactory () { - var mediaHandler = mediaHandlerFactory.apply(this, arguments); + register: function(register) { + if (typeof register === 'boolean') { + return register; + } + }, - function patchMethod (methodName) { - var method = mediaHandler[methodName]; - if (method.length > 1) { - var callbacksFirst = methodName === 'getDescription'; - mediaHandler[methodName] = SIP.Utils.promisify(mediaHandler, methodName, callbacksFirst); - } + registerExpires: function(registerExpires) { + var value; + if (SIP.Utils.isDecimal(registerExpires)) { + value = Number(registerExpires); + if (value > 0) { + return value; + } + } + }, + + registrarServer: function(registrarServer) { + var parsed; + + if(typeof registrarServer !== 'string') { + return; + } + + if (!/^sip:/i.test(registrarServer)) { + registrarServer = SIP.C.SIP + ':' + registrarServer; + } + parsed = SIP.URI.parse(registrarServer); + + if(!parsed) { + return; + } else if(parsed.user) { + return; + } else { + return parsed; + } + }, + + stunServers: function(stunServers) { + var idx, length, stun_server; + + if (typeof stunServers === 'string') { + stunServers = [stunServers]; + } else if (!(stunServers instanceof Array)) { + return; + } + + length = stunServers.length; + for (idx = 0; idx < length; idx++) { + stun_server = stunServers[idx]; + if (!(/^stuns?:/.test(stun_server))) { + stun_server = 'stun:' + stun_server; } - patchMethod('getDescription'); - patchMethod('setDescription'); + if(SIP.Grammar.parse(stun_server, 'stun_URI') === -1) { + return; + } else { + stunServers[idx] = stun_server; + } + } + return stunServers; + }, - return mediaHandler; - }; + traceSip: function(traceSip) { + if (typeof traceSip === 'boolean') { + return traceSip; + } + }, - promisifiedFactory.isSupported = mediaHandlerFactory.isSupported; - return promisifiedFactory; + turnServers: function(turnServers) { + var idx, jdx, length, turn_server, num_turn_server_urls, url; + + if (turnServers instanceof Array) { + // Do nothing + } else { + turnServers = [turnServers]; + } + + length = turnServers.length; + for (idx = 0; idx < length; idx++) { + turn_server = turnServers[idx]; + //Backwards compatibility: Allow defining the turn_server url with the 'server' property. + if (turn_server.server) { + turn_server.urls = [turn_server.server]; + } + + if (!turn_server.urls) { + return; + } + + if (turn_server.urls instanceof Array) { + num_turn_server_urls = turn_server.urls.length; + } else { + turn_server.urls = [turn_server.urls]; + num_turn_server_urls = 1; + } + + for (jdx = 0; jdx < num_turn_server_urls; jdx++) { + url = turn_server.urls[jdx]; + + if (!(/^turns?:/.test(url))) { + url = 'turn:' + url; + } + + if(SIP.Grammar.parse(url, 'turn_URI') === -1) { + return; + } + } + } + return turnServers; + }, + + rtcpMuxPolicy: function(rtcpMuxPolicy) { + if (typeof rtcpMuxPolicy === 'string') { + return rtcpMuxPolicy; + } + }, + + userAgentString: function(userAgentString) { + if (typeof userAgentString === 'string') { + return userAgentString; + } + }, + + usePreloadedRoute: function(usePreloadedRoute) { + if (typeof usePreloadedRoute === 'boolean') { + return usePreloadedRoute; + } + }, + + wsServerMaxReconnection: function(wsServerMaxReconnection) { + var value; + if (SIP.Utils.isDecimal(wsServerMaxReconnection)) { + value = Number(wsServerMaxReconnection); + if (value > 0) { + return value; + } + } + }, + + wsServerReconnectionTimeout: function(wsServerReconnectionTimeout) { + var value; + if (SIP.Utils.isDecimal(wsServerReconnectionTimeout)) { + value = Number(wsServerReconnectionTimeout); + if (value > 0) { + return value; + } + } + }, + + autostart: function(autostart) { + if (typeof autostart === 'boolean') { + return autostart; + } + }, + + autostop: function(autostop) { + if (typeof autostop === 'boolean') { + return autostop; + } + }, + + mediaHandlerFactory: function(mediaHandlerFactory) { + if (mediaHandlerFactory instanceof Function) { + var promisifiedFactory = function promisifiedFactory () { + var mediaHandler = mediaHandlerFactory.apply(this, arguments); + + function patchMethod (methodName) { + var method = mediaHandler[methodName]; + if (method.length > 1) { + var callbacksFirst = methodName === 'getDescription'; + mediaHandler[methodName] = SIP.Utils.promisify(mediaHandler, methodName, callbacksFirst); + } + } + + patchMethod('getDescription'); + patchMethod('setDescription'); + + return mediaHandler; + }; + + promisifiedFactory.isSupported = mediaHandlerFactory.isSupported; + return promisifiedFactory; + } + }, + + authenticationFactory: checkAuthenticationFactory, + + allowLegacyNotifications: function(allowLegacyNotifications) { + if (typeof allowLegacyNotifications === 'boolean') { + return allowLegacyNotifications; + } + }, + + custom: function(custom) { + if (typeof custom === 'object') { + return custom; + } } - }, - - authenticationFactory: checkAuthenticationFactory - } + } + }; }; UA.C = C; @@ -11064,12 +11044,14 @@ var MediaHandler = function(session, options) { this.mediaStreamManager = options.mediaStreamManager || new SIP.WebRTC.MediaStreamManager(this.logger); this.audioMuted = false; this.videoMuted = false; + this.local_hold = false; + this.remote_hold = false; // old init() from here on var servers = this.prepareIceServers(options.stunServers, options.turnServers); this.RTCConstraints = options.RTCConstraints || {}; - this.initPeerConnection(servers, this.RTCConstraints); + this.initPeerConnection(servers); function selfEmit(mh, event) { if (mh.mediaStreamManager.on) { @@ -11175,15 +11157,51 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { self.render(); return self.createOfferOrAnswer(self.RTCConstraints); }) + .then(function(sdp) { + sdp = SIP.Hacks.Firefox.hasMissingCLineInSDP(sdp); + + if (self.local_hold) { + // Don't receive media + // TODO - This will break for media streams with different directions. + if (!(/a=(sendrecv|sendonly|recvonly|inactive)/).test(sdp)) { + sdp = sdp.replace(/(m=[^\r]*\r\n)/g, '$1a=sendonly\r\n'); + } else { + sdp = sdp.replace(/a=sendrecv\r\n/g, 'a=sendonly\r\n'); + sdp = sdp.replace(/a=recvonly\r\n/g, 'a=inactive\r\n'); + } + } + + return { + body: sdp, + contentType: 'application/sdp' + }; + }) ; }}, /** - * Message reception. - * @param {String} type - * @param {String} sdp - */ - setDescription: {writable: true, value: function setDescription (sdp) { + * Check if a SIP message contains a session description. + * @param {SIP.SIPMessage} message + * @returns {boolean} + */ + hasDescription: {writeable: true, value: function hasDescription (message) { + return message.getHeader('Content-Type') === 'application/sdp' && !!message.body; + }}, + + /** + * Set the session description contained in a SIP message. + * @param {SIP.SIPMessage} message + * @returns {Promise} + */ + setDescription: {writable: true, value: function setDescription (message) { + var self = this; + var sdp = message.body; + + this.remote_hold = /a=(sendonly|inactive)/.test(sdp); + + sdp = SIP.Hacks.Firefox.cannotHandleExtraWhitespace(sdp); + sdp = SIP.Hacks.AllBrowsers.maskDtls(sdp); + var rawDescription = { type: this.hasOffer('local') ? 'answer' : 'offer', sdp: sdp @@ -11192,7 +11210,11 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { this.emit('setDescription', rawDescription); var description = new SIP.WebRTC.RTCSessionDescription(rawDescription); - return SIP.Utils.promisify(this.peerConnection, 'setRemoteDescription')(description); + return SIP.Utils.promisify(this.peerConnection, 'setRemoteDescription')(description) + .catch(function setRemoteDescriptionError(e) { + self.emit('peerConnection-setRemoteDescriptionFailed', e); + throw e; + }); }}, /** @@ -11222,7 +11244,7 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { var servers = this.prepareIceServers(options.stunServers, options.turnServers); this.RTCConstraints = options.RTCConstraints || this.RTCConstraints; - this.initPeerConnection(servers, this.RTCConstraints); + this.initPeerConnection(servers); /* once updateIce is implemented correctly, this is better than above //no op if browser does not support this @@ -11319,11 +11341,14 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { }}, hold: {writable: true, value: function hold () { + this.local_hold = true; this.toggleMuteAudio(true); this.toggleMuteVideo(true); }}, unhold: {writable: true, value: function unhold () { + this.local_hold = false; + if (!this.audioMuted) { this.toggleMuteAudio(false); } @@ -11389,17 +11414,20 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { }); [].concat(turnServers).forEach(function (server) { - servers.push({ - 'urls': server.urls, - 'username': server.username, - 'credential': server.password - }); + var turnServer = {'urls': server.urls}; + if (server.username) { + turnServer.username = server.username; + } + if (server.password) { + turnServer.credential = server.password; + } + servers.push(turnServer); }); return servers; }}, - initPeerConnection: {writable: true, value: function initPeerConnection(servers, RTCConstraints) { + initPeerConnection: {writable: true, value: function initPeerConnection(servers) { var self = this, config = this.session.ua.configuration; @@ -11416,7 +11444,15 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { this.peerConnection.close(); } - this.peerConnection = new SIP.WebRTC.RTCPeerConnection({'iceServers': servers}, RTCConstraints); + var connConfig = { + iceServers: servers + }; + + if (config.rtcpMuxPolicy) { + connConfig.rtcpMuxPolicy = config.rtcpMuxPolicy; + } + + this.peerConnection = new SIP.WebRTC.RTCPeerConnection(connConfig); // Firefox (35.0.1) sometimes throws on calls to peerConnection.getRemoteStreams // even if peerConnection.onaddstream was just called. In order to make @@ -11525,7 +11561,15 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { methodName = self.hasOffer('remote') ? 'createAnswer' : 'createOffer'; return SIP.Utils.promisify(pc, methodName, true)(constraints) + .catch(function methodError(e) { + self.emit('peerConnection-' + methodName + 'Failed', e); + throw e; + }) .then(SIP.Utils.promisify(pc, 'setLocalDescription')) + .catch(function localDescError(e) { + self.emit('peerConnection-selLocalDescriptionFailed', e); + throw e; + }) .then(function onSetLocalDescriptionSuccess() { var deferred = SIP.Utils.defer(); if (pc.iceGatheringState === 'complete' && (pc.iceConnectionState === 'connected' || pc.iceConnectionState === 'completed')) { @@ -11548,10 +11592,14 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, { self.emit('getDescription', sdpWrapper); + if (self.session.ua.configuration.hackStripTcp) { + sdpWrapper.sdp = sdpWrapper.sdp.replace(/^a=candidate:\d+ \d+ tcp .*?\r\n/img, ""); + } + self.ready = true; return sdpWrapper.sdp; }) - .catch(function methodFailed (e) { + .catch(function createOfferAnswerError (e) { self.logger.error(e); self.ready = true; throw new SIP.Exceptions.GetDescriptionError(e); @@ -11648,22 +11696,13 @@ MediaStreamManager.render = function render (streams, elements) { } function attachMediaStream(element, stream) { - if (typeof element.src !== 'undefined') { - environment.revokeObjectURL(element.src); - element.src = environment.createObjectURL(stream); - } else if (typeof (element.srcObject || element.mozSrcObject) !== 'undefined') { - element.srcObject = element.mozSrcObject = stream; - } else { - return false; - } - - return true; + element.srcObject = stream; } function ensureMediaPlaying (mediaElement) { var interval = 100; mediaElement.ensurePlayingIntervalId = SIP.Timers.setInterval(function () { - if (mediaElement.paused) { + if (mediaElement.paused && mediaElement.srcObject) { mediaElement.play(); } else { @@ -11673,10 +11712,10 @@ MediaStreamManager.render = function render (streams, elements) { } function attachAndPlay (elements, stream, index) { - if (typeof elements === 'function') { - elements = elements(); - } var element = elements[index % elements.length]; + if (typeof element === 'function') { + element = element(); + } (environment.attachMediaStream || attachMediaStream)(element, stream); ensureMediaPlaying(element); } @@ -11804,6 +11843,7 @@ module.exports = { RTCSessionDescription: getPrefixedProperty(toplevel, 'RTCSessionDescription'), addEventListener: getPrefixedProperty(toplevel, 'addEventListener'), + removeEventListener: getPrefixedProperty(toplevel, 'removeEventListener'), HTMLMediaElement: toplevel.HTMLMediaElement, attachMediaStream: toplevel.attachMediaStream, From daf67c2f001082aae35ed371cbdde4bec21bdf72 Mon Sep 17 00:00:00 2001 From: Fred Dixon Date: Mon, 11 Sep 2017 21:03:19 -0400 Subject: [PATCH 46/51] Update bigbluebutton-release --- bigbluebutton-config/bigbluebutton-release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigbluebutton-config/bigbluebutton-release b/bigbluebutton-config/bigbluebutton-release index 1f62510108..f487e6e9f9 100644 --- a/bigbluebutton-config/bigbluebutton-release +++ b/bigbluebutton-config/bigbluebutton-release @@ -1 +1 @@ -BIGBLUEBUTTON_RELEASE=2.0.0-dev +BIGBLUEBUTTON_RELEASE=2.0.0-beta From 31fe04180a45d23f24945fa7a5549dcdd70b6e8f Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Tue, 12 Sep 2017 11:18:13 +0100 Subject: [PATCH 47/51] Add missing locale for retry presnetation upload. --- bigbluebutton-client/locale/en_US/bbbResources.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties index f95da9aa76..28d71818b5 100755 --- a/bigbluebutton-client/locale/en_US/bbbResources.properties +++ b/bigbluebutton-client/locale/en_US/bbbResources.properties @@ -272,6 +272,7 @@ bbb.fileupload.uploadBtn = Upload bbb.fileupload.uploadBtn.toolTip = Upload the selected file bbb.fileupload.deleteBtn.toolTip = Delete Presentation bbb.fileupload.showBtn = Show +bbb.fileupload.retry = Try another file bbb.fileupload.showBtn.toolTip = Show Presentation bbb.fileupload.close.tooltip = Close bbb.fileupload.close.accessibilityName = Close the File Upload window From 4487ff3d2c647d8c7818fdd9c72c50621011305c Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Tue, 12 Sep 2017 11:18:48 +0100 Subject: [PATCH 48/51] Display all text in LogoutWindow by replacing width with minWidth. --- .../src/org/bigbluebutton/main/views/LogoutWindow.mxml | 2 +- .../bigbluebutton/main/views/MainApplicationShell.mxml | 10 +++++----- .../src/org/bigbluebutton/main/views/MainToolbar.mxml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/LogoutWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/LogoutWindow.mxml index 7ec359cc8a..1d7dfdbee6 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/LogoutWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/LogoutWindow.mxml @@ -27,7 +27,7 @@ with BigBlueButton; if not, see . horizontalAlign="center" showCloseButton="false" creationComplete="onCreationComplete()" - width="350" + minWidth="350" title="{ResourceUtil.getInstance().getString('bbb.logout.confirm.title')}"> diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml index 8399a800ac..f3b39a7ab5 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml @@ -682,16 +682,16 @@ with BigBlueButton; if not, see . handleExitApplicationEvent(); return; } - var logoutWindow:LoggedOutWindow = PopUpUtil.createModalPopUp(mdiCanvas, LoggedOutWindow, false) as LoggedOutWindow; - if (logoutWindow) { + var loggedOutWindow:LoggedOutWindow = PopUpUtil.createModalPopUp(mdiCanvas, LoggedOutWindow, false) as LoggedOutWindow; + if (loggedOutWindow) { var point1:Point = new Point(); // Calculate position of TitleWindow in Application's coordinates. point1.x = width / 2; point1.y = height / 2; - logoutWindow.x = point1.x - (logoutWindow.width / 2); - logoutWindow.y = point1.y - (logoutWindow.height / 2); + loggedOutWindow.x = point1.x - (loggedOutWindow.width / 2); + loggedOutWindow.y = point1.y - (loggedOutWindow.height / 2); - logoutWindow.setReason(reason); + loggedOutWindow.setReason(reason); mdiCanvas.removeAllPopUps(); removeToolBars(); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml index 9a2c7e42e1..417685697d 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml @@ -293,7 +293,7 @@ with BigBlueButton; if not, see . var logoutWindow:LogoutWindow; logoutWindow = LogoutWindow(PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, LogoutWindow, true)); - var newX:Number = this.width - logoutWindow.width; + var newX:Number = this.width - logoutWindow.width - 5; var newY:Number = btnLogout.y + btnLogout.height + 5; PopUpManager.centerPopUp(logoutWindow); From 3b6a182603a6ce8de01e7df0297873ced274dd3b Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Tue, 12 Sep 2017 15:33:11 +0100 Subject: [PATCH 49/51] Put always in top the close button in TitleWindow component. --- .../branding/default/style/css/V2Theme.css | 6 +-- .../main/views/AudioSelectionWindow.mxml | 23 ++++---- .../bigbluebutton/main/views/BBBSettings.mxml | 1 + .../main/views/CameraDisplaySettings.mxml | 8 +-- .../bigbluebutton/main/views/GuestWindow.mxml | 2 - .../present/ui/views/FileDownloadWindow.mxml | 14 +++-- .../present/ui/views/FileUploadWindow.mxml | 18 ++++--- .../views/SharedNotesNameWindow.mxml | 44 ++++++++------- .../users/views/JoinBreakoutRoomWindow.mxml | 53 ++++++++++--------- 9 files changed, 89 insertions(+), 80 deletions(-) diff --git a/bigbluebutton-client/branding/default/style/css/V2Theme.css b/bigbluebutton-client/branding/default/style/css/V2Theme.css index e11772fe61..1d4693ebae 100755 --- a/bigbluebutton-client/branding/default/style/css/V2Theme.css +++ b/bigbluebutton-client/branding/default/style/css/V2Theme.css @@ -437,11 +437,7 @@ users|BreakoutRoomSettings { } users|JoinBreakoutRoomWindow { - horizontalAlign : center; - iconRooms : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Join_Room"); - paddingBottom : 24; - paddingTop : 24; - verticalGap : 18; + iconRooms : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Join_Room"); } users|RoomActionsRenderer { diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml index 3a6612c8a6..618e63e8ab 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml @@ -24,6 +24,7 @@ with BigBlueButton; if not, see . xmlns:mate="http://mate.asfusion.com/" xmlns:common="org.bigbluebutton.common.*" initialize="init()" + layout="absolute" close="onCancelClicked()" verticalScrollPolicy="off" horizontalScrollPolicy="off" @@ -33,9 +34,6 @@ with BigBlueButton; if not, see . . - - - - + . + + + diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/BBBSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/BBBSettings.mxml index 9058ae8f54..9f7c907c15 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/BBBSettings.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/BBBSettings.mxml @@ -4,6 +4,7 @@ xmlns:common="org.bigbluebutton.common.*" xmlns:mate="http://mate.asfusion.com/" layout="vertical" + horizontalAlign="center" showCloseButton="false" minWidth="250" creationComplete="init()"> diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/CameraDisplaySettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/CameraDisplaySettings.mxml index 7801a5d1e0..c5460c81fc 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/CameraDisplaySettings.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/CameraDisplaySettings.mxml @@ -217,10 +217,10 @@ with BigBlueButton; if not, see . - + diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/GuestWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/GuestWindow.mxml index c2500aec3d..21262cec7d 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/GuestWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/GuestWindow.mxml @@ -36,8 +36,6 @@ $Id: $ . xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mate="http://mate.asfusion.com/" xmlns:common="org.bigbluebutton.common.*" + layout="absolute" width="580" height="410" close="onCancelClicked()" @@ -37,7 +38,6 @@ with BigBlueButton; if not, see . . + horizontalAlign="center" + paddingTop="15"> - . dataProvider="{downloadablePresentations}"> + + + diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml index 6102313273..65f9113fd9 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml @@ -26,6 +26,7 @@ with BigBlueButton; if not, see . width="580" verticalScrollPolicy="off" horizontalScrollPolicy="off" + layout="absolute" close="onCancelClicked()" initialize="initData()" creationComplete="onCreationComplete(event)" xmlns:common="org.bigbluebutton.common.*" xmlns:s="library://ns.adobe.com/flex/spark"> @@ -351,15 +352,13 @@ with BigBlueButton; if not, see . - - + + + - @@ -390,7 +389,7 @@ with BigBlueButton; if not, see . - + @@ -402,6 +401,11 @@ with BigBlueButton; if not, see . dragEnabled="false" dataProvider="{presentationNamesAC}"> - + > diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml index 996b40e88a..c2b280e663 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml @@ -27,6 +27,7 @@ with BigBlueButton; if not, see . horizontalScrollPolicy="off" horizontalAlign="center" close="onCancelClicked()" + layout="absolute" creationComplete="onCreationComplete()" keyUp="keyUpHandler(event)" width="250" xmlns:common="org.bigbluebutton.common.*"> @@ -78,27 +79,30 @@ with BigBlueButton; if not, see . } ]]> - - + + - - - - - - + + + + + + + + diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml index 0e5ff8a612..57e9529b5a 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml @@ -24,6 +24,7 @@ with BigBlueButton; if not, see . xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" close="onCloseClick()" + layout="absolute" width="600" xmlns:common="org.bigbluebutton.common.*"> . ]]> - + - - - - - - - + width="100%" + text="{ResourceUtil.getInstance().getString('bbb.users.breakout.confirm')}" /> + + + + + + - - - + + + + + From cc8e41bc16edcb1f22ccdcd91886e1c6cf700e35 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Tue, 12 Sep 2017 15:33:38 +0100 Subject: [PATCH 50/51] Hide the vertical separator in MainToolbar when the logo is not displayed. --- .../src/org/bigbluebutton/main/views/MainToolbar.mxml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml index 417685697d..49a1d7f96a 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml @@ -486,6 +486,7 @@ with BigBlueButton; if not, see . private function hideLogo():void { logo.visible = logo.includeInLayout = false; + logoSperatator.visible = logo.includeInLayout = false; } private function addSettingsComponent(e:SettingsComponentEvent = null):void { @@ -528,7 +529,7 @@ with BigBlueButton; if not, see . From 3c16f4d93eadb0812fe17239ed414e6337089a47 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Tue, 12 Sep 2017 16:45:35 +0100 Subject: [PATCH 51/51] Fully display presentation upload error message. --- .../branding/default/style/css/V2Theme.css | 5 +++-- .../modules/present/ui/views/FileUploadWindow.mxml | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/bigbluebutton-client/branding/default/style/css/V2Theme.css b/bigbluebutton-client/branding/default/style/css/V2Theme.css index 1d4693ebae..e8b260308b 100755 --- a/bigbluebutton-client/branding/default/style/css/V2Theme.css +++ b/bigbluebutton-client/branding/default/style/css/V2Theme.css @@ -1194,8 +1194,9 @@ mx|Panel { } .progressErrorLblStyle { - color : #DE2721; - fontSize : 16; + color : #DE2721; + fontSize : 16; + textAlign : center; } .presentationDownloadShowButtonStyle { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml index 65f9113fd9..ff6ccaf57a 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml @@ -307,6 +307,7 @@ with BigBlueButton; if not, see . } private function enableClosing():void { + uploadedFilesList.enabled = true; this.closeButton2.enabled = true; } @@ -389,7 +390,7 @@ with BigBlueButton; if not, see . - + @@ -401,11 +402,11 @@ with BigBlueButton; if not, see . dragEnabled="false" dataProvider="{presentationNamesAC}"> - > + accessibilityName="{ResourceUtil.getInstance().getString('bbb.fileupload.close.accessibilityName')}" />