2018-11-15 01:11:10 +08:00
|
|
|
import React, { Component } from 'react';
|
2018-11-20 00:53:25 +08:00
|
|
|
import { Session } from 'meteor/session';
|
2018-12-18 23:15:51 +08:00
|
|
|
import PropTypes from 'prop-types';
|
2018-11-15 01:11:10 +08:00
|
|
|
import Auth from '/imports/ui/services/auth';
|
|
|
|
import { setCustomLogoUrl } from '/imports/ui/components/user-list/service';
|
|
|
|
import { makeCall } from '/imports/ui/services/api';
|
|
|
|
import deviceInfo from '/imports/utils/deviceInfo';
|
|
|
|
import logger from '/imports/startup/client/logger';
|
2019-08-17 05:38:17 +08:00
|
|
|
import LoadingScreen from '/imports/ui/components/loading-screen/component';
|
2018-11-15 01:11:10 +08:00
|
|
|
|
2018-12-18 23:15:51 +08:00
|
|
|
const propTypes = {
|
|
|
|
children: PropTypes.element.isRequired,
|
|
|
|
};
|
2018-11-16 23:58:49 +08:00
|
|
|
|
2018-12-22 04:16:36 +08:00
|
|
|
const APP_CONFIG = Meteor.settings.public.app;
|
2019-01-08 00:26:23 +08:00
|
|
|
const { showParticipantsOnLogin } = APP_CONFIG;
|
2019-07-18 05:00:33 +08:00
|
|
|
const CHAT_ENABLED = Meteor.settings.public.chat.enabled;
|
2018-12-22 04:16:36 +08:00
|
|
|
|
2018-11-15 01:11:10 +08:00
|
|
|
class JoinHandler extends Component {
|
2019-08-17 05:38:17 +08:00
|
|
|
static setError(codeError) {
|
|
|
|
Session.set('hasError', true);
|
|
|
|
if (codeError) Session.set('codeError', codeError);
|
|
|
|
}
|
|
|
|
|
2018-11-15 01:11:10 +08:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2018-11-19 23:40:42 +08:00
|
|
|
this.fetchToken = this.fetchToken.bind(this);
|
2018-11-15 01:11:10 +08:00
|
|
|
|
|
|
|
this.state = {
|
|
|
|
joined: false,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
2019-07-13 03:22:47 +08:00
|
|
|
this._isMounted = true;
|
2019-08-20 00:24:27 +08:00
|
|
|
|
|
|
|
if (!this.firstJoinTime) {
|
|
|
|
this.firstJoinTime = new Date();
|
|
|
|
}
|
|
|
|
Tracker.autorun((c) => {
|
|
|
|
const {
|
|
|
|
connected,
|
|
|
|
status,
|
|
|
|
} = Meteor.status();
|
|
|
|
|
|
|
|
logger.debug(`Initial connection status change. status: ${status}, connected: ${connected}`);
|
|
|
|
if (connected) {
|
|
|
|
c.stop();
|
|
|
|
|
|
|
|
const msToConnect = (new Date() - this.firstJoinTime) / 1000;
|
|
|
|
const secondsToConnect = parseFloat(msToConnect).toFixed(2);
|
|
|
|
|
|
|
|
logger.info({
|
|
|
|
logCode: 'joinhandler_component_initial_connection_time',
|
|
|
|
extraInfo: {
|
|
|
|
attemptForUserInfo: Auth.fullInfo,
|
|
|
|
timeToConnect: secondsToConnect,
|
|
|
|
},
|
|
|
|
}, `Connection to Meteor took ${secondsToConnect}s`);
|
|
|
|
|
|
|
|
this.firstJoinTime = undefined;
|
|
|
|
this.fetchToken();
|
|
|
|
} else if (status === 'failed') {
|
|
|
|
c.stop();
|
|
|
|
|
|
|
|
const msToConnect = (new Date() - this.firstJoinTime) / 1000;
|
|
|
|
const secondsToConnect = parseFloat(msToConnect).toFixed(2);
|
|
|
|
logger.info({
|
|
|
|
logCode: 'joinhandler_component_initial_connection_failed',
|
|
|
|
extraInfo: {
|
|
|
|
attemptForUserInfo: Auth.fullInfo,
|
|
|
|
timeToConnect: secondsToConnect,
|
|
|
|
},
|
|
|
|
}, `Connection to Meteor failed, took ${secondsToConnect}s`);
|
|
|
|
|
|
|
|
JoinHandler.setError('400');
|
|
|
|
Session.set('errorMessageDescription', 'Failed to connect to server');
|
|
|
|
this.firstJoinTime = undefined;
|
|
|
|
}
|
|
|
|
});
|
2018-11-15 01:11:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-13 03:22:47 +08:00
|
|
|
componentWillUnmount() {
|
|
|
|
this._isMounted = false;
|
|
|
|
}
|
|
|
|
|
2018-12-10 23:52:25 +08:00
|
|
|
async fetchToken() {
|
2019-07-13 03:22:47 +08:00
|
|
|
if (!this._isMounted) return;
|
|
|
|
|
2018-11-15 01:11:10 +08:00
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
|
|
const sessionToken = urlParams.get('sessionToken');
|
2019-01-09 02:38:26 +08:00
|
|
|
|
2018-11-15 01:11:10 +08:00
|
|
|
if (!sessionToken) {
|
2019-08-17 05:38:17 +08:00
|
|
|
JoinHandler.setError('400');
|
2019-01-09 02:38:26 +08:00
|
|
|
Session.set('errorMessageDescription', 'Session token was not provided');
|
2018-11-15 01:11:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Old credentials stored in memory were being used when joining a new meeting
|
|
|
|
Auth.clearCredentials();
|
|
|
|
const logUserInfo = () => {
|
|
|
|
const userInfo = window.navigator;
|
|
|
|
|
|
|
|
// Browser information is sent once on startup
|
|
|
|
// Sent here instead of Meteor.startup, as the
|
|
|
|
// user might not be validated by then, thus user's data
|
|
|
|
// would not be sent with this information
|
|
|
|
const clientInfo = {
|
|
|
|
language: userInfo.language,
|
|
|
|
userAgent: userInfo.userAgent,
|
|
|
|
screenSize: { width: window.screen.width, height: window.screen.height },
|
|
|
|
windowSize: { width: window.innerWidth, height: window.innerHeight },
|
|
|
|
bbbVersion: Meteor.settings.public.app.bbbServerVersion,
|
|
|
|
location: window.location.href,
|
|
|
|
};
|
|
|
|
|
2019-06-29 05:45:50 +08:00
|
|
|
logger.info({
|
|
|
|
logCode: 'joinhandler_component_clientinfo',
|
|
|
|
extraInfo: { clientInfo },
|
|
|
|
},
|
2019-07-19 05:37:56 +08:00
|
|
|
'Log information about the client');
|
2018-11-15 01:11:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
const setAuth = (resp) => {
|
|
|
|
const {
|
|
|
|
meetingID, internalUserID, authToken, logoutUrl,
|
|
|
|
fullname, externUserID, confname,
|
|
|
|
} = resp;
|
2018-12-10 23:52:25 +08:00
|
|
|
return new Promise((resolve) => {
|
|
|
|
Auth.set(
|
|
|
|
meetingID, internalUserID, authToken, logoutUrl,
|
|
|
|
sessionToken, fullname, externUserID, confname,
|
|
|
|
);
|
|
|
|
resolve(resp);
|
|
|
|
});
|
2018-11-15 01:11:10 +08:00
|
|
|
};
|
|
|
|
|
2018-11-30 06:37:51 +08:00
|
|
|
const setLogoutURL = (url) => {
|
|
|
|
Auth.logoutURL = url;
|
|
|
|
return true;
|
2018-11-15 01:11:10 +08:00
|
|
|
};
|
|
|
|
|
2018-11-19 23:40:42 +08:00
|
|
|
const setLogoURL = (resp) => {
|
2018-11-15 01:11:10 +08:00
|
|
|
setCustomLogoUrl(resp.customLogoURL);
|
|
|
|
return resp;
|
|
|
|
};
|
|
|
|
|
|
|
|
const setCustomData = (resp) => {
|
|
|
|
const {
|
|
|
|
meetingID, internalUserID, customdata,
|
|
|
|
} = resp;
|
|
|
|
|
2018-12-10 23:52:25 +08:00
|
|
|
return new Promise((resolve) => {
|
|
|
|
if (customdata.length) {
|
|
|
|
makeCall('addUserSettings', meetingID, internalUserID, customdata).then(r => resolve(r));
|
|
|
|
}
|
|
|
|
resolve(true);
|
|
|
|
});
|
2018-11-15 01:11:10 +08:00
|
|
|
};
|
2019-03-16 04:07:14 +08:00
|
|
|
|
|
|
|
const setBannerProps = (resp) => {
|
|
|
|
Session.set('bannerText', resp.bannerText);
|
|
|
|
Session.set('bannerColor', resp.bannerColor);
|
|
|
|
};
|
|
|
|
|
2018-11-15 01:11:10 +08:00
|
|
|
// use enter api to get params for the client
|
|
|
|
const url = `/bigbluebutton/api/enter?sessionToken=${sessionToken}`;
|
2018-12-10 23:52:25 +08:00
|
|
|
const fetchContent = await fetch(url, { credentials: 'same-origin' });
|
|
|
|
const parseToJson = await fetchContent.json();
|
|
|
|
const { response } = parseToJson;
|
2019-01-08 00:26:23 +08:00
|
|
|
|
2018-12-10 23:52:25 +08:00
|
|
|
setLogoutURL(response);
|
2019-08-17 05:38:17 +08:00
|
|
|
|
2018-12-10 23:52:25 +08:00
|
|
|
if (response.returncode !== 'FAILED') {
|
|
|
|
await setAuth(response);
|
2019-03-16 04:07:14 +08:00
|
|
|
|
|
|
|
setBannerProps(response);
|
2018-12-10 23:52:25 +08:00
|
|
|
setLogoURL(response);
|
|
|
|
logUserInfo();
|
2018-12-18 11:28:47 +08:00
|
|
|
|
2019-07-31 03:41:03 +08:00
|
|
|
await setCustomData(response);
|
|
|
|
|
2019-01-08 00:26:23 +08:00
|
|
|
if (showParticipantsOnLogin && !deviceInfo.type().isPhone) {
|
2019-07-18 05:00:33 +08:00
|
|
|
Session.set('openPanel', 'userlist');
|
|
|
|
if (CHAT_ENABLED) {
|
|
|
|
Session.set('openPanel', 'chat');
|
|
|
|
Session.set('idChatOpen', '');
|
|
|
|
}
|
2018-12-22 04:16:36 +08:00
|
|
|
} else {
|
|
|
|
Session.set('openPanel', '');
|
|
|
|
}
|
|
|
|
|
2019-06-29 05:45:50 +08:00
|
|
|
logger.info({
|
|
|
|
logCode: 'joinhandler_component_joinroutehandler_success',
|
|
|
|
extraInfo: {
|
|
|
|
response,
|
|
|
|
},
|
|
|
|
}, 'User successfully went through main.joinRouteHandler');
|
2018-12-10 23:52:25 +08:00
|
|
|
} else {
|
2019-01-08 00:26:23 +08:00
|
|
|
const e = new Error(response.message);
|
2019-01-09 02:38:26 +08:00
|
|
|
if (!Session.get('codeError')) Session.set('errorMessageDescription', response.message);
|
2019-06-29 05:45:50 +08:00
|
|
|
logger.error({
|
|
|
|
logCode: 'joinhandler_component_joinroutehandler_error',
|
|
|
|
extraInfo: {
|
|
|
|
response,
|
|
|
|
error: e,
|
|
|
|
},
|
|
|
|
}, 'User faced an error on main.joinRouteHandler.');
|
2018-12-10 23:52:25 +08:00
|
|
|
}
|
2019-08-17 05:38:17 +08:00
|
|
|
this.setState({ joined: true });
|
2018-11-15 01:11:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const { children } = this.props;
|
|
|
|
const { joined } = this.state;
|
2019-08-17 05:38:17 +08:00
|
|
|
return joined
|
|
|
|
? children
|
|
|
|
: (<LoadingScreen />);
|
2018-11-15 01:11:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-17 05:38:17 +08:00
|
|
|
export default JoinHandler;
|
2018-12-18 23:15:51 +08:00
|
|
|
|
|
|
|
JoinHandler.propTypes = propTypes;
|