Merge pull request #4086 from oswaldoacauan/guest-policy

[HTML5] Guest Policy
This commit is contained in:
Anton Georgiev 2017-07-14 15:32:18 -04:00 committed by GitHub
commit 07ca5f5794
9 changed files with 123 additions and 45 deletions

View File

@ -6,6 +6,8 @@ import handleVoiceUpdate from './handlers/voiceUpdate';
import handlePresenterAssigned from './handlers/presenterAssigned';
import handleEmojiStatus from './handlers/emojiStatus';
import handleGetUsers from './handlers/getUsers';
import handleGuestsWaitingForApproval from './handlers/guestsWaitingForApproval';
import handleGuestApproved from './handlers/guestApproved';
RedisPubSub.on('PresenterAssignedEvtMsg', handlePresenterAssigned);
RedisPubSub.on('UserJoinedMeetingEvtMsg', handleUserJoined);
@ -15,3 +17,5 @@ RedisPubSub.on('UserJoinedVoiceConfToClientEvtMsg', handleVoiceUpdate);
RedisPubSub.on('ValidateAuthTokenRespMsg', handleValidateAuthToken);
RedisPubSub.on('UserEmojiChangedEvtMsg', handleEmojiStatus);
RedisPubSub.on('SyncGetUsersMeetingRespMsg', handleGetUsers);
RedisPubSub.on('GuestsWaitingForApprovalEvtMsg', handleGuestsWaitingForApproval);
RedisPubSub.on('GuestApprovedEvtMsg', handleGuestApproved);

View File

@ -0,0 +1,14 @@
import { check } from 'meteor/check';
import setApprovedStatus from '../modifiers/setApprovedStatus';
export default function handleGuestsWaitingForApproval({ header, body }, meetingId) {
const { userId } = header;
const { approved, approvedBy } = body;
check(userId, String);
check(meetingId, String);
check(approved, Boolean);
check(approvedBy, String);
return setApprovedStatus(meetingId, userId, approved, approvedBy);
}

View File

@ -0,0 +1,11 @@
import { check } from 'meteor/check';
import setApprovedStatus from '../modifiers/setApprovedStatus';
export default function handleGuestsWaitingForApproval({ body }, meetingId) {
const { guests } = body;
check(guests, Array);
return guests.map(guest => setApprovedStatus(meetingId, guest.intId, false));
}

View File

@ -35,10 +35,11 @@ const addWelcomeChatMessage = (meetingId, userId) => {
};
export default function handleValidateAuthToken({ body }, meetingId) {
const { userId, valid } = body;
const { userId, valid, waitForApproval } = body;
check(userId, String);
check(valid, Boolean);
check(waitForApproval, Boolean);
const selector = {
meetingId,
@ -56,6 +57,7 @@ export default function handleValidateAuthToken({ body }, meetingId) {
const modifier = {
$set: {
validated: valid,
approved: !waitForApproval,
},
};

View File

@ -0,0 +1,31 @@
import { check } from 'meteor/check';
import Users from '/imports/api/2.0/users';
import Logger from '/imports/startup/server/logger';
export default function setApprovedStatus(meetingId, userId, approved = false, approvedBy = null) {
check(meetingId, String);
check(userId, String);
check(approved, Boolean);
const selector = {
meetingId,
userId,
};
const modifier = {
$set: {
approved,
approvedBy,
},
};
const cb = (err) => {
if (err) {
return Logger.error(`Updating approved status user=${userId}: ${err}`);
}
return Logger.info(`Updated approved status user=${userId} approved=${approved} meeting=${meetingId}`);
};
return Users.update(selector, modifier, cb);
}

View File

@ -1,9 +1,14 @@
import React, { Component, cloneElement } from 'react';
import PropTypes from 'prop-types';
import React, { cloneElement } from 'react';
import { createContainer } from 'meteor/react-meteor-data';
import { withRouter } from 'react-router';
import { defineMessages, injectIntl } from 'react-intl';
import Auth from '/imports/ui/services/auth';
import Users from '/imports/api/2.0/users';
import Breakouts from '/imports/api/1.1/breakouts';
import ClosedCaptionsContainer from '/imports/ui/components/closed-captions/container';
import {
getFontSize,
getCaptionsStatus,
@ -11,16 +16,10 @@ import {
import { withModalMounter } from '../modal/service';
import Auth from '/imports/ui/services/auth';
import Users from '/imports/api/2.0/users';
import Breakouts from '/imports/api/1.1/breakouts';
import App from './component';
import NavBarContainer from '../nav-bar/container';
import ActionsBarContainer from '../actions-bar/container';
import MediaContainer from '../media/container';
import AudioModalContainer from '../audio/audio-modal/component';
import ClosedCaptionsContainer from '/imports/ui/components/closed-captions/container';
const defaultProps = {
navbar: <NavBarContainer />,
@ -33,41 +32,49 @@ const intlMessages = defineMessages({
id: 'app.error.kicked',
description: 'Message when the user is kicked out of the meeting',
},
waitingApprovalMessage: {
id: 'app.guest.waiting',
description: 'Message while a guest is waiting to be approved',
},
});
class AppContainer extends Component {
render() {
// inject location on the navbar container
const navbarWithLocation = cloneElement(this.props.navbar, { location: this.props.location });
const AppContainer = (props) => {
// inject location on the navbar container
const navbarWithLocation = cloneElement(props.navbar, { location: props.location });
return (
<App {...this.props} navbar={navbarWithLocation}>
{this.props.children}
</App>
);
}
}
return (
<App {...props} navbar={navbarWithLocation}>
{props.children}
</App>
);
};
export default withRouter(injectIntl(withModalMounter(createContainer((
{ router, intl, mountModal, baseControls }) => {
// Check if user is kicked out of the session
{ router, intl, baseControls }) => {
const currentUser = Users.findOne({ userId: Auth.userID });
if (!currentUser.approved) {
baseControls.updateLoadingState(intl.formatMessage(intlMessages.waitingApprovalMessage));
}
// Check if user is kicked out of the session
Users.find({ userId: Auth.userID }).observeChanges({
changed(id, fields) {
if (fields.user && fields.user.kicked) {
Auth.clearCredentials()
.then(() => {
router.push('/error/403');
baseControls.updateErrorState(
intl.formatMessage(intlMessages.kickedMessage),
);
});
.then(() => {
router.push('/error/403');
baseControls.updateErrorState(
intl.formatMessage(intlMessages.kickedMessage),
);
});
}
},
});
// Close the widow when the current breakout room ends
Breakouts.find({ breakoutMeetingId: Auth.meetingID }).observeChanges({
removed(old) {
removed() {
Auth.clearCredentials().then(window.close);
},
});

View File

@ -1,17 +1,17 @@
import React, { Component } from 'react';
import React from 'react';
import styles from './styles.scss';
class LoadingScreen extends Component {
render() {
return (
<div className={styles.background}>
<div className={styles.spinner}>
<div className={styles.bounce1} />
<div className={styles.bounce2} />
<div className={styles.bounce3} />
</div>
</div>
);
}
}
const LoadingScreen = ({ children }) => (
<div className={styles.background}>
<div className={styles.spinner}>
<div className={styles.bounce1} />
<div className={styles.bounce2} />
<div className={styles.bounce3} />
</div>
<div className={styles.message}>
{children}
</div>
</div>
);
export default LoadingScreen;

View File

@ -1,10 +1,11 @@
@import '../../stylesheets/variables/palette';
@import '../../stylesheets/variables/_all';
/* Variables
* ==========
*/
$loader-bg: $color-gray-dark;
$loader-bullet: $color-white;
$loader-message-color: $color-white;
.background {
position: fixed;
@ -16,10 +17,17 @@ $loader-bullet: $color-white;
background-color: $loader-bg;
}
.message {
font-size: $font-size-large;
color: $color-white;
text-align: center;
}
.spinner {
width: 100%;
text-align: center;
height: 22px;
margin-bottom: $md-padding-x;
}
.spinner > div {

View File

@ -199,5 +199,6 @@
"app.error.404": "Not found",
"app.error.401": "Unauthorized",
"app.error.403": "Forbidden",
"app.error.leaveLabel": "Log in again"
"app.error.leaveLabel": "Log in again",
"app.guest.waiting": "Waiting for approval to join"
}