Chore: Move admin permissions into redux

This commit is contained in:
Gustav Hansen 2023-06-20 14:18:07 +02:00
parent a6a86c30b9
commit c44cf5c5fd
41 changed files with 479 additions and 237 deletions

View File

@ -0,0 +1,90 @@
export const ADMIN_PERMISSIONS_CE = {
contentManager: {
main: [],
collectionTypesConfigurations: [
{
action: 'plugin::content-manager.collection-types.configure-view',
subject: null,
},
],
componentsConfigurations: [
{
action: 'plugin::content-manager.components.configure-layout',
subject: null,
},
],
singleTypesConfigurations: [
{
action: 'plugin::content-manager.single-types.configure-view',
subject: null,
},
],
},
marketplace: {
main: [{ action: 'admin::marketplace.read', subject: null }],
read: [{ action: 'admin::marketplace.read', subject: null }],
},
settings: {
roles: {
main: [
{ action: 'admin::roles.create', subject: null },
{ action: 'admin::roles.update', subject: null },
{ action: 'admin::roles.read', subject: null },
{ action: 'admin::roles.delete', subject: null },
],
create: [{ action: 'admin::roles.create', subject: null }],
delete: [{ action: 'admin::roles.delete', subject: null }],
read: [{ action: 'admin::roles.read', subject: null }],
update: [{ action: 'admin::roles.update', subject: null }],
},
users: {
main: [
{ action: 'admin::users.create', subject: null },
{ action: 'admin::users.read', subject: null },
{ action: 'admin::users.update', subject: null },
{ action: 'admin::users.delete', subject: null },
],
create: [{ action: 'admin::users.create', subject: null }],
delete: [{ action: 'admin::users.delete', subject: null }],
read: [{ action: 'admin::users.read', subject: null }],
update: [{ action: 'admin::users.update', subject: null }],
},
webhooks: {
main: [
{ action: 'admin::webhooks.create', subject: null },
{ action: 'admin::webhooks.read', subject: null },
{ action: 'admin::webhooks.update', subject: null },
{ action: 'admin::webhooks.delete', subject: null },
],
create: [{ action: 'admin::webhooks.create', subject: null }],
delete: [{ action: 'admin::webhooks.delete', subject: null }],
read: [
{ action: 'admin::webhooks.read', subject: null },
// NOTE: We need to check with the API
{ action: 'admin::webhooks.update', subject: null },
{ action: 'admin::webhooks.delete', subject: null },
],
update: [{ action: 'admin::webhooks.update', subject: null }],
},
'api-tokens': {
main: [{ action: 'admin::api-tokens.access', subject: null }],
create: [{ action: 'admin::api-tokens.create', subject: null }],
delete: [{ action: 'admin::api-tokens.delete', subject: null }],
read: [{ action: 'admin::api-tokens.read', subject: null }],
update: [{ action: 'admin::api-tokens.update', subject: null }],
regenerate: [{ action: 'admin::api-tokens.regenerate', subject: null }],
},
'transfer-tokens': {
main: [{ action: 'admin::transfer.tokens.access', subject: null }],
create: [{ action: 'admin::transfer.tokens.create', subject: null }],
delete: [{ action: 'admin::transfer.tokens.delete', subject: null }],
read: [{ action: 'admin::transfer.tokens.read', subject: null }],
update: [{ action: 'admin::transfer.tokens.update', subject: null }],
regenerate: [{ action: 'admin::transfer.tokens.regenerate', subject: null }],
},
'project-settings': {
read: [{ action: 'admin::project-settings.read', subject: null }],
update: [{ action: 'admin::project-settings.update', subject: null }],
},
},
};

View File

@ -10,10 +10,11 @@ import {
import sortBy from 'lodash/sortBy';
import { Helmet } from 'react-helmet';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import { Redirect, Route, Switch, useLocation, useRouteMatch } from 'react-router-dom';
import { DragLayer } from '../../../components/DragLayer';
import permissions from '../../../permissions';
import { selectAdminPermissions } from '../../../pages/App/selectors';
import ModelsContext from '../../contexts/ModelsContext';
import getTrad from '../../utils/getTrad';
import ItemTypes from '../../utils/ItemTypes';
@ -29,8 +30,6 @@ import { RelationDragPreview } from './components/RelationDragPreview';
import LeftMenu from './LeftMenu';
import useContentManagerInitData from './useContentManagerInitData';
const cmPermissions = permissions.contentManager;
function renderDraglayerItem({ type, item }) {
if ([ItemTypes.EDIT_FIELD, ItemTypes.FIELD].includes(type)) {
return <CardDragPreview labelField={item.labelField} />;
@ -73,6 +72,7 @@ const App = () => {
const { formatMessage } = useIntl();
const { startSection } = useGuidedTour();
const startSectionRef = useRef(startSection);
const permissions = useSelector(selectAdminPermissions);
useEffect(() => {
if (startSectionRef.current) {
@ -127,7 +127,7 @@ const App = () => {
<ModelsContext.Provider value={{ refetchData }}>
<Switch>
<Route path="/content-manager/components/:uid/configurations/edit">
<CheckPagePermissions permissions={cmPermissions.componentsConfigurations}>
<CheckPagePermissions permissions={permissions.contentManager.componentsConfigurations}>
<ComponentSettingsView />
</CheckPagePermissions>
</Route>

View File

@ -3,9 +3,10 @@ import React, { memo, useMemo } from 'react';
import { CheckPagePermissions, LoadingIndicatorPage } from '@strapi/helper-plugin';
import PropTypes from 'prop-types';
import { ErrorBoundary } from 'react-error-boundary';
import { useSelector } from 'react-redux';
import { Route, Switch } from 'react-router-dom';
import permissions from '../../../permissions';
import { selectAdminPermissions } from '../../../pages/App/selectors';
import { ContentTypeLayoutContext } from '../../contexts';
import { useFetchContentTypeLayout } from '../../hooks';
import { formatLayoutToApi } from '../../utils';
@ -16,14 +17,13 @@ import ListViewLayout from '../ListViewLayoutManager';
import ErrorFallback from './components/ErrorFallback';
const cmPermissions = permissions.contentManager;
const CollectionTypeRecursivePath = ({
match: {
params: { slug },
url,
},
}) => {
const permissions = useSelector(selectAdminPermissions);
const { isLoading, layout, updateLayout } = useFetchContentTypeLayout(slug);
const { rawContentTypeLayout, rawComponentsLayouts } = useMemo(() => {
@ -92,7 +92,9 @@ const CollectionTypeRecursivePath = ({
<ContentTypeLayoutContext.Provider value={layout}>
<Switch>
<Route path={`${url}/configurations/list`}>
<CheckPagePermissions permissions={cmPermissions.collectionTypesConfigurations}>
<CheckPagePermissions
permissions={permissions.contentManager.collectionTypesConfigurations}
>
<ListSettingsView
layout={rawContentTypeLayout}
slug={slug}
@ -101,7 +103,9 @@ const CollectionTypeRecursivePath = ({
</CheckPagePermissions>
</Route>
<Route path={`${url}/configurations/edit`}>
<CheckPagePermissions permissions={cmPermissions.collectionTypesConfigurations}>
<CheckPagePermissions
permissions={permissions.contentManager.collectionTypesConfigurations}
>
<EditSettingsView
components={rawComponentsLayouts}
isContentTypeView

View File

@ -5,19 +5,18 @@ import axios from 'axios';
import { shallowEqual, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import permissions from '../../../permissions';
import { selectAdminPermissions } from '../../../pages/App/selectors';
import { getData, getDataSucceeded } from '../../sharedReducers/crudReducer/actions';
import crudReducer, { crudInitialState } from '../../sharedReducers/crudReducer/reducer';
import { mergeMetasWithSchema } from '../../utils';
import { makeSelectModelAndComponentSchemas } from '../App/selectors';
import EditSettingsView from '../EditSettingsView';
const cmPermissions = permissions.contentManager;
const ComponentSettingsView = () => {
const [{ isLoading, data: layout }, dispatch] = useReducer(crudReducer, crudInitialState);
const schemasSelector = useMemo(makeSelectModelAndComponentSchemas, []);
const { schemas } = useSelector((state) => schemasSelector(state), shallowEqual);
const permissions = useSelector(selectAdminPermissions);
const { uid } = useParams();
const { get } = useFetchClient();
@ -54,7 +53,7 @@ const ComponentSettingsView = () => {
}
return (
<CheckPagePermissions permissions={cmPermissions.componentsConfigurations}>
<CheckPagePermissions permissions={permissions.contentManager.componentsConfigurations}>
<EditSettingsView components={layout.components} mainLayout={layout.component} slug={uid} />
</CheckPagePermissions>
);

View File

@ -13,7 +13,7 @@ import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import permissions from '../../../permissions';
import { selectAdminPermissions } from '../../../pages/App/selectors';
import { InjectionZone } from '../../../shared/components';
import CollectionTypeFormWrapper from '../../components/CollectionTypeFormWrapper';
import { DynamicZone } from '../../components/DynamicZone';
@ -29,14 +29,14 @@ import Header from './Header';
import { selectAttributesLayout, selectCurrentLayout, selectCustomFieldUids } from './selectors';
import { getFieldsActionMatchingPermissions } from './utils';
const cmPermissions = permissions.contentManager;
const ctbPermissions = [{ action: 'plugin::content-type-builder.read', subject: null }];
// TODO: this seems suspicious
const CTB_PERMISSIONS = [{ action: 'plugin::content-type-builder.read', subject: null }];
/* eslint-disable react/no-array-index-key */
const EditView = ({ allowedActions, isSingleType, goBack, slug, id, origin, userPermissions }) => {
const { trackUsage } = useTracking();
const { formatMessage } = useIntl();
const permissions = useSelector(selectAdminPermissions);
const { layout, formattedContentTypeLayout, customFieldUids } = useSelector((state) => ({
layout: selectCurrentLayout(state),
formattedContentTypeLayout: selectAttributesLayout(state),
@ -49,8 +49,8 @@ const EditView = ({ allowedActions, isSingleType, goBack, slug, id, origin, user
getFieldsActionMatchingPermissions(userPermissions, slug);
const configurationPermissions = isSingleType
? cmPermissions.singleTypesConfigurations
: cmPermissions.collectionTypesConfigurations;
? permissions.contentManager.singleTypesConfigurations
: permissions.contentManager.collectionTypesConfigurations;
// // FIXME when changing the routing
const configurationsURL = `/content-manager/${
@ -188,7 +188,7 @@ const EditView = ({ allowedActions, isSingleType, goBack, slug, id, origin, user
<Flex direction="column" alignItems="stretch" gap={2}>
<InjectionZone area="contentManager.editView.right-links" slug={slug} />
{slug !== 'strapi::administrator' && (
<CheckPermissions permissions={ctbPermissions}>
<CheckPermissions permissions={CTB_PERMISSIONS}>
<LinkButton
onClick={() => {
trackUsage('willEditEditLayout');

View File

@ -31,12 +31,12 @@ import PropTypes from 'prop-types';
import { stringify } from 'qs';
import { useIntl } from 'react-intl';
import { useMutation } from 'react-query';
import { connect } from 'react-redux';
import { connect, useSelector } from 'react-redux';
import { Link as ReactRouterLink, useHistory, useLocation } from 'react-router-dom';
import { bindActionCreators, compose } from 'redux';
import styled from 'styled-components';
import permissions from '../../../permissions';
import { selectAdminPermissions } from '../../../pages/App/selectors';
import { InjectionZone } from '../../../shared/components';
import AttributeFilter from '../../components/AttributeFilter';
import DynamicTable from '../../components/DynamicTable';
@ -48,8 +48,6 @@ import PaginationFooter from './PaginationFooter';
import makeSelectListView from './selectors';
import { buildQueryString } from './utils';
const cmPermissions = permissions.contentManager;
const ConfigureLayoutBox = styled(Box)`
svg {
path {
@ -85,6 +83,7 @@ function ListView({
const fetchPermissionsRef = useRef(refetchPermissions);
const { notifyStatus } = useNotifyAT();
const { formatAPIError } = useAPIErrorHandler(getTrad);
const permissions = useSelector(selectAdminPermissions);
useFocusWhenNavigate();
@ -391,7 +390,9 @@ function ListView({
<>
<InjectionZone area="contentManager.listView.actions" />
<FieldPicker layout={layout} />
<CheckPermissions permissions={cmPermissions.collectionTypesConfigurations}>
<CheckPermissions
permissions={permissions.contentManager.collectionTypesConfigurations}
>
<ConfigureLayoutBox paddingTop={1} paddingBottom={1}>
<IconButton
onClick={() => {

View File

@ -2,23 +2,23 @@ import React, { memo, useMemo } from 'react';
import { CheckPagePermissions, LoadingIndicatorPage } from '@strapi/helper-plugin';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { Route, Switch } from 'react-router-dom';
import permissions from '../../../permissions';
import { selectAdminPermissions } from '../../../pages/App/selectors';
import { ContentTypeLayoutContext } from '../../contexts';
import { useFetchContentTypeLayout } from '../../hooks';
import { formatLayoutToApi } from '../../utils';
import EditSettingsView from '../EditSettingsView';
import EditViewLayoutManager from '../EditViewLayoutManager';
const cmPermissions = permissions.contentManager;
const SingleTypeRecursivePath = ({
match: {
params: { slug },
url,
},
}) => {
const permissions = useSelector(selectAdminPermissions);
const { isLoading, layout, updateLayout } = useFetchContentTypeLayout(slug);
const { rawContentTypeLayout, rawComponentsLayouts } = useMemo(() => {
@ -48,7 +48,7 @@ const SingleTypeRecursivePath = ({
<ContentTypeLayoutContext.Provider value={layout}>
<Switch>
<Route path={`${url}/configurations/edit`}>
<CheckPagePermissions permissions={cmPermissions.singleTypesConfigurations}>
<CheckPagePermissions permissions={permissions.contentManager.singleTypesConfigurations}>
<EditSettingsView
components={rawComponentsLayouts}
isContentTypeView

View File

@ -1,3 +1,4 @@
export const SET_APP_RUNTIME_STATUS = 'StrapiAdmin/APP/SET_APP_RUNTIME_STATUS';
export const SET_ADMIN_PERMISSIONS = 'StrapiAdmin/App/SET_ADMIN_PERMISSIONS';
export const ROUTES_CE = [];

View File

@ -16,10 +16,13 @@ import {
useFetchClient,
useNotification,
} from '@strapi/helper-plugin';
import merge from 'lodash/merge';
import { useIntl } from 'react-intl';
import { useDispatch } from 'react-redux';
import { Route, Switch } from 'react-router-dom';
import PrivateRoute from '../../components/PrivateRoute';
import { ADMIN_PERMISSIONS_CE } from '../../constants';
import { useConfigurations } from '../../hooks';
import { useEnterprise } from '../../hooks/useEnterprise';
import { createRoute, makeUniqueRoutes } from '../../utils';
@ -27,7 +30,7 @@ import AuthPage from '../AuthPage';
import NotFoundPage from '../NotFoundPage';
import UseCasePage from '../UseCasePage';
import { ROUTES_CE } from './constants';
import { ROUTES_CE, SET_ADMIN_PERMISSIONS } from './constants';
import { getUID } from './utils';
const AuthenticatedApp = lazy(() =>
@ -35,6 +38,14 @@ const AuthenticatedApp = lazy(() =>
);
function App() {
const adminPermissions = useEnterprise(ADMIN_PERMISSIONS_CE, async () => (await import('../../../../ee/admin/constants')).ADMIN_PERMISSIONS_EE, {
combine(cePermissions, eePermissions) {
// the `settings` NS e.g. are deep nested objects, that need a deep merge
return merge({}, cePermissions, eePermissions);
},
defaultValue: ADMIN_PERMISSIONS_CE,
})
const routes = useEnterprise(
ROUTES_CE,
async () => (await import('../../../../ee/admin/pages/App/constants')).ROUTES_EE,
@ -49,6 +60,7 @@ function App() {
isLoading: true,
hasAdmin: false,
});
const dispatch = useDispatch();
const appInfo = useAppInfo();
const { get, post } = useFetchClient();
@ -60,6 +72,10 @@ function App() {
const [telemetryProperties, setTelemetryProperties] = useState(null);
useEffect(() => {
dispatch({ type: SET_ADMIN_PERMISSIONS, payload: adminPermissions });
}, [adminPermissions, dispatch]);
useEffect(() => {
const currentToken = auth.getToken();

View File

@ -1,8 +1,9 @@
import produce from 'immer';
import { SET_APP_RUNTIME_STATUS } from './constants';
import { SET_APP_RUNTIME_STATUS, SET_ADMIN_PERMISSIONS } from './constants';
const initialState = {
permissions: {},
status: 'init',
};
@ -14,6 +15,12 @@ const reducer = (state = initialState, action) =>
draftState.status = 'runtime';
break;
}
case SET_ADMIN_PERMISSIONS: {
draftState.permissions = action.payload;
break;
}
default:
return draftState;
}

View File

@ -0,0 +1,12 @@
import { createSelector } from 'reselect';
import { initialState } from './reducer';
const selectAppDomain = () => (state) => {
return state.admin_app || initialState;
};
export const selectAdminPermissions = createSelector(
selectAppDomain(),
(state) => state.permissions
);

View File

@ -3,21 +3,24 @@ import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { Helmet } from 'react-helmet';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import adminPermissions from '../../permissions';
import { selectAdminPermissions } from '../App/selectors';
import Plugins from './Plugins';
const InstalledPluginsPage = () => {
const { formatMessage } = useIntl();
const title = formatMessage({
id: 'global.plugins',
defaultMessage: 'Plugins',
});
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={adminPermissions.marketplace.main}>
<Helmet title={title} />
<CheckPagePermissions permissions={permissions.marketplace.main}>
<Helmet
title={formatMessage({
id: 'global.plugins',
defaultMessage: 'Plugins',
})}
/>
<Plugins />
</CheckPagePermissions>
);

View File

@ -23,10 +23,11 @@ import {
} from '@strapi/helper-plugin';
import { Helmet } from 'react-helmet';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import useDebounce from '../../hooks/useDebounce';
import useNavigatorOnLine from '../../hooks/useNavigatorOnLine';
import adminPermissions from '../../permissions';
import { selectAdminPermissions } from '../App/selectors';
import MissingPluginBanner from './components/MissingPluginBanner';
import NpmPackagesFilters from './components/NpmPackagesFilters';
@ -249,11 +250,15 @@ const MarketPlacePage = () => {
);
};
const ProtectedMarketPlace = () => (
<CheckPagePermissions permissions={adminPermissions.marketplace.main}>
<MarketPlacePage />
</CheckPagePermissions>
);
const ProtectedMarketPlace = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.marketplace.main}>
<MarketPlacePage />
</CheckPagePermissions>
);
};
export { MarketPlacePage };
export default ProtectedMarketPlace;

View File

@ -15,11 +15,12 @@ import {
import { Formik } from 'formik';
import { useIntl } from 'react-intl';
import { useQuery } from 'react-query';
import { useSelector } from 'react-redux';
import { useHistory, useRouteMatch } from 'react-router-dom';
import { ApiTokenPermissionsContextProvider } from '../../../../../contexts/ApiTokenPermissions';
import adminPermissions from '../../../../../permissions';
import { formatAPIErrors } from '../../../../../utils';
import { selectAdminPermissions } from '../../../../App/selectors';
import { API_TOKEN_TYPE } from '../../../components/Tokens/constants';
import FormHead from '../../../components/Tokens/FormHead';
import TokenBox from '../../../components/Tokens/TokenBox';
@ -39,6 +40,7 @@ const ApiTokenCreateView = () => {
const { lockApp, unlockApp } = useOverlayBlocker();
const toggleNotification = useNotification();
const history = useHistory();
const permissions = useSelector(selectAdminPermissions);
const [apiToken, setApiToken] = useState(
history.location.state?.apiToken.accessKey
? {
@ -51,7 +53,7 @@ const ApiTokenCreateView = () => {
const { setCurrentStep } = useGuidedTour();
const {
allowedActions: { canCreate, canUpdate, canRegenerate },
} = useRBAC(adminPermissions.settings['api-tokens']);
} = useRBAC(permissions.settings['api-tokens']);
const [state, dispatch] = useReducer(reducer, initialState, (state) => init(state, {}));
const {
params: { id },

View File

@ -17,9 +17,10 @@ import { Plus } from '@strapi/icons';
import qs from 'qs';
import { useIntl } from 'react-intl';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import { API_TOKEN_TYPE } from '../../../components/Tokens/constants';
import Table from '../../../components/Tokens/Table';
@ -30,9 +31,10 @@ const ApiTokenListView = () => {
const queryClient = useQueryClient();
const { formatMessage } = useIntl();
const toggleNotification = useNotification();
const permissions = useSelector(selectAdminPermissions);
const {
allowedActions: { canCreate, canDelete, canUpdate, canRead },
} = useRBAC(adminPermissions.settings['api-tokens']);
} = useRBAC(permissions.settings['api-tokens']);
const { push } = useHistory();
const { trackUsage } = useTracking();
const { startSection } = useGuidedTour();

View File

@ -1,13 +1,16 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EditView from '../EditView';
const ProtectedApiTokenCreateView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={adminPermissions.settings['api-tokens'].create}>
<CheckPagePermissions permissions={permissions.settings['api-tokens'].create}>
<EditView />
</CheckPagePermissions>
);

View File

@ -1,13 +1,16 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EditView from '../EditView';
const ProtectedApiTokenCreateView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={adminPermissions.settings['api-tokens'].read}>
<CheckPagePermissions permissions={permissions.settings['api-tokens'].read}>
<EditView />
</CheckPagePermissions>
);

View File

@ -1,14 +1,19 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import ListView from '../ListView';
const ProtectedApiTokenListView = () => (
<CheckPagePermissions permissions={adminPermissions.settings['api-tokens'].main}>
<ListView />
</CheckPagePermissions>
);
const ProtectedApiTokenListView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings['api-tokens'].main}>
<ListView />
</CheckPagePermissions>
);
};
export default ProtectedApiTokenListView;

View File

@ -24,9 +24,10 @@ import { Check, ExternalLink } from '@strapi/icons';
import AdminSeatInfo from 'ee_else_ce/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo';
import { useIntl } from 'react-intl';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import { useSelector } from 'react-redux';
import { useConfigurations } from '../../../../hooks';
import adminPermissions from '../../../../permissions';
import { selectAdminPermissions } from '../../../App/selectors';
import CustomizationInfos from './components/CustomizationInfos';
import { fetchProjectSettings, postProjectSettings } from './utils/api';
@ -39,13 +40,19 @@ const ApplicationInfosPage = () => {
const { formatMessage } = useIntl();
const queryClient = useQueryClient();
useFocusWhenNavigate();
const appInfos = useAppInfo();
const { latestStrapiReleaseTag, shouldUpdateStrapi, strapiVersion } = appInfos;
const {
communityEdition,
latestStrapiReleaseTag,
nodeVersion,
shouldUpdateStrapi,
strapiVersion,
} = useAppInfo();
const { updateProjectSettings } = useConfigurations();
const permissions = useSelector(selectAdminPermissions);
const {
allowedActions: { canRead, canUpdate },
} = useRBAC(adminPermissions.settings['project-settings']);
} = useRBAC(permissions.settings['project-settings']);
const canSubmit = canRead && canUpdate;
const { data } = useQuery('project-settings', fetchProjectSettings, { enabled: canRead });
@ -174,7 +181,7 @@ const ApplicationInfosPage = () => {
defaultMessage:
'{communityEdition, select, true {Community Edition} other {Enterprise Edition}}',
},
{ communityEdition: appInfos.communityEdition }
{ communityEdition }
)}
</Typography>
<Link
@ -197,7 +204,7 @@ const ApplicationInfosPage = () => {
defaultMessage: 'node version',
})}
</Typography>
<Typography as="dd">{appInfos.nodeVersion}</Typography>
<Typography as="dd">{nodeVersion}</Typography>
</GridItem>
<AdminSeatInfo />
</Grid>

View File

@ -30,11 +30,12 @@ import { Formik } from 'formik';
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import { useHistory, useRouteMatch } from 'react-router-dom';
import styled from 'styled-components';
import { useFetchPermissionsLayout, useFetchRole } from '../../../../../hooks';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import Permissions from '../EditPage/components/Permissions';
import schema from './utils/schema';
@ -61,7 +62,6 @@ const CreatePage = () => {
const id = get(params, 'params.id', null);
const { isLoading: isLayoutLoading, data: permissionsLayout } = useFetchPermissionsLayout();
const { permissions: rolePermissions, isLoading: isRoleLoading } = useFetchRole(id);
const { post, put } = useFetchClient();
const handleCreateRoleSubmit = (data) => {
@ -257,8 +257,10 @@ const CreatePage = () => {
};
export default function () {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={adminPermissions.settings.roles.create}>
<CheckPagePermissions permissions={permissions.settings.roles.create}>
<CreatePage />
</CheckPagePermissions>
);

View File

@ -31,10 +31,11 @@ import {
import { Duplicate, Pencil, Plus, Trash } from '@strapi/icons';
import get from 'lodash/get';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { useRolesList } from '../../../../../hooks';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EmptyRole from './components/EmptyRole';
import BaseRoleRow from './components/RoleRow';
@ -43,10 +44,11 @@ import reducer, { initialState } from './reducer';
const useSortedRoles = () => {
useFocusWhenNavigate();
const { locale } = useIntl();
const permissions = useSelector(selectAdminPermissions);
const {
isLoading: isLoadingForPermissions,
allowedActions: { canCreate, canDelete, canRead, canUpdate },
} = useRBAC(adminPermissions.settings.roles);
} = useRBAC(permissions.settings.roles);
const { getData, roles, isLoading } = useRolesList(false);
const [{ query }] = useQueryParams();

View File

@ -1,23 +1,21 @@
import React, { useMemo } from 'react';
import React from 'react';
import { LoadingIndicatorPage, useRBAC } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import { Redirect } from 'react-router-dom';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EditPage from '../EditPage';
const ProtectedEditPage = () => {
const permissions = useMemo(() => {
return {
read: adminPermissions.settings.roles.read,
update: adminPermissions.settings.roles.update,
};
}, []);
const permissions = useSelector(selectAdminPermissions);
const {
isLoading,
allowedActions: { canRead, canUpdate },
} = useRBAC(permissions);
} = useRBAC({
read: permissions.settings.roles.read,
update: permissions.settings.roles.update,
});
if (isLoading) {
return <LoadingIndicatorPage />;

View File

@ -1,14 +1,19 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import ListPage from '../ListPage';
const ProtectedListPage = () => (
<CheckPagePermissions permissions={adminPermissions.settings.roles.main}>
<ListPage />
</CheckPagePermissions>
);
const ProtectedListPage = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings.roles.main}>
<ListPage />
</CheckPagePermissions>
);
};
export default ProtectedListPage;

View File

@ -16,10 +16,11 @@ import {
import { Formik } from 'formik';
import { useIntl } from 'react-intl';
import { useQuery } from 'react-query';
import { useSelector } from 'react-redux';
import { useHistory, useRouteMatch } from 'react-router-dom';
import adminPermissions from '../../../../../permissions';
import { formatAPIErrors } from '../../../../../utils';
import { selectAdminPermissions } from '../../../../App/selectors';
import { TRANSFER_TOKEN_TYPE } from '../../../components/Tokens/constants';
import FormHead from '../../../components/Tokens/FormHead';
import TokenBox from '../../../components/Tokens/TokenBox';
@ -46,9 +47,10 @@ const TransferTokenCreateView = () => {
const { trackUsage } = useTracking();
const trackUsageRef = useRef(trackUsage);
const { setCurrentStep } = useGuidedTour();
const permissions = useSelector(selectAdminPermissions);
const {
allowedActions: { canCreate, canUpdate, canRegenerate },
} = useRBAC(adminPermissions.settings['transfer-tokens']);
} = useRBAC(permissions.settings['transfer-tokens']);
const {
params: { id },
} = useRouteMatch('/settings/transfer-tokens/:id');

View File

@ -17,9 +17,10 @@ import { Plus } from '@strapi/icons';
import qs from 'qs';
import { useIntl } from 'react-intl';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import { TRANSFER_TOKEN_TYPE } from '../../../components/Tokens/constants';
import Table from '../../../components/Tokens/Table';
@ -30,9 +31,10 @@ const TransferTokenListView = () => {
const queryClient = useQueryClient();
const { formatMessage } = useIntl();
const toggleNotification = useNotification();
const permissions = useSelector(selectAdminPermissions);
const {
allowedActions: { canCreate, canDelete, canUpdate, canRead },
} = useRBAC(adminPermissions.settings['transfer-tokens']);
} = useRBAC(permissions.settings['transfer-tokens']);
const { push } = useHistory();
const { trackUsage } = useTracking();

View File

@ -1,13 +1,16 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EditView from '../EditView';
const ProtectedTransferTokenCreateView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={adminPermissions.settings['transfer-tokens'].create}>
<CheckPagePermissions permissions={permissions.settings['transfer-tokens'].create}>
<EditView />
</CheckPagePermissions>
);

View File

@ -1,13 +1,16 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EditView from '../EditView';
const ProtectedTransferTokenCreateView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={adminPermissions.settings['transfer-tokens'].read}>
<CheckPagePermissions permissions={permissions.settings['transfer-tokens'].read}>
<EditView />
</CheckPagePermissions>
);

View File

@ -1,14 +1,19 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import ListView from '../ListView';
const ProtectedTransferTokenListView = () => (
<CheckPagePermissions permissions={adminPermissions.settings['transfer-tokens'].main}>
<ListView />
</CheckPagePermissions>
);
const ProtectedTransferTokenListView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings['transfer-tokens'].main}>
<ListView />
</CheckPagePermissions>
);
};
export default ProtectedTransferTokenListView;

View File

@ -17,10 +17,11 @@ import CreateAction from 'ee_else_ce/pages/SettingsPage/pages/Users/ListPage/Cre
import qs from 'qs';
import { useIntl } from 'react-intl';
import { useMutation, useQueryClient } from 'react-query';
import { useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';
import { useAdminUsers } from '../../../../../hooks/useAdminUsers';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import Filters from '../../../components/Filters';
import TableRows from './DynamicTable/TableRows';
@ -35,9 +36,10 @@ const ListPage = () => {
const { post } = useFetchClient();
const { formatAPIError } = useAPIErrorHandler();
const [isModalOpened, setIsModalOpen] = useState(false);
const permissions = useSelector(selectAdminPermissions);
const {
allowedActions: { canCreate, canDelete, canRead },
} = useRBAC(adminPermissions.settings.users);
} = useRBAC(permissions.settings.users);
const queryClient = useQueryClient();
const toggleNotification = useNotification();
const { formatMessage } = useIntl();

View File

@ -1,24 +1,22 @@
import React, { useEffect, useMemo } from 'react';
import React, { useEffect } from 'react';
import { LoadingIndicatorPage, useNotification, useRBAC } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import { Redirect, useLocation } from 'react-router-dom';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EditPage from '../EditPage';
const ProtectedEditPage = () => {
const toggleNotification = useNotification();
const permissions = useMemo(() => {
return {
read: adminPermissions.settings.users.read,
update: adminPermissions.settings.users.update,
};
}, []);
const permissions = useSelector(selectAdminPermissions);
const {
isLoading,
allowedActions: { canRead, canUpdate },
} = useRBAC(permissions);
} = useRBAC({
read: permissions.settings.users.read,
update: permissions.settings.users.update,
});
const { state } = useLocation();
const from = state?.from ?? '/';

View File

@ -1,14 +1,19 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import ListPage from '../ListPage';
const ProtectedListPage = () => (
<CheckPagePermissions permissions={adminPermissions.settings.users.main}>
<ListPage />
</CheckPagePermissions>
);
const ProtectedListPage = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings.users.main}>
<ListPage />
</CheckPagePermissions>
);
};
export default ProtectedListPage;

View File

@ -41,14 +41,15 @@ import {
import { EmptyDocuments, Pencil, Plus, Trash } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { useMutation, useQuery } from 'react-query';
import { useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
const ListView = () => {
const [showModal, setShowModal] = useState(false);
const [webhooksToDelete, setWebhooksToDelete] = useState([]);
const permissions = useSelector(selectAdminPermissions);
const { formatMessage } = useIntl();
const { formatAPIError } = useAPIErrorHandler();
const toggleNotification = useNotification();
@ -59,7 +60,7 @@ const ListView = () => {
const {
isLoading: isRBACLoading,
allowedActions: { canCreate, canUpdate, canDelete },
} = useRBAC(adminPermissions.settings.webhooks);
} = useRBAC(permissions.settings.webhooks);
const { get, post, put } = useFetchClient();
const { notifyStatus } = useNotifyAT();

View File

@ -1,14 +1,19 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EditView from '../EditView';
const ProtectedCreateView = () => (
<CheckPagePermissions permissions={adminPermissions.settings.webhooks.create}>
<EditView />
</CheckPagePermissions>
);
const ProtectedCreateView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings.webhooks.create}>
<EditView />
</CheckPagePermissions>
);
};
export default ProtectedCreateView;

View File

@ -1,14 +1,19 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import EditView from '../EditView';
const ProtectedEditView = () => (
<CheckPagePermissions permissions={adminPermissions.settings.webhooks.update}>
<EditView />
</CheckPagePermissions>
);
const ProtectedEditView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings.webhooks.update}>
<EditView />
</CheckPagePermissions>
);
};
export default ProtectedEditView;

View File

@ -1,14 +1,19 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../permissions';
import { selectAdminPermissions } from '../../../../App/selectors';
import ListView from '../ListView';
const ProtectedListView = () => (
<CheckPagePermissions permissions={adminPermissions.settings.webhooks.main}>
<ListView />
</CheckPagePermissions>
);
const ProtectedListView = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings.webhooks.main}>
<ListView />
</CheckPagePermissions>
);
};
export default ProtectedListView;

View File

@ -0,0 +1,16 @@
export const ADMIN_PERMISSIONS_EE = {
settings: {
auditLogs: {
main: [{ action: 'admin::audit-logs.read', subject: null }],
read: [{ action: 'admin::audit-logs.read', subject: null }],
},
'review-workflows': {
main: [{ action: 'admin::review-workflows.read', subject: null }],
},
sso: {
main: [{ action: 'admin::provider-login.read', subject: null }],
read: [{ action: 'admin::provider-login.read', subject: null }],
update: [{ action: 'admin::provider-login.update', subject: null }],
},
},
};

View File

@ -17,9 +17,10 @@ import {
useRBAC,
} from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import { selectAdminPermissions } from '../../../../../../../admin/src/pages/App/selectors';
import Filters from '../../../../../../../admin/src/pages/SettingsPage/components/Filters';
import adminPermissions from '../../../../../../../admin/src/permissions';
import useAuditLogsData from './hooks/useAuditLogsData';
import Modal from './Modal';
@ -28,17 +29,15 @@ import TableRows from './TableRows';
import getDisplayedFilters from './utils/getDisplayedFilters';
import tableHeaders from './utils/tableHeaders';
const auditLogsPermissions = {
...adminPermissions.settings.auditLogs,
readUsers: adminPermissions.settings.users.read,
};
const ListView = () => {
const { formatMessage } = useIntl();
const permissions = useSelector(selectAdminPermissions);
const {
allowedActions: { canRead: canReadAuditLogs, canReadUsers },
} = useRBAC(auditLogsPermissions);
} = useRBAC({
...permissions.settings.auditLogs,
readUsers: permissions.settings.users.read,
});
const [{ query }, setQuery] = useQueryParams();
const { auditLogs, users, isLoading, hasError } = useAuditLogsData({

View File

@ -1,14 +1,19 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import adminPermissions from '../../../../../../../admin/src/permissions';
import { selectAdminPermissions } from '../../../../../../../admin/src/pages/App/selectors';
import ListView from '../ListView';
const ProtectedListPage = () => (
<CheckPagePermissions permissions={adminPermissions.settings.auditLogs.main}>
<ListView />
</CheckPagePermissions>
);
const ProtectedListPage = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings.auditLogs.main}>
<ListView />
</CheckPagePermissions>
);
};
export default ProtectedListPage;

View File

@ -0,0 +1,20 @@
import React from 'react';
import { CheckPagePermissions } from '@strapi/helper-plugin';
import { useSelector } from 'react-redux';
import { selectAdminPermissions } from '../../../../../../admin/src/pages/App/selectors';
import { ReviewWorkflowsPage } from './ReviewWorkflows';
const ProtectedListPage = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.settings['review-workflows'].main}>
<ReviewWorkflowsPage />
</CheckPagePermissions>
);
};
export default ProtectedListPage;

View File

@ -2,7 +2,6 @@ import React, { useEffect, useState } from 'react';
import { Button, ContentLayout, HeaderLayout, Layout, Loader, Main } from '@strapi/design-system';
import {
CheckPagePermissions,
ConfirmDialog,
SettingsPageTitle,
useAPIErrorHandler,
@ -18,7 +17,6 @@ import { useDispatch, useSelector } from 'react-redux';
import { DragLayer } from '../../../../../../admin/src/components/DragLayer';
import { useInjectReducer } from '../../../../../../admin/src/hooks/useInjectReducer';
import adminPermissions from '../../../../../../admin/src/permissions';
import { setWorkflows } from './actions';
import { StageDragPreview } from './components/StageDragPreview';
@ -57,7 +55,6 @@ export function ReviewWorkflowsPage() {
},
} = useSelector((state) => state?.[REDUX_NAMESPACE] ?? initialState);
const [isConfirmDeleteDialogOpen, setIsConfirmDeleteDialogOpen] = useState(false);
const { mutateAsync, isLoading } = useMutation(
async ({ workflowId, stages }) => {
const {
@ -134,76 +131,74 @@ export function ReviewWorkflowsPage() {
}, []);
return (
<CheckPagePermissions permissions={adminPermissions.settings['review-workflows'].main}>
<Layout>
<SettingsPageTitle
name={formatMessage({
id: 'Settings.review-workflows.page.title',
defaultMessage: 'Review Workflows',
})}
<Layout>
<SettingsPageTitle
name={formatMessage({
id: 'Settings.review-workflows.page.title',
defaultMessage: 'Review Workflows',
})}
/>
<Main tabIndex={-1}>
<DragLayer renderItem={renderDragLayerItem} />
<FormikProvider value={formik}>
<Form onSubmit={formik.handleSubmit}>
<HeaderLayout
primaryAction={
<Button
startIcon={<Check />}
type="submit"
size="M"
disabled={!currentWorkflowIsDirty}
// if the confirm dialog is open the loading state is on
// the confirm button already
loading={!isConfirmDeleteDialogOpen && isLoading}
>
{formatMessage({
id: 'global.save',
defaultMessage: 'Save',
})}
</Button>
}
title={formatMessage({
id: 'Settings.review-workflows.page.title',
defaultMessage: 'Review Workflows',
})}
subtitle={formatMessage(
{
id: 'Settings.review-workflows.page.subtitle',
defaultMessage: '{count, plural, one {# stage} other {# stages}}',
},
{ count: currentWorkflow?.stages?.length ?? 0 }
)}
/>
<ContentLayout>
{status === 'loading' && (
<Loader>
{formatMessage({
id: 'Settings.review-workflows.page.isLoading',
defaultMessage: 'Workflow is loading',
})}
</Loader>
)}
<Stages stages={formik.values?.stages} />
</ContentLayout>
</Form>
</FormikProvider>
<ConfirmDialog
bodyText={{
id: 'Settings.review-workflows.page.delete.confirm.body',
defaultMessage:
'All entries assigned to deleted stages will be moved to the previous stage. Are you sure you want to save?',
}}
isConfirmButtonLoading={isLoading}
isOpen={isConfirmDeleteDialogOpen}
onToggleDialog={toggleConfirmDeleteDialog}
onConfirm={handleConfirmDeleteDialog}
/>
<Main tabIndex={-1}>
<DragLayer renderItem={renderDragLayerItem} />
<FormikProvider value={formik}>
<Form onSubmit={formik.handleSubmit}>
<HeaderLayout
primaryAction={
<Button
startIcon={<Check />}
type="submit"
size="M"
disabled={!currentWorkflowIsDirty}
// if the confirm dialog is open the loading state is on
// the confirm button already
loading={!isConfirmDeleteDialogOpen && isLoading}
>
{formatMessage({
id: 'global.save',
defaultMessage: 'Save',
})}
</Button>
}
title={formatMessage({
id: 'Settings.review-workflows.page.title',
defaultMessage: 'Review Workflows',
})}
subtitle={formatMessage(
{
id: 'Settings.review-workflows.page.subtitle',
defaultMessage: '{count, plural, one {# stage} other {# stages}}',
},
{ count: currentWorkflow?.stages?.length ?? 0 }
)}
/>
<ContentLayout>
{status === 'loading' && (
<Loader>
{formatMessage({
id: 'Settings.review-workflows.page.isLoading',
defaultMessage: 'Workflow is loading',
})}
</Loader>
)}
<Stages stages={formik.values?.stages} />
</ContentLayout>
</Form>
</FormikProvider>
<ConfirmDialog
bodyText={{
id: 'Settings.review-workflows.page.delete.confirm.body',
defaultMessage:
'All entries assigned to deleted stages will be moved to the previous stage. Are you sure you want to save?',
}}
isConfirmButtonLoading={isLoading}
isOpen={isConfirmDeleteDialogOpen}
onToggleDialog={toggleConfirmDeleteDialog}
onConfirm={handleConfirmDeleteDialog}
/>
</Main>
</Layout>
</CheckPagePermissions>
</Main>
</Layout>
);
}

View File

@ -26,25 +26,25 @@ import {
import { Check } from '@strapi/icons';
import isEqual from 'lodash/isEqual';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import { useRolesList, useSettingsForm } from '../../../../../../admin/src/hooks';
import adminPermissions from '../../../../../../admin/src/permissions';
import { selectAdminPermissions } from '../../../../../../admin/src/pages/App/selectors';
import { getRequestUrl } from '../../../../../../admin/src/utils';
import schema from './utils/schema';
const ssoPermissions = {
...adminPermissions.settings.sso,
readRoles: adminPermissions.settings.roles.read,
};
export const SingleSignOn = () => {
const { formatMessage } = useIntl();
const permissions = useSelector(selectAdminPermissions);
const {
isLoading: isLoadingForPermissions,
allowedActions: { canUpdate, canReadRoles },
} = useRBAC(ssoPermissions);
} = useRBAC({
...permissions.settings.sso,
readRoles: permissions.settings.roles.read,
});
const [
{ formErrors, initialData, isLoading, modifiedData, showHeaderButtonLoader },
@ -247,10 +247,14 @@ export const SingleSignOn = () => {
);
};
const ProtectedSSO = () => (
<CheckPagePermissions permissions={ssoPermissions.main}>
<SingleSignOn />
</CheckPagePermissions>
);
const ProtectedSSO = () => {
const permissions = useSelector(selectAdminPermissions);
return (
<CheckPagePermissions permissions={permissions.sso.main}>
<SingleSignOn />
</CheckPagePermissions>
);
};
export default ProtectedSSO;