import React, { Component } from 'react'; import { Session } from 'meteor/session'; 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 LoadingScreen from '/imports/ui/components/loading-screen/component'; class JoinHandler extends Component { static setError(codeError) { Session.set('hasError', true); if (codeError) Session.set('codeError', codeError); } constructor(props) { super(props); this.fetchToken = this.fetchToken.bind(this); this.changeToJoin = this.changeToJoin.bind(this); this.state = { joined: false, }; } componentDidMount() { this.fetchToken(); } changeToJoin(bool) { this.setState({ joined: bool }); } fetchToken() { const urlParams = new URLSearchParams(window.location.search); const sessionToken = urlParams.get('sessionToken'); if (!sessionToken) { JoinHandler.setError('404'); } // 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(clientInfo); }; const setAuth = (resp) => { const { meetingID, internalUserID, authToken, logoutUrl, fullname, externUserID, confname, } = resp; Auth.set( meetingID, internalUserID, authToken, logoutUrl, sessionToken, fullname, externUserID, confname, ); return 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; if (customdata.length) { makeCall('addUserSettings', meetingID, internalUserID, customdata); } return resp; }; // use enter api to get params for the client const url = `/bigbluebutton/api/enter?sessionToken=${sessionToken}`; const validAuth = new Promise((resolve, reject) => { fetch(url, { credentials: 'same-origin' }) .then(response => response.json()) .then(({ response }) => response) .then((resp) => { setLogoutURL(resp.logoutURL); if (resp.returncode !== 'FAILED') { logger.info(`User successfully went through main.joinRouteHandler with [${JSON.stringify(resp)}].`); return resolve(resp); } const e = new Error('Session not found'); logger.error(`User faced [${e}] on main.joinRouteHandler. Error was:`, JSON.stringify(resp)); return reject(e); }); }); validAuth .then(setCustomData) .then(setAuth) .then(setLogoURL) .then(logUserInfo) .then(() => Session.set('isUserListOpen', deviceInfo.type().isPhone)) .then(() => this.changeToJoin(true)) .catch(() => this.changeToJoin(true)); } render() { const { children } = this.props; const { joined } = this.state; return joined ? children : (); } } export default JoinHandler;