bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/join-handler/component.jsx

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;