199 lines
5.7 KiB
JavaScript
199 lines
5.7 KiB
JavaScript
import React, { Component } from 'react';
|
|
import { Session } from 'meteor/session';
|
|
import PropTypes from 'prop-types';
|
|
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';
|
|
import { withConsumer } from '/imports/ui/components/join-loading/context/context';
|
|
|
|
const propTypes = {
|
|
children: PropTypes.element.isRequired,
|
|
};
|
|
|
|
const APP_CONFIG = Meteor.settings.public.app;
|
|
const { showParticipantsOnLogin } = APP_CONFIG;
|
|
const CHAT_ENABLED = Meteor.settings.public.chat.enabled;
|
|
|
|
class JoinHandler extends Component {
|
|
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
this.fetchToken = this.fetchToken.bind(this);
|
|
this.setError = this.setError.bind(this);
|
|
this.numFetchTokenRetries = 0;
|
|
|
|
this.state = {
|
|
joined: false,
|
|
};
|
|
}
|
|
|
|
componentDidMount() {
|
|
this._isMounted = true;
|
|
this.fetchToken();
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this._isMounted = false;
|
|
}
|
|
|
|
setError(codeError) {
|
|
const { dispatch } = this.props;
|
|
Session.set('hasError', true);
|
|
if (codeError) Session.set('codeError', codeError);
|
|
dispatch('hasError');
|
|
}
|
|
|
|
async fetchToken() {
|
|
if (!this._isMounted) return;
|
|
|
|
if (!Meteor.status().connected) {
|
|
if (this.numFetchTokenRetries % 9) {
|
|
logger.error({
|
|
logCode: 'joinhandler_component_fetchToken_not_connected',
|
|
extraInfo: {
|
|
attemptForUserInfo: Auth.fullInfo,
|
|
numFetchTokenRetries: this.numFetchTokenRetries,
|
|
},
|
|
}, 'Meteor was not connected, retry in a few moments');
|
|
}
|
|
this.numFetchTokenRetries += 1;
|
|
|
|
setTimeout(() => this.fetchToken(), 200);
|
|
return;
|
|
}
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const sessionToken = urlParams.get('sessionToken');
|
|
|
|
if (!sessionToken) {
|
|
this.setError('400');
|
|
Session.set('errorMessageDescription', 'Session token was not provided');
|
|
}
|
|
|
|
// 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,
|
|
};
|
|
|
|
logger.info({
|
|
logCode: 'joinhandler_component_clientinfo',
|
|
extraInfo: { clientInfo },
|
|
},
|
|
'Log information about the client');
|
|
};
|
|
|
|
const setAuth = (resp) => {
|
|
const {
|
|
meetingID, internalUserID, authToken, logoutUrl,
|
|
fullname, externUserID, confname,
|
|
} = resp;
|
|
return new Promise((resolve) => {
|
|
Auth.set(
|
|
meetingID, internalUserID, authToken, logoutUrl,
|
|
sessionToken, fullname, externUserID, confname,
|
|
);
|
|
resolve(resp);
|
|
});
|
|
};
|
|
|
|
const setLogoutURL = (url) => {
|
|
Auth.logoutURL = url;
|
|
return true;
|
|
};
|
|
|
|
const setLogoURL = (resp) => {
|
|
setCustomLogoUrl(resp.customLogoURL);
|
|
return resp;
|
|
};
|
|
|
|
const setCustomData = (resp) => {
|
|
const {
|
|
meetingID, internalUserID, customdata,
|
|
} = resp;
|
|
|
|
return new Promise((resolve) => {
|
|
if (customdata.length) {
|
|
makeCall('addUserSettings', meetingID, internalUserID, customdata).then(r => resolve(r));
|
|
}
|
|
resolve(true);
|
|
});
|
|
};
|
|
|
|
const setBannerProps = (resp) => {
|
|
Session.set('bannerText', resp.bannerText);
|
|
Session.set('bannerColor', resp.bannerColor);
|
|
};
|
|
|
|
// use enter api to get params for the client
|
|
const url = `/bigbluebutton/api/enter?sessionToken=${sessionToken}`;
|
|
const fetchContent = await fetch(url, { credentials: 'same-origin' });
|
|
const parseToJson = await fetchContent.json();
|
|
const { response } = parseToJson;
|
|
|
|
setLogoutURL(response);
|
|
if (response.returncode !== 'FAILED') {
|
|
await setAuth(response);
|
|
|
|
setBannerProps(response);
|
|
setLogoURL(response);
|
|
logUserInfo();
|
|
|
|
await setCustomData(response);
|
|
|
|
if (showParticipantsOnLogin && !deviceInfo.type().isPhone) {
|
|
Session.set('openPanel', 'userlist');
|
|
if (CHAT_ENABLED) {
|
|
Session.set('openPanel', 'chat');
|
|
Session.set('idChatOpen', '');
|
|
}
|
|
} else {
|
|
Session.set('openPanel', '');
|
|
}
|
|
|
|
logger.info({
|
|
logCode: 'joinhandler_component_joinroutehandler_success',
|
|
extraInfo: {
|
|
response,
|
|
},
|
|
}, 'User successfully went through main.joinRouteHandler');
|
|
this.setState({ joined: true });
|
|
} else {
|
|
const e = new Error(response.message);
|
|
if (!Session.get('codeError')) Session.set('errorMessageDescription', response.message);
|
|
this.setError(401);
|
|
logger.error({
|
|
logCode: 'joinhandler_component_joinroutehandler_error',
|
|
extraInfo: {
|
|
response,
|
|
error: e,
|
|
},
|
|
}, 'User faced an error on main.joinRouteHandler.');
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const { children } = this.props;
|
|
const { joined } = this.state;
|
|
return joined && children;
|
|
}
|
|
}
|
|
|
|
export default withConsumer(JoinHandler);
|
|
|
|
JoinHandler.propTypes = propTypes;
|