[CHORE] Add permissions to Redux (#2914)
* [FIX] Add permissions to Redux store * add only permissions being used in the app * add clear permissions reducer * call RocketChat.hasPermission from reducer * add server version comparison on getPermissions * refactor hasPermission function * refactor hasPermission function * remove uncomment code * use Q.experimentalSortBy() * add coerce function * Change Rocketchat.hasPermission * Apply on isReadOnly * Apply to RoomInfoEditView * Apply to RoomInfoView and RoomInfoEditView * canAutoTranslate * Unnecessary clear permissions * Revert getUpdatedSince * Naming fix Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
parent
6e32a15cad
commit
e98116587d
|
@ -70,3 +70,5 @@ export const SETTINGS = createRequestTypes('SETTINGS', ['CLEAR', 'ADD']);
|
||||||
export const APP_STATE = createRequestTypes('APP_STATE', ['FOREGROUND', 'BACKGROUND']);
|
export const APP_STATE = createRequestTypes('APP_STATE', ['FOREGROUND', 'BACKGROUND']);
|
||||||
export const ENTERPRISE_MODULES = createRequestTypes('ENTERPRISE_MODULES', ['CLEAR', 'SET']);
|
export const ENTERPRISE_MODULES = createRequestTypes('ENTERPRISE_MODULES', ['CLEAR', 'SET']);
|
||||||
export const ENCRYPTION = createRequestTypes('ENCRYPTION', ['INIT', 'STOP', 'DECODE_KEY', 'SET', 'SET_BANNER']);
|
export const ENCRYPTION = createRequestTypes('ENCRYPTION', ['INIT', 'STOP', 'DECODE_KEY', 'SET', 'SET_BANNER']);
|
||||||
|
|
||||||
|
export const PERMISSIONS = createRequestTypes('PERMISSIONS', ['SET']);
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import * as types from './actionsTypes';
|
||||||
|
|
||||||
|
export function setPermissions(permissions) {
|
||||||
|
return {
|
||||||
|
type: types.PERMISSIONS.SET,
|
||||||
|
permissions
|
||||||
|
};
|
||||||
|
}
|
|
@ -34,20 +34,24 @@ const MessageActions = React.memo(forwardRef(({
|
||||||
Message_AllowPinning,
|
Message_AllowPinning,
|
||||||
Message_AllowStarring,
|
Message_AllowStarring,
|
||||||
Message_Read_Receipt_Store_Users,
|
Message_Read_Receipt_Store_Users,
|
||||||
isMasterDetail
|
isMasterDetail,
|
||||||
|
editMessagePermission,
|
||||||
|
deleteMessagePermission,
|
||||||
|
forceDeleteMessagePermission,
|
||||||
|
pinMessagePermission
|
||||||
}, ref) => {
|
}, ref) => {
|
||||||
let permissions = {};
|
let permissions = {};
|
||||||
const { showActionSheet, hideActionSheet } = useActionSheet();
|
const { showActionSheet, hideActionSheet } = useActionSheet();
|
||||||
|
|
||||||
const getPermissions = async() => {
|
const getPermissions = async() => {
|
||||||
try {
|
try {
|
||||||
const permission = ['edit-message', 'delete-message', 'force-delete-message', 'pin-message'];
|
const permission = [editMessagePermission, deleteMessagePermission, forceDeleteMessagePermission, pinMessagePermission];
|
||||||
const result = await RocketChat.hasPermission(permission, room.rid);
|
const result = await RocketChat.hasPermission(permission, room.rid);
|
||||||
permissions = {
|
permissions = {
|
||||||
hasEditPermission: result[permission[0]],
|
hasEditPermission: result[0],
|
||||||
hasDeletePermission: result[permission[1]],
|
hasDeletePermission: result[1],
|
||||||
hasForceDeletePermission: result[permission[2]],
|
hasForceDeletePermission: result[2],
|
||||||
hasPinPermission: result[permission[3]]
|
hasPinPermission: result[3]
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
@ -440,7 +444,11 @@ MessageActions.propTypes = {
|
||||||
Message_AllowPinning: PropTypes.bool,
|
Message_AllowPinning: PropTypes.bool,
|
||||||
Message_AllowStarring: PropTypes.bool,
|
Message_AllowStarring: PropTypes.bool,
|
||||||
Message_Read_Receipt_Store_Users: PropTypes.bool,
|
Message_Read_Receipt_Store_Users: PropTypes.bool,
|
||||||
server: PropTypes.string
|
server: PropTypes.string,
|
||||||
|
editMessagePermission: PropTypes.array,
|
||||||
|
deleteMessagePermission: PropTypes.array,
|
||||||
|
forceDeleteMessagePermission: PropTypes.array,
|
||||||
|
pinMessagePermission: PropTypes.array
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
|
@ -452,7 +460,11 @@ const mapStateToProps = state => ({
|
||||||
Message_AllowPinning: state.settings.Message_AllowPinning,
|
Message_AllowPinning: state.settings.Message_AllowPinning,
|
||||||
Message_AllowStarring: state.settings.Message_AllowStarring,
|
Message_AllowStarring: state.settings.Message_AllowStarring,
|
||||||
Message_Read_Receipt_Store_Users: state.settings.Message_Read_Receipt_Store_Users,
|
Message_Read_Receipt_Store_Users: state.settings.Message_Read_Receipt_Store_Users,
|
||||||
isMasterDetail: state.app.isMasterDetail
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
|
editMessagePermission: state.permissions['edit-message'],
|
||||||
|
deleteMessagePermission: state.permissions['delete-message'],
|
||||||
|
forceDeleteMessagePermission: state.permissions['force-delete-message'],
|
||||||
|
pinMessagePermission: state.permissions['pin-message']
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, null, null, { forwardRef: true })(MessageActions);
|
export default connect(mapStateToProps, null, null, { forwardRef: true })(MessageActions);
|
||||||
|
|
|
@ -1,11 +1,55 @@
|
||||||
import lt from 'semver/functions/lt';
|
import lt from 'semver/functions/lt';
|
||||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||||
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
import coerce from 'semver/functions/coerce';
|
||||||
import orderBy from 'lodash/orderBy';
|
import orderBy from 'lodash/orderBy';
|
||||||
|
|
||||||
import database from '../database';
|
import database from '../database';
|
||||||
import log from '../../utils/log';
|
import log from '../../utils/log';
|
||||||
import reduxStore from '../createStore';
|
import reduxStore from '../createStore';
|
||||||
import protectedFunction from './helpers/protectedFunction';
|
import protectedFunction from './helpers/protectedFunction';
|
||||||
|
import { setPermissions as setPermissionsAction } from '../../actions/permissions';
|
||||||
|
|
||||||
|
const PERMISSIONS = [
|
||||||
|
'add-user-to-any-c-room',
|
||||||
|
'add-user-to-any-p-room',
|
||||||
|
'add-user-to-joined-room',
|
||||||
|
'archive-room',
|
||||||
|
'auto-translate',
|
||||||
|
'create-invite-links',
|
||||||
|
'delete-c',
|
||||||
|
'delete-message',
|
||||||
|
'delete-p',
|
||||||
|
'edit-message',
|
||||||
|
'edit-room',
|
||||||
|
'force-delete-message',
|
||||||
|
'mute-user',
|
||||||
|
'pin-message',
|
||||||
|
'post-readonly',
|
||||||
|
'remove-user',
|
||||||
|
'set-leader',
|
||||||
|
'set-moderator',
|
||||||
|
'set-owner',
|
||||||
|
'set-react-when-readonly',
|
||||||
|
'set-readonly',
|
||||||
|
'toggle-room-e2e-encryption',
|
||||||
|
'transfer-livechat-guest',
|
||||||
|
'unarchive-room',
|
||||||
|
'view-broadcast-member-list',
|
||||||
|
'view-privileged-setting',
|
||||||
|
'view-room-administration',
|
||||||
|
'view-statistics',
|
||||||
|
'view-user-administration'
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function setPermissions() {
|
||||||
|
const db = database.active;
|
||||||
|
const permissionsCollection = db.collections.get('permissions');
|
||||||
|
const allPermissions = await permissionsCollection.query(Q.where('id', Q.oneOf(PERMISSIONS))).fetch();
|
||||||
|
const parsed = allPermissions.reduce((acc, item) => ({ ...acc, [item.id]: item.roles }), {});
|
||||||
|
|
||||||
|
reduxStore.dispatch(setPermissionsAction(parsed));
|
||||||
|
}
|
||||||
|
|
||||||
const getUpdatedSince = (allRecords) => {
|
const getUpdatedSince = (allRecords) => {
|
||||||
try {
|
try {
|
||||||
|
@ -64,12 +108,13 @@ const updatePermissions = async({ update = [], remove = [], allRecords }) => {
|
||||||
await db.action(async() => {
|
await db.action(async() => {
|
||||||
await db.batch(...batch);
|
await db.batch(...batch);
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function() {
|
export function getPermissions() {
|
||||||
return new Promise(async(resolve) => {
|
return new Promise(async(resolve) => {
|
||||||
try {
|
try {
|
||||||
const serverVersion = reduxStore.getState().server.version;
|
const serverVersion = reduxStore.getState().server.version;
|
||||||
|
@ -78,17 +123,20 @@ export default function() {
|
||||||
const allRecords = await permissionsCollection.query().fetch();
|
const allRecords = await permissionsCollection.query().fetch();
|
||||||
|
|
||||||
// if server version is lower than 0.73.0, fetches from old api
|
// if server version is lower than 0.73.0, fetches from old api
|
||||||
if (serverVersion && lt(serverVersion, '0.73.0')) {
|
if (serverVersion && lt(coerce(serverVersion), '0.73.0')) {
|
||||||
// RC 0.66.0
|
// RC 0.66.0
|
||||||
const result = await this.sdk.get('permissions.list');
|
const result = await this.sdk.get('permissions.list');
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
await updatePermissions({ update: result.permissions, allRecords });
|
const changePermissions = await updatePermissions({ update: result.permissions, allRecords });
|
||||||
|
if (changePermissions) {
|
||||||
|
setPermissions();
|
||||||
|
}
|
||||||
return resolve();
|
return resolve();
|
||||||
} else {
|
} else {
|
||||||
const params = {};
|
const params = {};
|
||||||
const updatedSince = await getUpdatedSince(allRecords);
|
const updatedSince = getUpdatedSince(allRecords);
|
||||||
if (updatedSince) {
|
if (updatedSince) {
|
||||||
params.updatedSince = updatedSince;
|
params.updatedSince = updatedSince;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +147,10 @@ export default function() {
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
await updatePermissions({ update: result.update, remove: result.delete, allRecords });
|
const changePermissions = await updatePermissions({ update: result.update, remove: result.delete, allRecords });
|
||||||
|
if (changePermissions) {
|
||||||
|
setPermissions();
|
||||||
|
}
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ import readMessages from './methods/readMessages';
|
||||||
import getSettings, { getLoginSettings, setSettings } from './methods/getSettings';
|
import getSettings, { getLoginSettings, setSettings } from './methods/getSettings';
|
||||||
|
|
||||||
import getRooms from './methods/getRooms';
|
import getRooms from './methods/getRooms';
|
||||||
import getPermissions from './methods/getPermissions';
|
import { setPermissions, getPermissions } from './methods/getPermissions';
|
||||||
import { getCustomEmojis, setCustomEmojis } from './methods/getCustomEmojis';
|
import { getCustomEmojis, setCustomEmojis } from './methods/getCustomEmojis';
|
||||||
import {
|
import {
|
||||||
getEnterpriseModules, setEnterpriseModules, hasLicense, isOmnichannelModuleAvailable
|
getEnterpriseModules, setEnterpriseModules, hasLicense, isOmnichannelModuleAvailable
|
||||||
|
@ -70,7 +70,6 @@ const CERTIFICATE_KEY = 'RC_CERTIFICATE_KEY';
|
||||||
export const THEME_PREFERENCES_KEY = 'RC_THEME_PREFERENCES_KEY';
|
export const THEME_PREFERENCES_KEY = 'RC_THEME_PREFERENCES_KEY';
|
||||||
export const CRASH_REPORT_KEY = 'RC_CRASH_REPORT_KEY';
|
export const CRASH_REPORT_KEY = 'RC_CRASH_REPORT_KEY';
|
||||||
export const ANALYTICS_EVENTS_KEY = 'RC_ANALYTICS_EVENTS_KEY';
|
export const ANALYTICS_EVENTS_KEY = 'RC_ANALYTICS_EVENTS_KEY';
|
||||||
const returnAnArray = obj => obj || [];
|
|
||||||
const MIN_ROCKETCHAT_VERSION = '0.70.0';
|
const MIN_ROCKETCHAT_VERSION = '0.70.0';
|
||||||
|
|
||||||
const STATUSES = ['offline', 'online', 'away', 'busy'];
|
const STATUSES = ['offline', 'online', 'away', 'busy'];
|
||||||
|
@ -740,6 +739,7 @@ const RocketChat = {
|
||||||
getLoginSettings,
|
getLoginSettings,
|
||||||
setSettings,
|
setSettings,
|
||||||
getPermissions,
|
getPermissions,
|
||||||
|
setPermissions,
|
||||||
getCustomEmojis,
|
getCustomEmojis,
|
||||||
setCustomEmojis,
|
setCustomEmojis,
|
||||||
getEnterpriseModules,
|
getEnterpriseModules,
|
||||||
|
@ -1172,10 +1172,13 @@ const RocketChat = {
|
||||||
// RC 0.65.0
|
// RC 0.65.0
|
||||||
return this.sdk.get(`${ this.roomTypeToApiType(type) }.roles`, { roomId });
|
return this.sdk.get(`${ this.roomTypeToApiType(type) }.roles`, { roomId });
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Permissions: array of permissions' roles from redux. Example: [['owner', 'admin'], ['leader']]
|
||||||
|
* Returns an array of boolean for each permission from permissions arg
|
||||||
|
*/
|
||||||
async hasPermission(permissions, rid) {
|
async hasPermission(permissions, rid) {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const subsCollection = db.collections.get('subscriptions');
|
const subsCollection = db.collections.get('subscriptions');
|
||||||
const permissionsCollection = db.collections.get('permissions');
|
|
||||||
let roomRoles = [];
|
let roomRoles = [];
|
||||||
try {
|
try {
|
||||||
// get the room from database
|
// get the room from database
|
||||||
|
@ -1184,31 +1187,16 @@ const RocketChat = {
|
||||||
roomRoles = room.roles || [];
|
roomRoles = room.roles || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('hasPermission -> Room not found');
|
console.log('hasPermission -> Room not found');
|
||||||
return permissions.reduce((result, permission) => {
|
return permissions.map(() => false);
|
||||||
result[permission] = false;
|
|
||||||
return result;
|
|
||||||
}, {});
|
|
||||||
}
|
}
|
||||||
// get permissions from database
|
|
||||||
try {
|
try {
|
||||||
const permissionsFiltered = await permissionsCollection.query(Q.where('id', Q.oneOf(permissions))).fetch();
|
|
||||||
const shareUser = reduxStore.getState().share.user;
|
const shareUser = reduxStore.getState().share.user;
|
||||||
const loginUser = reduxStore.getState().login.user;
|
const loginUser = reduxStore.getState().login.user;
|
||||||
// get user roles on the server from redux
|
// get user roles on the server from redux
|
||||||
const userRoles = (shareUser?.roles || loginUser?.roles) || [];
|
const userRoles = (shareUser?.roles || loginUser?.roles) || [];
|
||||||
// merge both roles
|
|
||||||
const mergedRoles = [...new Set([...roomRoles, ...userRoles])];
|
const mergedRoles = [...new Set([...roomRoles, ...userRoles])];
|
||||||
|
return permissions.map(permission => permission.some(r => mergedRoles.includes(r) ?? false));
|
||||||
// return permissions in object format
|
|
||||||
// e.g. { 'edit-room': true, 'set-readonly': false }
|
|
||||||
return permissions.reduce((result, permission) => {
|
|
||||||
result[permission] = false;
|
|
||||||
const permissionFound = permissionsFiltered.find(p => p.id === permission);
|
|
||||||
if (permissionFound) {
|
|
||||||
result[permission] = returnAnArray(permissionFound.roles).some(r => mergedRoles.includes(r));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}, {});
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
|
@ -1438,17 +1426,15 @@ const RocketChat = {
|
||||||
query, count, offset, sort
|
query, count, offset, sort
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async canAutoTranslate() {
|
canAutoTranslate() {
|
||||||
const db = database.active;
|
|
||||||
try {
|
try {
|
||||||
const AutoTranslate_Enabled = reduxStore.getState().settings && reduxStore.getState().settings.AutoTranslate_Enabled;
|
const { AutoTranslate_Enabled } = reduxStore.getState().settings;
|
||||||
if (!AutoTranslate_Enabled) {
|
if (!AutoTranslate_Enabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const permissionsCollection = db.collections.get('permissions');
|
const autoTranslatePermission = reduxStore.getState().permissions['auto-translate'];
|
||||||
const autoTranslatePermission = await permissionsCollection.find('auto-translate');
|
const userRoles = (reduxStore.getState().login?.user?.roles) ?? [];
|
||||||
const userRoles = (reduxStore.getState().login.user && reduxStore.getState().login.user.roles) || [];
|
return autoTranslatePermission?.some(role => userRoles.includes(role));
|
||||||
return autoTranslatePermission.roles.some(role => userRoles.includes(role));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -18,6 +18,7 @@ import inviteLinks from './inviteLinks';
|
||||||
import createDiscussion from './createDiscussion';
|
import createDiscussion from './createDiscussion';
|
||||||
import enterpriseModules from './enterpriseModules';
|
import enterpriseModules from './enterpriseModules';
|
||||||
import encryption from './encryption';
|
import encryption from './encryption';
|
||||||
|
import permissions from './permissions';
|
||||||
|
|
||||||
import inquiry from '../ee/omnichannel/reducers/inquiry';
|
import inquiry from '../ee/omnichannel/reducers/inquiry';
|
||||||
|
|
||||||
|
@ -41,5 +42,6 @@ export default combineReducers({
|
||||||
createDiscussion,
|
createDiscussion,
|
||||||
inquiry,
|
inquiry,
|
||||||
enterpriseModules,
|
enterpriseModules,
|
||||||
encryption
|
encryption,
|
||||||
|
permissions
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { PERMISSIONS } from '../actions/actionsTypes';
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
permissions: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function permissions(state = initialState, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case PERMISSIONS.SET:
|
||||||
|
return action.permissions;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
|
@ -124,6 +124,7 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
|
||||||
// and block the selectServerSuccess raising multiples errors
|
// and block the selectServerSuccess raising multiples errors
|
||||||
RocketChat.setSettings();
|
RocketChat.setSettings();
|
||||||
RocketChat.setCustomEmojis();
|
RocketChat.setCustomEmojis();
|
||||||
|
RocketChat.setPermissions();
|
||||||
RocketChat.setEnterpriseModules();
|
RocketChat.setEnterpriseModules();
|
||||||
|
|
||||||
let serverInfo;
|
let serverInfo;
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
|
import reduxStore from '../lib/createStore';
|
||||||
|
|
||||||
const canPost = async({ rid }) => {
|
const canPostReadOnly = async({ rid }) => {
|
||||||
try {
|
// TODO: this is not reactive. If this permission changes, the component won't be updated
|
||||||
const permission = await RocketChat.hasPermission(['post-readonly'], rid);
|
const postReadOnlyPermission = reduxStore.getState().permissions['post-readonly'];
|
||||||
return permission && permission['post-readonly'];
|
const permission = await RocketChat.hasPermission([postReadOnlyPermission], rid);
|
||||||
} catch {
|
return permission[0];
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isMuted = (room, user) => room && room.muted && room.muted.find && !!room.muted.find(m => m === user.username);
|
const isMuted = (room, user) => room && room.muted && room.muted.find && !!room.muted.find(m => m === user.username);
|
||||||
|
@ -20,7 +18,7 @@ export const isReadOnly = async(room, user) => {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (room?.ro) {
|
if (room?.ro) {
|
||||||
const allowPost = await canPost(room);
|
const allowPost = await canPostReadOnly(room);
|
||||||
if (allowPost) {
|
if (allowPost) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,15 @@ class RoomActionsView extends React.Component {
|
||||||
closeRoom: PropTypes.func,
|
closeRoom: PropTypes.func,
|
||||||
theme: PropTypes.string,
|
theme: PropTypes.string,
|
||||||
fontScale: PropTypes.number,
|
fontScale: PropTypes.number,
|
||||||
serverVersion: PropTypes.string
|
serverVersion: PropTypes.string,
|
||||||
|
addUserToJoinedRoomPermission: PropTypes.array,
|
||||||
|
addUserToAnyCRoomPermission: PropTypes.array,
|
||||||
|
addUserToAnyPRoomPermission: PropTypes.array,
|
||||||
|
createInviteLinksPermission: PropTypes.array,
|
||||||
|
editRoomPermission: PropTypes.array,
|
||||||
|
toggleRoomE2EEncryptionPermission: PropTypes.array,
|
||||||
|
viewBroadcastMemberListPermission: PropTypes.array,
|
||||||
|
transferLivechatGuestPermission: PropTypes.array
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -118,7 +126,7 @@ class RoomActionsView extends React.Component {
|
||||||
this.updateRoomMember();
|
this.updateRoomMember();
|
||||||
}
|
}
|
||||||
|
|
||||||
const canAutoTranslate = await RocketChat.canAutoTranslate();
|
const canAutoTranslate = RocketChat.canAutoTranslate();
|
||||||
this.setState({ canAutoTranslate });
|
this.setState({ canAutoTranslate });
|
||||||
|
|
||||||
this.canAddUser();
|
this.canAddUser();
|
||||||
|
@ -159,60 +167,62 @@ class RoomActionsView extends React.Component {
|
||||||
|
|
||||||
canAddUser = async() => {
|
canAddUser = async() => {
|
||||||
const { room, joined } = this.state;
|
const { room, joined } = this.state;
|
||||||
|
const { addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission } = this.props;
|
||||||
const { rid, t } = room;
|
const { rid, t } = room;
|
||||||
let canAdd = false;
|
let canAddUser = false;
|
||||||
|
|
||||||
const userInRoom = joined;
|
const userInRoom = joined;
|
||||||
const permissions = await RocketChat.hasPermission(['add-user-to-joined-room', 'add-user-to-any-c-room', 'add-user-to-any-p-room'], rid);
|
const permissions = await RocketChat.hasPermission([addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission], rid);
|
||||||
|
|
||||||
if (permissions) {
|
if (userInRoom && permissions[0]) {
|
||||||
if (userInRoom && permissions['add-user-to-joined-room']) {
|
canAddUser = true;
|
||||||
canAdd = true;
|
|
||||||
}
|
|
||||||
if (t === 'c' && permissions['add-user-to-any-c-room']) {
|
|
||||||
canAdd = true;
|
|
||||||
}
|
|
||||||
if (t === 'p' && permissions['add-user-to-any-p-room']) {
|
|
||||||
canAdd = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.setState({ canAddUser: canAdd });
|
if (t === 'c' && permissions[1]) {
|
||||||
|
canAddUser = true;
|
||||||
|
}
|
||||||
|
if (t === 'p' && permissions[2]) {
|
||||||
|
canAddUser = true;
|
||||||
|
}
|
||||||
|
this.setState({ canAddUser });
|
||||||
}
|
}
|
||||||
|
|
||||||
canInviteUser = async() => {
|
canInviteUser = async() => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
|
const { createInviteLinksPermission } = this.props;
|
||||||
const { rid } = room;
|
const { rid } = room;
|
||||||
const permissions = await RocketChat.hasPermission(['create-invite-links'], rid);
|
const permissions = await RocketChat.hasPermission([createInviteLinksPermission], rid);
|
||||||
|
|
||||||
const canInviteUser = permissions && permissions['create-invite-links'];
|
const canInviteUser = permissions[0];
|
||||||
this.setState({ canInviteUser });
|
this.setState({ canInviteUser });
|
||||||
}
|
}
|
||||||
|
|
||||||
canEdit = async() => {
|
canEdit = async() => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
|
const { editRoomPermission } = this.props;
|
||||||
const { rid } = room;
|
const { rid } = room;
|
||||||
const permissions = await RocketChat.hasPermission(['edit-room'], rid);
|
const permissions = await RocketChat.hasPermission([editRoomPermission], rid);
|
||||||
|
|
||||||
const canEdit = permissions && permissions['edit-room'];
|
const canEdit = permissions[0];
|
||||||
this.setState({ canEdit });
|
this.setState({ canEdit });
|
||||||
}
|
}
|
||||||
|
|
||||||
canToggleEncryption = async() => {
|
canToggleEncryption = async() => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
|
const { toggleRoomE2EEncryptionPermission } = this.props;
|
||||||
const { rid } = room;
|
const { rid } = room;
|
||||||
const permissions = await RocketChat.hasPermission(['toggle-room-e2e-encryption'], rid);
|
const permissions = await RocketChat.hasPermission([toggleRoomE2EEncryptionPermission], rid);
|
||||||
|
|
||||||
const canToggleEncryption = permissions && permissions['toggle-room-e2e-encryption'];
|
const canToggleEncryption = permissions[0];
|
||||||
this.setState({ canToggleEncryption });
|
this.setState({ canToggleEncryption });
|
||||||
}
|
}
|
||||||
|
|
||||||
canViewMembers = async() => {
|
canViewMembers = async() => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
|
const { viewBroadcastMemberListPermission } = this.props;
|
||||||
const { rid, t, broadcast } = room;
|
const { rid, t, broadcast } = room;
|
||||||
if (broadcast) {
|
if (broadcast) {
|
||||||
const viewBroadcastMemberListPermission = 'view-broadcast-member-list';
|
|
||||||
const permissions = await RocketChat.hasPermission([viewBroadcastMemberListPermission], rid);
|
const permissions = await RocketChat.hasPermission([viewBroadcastMemberListPermission], rid);
|
||||||
if (!permissions[viewBroadcastMemberListPermission]) {
|
if (!permissions[0]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,16 +236,10 @@ class RoomActionsView extends React.Component {
|
||||||
|
|
||||||
canForwardGuest = async() => {
|
canForwardGuest = async() => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
|
const { transferLivechatGuestPermission } = this.props;
|
||||||
const { rid } = room;
|
const { rid } = room;
|
||||||
let result = true;
|
const permissions = await RocketChat.hasPermission([transferLivechatGuestPermission], rid);
|
||||||
|
this.setState({ canForwardGuest: permissions[0] });
|
||||||
const transferLivechatGuest = 'transfer-livechat-guest';
|
|
||||||
const permissions = await RocketChat.hasPermission([transferLivechatGuest], rid);
|
|
||||||
if (!permissions[transferLivechatGuest]) {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ canForwardGuest: result });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canReturnQueue = async() => {
|
canReturnQueue = async() => {
|
||||||
|
@ -866,7 +870,15 @@ class RoomActionsView extends React.Component {
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
jitsiEnabled: state.settings.Jitsi_Enabled || false,
|
jitsiEnabled: state.settings.Jitsi_Enabled || false,
|
||||||
encryptionEnabled: state.encryption.enabled,
|
encryptionEnabled: state.encryption.enabled,
|
||||||
serverVersion: state.server.version
|
serverVersion: state.server.version,
|
||||||
|
addUserToJoinedRoomPermission: state.permissions['add-user-to-joined-room'],
|
||||||
|
addUserToAnyCRoomPermission: state.permissions['add-user-to-any-c-room'],
|
||||||
|
addUserToAnyPRoomPermission: state.permissions['add-user-to-any-p-room'],
|
||||||
|
createInviteLinksPermission: state.permissions['create-invite-links'],
|
||||||
|
editRoomPermission: state.permissions['edit-room'],
|
||||||
|
toggleRoomE2EEncryptionPermission: state.permissions['toggle-room-e2e-encryption'],
|
||||||
|
viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'],
|
||||||
|
transferLivechatGuestPermission: state.permissions['transfer-livechat-guest']
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
|
|
@ -44,14 +44,6 @@ const PERMISSION_ARCHIVE = 'archive-room';
|
||||||
const PERMISSION_UNARCHIVE = 'unarchive-room';
|
const PERMISSION_UNARCHIVE = 'unarchive-room';
|
||||||
const PERMISSION_DELETE_C = 'delete-c';
|
const PERMISSION_DELETE_C = 'delete-c';
|
||||||
const PERMISSION_DELETE_P = 'delete-p';
|
const PERMISSION_DELETE_P = 'delete-p';
|
||||||
const PERMISSIONS_ARRAY = [
|
|
||||||
PERMISSION_SET_READONLY,
|
|
||||||
PERMISSION_SET_REACT_WHEN_READONLY,
|
|
||||||
PERMISSION_ARCHIVE,
|
|
||||||
PERMISSION_UNARCHIVE,
|
|
||||||
PERMISSION_DELETE_C,
|
|
||||||
PERMISSION_DELETE_P
|
|
||||||
];
|
|
||||||
|
|
||||||
class RoomInfoEditView extends React.Component {
|
class RoomInfoEditView extends React.Component {
|
||||||
static navigationOptions = () => ({
|
static navigationOptions = () => ({
|
||||||
|
@ -63,7 +55,13 @@ class RoomInfoEditView extends React.Component {
|
||||||
deleteRoom: PropTypes.func,
|
deleteRoom: PropTypes.func,
|
||||||
serverVersion: PropTypes.string,
|
serverVersion: PropTypes.string,
|
||||||
encryptionEnabled: PropTypes.bool,
|
encryptionEnabled: PropTypes.bool,
|
||||||
theme: PropTypes.string
|
theme: PropTypes.string,
|
||||||
|
setReadOnlyPermission: PropTypes.array,
|
||||||
|
setReactWhenReadOnlyPermission: PropTypes.array,
|
||||||
|
archiveRoomPermission: PropTypes.array,
|
||||||
|
unarchiveRoomPermission: PropTypes.array,
|
||||||
|
deleteCPermission: PropTypes.array,
|
||||||
|
deletePPermission: PropTypes.array
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -108,7 +106,15 @@ class RoomInfoEditView extends React.Component {
|
||||||
|
|
||||||
// eslint-disable-next-line react/sort-comp
|
// eslint-disable-next-line react/sort-comp
|
||||||
loadRoom = async() => {
|
loadRoom = async() => {
|
||||||
const { route } = this.props;
|
const {
|
||||||
|
route,
|
||||||
|
setReadOnlyPermission,
|
||||||
|
setReactWhenReadOnlyPermission,
|
||||||
|
archiveRoomPermission,
|
||||||
|
unarchiveRoomPermission,
|
||||||
|
deleteCPermission,
|
||||||
|
deletePPermission
|
||||||
|
} = this.props;
|
||||||
const rid = route.params?.rid;
|
const rid = route.params?.rid;
|
||||||
if (!rid) {
|
if (!rid) {
|
||||||
return;
|
return;
|
||||||
|
@ -123,8 +129,25 @@ class RoomInfoEditView extends React.Component {
|
||||||
this.init(this.room);
|
this.init(this.room);
|
||||||
});
|
});
|
||||||
|
|
||||||
const permissions = await RocketChat.hasPermission(PERMISSIONS_ARRAY, rid);
|
const result = await RocketChat.hasPermission([
|
||||||
this.setState({ permissions });
|
setReadOnlyPermission,
|
||||||
|
setReactWhenReadOnlyPermission,
|
||||||
|
archiveRoomPermission,
|
||||||
|
unarchiveRoomPermission,
|
||||||
|
deleteCPermission,
|
||||||
|
deletePPermission
|
||||||
|
], rid);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
permissions: {
|
||||||
|
[PERMISSION_SET_READONLY]: result[0],
|
||||||
|
[PERMISSION_SET_REACT_WHEN_READONLY]: result[1],
|
||||||
|
[PERMISSION_ARCHIVE]: result[2],
|
||||||
|
[PERMISSION_UNARCHIVE]: result[3],
|
||||||
|
[PERMISSION_DELETE_C]: result[4],
|
||||||
|
[PERMISSION_DELETE_P]: result[5]
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
|
@ -667,7 +690,13 @@ class RoomInfoEditView extends React.Component {
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
serverVersion: state.server.version,
|
serverVersion: state.server.version,
|
||||||
encryptionEnabled: state.encryption.enabled
|
encryptionEnabled: state.encryption.enabled,
|
||||||
|
setReadOnlyPermission: state.permissions[PERMISSION_SET_READONLY],
|
||||||
|
setReactWhenReadOnlyPermission: state.permissions[PERMISSION_SET_REACT_WHEN_READONLY],
|
||||||
|
archiveRoomPermission: state.permissions[PERMISSION_ARCHIVE],
|
||||||
|
unarchiveRoomPermission: state.permissions[PERMISSION_UNARCHIVE],
|
||||||
|
deleteCPermission: state.permissions[PERMISSION_DELETE_C],
|
||||||
|
deletePPermission: state.permissions[PERMISSION_DELETE_P]
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
|
|
@ -31,7 +31,6 @@ import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import { goRoom } from '../../utils/goRoom';
|
import { goRoom } from '../../utils/goRoom';
|
||||||
import Navigation from '../../lib/Navigation';
|
import Navigation from '../../lib/Navigation';
|
||||||
|
|
||||||
const PERMISSION_EDIT_ROOM = 'edit-room';
|
|
||||||
const getRoomTitle = (room, type, name, username, statusText, theme) => (type === 'd'
|
const getRoomTitle = (room, type, name, username, statusText, theme) => (type === 'd'
|
||||||
? (
|
? (
|
||||||
<>
|
<>
|
||||||
|
@ -55,7 +54,8 @@ class RoomInfoView extends React.Component {
|
||||||
rooms: PropTypes.array,
|
rooms: PropTypes.array,
|
||||||
theme: PropTypes.string,
|
theme: PropTypes.string,
|
||||||
isMasterDetail: PropTypes.bool,
|
isMasterDetail: PropTypes.bool,
|
||||||
jitsiEnabled: PropTypes.bool
|
jitsiEnabled: PropTypes.bool,
|
||||||
|
editRoomPermission: PropTypes.array
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -193,7 +193,7 @@ class RoomInfoView extends React.Component {
|
||||||
|
|
||||||
loadRoom = async() => {
|
loadRoom = async() => {
|
||||||
const { room: roomState } = this.state;
|
const { room: roomState } = this.state;
|
||||||
const { route } = this.props;
|
const { route, editRoomPermission } = this.props;
|
||||||
let room = route.params?.room;
|
let room = route.params?.room;
|
||||||
if (room && room.observe) {
|
if (room && room.observe) {
|
||||||
this.roomObservable = room.observe();
|
this.roomObservable = room.observe();
|
||||||
|
@ -213,8 +213,8 @@ class RoomInfoView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const permissions = await RocketChat.hasPermission([PERMISSION_EDIT_ROOM], room.rid);
|
const permissions = await RocketChat.hasPermission([editRoomPermission], room.rid);
|
||||||
if (permissions[PERMISSION_EDIT_ROOM] && !room.prid) {
|
if (permissions[0] && !room.prid) {
|
||||||
this.setState({ showEdit: true }, () => this.setHeader());
|
this.setState({ showEdit: true }, () => this.setHeader());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -369,7 +369,8 @@ class RoomInfoView extends React.Component {
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
rooms: state.room.rooms,
|
rooms: state.room.rooms,
|
||||||
isMasterDetail: state.app.isMasterDetail,
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
jitsiEnabled: state.settings.Jitsi_Enabled || false
|
jitsiEnabled: state.settings.Jitsi_Enabled || false,
|
||||||
|
editRoomPermission: state.permissions['edit-room']
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(withTheme(RoomInfoView));
|
export default connect(mapStateToProps)(withTheme(RoomInfoView));
|
||||||
|
|
|
@ -28,6 +28,12 @@ import { goRoom } from '../../utils/goRoom';
|
||||||
|
|
||||||
const PAGE_SIZE = 25;
|
const PAGE_SIZE = 25;
|
||||||
|
|
||||||
|
const PERMISSION_MUTE_USER = 'mute-user';
|
||||||
|
const PERMISSION_SET_LEADER = 'set-leader';
|
||||||
|
const PERMISSION_SET_OWNER = 'set-owner';
|
||||||
|
const PERMISSION_SET_MODERATOR = 'set-moderator';
|
||||||
|
const PERMISSION_REMOVE_USER = 'remove-user';
|
||||||
|
|
||||||
class RoomMembersView extends React.Component {
|
class RoomMembersView extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigation: PropTypes.object,
|
navigation: PropTypes.object,
|
||||||
|
@ -43,7 +49,12 @@ class RoomMembersView extends React.Component {
|
||||||
showActionSheet: PropTypes.func,
|
showActionSheet: PropTypes.func,
|
||||||
theme: PropTypes.string,
|
theme: PropTypes.string,
|
||||||
isMasterDetail: PropTypes.bool,
|
isMasterDetail: PropTypes.bool,
|
||||||
useRealName: PropTypes.bool
|
useRealName: PropTypes.bool,
|
||||||
|
muteUserPermission: PropTypes.array,
|
||||||
|
setLeaderPermission: PropTypes.array,
|
||||||
|
setOwnerPermission: PropTypes.array,
|
||||||
|
setModeratorPermission: PropTypes.array,
|
||||||
|
removeUserPermission: PropTypes.array
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -81,7 +92,20 @@ class RoomMembersView extends React.Component {
|
||||||
this.fetchMembers();
|
this.fetchMembers();
|
||||||
|
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
this.permissions = await RocketChat.hasPermission(['mute-user', 'set-leader', 'set-owner', 'set-moderator', 'remove-user'], room.rid);
|
const {
|
||||||
|
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission
|
||||||
|
} = this.props;
|
||||||
|
const result = await RocketChat.hasPermission([
|
||||||
|
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission
|
||||||
|
], room.rid);
|
||||||
|
|
||||||
|
this.permissions = {
|
||||||
|
[PERMISSION_MUTE_USER]: result[0],
|
||||||
|
[PERMISSION_SET_LEADER]: result[1],
|
||||||
|
[PERMISSION_SET_OWNER]: result[2],
|
||||||
|
[PERMISSION_SET_MODERATOR]: result[3],
|
||||||
|
[PERMISSION_REMOVE_USER]: result[4]
|
||||||
|
};
|
||||||
|
|
||||||
const hasSinglePermission = Object.values(this.permissions).some(p => !!p);
|
const hasSinglePermission = Object.values(this.permissions).some(p => !!p);
|
||||||
if (hasSinglePermission) {
|
if (hasSinglePermission) {
|
||||||
|
@ -452,7 +476,12 @@ const mapStateToProps = state => ({
|
||||||
baseUrl: state.server.server,
|
baseUrl: state.server.server,
|
||||||
user: getUserSelector(state),
|
user: getUserSelector(state),
|
||||||
isMasterDetail: state.app.isMasterDetail,
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
useRealName: state.settings.UI_Use_Real_Name
|
useRealName: state.settings.UI_Use_Real_Name,
|
||||||
|
muteUserPermission: state.permissions[PERMISSION_MUTE_USER],
|
||||||
|
setLeaderPermission: state.permissions[PERMISSION_SET_LEADER],
|
||||||
|
setOwnerPermission: state.permissions[PERMISSION_SET_OWNER],
|
||||||
|
setModeratorPermission: state.permissions[PERMISSION_SET_MODERATOR],
|
||||||
|
removeUserPermission: state.permissions[PERMISSION_REMOVE_USER]
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(withActionSheet(withTheme(RoomMembersView)));
|
export default connect(mapStateToProps)(withActionSheet(withTheme(RoomMembersView)));
|
||||||
|
|
|
@ -436,10 +436,7 @@ class RoomView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We run `canAutoTranslate` again in order to refetch auto translate permission
|
const canAutoTranslate = RocketChat.canAutoTranslate();
|
||||||
// in case of a missing connection or poor connection on room open
|
|
||||||
const canAutoTranslate = await RocketChat.canAutoTranslate();
|
|
||||||
|
|
||||||
const member = await this.getRoomMember();
|
const member = await this.getRoomMember();
|
||||||
|
|
||||||
this.setState({ canAutoTranslate, member, loading: false });
|
this.setState({ canAutoTranslate, member, loading: false });
|
||||||
|
|
|
@ -4,19 +4,16 @@ import {
|
||||||
ScrollView, Text, View, TouchableWithoutFeedback
|
ScrollView, Text, View, TouchableWithoutFeedback
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
|
||||||
import isEqual from 'react-fast-compare';
|
import isEqual from 'react-fast-compare';
|
||||||
|
|
||||||
import Avatar from '../../containers/Avatar';
|
import Avatar from '../../containers/Avatar';
|
||||||
import Status from '../../containers/Status/Status';
|
import Status from '../../containers/Status/Status';
|
||||||
import log, { logEvent, events } from '../../utils/log';
|
import { logEvent, events } from '../../utils/log';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import SidebarItem from './SidebarItem';
|
import SidebarItem from './SidebarItem';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
import database from '../../lib/database';
|
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { getUserSelector } from '../../selectors/login';
|
import { getUserSelector } from '../../selectors/login';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
|
@ -27,13 +24,6 @@ Separator.propTypes = {
|
||||||
theme: PropTypes.string
|
theme: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
const permissions = [
|
|
||||||
'view-statistics',
|
|
||||||
'view-room-administration',
|
|
||||||
'view-user-administration',
|
|
||||||
'view-privileged-setting'
|
|
||||||
];
|
|
||||||
|
|
||||||
class Sidebar extends Component {
|
class Sidebar extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
baseUrl: PropTypes.string,
|
baseUrl: PropTypes.string,
|
||||||
|
@ -45,32 +35,24 @@ class Sidebar extends Component {
|
||||||
loadingServer: PropTypes.bool,
|
loadingServer: PropTypes.bool,
|
||||||
useRealName: PropTypes.bool,
|
useRealName: PropTypes.bool,
|
||||||
allowStatusMessage: PropTypes.bool,
|
allowStatusMessage: PropTypes.bool,
|
||||||
isMasterDetail: PropTypes.bool
|
isMasterDetail: PropTypes.bool,
|
||||||
|
viewStatisticsPermission: PropTypes.object,
|
||||||
|
viewRoomAdministrationPermission: PropTypes.object,
|
||||||
|
viewUserAdministrationPermission: PropTypes.object,
|
||||||
|
viewPrivilegedSettingPermission: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
showStatus: false,
|
showStatus: false
|
||||||
isAdmin: false
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.setIsAdmin();
|
|
||||||
}
|
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
||||||
const { loadingServer } = this.props;
|
|
||||||
if (loadingServer && nextProps.loadingServer !== loadingServer) {
|
|
||||||
this.setIsAdmin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
const { showStatus, isAdmin } = this.state;
|
const { showStatus, isAdmin } = this.state;
|
||||||
const {
|
const {
|
||||||
Site_Name, user, baseUrl, state, isMasterDetail, useRealName, theme
|
Site_Name, user, baseUrl, state, isMasterDetail, useRealName, theme, viewStatisticsPermission, viewRoomAdministrationPermission, viewUserAdministrationPermission, viewPrivilegedSettingPermission
|
||||||
} = this.props;
|
} = this.props;
|
||||||
// Drawer navigation state
|
// Drawer navigation state
|
||||||
if (state?.index !== nextProps.state?.index) {
|
if (state?.index !== nextProps.state?.index) {
|
||||||
|
@ -103,25 +85,42 @@ class Sidebar extends Component {
|
||||||
if (nextState.isAdmin !== isAdmin) {
|
if (nextState.isAdmin !== isAdmin) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!isEqual(nextProps.viewStatisticsPermission, viewStatisticsPermission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!isEqual(nextProps.viewRoomAdministrationPermission, viewRoomAdministrationPermission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!isEqual(nextProps.viewUserAdministrationPermission, viewUserAdministrationPermission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!isEqual(nextProps.viewPrivilegedSettingPermission, viewPrivilegedSettingPermission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async setIsAdmin() {
|
|
||||||
const db = database.active;
|
getIsAdmin() {
|
||||||
const { user } = this.props;
|
const {
|
||||||
|
user, viewStatisticsPermission, viewRoomAdministrationPermission, viewUserAdministrationPermission, viewPrivilegedSettingPermission
|
||||||
|
} = this.props;
|
||||||
const { roles } = user;
|
const { roles } = user;
|
||||||
try {
|
const allPermissions = [viewStatisticsPermission, viewRoomAdministrationPermission, viewUserAdministrationPermission, viewPrivilegedSettingPermission];
|
||||||
if (roles) {
|
let isAdmin = false;
|
||||||
const permissionsCollection = db.collections.get('permissions');
|
|
||||||
const permissionsFiltered = await permissionsCollection.query(Q.where('id', Q.oneOf(permissions))).fetch();
|
if (roles) {
|
||||||
const isAdmin = permissionsFiltered.reduce((result, permission) => (
|
isAdmin = allPermissions.reduce((result, permission) => {
|
||||||
result || permission.roles.some(r => roles.indexOf(r) !== -1)),
|
if (permission) {
|
||||||
false);
|
return (
|
||||||
this.setState({ isAdmin });
|
result || permission.some(r => roles.indexOf(r) !== -1)
|
||||||
}
|
);
|
||||||
} catch (e) {
|
}
|
||||||
log(e);
|
return result;
|
||||||
|
},
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
return isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
sidebarNavigate = (route) => {
|
sidebarNavigate = (route) => {
|
||||||
|
@ -143,9 +142,8 @@ class Sidebar extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderAdmin = () => {
|
renderAdmin = () => {
|
||||||
const { isAdmin } = this.state;
|
|
||||||
const { theme, isMasterDetail } = this.props;
|
const { theme, isMasterDetail } = this.props;
|
||||||
if (!isAdmin) {
|
if (!this.getIsAdmin()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const routeName = isMasterDetail ? 'AdminPanelView' : 'AdminPanelStackNavigator';
|
const routeName = isMasterDetail ? 'AdminPanelView' : 'AdminPanelStackNavigator';
|
||||||
|
@ -275,7 +273,11 @@ const mapStateToProps = state => ({
|
||||||
loadingServer: state.server.loading,
|
loadingServer: state.server.loading,
|
||||||
useRealName: state.settings.UI_Use_Real_Name,
|
useRealName: state.settings.UI_Use_Real_Name,
|
||||||
allowStatusMessage: state.settings.Accounts_AllowUserStatusMessageChange,
|
allowStatusMessage: state.settings.Accounts_AllowUserStatusMessageChange,
|
||||||
isMasterDetail: state.app.isMasterDetail
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
|
viewStatisticsPermission: state.permissions['view-statistics'],
|
||||||
|
viewRoomAdministrationPermission: state.permissions['view-room-administration'],
|
||||||
|
viewUserAdministrationPermission: state.permissions['view-user-administration'],
|
||||||
|
viewPrivilegedSettingPermission: state.permissions['view-privileged-setting']
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(withTheme(Sidebar));
|
export default connect(mapStateToProps)(withTheme(Sidebar));
|
||||||
|
|
Loading…
Reference in New Issue