New option for handling permissions in rooms. Set allowWhenRoleMissing to permit actions before a peer with that permission joins. Ref #303
This commit is contained in:
@@ -2847,8 +2847,8 @@ export default class RoomClient
|
||||
roles,
|
||||
peers,
|
||||
tracker,
|
||||
permissionsFromRoles,
|
||||
userRoles,
|
||||
roomPermissions,
|
||||
allowWhenRoleMissing,
|
||||
chatHistory,
|
||||
fileHistory,
|
||||
lastNHistory,
|
||||
@@ -2874,8 +2874,10 @@ export default class RoomClient
|
||||
|
||||
store.dispatch(meActions.loggedIn(authenticated));
|
||||
|
||||
store.dispatch(roomActions.setUserRoles(userRoles));
|
||||
store.dispatch(roomActions.setPermissionsFromRoles(permissionsFromRoles));
|
||||
store.dispatch(roomActions.setRoomPermissions(roomPermissions));
|
||||
|
||||
if (allowWhenRoleMissing)
|
||||
store.dispatch(roomActions.setAllowWhenRoleMissing(allowWhenRoleMissing));
|
||||
|
||||
const myRoles = store.getState().me.roles;
|
||||
|
||||
|
||||
@@ -177,14 +177,14 @@ export const setClearFileSharingInProgress = (flag) =>
|
||||
payload : { flag }
|
||||
});
|
||||
|
||||
export const setUserRoles = (userRoles) =>
|
||||
export const setRoomPermissions = (roomPermissions) =>
|
||||
({
|
||||
type : 'SET_USER_ROLES',
|
||||
payload : { userRoles }
|
||||
type : 'SET_ROOM_PERMISSIONS',
|
||||
payload : { roomPermissions }
|
||||
});
|
||||
|
||||
export const setPermissionsFromRoles = (permissionsFromRoles) =>
|
||||
export const setAllowWhenRoleMissing = (allowWhenRoleMissing) =>
|
||||
({
|
||||
type : 'SET_PERMISSIONS_FROM_ROLES',
|
||||
payload : { permissionsFromRoles }
|
||||
type : 'SET_ALLOW_WHEN_ROLE_MISSING',
|
||||
payload : { allowWhenRoleMissing }
|
||||
});
|
||||
|
||||
@@ -5,6 +5,8 @@ import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { withRoomContext } from '../../../RoomContext';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { permissions } from '../../../permissions';
|
||||
import { makePermissionSelector } from '../../Selectors';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
@@ -85,28 +87,32 @@ ListLobbyPeer.propTypes =
|
||||
classes : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, { id }) =>
|
||||
const makeMapStateToProps = (initialState, { id }) =>
|
||||
{
|
||||
return {
|
||||
peer : state.lobbyPeers[id],
|
||||
promotionInProgress : state.room.lobbyPeersPromotionInProgress,
|
||||
canPromote :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.PROMOTE_PEER.includes(role))
|
||||
const hasPermission = makePermissionSelector(permissions.PROMOTE_PEER);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
return {
|
||||
peer : state.lobbyPeers[id],
|
||||
promotionInProgress : state.room.lobbyPeersPromotionInProgress,
|
||||
canPromote : hasPermission(state)
|
||||
};
|
||||
};
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
areStatesEqual : (next, prev) =>
|
||||
{
|
||||
return (
|
||||
prev.room.permissionsFromRoles === next.room.permissionsFromRoles &&
|
||||
prev.room.lobbyPeersPromotionInProgress ===
|
||||
next.room.lobbyPeersPromotionInProgress &&
|
||||
prev.room === next.room &&
|
||||
prev.peers === next.peers && // For checking permissions
|
||||
prev.me.roles === next.me.roles &&
|
||||
prev.lobbyPeers === next.lobbyPeers
|
||||
);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
lobbyPeersKeySelector
|
||||
lobbyPeersKeySelector,
|
||||
makePermissionSelector
|
||||
} from '../../Selectors';
|
||||
import { permissions } from '../../../permissions';
|
||||
import * as appPropTypes from '../../appPropTypes';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import { withRoomContext } from '../../../RoomContext';
|
||||
@@ -140,15 +142,20 @@ LockDialog.propTypes =
|
||||
classes : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
return {
|
||||
room : state.room,
|
||||
lobbyPeers : lobbyPeersKeySelector(state),
|
||||
canPromote :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.PROMOTE_PEER.includes(role))
|
||||
const hasPermission = makePermissionSelector(permissions.PROMOTE_PEER);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
return {
|
||||
room : state.room,
|
||||
lobbyPeers : lobbyPeersKeySelector(state),
|
||||
canPromote : hasPermission(state)
|
||||
};
|
||||
};
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
@@ -157,7 +164,7 @@ const mapDispatchToProps = {
|
||||
};
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
null,
|
||||
{
|
||||
@@ -166,6 +173,7 @@ export default withRoomContext(connect(
|
||||
return (
|
||||
prev.room === next.room &&
|
||||
prev.me.roles === next.me.roles &&
|
||||
prev.peers === next.peers &&
|
||||
prev.lobbyPeers === next.lobbyPeers
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import React, { useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { meProducersSelector } from '../Selectors';
|
||||
import {
|
||||
meProducersSelector,
|
||||
makePermissionSelector
|
||||
} from '../Selectors';
|
||||
import { permissions } from '../../permissions';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import PropTypes from 'prop-types';
|
||||
@@ -807,32 +811,37 @@ Me.propTypes =
|
||||
theme : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
return {
|
||||
me : state.me,
|
||||
...meProducersSelector(state),
|
||||
settings : state.settings,
|
||||
activeSpeaker : state.me.id === state.room.activeSpeakerId,
|
||||
canShareScreen :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.SHARE_SCREEN.includes(role))
|
||||
const hasPermission = makePermissionSelector(permissions.SHARE_SCREEN);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
return {
|
||||
me : state.me,
|
||||
...meProducersSelector(state),
|
||||
settings : state.settings,
|
||||
activeSpeaker : state.me.id === state.room.activeSpeakerId,
|
||||
canShareScreen : hasPermission(state)
|
||||
};
|
||||
};
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
areStatesEqual : (next, prev) =>
|
||||
{
|
||||
return (
|
||||
prev.room.permissionsFromRoles === next.room.permissionsFromRoles &&
|
||||
prev.room === next.room &&
|
||||
prev.me === next.me &&
|
||||
prev.peers === next.peers &&
|
||||
prev.producers === next.producers &&
|
||||
prev.settings === next.settings &&
|
||||
prev.room.activeSpeakerId === next.room.activeSpeakerId
|
||||
prev.settings === next.settings
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import PropTypes from 'prop-types';
|
||||
import {
|
||||
lobbyPeersKeySelector,
|
||||
peersLengthSelector,
|
||||
raisedHandsSelector
|
||||
raisedHandsSelector,
|
||||
makePermissionSelector
|
||||
} from '../Selectors';
|
||||
import { permissions } from '../../permissions';
|
||||
import * as appPropTypes from '../appPropTypes';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
@@ -751,27 +753,35 @@ TopBar.propTypes =
|
||||
theme : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
room : state.room,
|
||||
peersLength : peersLengthSelector(state),
|
||||
lobbyPeers : lobbyPeersKeySelector(state),
|
||||
permanentTopBar : state.settings.permanentTopBar,
|
||||
loggedIn : state.me.loggedIn,
|
||||
loginEnabled : state.me.loginEnabled,
|
||||
myPicture : state.me.picture,
|
||||
unread : state.toolarea.unreadMessages +
|
||||
state.toolarea.unreadFiles + raisedHandsSelector(state),
|
||||
canProduceExtraVideo :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.EXTRA_VIDEO.includes(role)),
|
||||
canLock :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.CHANGE_ROOM_LOCK.includes(role)),
|
||||
canPromote :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.PROMOTE_PEER.includes(role))
|
||||
});
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
const hasExtraVideoPermission =
|
||||
makePermissionSelector(permissions.EXTRA_VIDEO);
|
||||
|
||||
const hasLockPermission =
|
||||
makePermissionSelector(permissions.CHANGE_ROOM_LOCK);
|
||||
|
||||
const hasPromotionPermission =
|
||||
makePermissionSelector(permissions.PROMOTE_PEER);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
room : state.room,
|
||||
peersLength : peersLengthSelector(state),
|
||||
lobbyPeers : lobbyPeersKeySelector(state),
|
||||
permanentTopBar : state.settings.permanentTopBar,
|
||||
loggedIn : state.me.loggedIn,
|
||||
loginEnabled : state.me.loginEnabled,
|
||||
myPicture : state.me.picture,
|
||||
unread : state.toolarea.unreadMessages +
|
||||
state.toolarea.unreadFiles + raisedHandsSelector(state),
|
||||
canProduceExtraVideo : hasExtraVideoPermission(state),
|
||||
canLock : hasLockPermission(state),
|
||||
canPromote : hasPromotionPermission(state)
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
({
|
||||
@@ -811,7 +821,7 @@ const mapDispatchToProps = (dispatch) =>
|
||||
});
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
null,
|
||||
{
|
||||
|
||||
@@ -4,6 +4,8 @@ import PropTypes from 'prop-types';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import { withRoomContext } from '../../../RoomContext';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { permissions } from '../../../permissions';
|
||||
import { makePermissionSelector } from '../../Selectors';
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
import InputBase from '@material-ui/core/InputBase';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
@@ -119,26 +121,32 @@ ChatInput.propTypes =
|
||||
classes : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
displayName : state.settings.displayName,
|
||||
picture : state.me.picture,
|
||||
canChat :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.SEND_CHAT.includes(role))
|
||||
});
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
const hasPermission = makePermissionSelector(permissions.SEND_CHAT);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
displayName : state.settings.displayName,
|
||||
picture : state.me.picture,
|
||||
canChat : hasPermission(state)
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
export default withRoomContext(
|
||||
connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
areStatesEqual : (next, prev) =>
|
||||
{
|
||||
return (
|
||||
prev.room.permissionsFromRoles === next.room.permissionsFromRoles &&
|
||||
prev.room === next.room &&
|
||||
prev.me.roles === next.me.roles &&
|
||||
prev.peers === next.peers &&
|
||||
prev.settings.displayName === next.settings.displayName &&
|
||||
prev.me.picture === next.me.picture
|
||||
);
|
||||
|
||||
@@ -4,6 +4,8 @@ import PropTypes from 'prop-types';
|
||||
import { withRoomContext } from '../../../RoomContext';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import { useIntl, FormattedMessage } from 'react-intl';
|
||||
import { permissions } from '../../../permissions';
|
||||
import { makePermissionSelector } from '../../Selectors';
|
||||
import Button from '@material-ui/core/Button';
|
||||
|
||||
const styles = (theme) =>
|
||||
@@ -76,16 +78,21 @@ ChatModerator.propTypes =
|
||||
classes : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
isChatModerator :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.MODERATE_CHAT.includes(role)),
|
||||
room : state.room
|
||||
});
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
const hasPermission = makePermissionSelector(permissions.MODERATE_CHAT);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
isChatModerator : hasPermission(state),
|
||||
room : state.room
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
@@ -93,7 +100,8 @@ export default withRoomContext(connect(
|
||||
{
|
||||
return (
|
||||
prev.room === next.room &&
|
||||
prev.me === next.me
|
||||
prev.me === next.me &&
|
||||
prev.peers === next.peers
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import { connect } from 'react-redux';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import { withRoomContext } from '../../../RoomContext';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { permissions } from '../../../permissions';
|
||||
import { makePermissionSelector } from '../../Selectors';
|
||||
import FileList from './FileList';
|
||||
import FileSharingModerator from './FileSharingModerator';
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
@@ -131,30 +133,36 @@ FileSharing.propTypes = {
|
||||
classes : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
return {
|
||||
canShareFiles : state.me.canShareFiles,
|
||||
browser : state.me.browser,
|
||||
tabOpen : state.toolarea.currentToolTab === 'files',
|
||||
canShare :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.SHARE_FILE.includes(role))
|
||||
const hasPermission = makePermissionSelector(permissions.SHARE_FILE);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
return {
|
||||
canShareFiles : state.me.canShareFiles,
|
||||
browser : state.me.browser,
|
||||
tabOpen : state.toolarea.currentToolTab === 'files',
|
||||
canShare : hasPermission(state)
|
||||
};
|
||||
};
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
areStatesEqual : (next, prev) =>
|
||||
{
|
||||
return (
|
||||
prev.room.permissionsFromRoles === next.room.permissionsFromRoles &&
|
||||
prev.room === next.room &&
|
||||
prev.me.browser === next.me.browser &&
|
||||
prev.me.roles === next.me.roles &&
|
||||
prev.me.canShareFiles === next.me.canShareFiles &&
|
||||
prev.peers === next.peers &&
|
||||
prev.toolarea.currentToolTab === next.toolarea.currentToolTab
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import PropTypes from 'prop-types';
|
||||
import { withRoomContext } from '../../../RoomContext';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import { useIntl, FormattedMessage } from 'react-intl';
|
||||
import { permissions } from '../../../permissions';
|
||||
import { makePermissionSelector } from '../../Selectors';
|
||||
import Button from '@material-ui/core/Button';
|
||||
|
||||
const styles = (theme) =>
|
||||
@@ -76,16 +78,21 @@ FileSharingModerator.propTypes =
|
||||
classes : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
isFileSharingModerator :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.MODERATE_FILES.includes(role)),
|
||||
room : state.room
|
||||
});
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
const hasPermission = makePermissionSelector(permissions.MODERATE_FILES);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
isFileSharingModerator : hasPermission(state),
|
||||
room : state.room
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
@@ -93,7 +100,8 @@ export default withRoomContext(connect(
|
||||
{
|
||||
return (
|
||||
prev.room === next.room &&
|
||||
prev.me === next.me
|
||||
prev.me === next.me &&
|
||||
prev.peers === next.peers
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
participantListSelector
|
||||
participantListSelector,
|
||||
makePermissionSelector
|
||||
} from '../../Selectors';
|
||||
import { permissions } from '../../../permissions';
|
||||
import classnames from 'classnames';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import { withRoomContext } from '../../../RoomContext';
|
||||
@@ -160,31 +162,34 @@ ParticipantList.propTypes =
|
||||
classes : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
return {
|
||||
isModerator :
|
||||
state.me.roles.some((role) =>
|
||||
state.room.permissionsFromRoles.MODERATE_ROOM.includes(role)),
|
||||
participants : participantListSelector(state),
|
||||
spotlights : state.room.spotlights,
|
||||
selectedPeerId : state.room.selectedPeerId
|
||||
const hasPermission = makePermissionSelector(permissions.MODERATE_ROOM);
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
return {
|
||||
isModerator : hasPermission(state),
|
||||
participants : participantListSelector(state),
|
||||
spotlights : state.room.spotlights,
|
||||
selectedPeerId : state.room.selectedPeerId
|
||||
};
|
||||
};
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const ParticipantListContainer = withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
areStatesEqual : (next, prev) =>
|
||||
{
|
||||
return (
|
||||
prev.room.permissionsFromRoles === next.room.permissionsFromRoles &&
|
||||
prev.room === next.room &&
|
||||
prev.me.roles === next.me.roles &&
|
||||
prev.peers === next.peers &&
|
||||
prev.room.spotlights === next.room.spotlights &&
|
||||
prev.room.selectedPeerId === next.room.selectedPeerId
|
||||
prev.peers === next.peers
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
const meRolesSelect = (state) => state.me.roles;
|
||||
const roomPermissionsSelect = (state) => state.room.roomPermissions;
|
||||
const roomAllowWhenRoleMissing = (state) => state.room.allowWhenRoleMissing;
|
||||
const producersSelect = (state) => state.producers;
|
||||
const consumersSelect = (state) => state.consumers;
|
||||
const spotlightsSelector = (state) => state.room.spotlights;
|
||||
@@ -217,3 +220,53 @@ export const makePeerConsumerSelector = () =>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Very important that the Components that use this
|
||||
// selector need to check at least these state changes:
|
||||
//
|
||||
// areStatesEqual : (next, prev) =>
|
||||
// {
|
||||
// return (
|
||||
// prev.room.roomPermissions === next.room.roomPermissions &&
|
||||
// prev.room.allowWhenRoleMissing === next.room.allowWhenRoleMissing &&
|
||||
// prev.peers === next.peers &&
|
||||
// prev.me.roles === next.me.roles
|
||||
// );
|
||||
// }
|
||||
export const makePermissionSelector = (permission) =>
|
||||
{
|
||||
return createSelector(
|
||||
meRolesSelect,
|
||||
roomPermissionsSelect,
|
||||
roomAllowWhenRoleMissing,
|
||||
peersValueSelector,
|
||||
(roles, roomPermissions, allowWhenRoleMissing, peers) =>
|
||||
{
|
||||
if (!roomPermissions)
|
||||
return false;
|
||||
|
||||
const permitted = roles.some((role) =>
|
||||
roomPermissions[permission].includes(role)
|
||||
);
|
||||
|
||||
if (permitted)
|
||||
return true;
|
||||
|
||||
if (!allowWhenRoleMissing)
|
||||
return false;
|
||||
|
||||
// Allow if config is set, and no one is present
|
||||
if (allowWhenRoleMissing.includes(permission) &&
|
||||
peers.filter(
|
||||
(peer) =>
|
||||
peer.roles.some(
|
||||
(role) => roomPermissions[permission].includes(role)
|
||||
)
|
||||
).length === 0
|
||||
)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
export const permissions = {
|
||||
// The role(s) have permission to lock/unlock a room
|
||||
CHANGE_ROOM_LOCK : 'CHANGE_ROOM_LOCK',
|
||||
// The role(s) have permission to promote a peer from the lobby
|
||||
PROMOTE_PEER : 'PROMOTE_PEER',
|
||||
// The role(s) have permission to send chat messages
|
||||
SEND_CHAT : 'SEND_CHAT',
|
||||
// The role(s) have permission to moderate chat
|
||||
MODERATE_CHAT : 'MODERATE_CHAT',
|
||||
// The role(s) have permission to share screen
|
||||
SHARE_SCREEN : 'SHARE_SCREEN',
|
||||
// The role(s) have permission to produce extra video
|
||||
EXTRA_VIDEO : 'EXTRA_VIDEO',
|
||||
// The role(s) have permission to share files
|
||||
SHARE_FILE : 'SHARE_FILE',
|
||||
// The role(s) have permission to moderate files
|
||||
MODERATE_FILES : 'MODERATE_FILES',
|
||||
// The role(s) have permission to moderate room (e.g. kick user)
|
||||
MODERATE_ROOM : 'MODERATE_ROOM'
|
||||
};
|
||||
@@ -33,18 +33,8 @@ const initialState =
|
||||
closeMeetingInProgress : false,
|
||||
clearChatInProgress : false,
|
||||
clearFileSharingInProgress : false,
|
||||
userRoles : { NORMAL: 'normal' }, // Default role
|
||||
permissionsFromRoles : {
|
||||
CHANGE_ROOM_LOCK : [],
|
||||
PROMOTE_PEER : [],
|
||||
SEND_CHAT : [],
|
||||
MODERATE_CHAT : [],
|
||||
SHARE_SCREEN : [],
|
||||
EXTRA_VIDEO : [],
|
||||
SHARE_FILE : [],
|
||||
MODERATE_FILES : [],
|
||||
MODERATE_ROOM : []
|
||||
}
|
||||
roomPermissions : null,
|
||||
allowWhenRoleMissing : null
|
||||
};
|
||||
|
||||
const room = (state = initialState, action) =>
|
||||
@@ -240,18 +230,18 @@ const room = (state = initialState, action) =>
|
||||
case 'CLEAR_FILE_SHARING_IN_PROGRESS':
|
||||
return { ...state, clearFileSharingInProgress: action.payload.flag };
|
||||
|
||||
case 'SET_USER_ROLES':
|
||||
case 'SET_ROOM_PERMISSIONS':
|
||||
{
|
||||
const { userRoles } = action.payload;
|
||||
const { roomPermissions } = action.payload;
|
||||
|
||||
return { ...state, userRoles };
|
||||
return { ...state, roomPermissions };
|
||||
}
|
||||
|
||||
case 'SET_PERMISSIONS_FROM_ROLES':
|
||||
case 'SET_ALLOW_WHEN_ROLE_MISSING':
|
||||
{
|
||||
const { permissionsFromRoles } = action.payload;
|
||||
const { allowWhenRoleMissing } = action.payload;
|
||||
|
||||
return { ...state, permissionsFromRoles };
|
||||
return { ...state, allowWhenRoleMissing };
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user