From 62454b826b67a042708693e8b7cd51ab8a79003b Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan Date: Wed, 13 Dec 2017 13:45:54 -0200 Subject: [PATCH 1/7] Remove duplicated log --- .../imports/api/users/server/modifiers/createDummyUser.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bigbluebutton-html5/imports/api/users/server/modifiers/createDummyUser.js b/bigbluebutton-html5/imports/api/users/server/modifiers/createDummyUser.js index e7e6dadf64..9625884aae 100644 --- a/bigbluebutton-html5/imports/api/users/server/modifiers/createDummyUser.js +++ b/bigbluebutton-html5/imports/api/users/server/modifiers/createDummyUser.js @@ -27,10 +27,8 @@ export default function createDummyUser(meetingId, userId, authToken) { return; } if (numChanged) { - Logger.info(`Created dummy user 2x id=${userId} token=${authToken} meeting=${meetingId}`); + Logger.info(`Created dummy user id=${userId} token=${authToken} meeting=${meetingId}`); } - - Logger.info(`Created dummy user id=${userId} token=${authToken} meeting=${meetingId}`); }; return Users.insert(doc, cb); From 2faf40e381e2b1454db02572904b4db449089fab Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan Date: Wed, 13 Dec 2017 14:54:01 -0200 Subject: [PATCH 2/7] Throw meteor error when Acl fails for subscriptions --- bigbluebutton-html5/imports/startup/mapToAcl.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bigbluebutton-html5/imports/startup/mapToAcl.js b/bigbluebutton-html5/imports/startup/mapToAcl.js index 6b4d4755eb..207c44101b 100644 --- a/bigbluebutton-html5/imports/startup/mapToAcl.js +++ b/bigbluebutton-html5/imports/startup/mapToAcl.js @@ -1,13 +1,14 @@ import Acl from '/imports/startup/acl'; import { Meteor } from 'meteor/meteor'; -import Logger from '/imports/startup/server/logger'; const injectAclActionCheck = (name, handler) => ( (...args) => { const credentials = args[0]; if (!Acl.can(name, credentials)) { - throw new Meteor.Error('acl-not-allowed', - `The user can't perform the action "${name}".`); + throw new Meteor.Error( + 'acl-not-allowed', + `The user can't perform the action "${name}".`, + ); } return handler(...args); @@ -18,8 +19,7 @@ const injectAclSubscribeCheck = (name, handler) => ( (...args) => { const credentials = args[args.length - 1]; if (!Acl.can(name, ...credentials)) { - Logger.error(`acl-not-allowed, the user can't perform the subscription "${name}".`); - return []; + throw new Meteor.Error(`acl-not-allowed, the user can't perform the subscription "${name}".`); } return handler(...credentials); From b7fa508d9d1b5344830459023015180274d205dc Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan Date: Wed, 13 Dec 2017 15:40:46 -0200 Subject: [PATCH 3/7] Simplify auth code and remove clearCredentials on errors. Fix #4812 --- .../imports/ui/services/auth/index.js | 90 +++++++------------ 1 file changed, 31 insertions(+), 59 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/services/auth/index.js b/bigbluebutton-html5/imports/ui/services/auth/index.js index 42dfce94f3..3c36ed735d 100644 --- a/bigbluebutton-html5/imports/ui/services/auth/index.js +++ b/bigbluebutton-html5/imports/ui/services/auth/index.js @@ -1,4 +1,4 @@ - +/* eslint prefer-promise-reject-errors: 0 */ import { Tracker } from 'meteor/tracker'; import Storage from '/imports/ui/services/storage/session'; @@ -134,78 +134,50 @@ class Auth { authenticate(force) { if (this.loggedIn && !force) return Promise.resolve(); - return this._subscribeToCurrentUser() - .then(this._addObserverToValidatedField.bind(this)); - } - - _subscribeToCurrentUser() { - const credentials = this.credentials; - - return new Promise((resolve, reject) => { - Tracker.autorun((c) => { - if (!(credentials.meetingId && credentials.requesterToken && credentials.requesterUserId)) { - reject({ - error: 500, - description: 'Authentication subscription failed due to missing credentials.', - }); - } - - setTimeout(() => { - c.stop(); - reject({ - error: 500, - description: 'Authentication subscription timeout.', - }); - }, 5000); - - const subscription = Meteor.subscribe('current-user', credentials); - if (!subscription.ready()) return; - - resolve(c); + if (!(this.meetingID && this.userID && this.token)) { + return Promise.reject({ + error: 401, + description: 'Authentication failed due to missing credentials.', }); - }); + } + + return this.validateAuthToken(); } - _addObserverToValidatedField(prevComp) { + validateAuthToken() { return new Promise((resolve, reject) => { const validationTimeout = setTimeout(() => { - clearTimeout(validationTimeout); - prevComp.stop(); - this.clearCredentials(); reject({ - error: 500, + error: 401, description: 'Authentication timeout.', }); }, CONNECTION_TIMEOUT); - const didValidate = () => { - this.loggedIn = true; - clearTimeout(validationTimeout); - prevComp.stop(); - resolve(); - }; - Tracker.autorun((c) => { + const subscription = Meteor.subscribe('current-user', this.credentials); + if (!subscription.ready()) return; + const selector = { meetingId: this.meetingID, userId: this.userID }; - const query = Users.find(selector); + const User = Users.findOne(selector); - query.observeChanges({ - changed: (id, fields) => { - if (fields.validated === true) { - c.stop(); - didValidate(); - } + // Skip in case the user is not in the collection yet or is a dummy user + if (!User || !('intId' in User)) return; - if (fields.validated === false) { - c.stop(); - this.clearCredentials(); - reject({ - error: 401, - description: 'Authentication failed.', - }); - } - }, - }); + if (User.validated === true) { + clearTimeout(validationTimeout); + this.loggedIn = true; + resolve(); + } + + if (User.validated === false) { + clearTimeout(validationTimeout); + reject({ + error: 401, + description: 'Authentication failed.', + }); + } + + c.stop(); }); makeCall('validateAuthToken'); From d19c127b1fa3d81f7811818e7a7eadc1fea5472f Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan Date: Wed, 13 Dec 2017 15:58:56 -0200 Subject: [PATCH 4/7] Add redirect to /logout if not loggedin or on subscription errors --- .../imports/startup/client/base.jsx | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx index d825b5dc70..1967e0580d 100644 --- a/bigbluebutton-html5/imports/startup/client/base.jsx +++ b/bigbluebutton-html5/imports/startup/client/base.jsx @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import { createContainer } from 'meteor/react-meteor-data'; +import { withRouter } from 'react-router'; import PropTypes from 'prop-types'; import Auth from '/imports/ui/services/auth'; import AppContainer from '/imports/ui/components/app/container'; @@ -86,22 +87,29 @@ const SUBSCRIPTIONS_NAME = [ 'slides', 'captions', 'breakouts', 'voiceUsers', 'whiteboard-multi-user', ]; -const BaseContainer = createContainer(({ params }) => { +const BaseContainer = withRouter(createContainer(({ params, router }) => { if (params.errorCode) return params; if (!Auth.loggedIn) { - return { - errorCode: 401, - error: 'You are unauthorized to access this meeting', - }; + return router.push('/logout'); } - const credentials = Auth.credentials; - const subscriptionsHandlers = SUBSCRIPTIONS_NAME.map(name => Meteor.subscribe(name, credentials)); + const { credentials } = Auth; + + const subscriptionErrorHandler = { + onError: (error) => { + console.error(error); + return router.push('/logout'); + }, + }; + + const subscriptionsHandlers = SUBSCRIPTIONS_NAME.map(name => + Meteor.subscribe(name, credentials, subscriptionErrorHandler)); + return { locale: Settings.application.locale, subscriptionsReady: subscriptionsHandlers.every(handler => handler.ready()), }; -}, Base); +}, Base)); export default BaseContainer; From 1eacfcb5a1abedb0b8f62e7f5e0aa7b74d410389 Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan Date: Wed, 13 Dec 2017 16:27:53 -0200 Subject: [PATCH 5/7] Fix Meteor.error subscription params --- bigbluebutton-html5/imports/startup/mapToAcl.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/startup/mapToAcl.js b/bigbluebutton-html5/imports/startup/mapToAcl.js index 207c44101b..a21cfbd945 100644 --- a/bigbluebutton-html5/imports/startup/mapToAcl.js +++ b/bigbluebutton-html5/imports/startup/mapToAcl.js @@ -19,7 +19,10 @@ const injectAclSubscribeCheck = (name, handler) => ( (...args) => { const credentials = args[args.length - 1]; if (!Acl.can(name, ...credentials)) { - throw new Meteor.Error(`acl-not-allowed, the user can't perform the subscription "${name}".`); + throw new Meteor.Error( + 'acl-not-allowed', + `The user can't perform the subscription "${name}".`, + ); } return handler(...credentials); From ced25948dd035da0ab1d41f57e707cd21d9adebc Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan Date: Mon, 18 Dec 2017 13:52:04 -0200 Subject: [PATCH 6/7] Fix 401 on page refresh --- bigbluebutton-html5/imports/ui/services/auth/index.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/services/auth/index.js b/bigbluebutton-html5/imports/ui/services/auth/index.js index 3c36ed735d..511b2bb5d7 100644 --- a/bigbluebutton-html5/imports/ui/services/auth/index.js +++ b/bigbluebutton-html5/imports/ui/services/auth/index.js @@ -169,14 +169,6 @@ class Auth { resolve(); } - if (User.validated === false) { - clearTimeout(validationTimeout); - reject({ - error: 401, - description: 'Authentication failed.', - }); - } - c.stop(); }); From eb4c89aefc32f87df4ccb8558e40d852750baace Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan Date: Tue, 19 Dec 2017 10:19:47 -0200 Subject: [PATCH 7/7] Fix bug when users re-validate after refresh --- .../api/users/server/handlers/validateAuthToken.js | 4 +--- bigbluebutton-html5/imports/ui/services/auth/index.js | 8 ++++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/bigbluebutton-html5/imports/api/users/server/handlers/validateAuthToken.js b/bigbluebutton-html5/imports/api/users/server/handlers/validateAuthToken.js index 5eb376625e..3066102abc 100644 --- a/bigbluebutton-html5/imports/api/users/server/handlers/validateAuthToken.js +++ b/bigbluebutton-html5/imports/api/users/server/handlers/validateAuthToken.js @@ -69,9 +69,7 @@ export default function handleValidateAuthToken({ body }, meetingId) { addWelcomeChatMessage(meetingId, userId); } - return Logger.info(`Validated auth token as ${valid - }${+' user='}${userId} meeting=${meetingId}`, - ); + return Logger.info(`Validated auth token as ${valid} user=${userId} meeting=${meetingId}`); } return Logger.info('No auth to validate'); diff --git a/bigbluebutton-html5/imports/ui/services/auth/index.js b/bigbluebutton-html5/imports/ui/services/auth/index.js index 511b2bb5d7..92fa54f5dd 100644 --- a/bigbluebutton-html5/imports/ui/services/auth/index.js +++ b/bigbluebutton-html5/imports/ui/services/auth/index.js @@ -146,7 +146,10 @@ class Auth { validateAuthToken() { return new Promise((resolve, reject) => { + let computation = null; + const validationTimeout = setTimeout(() => { + computation.stop(); reject({ error: 401, description: 'Authentication timeout.', @@ -154,7 +157,9 @@ class Auth { }, CONNECTION_TIMEOUT); Tracker.autorun((c) => { + computation = c; const subscription = Meteor.subscribe('current-user', this.credentials); + if (!subscription.ready()) return; const selector = { meetingId: this.meetingID, userId: this.userID }; @@ -164,12 +169,11 @@ class Auth { if (!User || !('intId' in User)) return; if (User.validated === true) { + computation.stop(); clearTimeout(validationTimeout); this.loggedIn = true; resolve(); } - - c.stop(); }); makeCall('validateAuthToken');