@strapi/plugin-users-permissions 4.11.1 → 4.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/admin/src/components/BoundRoute/index.js +5 -3
  2. package/admin/src/components/FormModal/Input/index.js +3 -2
  3. package/admin/src/components/FormModal/index.js +13 -10
  4. package/admin/src/components/Permissions/PermissionRow/CheckboxWrapper.js +1 -1
  5. package/admin/src/components/Permissions/PermissionRow/SubCategory.js +26 -5
  6. package/admin/src/components/Permissions/PermissionRow/index.js +4 -2
  7. package/admin/src/components/Permissions/index.js +5 -2
  8. package/admin/src/components/Policies/index.js +3 -2
  9. package/admin/src/components/UsersPermissions/index.js +8 -5
  10. package/admin/src/contexts/UsersPermissionsContext/index.js +1 -0
  11. package/admin/src/hooks/index.js +1 -1
  12. package/admin/src/hooks/useFetchRole/index.js +6 -3
  13. package/admin/src/hooks/useForm/index.js +4 -1
  14. package/admin/src/hooks/usePlugins.js +71 -0
  15. package/admin/src/hooks/useRolesList/index.js +4 -1
  16. package/admin/src/index.js +2 -0
  17. package/admin/src/pages/AdvancedSettings/index.js +21 -18
  18. package/admin/src/pages/AdvancedSettings/utils/api.js +1 -0
  19. package/admin/src/pages/AdvancedSettings/utils/schema.js +1 -1
  20. package/admin/src/pages/EmailTemplates/components/EmailForm.js +13 -12
  21. package/admin/src/pages/EmailTemplates/components/EmailTable.js +9 -7
  22. package/admin/src/pages/EmailTemplates/index.js +12 -9
  23. package/admin/src/pages/EmailTemplates/utils/api.js +1 -0
  24. package/admin/src/pages/EmailTemplates/utils/schema.js +1 -1
  25. package/admin/src/pages/Providers/index.js +29 -26
  26. package/admin/src/pages/Providers/utils/api.js +1 -0
  27. package/admin/src/pages/Providers/utils/forms.js +1 -1
  28. package/admin/src/pages/Roles/{CreatePage/index.js → CreatePage.js} +25 -22
  29. package/admin/src/pages/Roles/{EditPage/index.js → EditPage.js} +22 -19
  30. package/admin/src/pages/Roles/ListPage/components/TableBody.js +4 -3
  31. package/admin/src/pages/Roles/ListPage/index.js +20 -18
  32. package/admin/src/pages/Roles/ListPage/utils/api.js +2 -1
  33. package/admin/src/pages/Roles/{ProtectedCreatePage/index.js → ProtectedCreatePage.js} +5 -2
  34. package/admin/src/pages/Roles/{ProtectedEditPage/index.js → ProtectedEditPage.js} +5 -2
  35. package/admin/src/pages/Roles/{ProtectedListPage/index.js → ProtectedListPage.js} +4 -2
  36. package/admin/src/pages/Roles/{CreatePage/utils/schema.js → constants.js} +2 -4
  37. package/admin/src/pages/Roles/index.js +8 -5
  38. package/admin/src/utils/index.js +1 -1
  39. package/jest.config.front.js +1 -0
  40. package/package.json +4 -5
  41. package/server/strategies/users-permissions.js +1 -8
  42. package/admin/src/hooks/usePlugins/index.js +0 -67
  43. package/admin/src/hooks/usePlugins/init.js +0 -5
  44. package/admin/src/hooks/usePlugins/reducer.js +0 -34
  45. package/admin/src/pages/Roles/EditPage/utils/schema.js +0 -9
@@ -1,10 +1,12 @@
1
1
  import React from 'react';
2
- import styled from 'styled-components';
3
- import { Flex, Box, Typography } from '@strapi/design-system';
2
+
3
+ import { Box, Flex, Typography } from '@strapi/design-system';
4
4
  import map from 'lodash/map';
5
5
  import tail from 'lodash/tail';
6
- import { useIntl } from 'react-intl';
7
6
  import PropTypes from 'prop-types';
7
+ import { useIntl } from 'react-intl';
8
+ import styled from 'styled-components';
9
+
8
10
  import getMethodColor from './getMethodColor';
9
11
 
10
12
  const MethodBox = styled(Box)`
@@ -5,9 +5,10 @@
5
5
  */
6
6
 
7
7
  import React from 'react';
8
- import { useIntl } from 'react-intl';
9
- import { ToggleInput, TextInput } from '@strapi/design-system';
8
+
9
+ import { TextInput, ToggleInput } from '@strapi/design-system';
10
10
  import PropTypes from 'prop-types';
11
+ import { useIntl } from 'react-intl';
11
12
 
12
13
  const Input = ({
13
14
  description,
@@ -5,22 +5,23 @@
5
5
  */
6
6
 
7
7
  import React from 'react';
8
- import { useIntl } from 'react-intl';
8
+
9
9
  import {
10
10
  Button,
11
11
  Flex,
12
- Breadcrumbs,
13
- Crumb,
14
12
  Grid,
15
13
  GridItem,
16
- ModalLayout,
17
- ModalHeader,
18
- ModalFooter,
19
14
  ModalBody,
15
+ ModalFooter,
16
+ ModalHeader,
17
+ ModalLayout,
20
18
  } from '@strapi/design-system';
21
- import PropTypes from 'prop-types';
22
- import { Formik } from 'formik';
19
+ import { Breadcrumbs, Crumb } from '@strapi/design-system/v2';
23
20
  import { Form } from '@strapi/helper-plugin';
21
+ import { Formik } from 'formik';
22
+ import PropTypes from 'prop-types';
23
+ import { useIntl } from 'react-intl';
24
+
24
25
  import Input from './Input';
25
26
 
26
27
  const FormModal = ({
@@ -43,8 +44,10 @@ const FormModal = ({
43
44
  <ModalLayout onClose={onToggle} labelledBy="title">
44
45
  <ModalHeader>
45
46
  <Breadcrumbs label={headerBreadcrumbs.join(', ')}>
46
- {headerBreadcrumbs.map((crumb) => (
47
- <Crumb key={crumb}>{crumb}</Crumb>
47
+ {headerBreadcrumbs.map((crumb, index, arr) => (
48
+ <Crumb isCurrent={index === arr.length - 1} key={crumb}>
49
+ {crumb}
50
+ </Crumb>
48
51
  ))}
49
52
  </Breadcrumbs>
50
53
  </ModalHeader>
@@ -1,5 +1,5 @@
1
- import styled, { css } from 'styled-components';
2
1
  import { Box } from '@strapi/design-system';
2
+ import styled, { css } from 'styled-components';
3
3
 
4
4
  const activeCheckboxWrapperStyles = css`
5
5
  background: ${(props) => props.theme.colors.primary100};
@@ -1,13 +1,24 @@
1
1
  import React, { useCallback, useMemo } from 'react';
2
+
3
+ import {
4
+ Box,
5
+ Checkbox,
6
+ Flex,
7
+ Typography,
8
+ Grid,
9
+ GridItem,
10
+ VisuallyHidden,
11
+ } from '@strapi/design-system';
12
+ import { Cog as CogIcon } from '@strapi/icons';
2
13
  import get from 'lodash/get';
3
- import styled from 'styled-components';
4
14
  import PropTypes from 'prop-types';
5
- import { Box, Checkbox, Flex, Typography, Grid, GridItem } from '@strapi/design-system';
6
- import { Cog as CogIcon } from '@strapi/icons';
7
15
  import { useIntl } from 'react-intl';
8
- import CheckboxWrapper from './CheckboxWrapper';
16
+ import styled from 'styled-components';
17
+
9
18
  import { useUsersPermissions } from '../../../contexts/UsersPermissionsContext';
10
19
 
20
+ import CheckboxWrapper from './CheckboxWrapper';
21
+
11
22
  const Border = styled.div`
12
23
  flex: 1;
13
24
  align-self: center;
@@ -87,10 +98,20 @@ const SubCategory = ({ subCategory }) => {
87
98
  </Checkbox>
88
99
  <button
89
100
  type="button"
90
- data-testid="action-cog"
91
101
  onClick={() => onSelectedAction(action.name)}
92
102
  style={{ display: 'inline-flex', alignItems: 'center' }}
93
103
  >
104
+ <VisuallyHidden as="span">
105
+ {formatMessage(
106
+ {
107
+ id: 'app.utils.show-bound-route',
108
+ defaultMessage: 'Show bound route for {route}',
109
+ },
110
+ {
111
+ route: action.name,
112
+ }
113
+ )}
114
+ </VisuallyHidden>
94
115
  <CogIcon />
95
116
  </button>
96
117
  </CheckboxWrapper>
@@ -1,7 +1,9 @@
1
1
  import React, { useMemo } from 'react';
2
- import PropTypes from 'prop-types';
3
- import sortBy from 'lodash/sortBy';
2
+
4
3
  import { Box } from '@strapi/design-system';
4
+ import sortBy from 'lodash/sortBy';
5
+ import PropTypes from 'prop-types';
6
+
5
7
  import SubCategory from './SubCategory';
6
8
 
7
9
  const PermissionRow = ({ name, permissions }) => {
@@ -1,10 +1,13 @@
1
1
  import React, { useReducer } from 'react';
2
- import { Accordion, AccordionToggle, AccordionContent, Box, Flex } from '@strapi/design-system';
2
+
3
+ import { Accordion, AccordionContent, AccordionToggle, Box, Flex } from '@strapi/design-system';
3
4
  import { useIntl } from 'react-intl';
5
+
4
6
  import { useUsersPermissions } from '../../contexts/UsersPermissionsContext';
5
7
  import formatPluginName from '../../utils/formatPluginName';
6
- import PermissionRow from './PermissionRow';
8
+
7
9
  import init from './init';
10
+ import PermissionRow from './PermissionRow';
8
11
  import { initialState, reducer } from './reducer';
9
12
 
10
13
  const Permissions = () => {
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
- import { useIntl } from 'react-intl';
3
- import { Typography, Flex, GridItem } from '@strapi/design-system';
2
+
3
+ import { Flex, GridItem, Typography } from '@strapi/design-system';
4
4
  import get from 'lodash/get';
5
5
  import isEmpty from 'lodash/isEmpty';
6
6
  import without from 'lodash/without';
7
+ import { useIntl } from 'react-intl';
7
8
 
8
9
  import { useUsersPermissions } from '../../contexts/UsersPermissionsContext';
9
10
  import BoundRoute from '../BoundRoute';
@@ -1,13 +1,16 @@
1
- import React, { memo, useReducer, forwardRef, useImperativeHandle } from 'react';
1
+ import React, { forwardRef, memo, useImperativeHandle, useReducer } from 'react';
2
+
3
+ import { Flex, Grid, GridItem, Typography } from '@strapi/design-system';
2
4
  import PropTypes from 'prop-types';
3
- import { Typography, Flex, Grid, GridItem } from '@strapi/design-system';
4
5
  import { useIntl } from 'react-intl';
6
+
7
+ import { UsersPermissionsProvider } from '../../contexts/UsersPermissionsContext';
5
8
  import getTrad from '../../utils/getTrad';
6
- import Policies from '../Policies';
7
9
  import Permissions from '../Permissions';
8
- import reducer, { initialState } from './reducer';
9
- import { UsersPermissionsProvider } from '../../contexts/UsersPermissionsContext';
10
+ import Policies from '../Policies';
11
+
10
12
  import init from './init';
13
+ import reducer, { initialState } from './reducer';
11
14
 
12
15
  const UsersPermissions = forwardRef(({ permissions, routes }, ref) => {
13
16
  const { formatMessage } = useIntl();
@@ -1,4 +1,5 @@
1
1
  import React, { createContext, useContext } from 'react';
2
+
2
3
  import PropTypes from 'prop-types';
3
4
 
4
5
  const UsersPermissions = createContext({});
@@ -1,5 +1,5 @@
1
1
  // eslint-disable-next-line import/prefer-default-export
2
2
  export { default as useForm } from './useForm';
3
3
  export { default as useRolesList } from './useRolesList';
4
- export { default as usePlugins } from './usePlugins';
4
+ export * from './usePlugins';
5
5
  export { default as useFetchRole } from './useFetchRole';
@@ -1,8 +1,11 @@
1
- import { useCallback, useReducer, useEffect, useRef } from 'react';
2
- import { useNotification, useFetchClient } from '@strapi/helper-plugin';
3
- import reducer, { initialState } from './reducer';
1
+ import { useCallback, useEffect, useReducer, useRef } from 'react';
2
+
3
+ import { useFetchClient, useNotification } from '@strapi/helper-plugin';
4
+
4
5
  import pluginId from '../../pluginId';
5
6
 
7
+ import reducer, { initialState } from './reducer';
8
+
6
9
  const useFetchRole = (id) => {
7
10
  const [state, dispatch] = useReducer(reducer, initialState);
8
11
  const toggleNotification = useNotification();
@@ -1,6 +1,9 @@
1
1
  import { useCallback, useEffect, useReducer, useRef } from 'react';
2
- import { useRBAC, useFetchClient, useNotification } from '@strapi/helper-plugin';
2
+
3
+ import { useFetchClient, useNotification, useRBAC } from '@strapi/helper-plugin';
4
+
3
5
  import { getRequestURL } from '../../utils';
6
+
4
7
  import reducer, { initialState } from './reducer';
5
8
 
6
9
  const useUserForm = (endPoint, permissions) => {
@@ -0,0 +1,71 @@
1
+ import { useEffect } from 'react';
2
+
3
+ import { useNotification, useFetchClient, useAPIErrorHandler } from '@strapi/helper-plugin';
4
+ import { useQueries } from 'react-query';
5
+
6
+ import pluginId from '../pluginId';
7
+ import { cleanPermissions, getTrad } from '../utils';
8
+
9
+ export const usePlugins = () => {
10
+ const toggleNotification = useNotification();
11
+ const { get } = useFetchClient();
12
+ const { formatAPIError } = useAPIErrorHandler(getTrad);
13
+
14
+ const [
15
+ {
16
+ data: permissions,
17
+ isLoading: isLoadingPermissions,
18
+ error: permissionsError,
19
+ refetch: refetchPermissions,
20
+ },
21
+ { data: routes, isLoading: isLoadingRoutes, error: routesError, refetch: refetchRoutes },
22
+ ] = useQueries([
23
+ {
24
+ queryKey: [pluginId, 'permissions'],
25
+ async queryFn() {
26
+ const res = await get(`/${pluginId}/permissions`);
27
+
28
+ return res.data.permissions;
29
+ },
30
+ },
31
+ {
32
+ queryKey: [pluginId, 'routes'],
33
+ async queryFn() {
34
+ const res = await get(`/${pluginId}/routes`);
35
+
36
+ return res.data.routes;
37
+ },
38
+ },
39
+ ]);
40
+
41
+ const refetchQueries = async () => {
42
+ await Promise.all([refetchPermissions(), refetchRoutes()]);
43
+ };
44
+
45
+ useEffect(() => {
46
+ if (permissionsError) {
47
+ toggleNotification({
48
+ type: 'warning',
49
+ message: formatAPIError(permissionsError),
50
+ });
51
+ }
52
+ }, [toggleNotification, permissionsError, formatAPIError]);
53
+
54
+ useEffect(() => {
55
+ if (routesError) {
56
+ toggleNotification({
57
+ type: 'warning',
58
+ message: formatAPIError(routesError),
59
+ });
60
+ }
61
+ }, [toggleNotification, routesError, formatAPIError]);
62
+
63
+ const isLoading = isLoadingPermissions || isLoadingRoutes;
64
+
65
+ return {
66
+ permissions: permissions ? cleanPermissions(permissions) : {},
67
+ routes: routes ?? {},
68
+ getData: refetchQueries,
69
+ isLoading,
70
+ };
71
+ };
@@ -1,8 +1,11 @@
1
1
  import { useCallback, useEffect, useReducer, useRef } from 'react';
2
+
2
3
  import { useFetchClient, useNotification } from '@strapi/helper-plugin';
3
4
  import get from 'lodash/get';
4
- import init from './init';
5
+
5
6
  import pluginId from '../../pluginId';
7
+
8
+ import init from './init';
6
9
  import reducer, { initialState } from './reducer';
7
10
 
8
11
  const useRolesList = (shouldFetchData = true) => {
@@ -5,7 +5,9 @@
5
5
  // Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
6
6
  // IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
7
7
  import { prefixPluginTranslations } from '@strapi/helper-plugin';
8
+
8
9
  import pluginPkg from '../../package.json';
10
+
9
11
  import pluginPermissions from './permissions';
10
12
  import pluginId from './pluginId';
11
13
  import getTrad from './utils/getTrad';
@@ -1,7 +1,19 @@
1
1
  import React, { useMemo } from 'react';
2
- import { useQuery, useMutation, useQueryClient } from 'react-query';
3
- import { useIntl } from 'react-intl';
4
- import { Formik } from 'formik';
2
+
3
+ import {
4
+ Box,
5
+ Button,
6
+ ContentLayout,
7
+ Flex,
8
+ Grid,
9
+ GridItem,
10
+ HeaderLayout,
11
+ Main,
12
+ Option,
13
+ Select,
14
+ Typography,
15
+ useNotifyAT,
16
+ } from '@strapi/design-system';
5
17
  import {
6
18
  CheckPagePermissions,
7
19
  Form,
@@ -13,26 +25,17 @@ import {
13
25
  useOverlayBlocker,
14
26
  useRBAC,
15
27
  } from '@strapi/helper-plugin';
16
- import {
17
- useNotifyAT,
18
- Main,
19
- HeaderLayout,
20
- ContentLayout,
21
- Button,
22
- Box,
23
- Flex,
24
- Select,
25
- Option,
26
- Typography,
27
- Grid,
28
- GridItem,
29
- } from '@strapi/design-system';
30
28
  import { Check } from '@strapi/icons';
29
+ import { Formik } from 'formik';
30
+ import { useIntl } from 'react-intl';
31
+ import { useMutation, useQuery, useQueryClient } from 'react-query';
32
+
31
33
  import pluginPermissions from '../../permissions';
32
34
  import { getTrad } from '../../utils';
35
+
36
+ import { fetchData, putAdvancedSettings } from './utils/api';
33
37
  import layout from './utils/layout';
34
38
  import schema from './utils/schema';
35
- import { fetchData, putAdvancedSettings } from './utils/api';
36
39
 
37
40
  const ProtectedAdvancedSettingsPage = () => (
38
41
  <CheckPagePermissions permissions={pluginPermissions.readAdvancedSettings}>
@@ -1,4 +1,5 @@
1
1
  import { getFetchClient } from '@strapi/helper-plugin';
2
+
2
3
  import { getRequestURL } from '../../../utils';
3
4
 
4
5
  const fetchData = async () => {
@@ -1,5 +1,5 @@
1
- import * as yup from 'yup';
2
1
  import { translatedErrors } from '@strapi/helper-plugin';
2
+ import * as yup from 'yup';
3
3
 
4
4
  // eslint-disable-next-line prefer-regex-literals
5
5
  const URL_REGEX = new RegExp('(^$)|((.+:\\/\\/.*)(d*)\\/?(.*))');
@@ -1,20 +1,21 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useIntl } from 'react-intl';
4
- import { Form, GenericInput } from '@strapi/helper-plugin';
5
- import { Formik } from 'formik';
2
+
6
3
  import {
7
- ModalLayout,
8
- ModalHeader,
9
- ModalFooter,
10
- ModalBody,
4
+ Button,
11
5
  Grid,
12
6
  GridItem,
13
- Button,
14
- Breadcrumbs,
15
- Crumb,
7
+ ModalBody,
8
+ ModalFooter,
9
+ ModalHeader,
10
+ ModalLayout,
16
11
  Textarea,
17
12
  } from '@strapi/design-system';
13
+ import { Breadcrumbs, Crumb } from '@strapi/design-system/v2';
14
+ import { Form, GenericInput } from '@strapi/helper-plugin';
15
+ import { Formik } from 'formik';
16
+ import PropTypes from 'prop-types';
17
+ import { useIntl } from 'react-intl';
18
+
18
19
  import { getTrad } from '../../../utils';
19
20
  import schema from '../utils/schema';
20
21
 
@@ -45,7 +46,7 @@ const EmailForm = ({ template, onToggle, onSubmit }) => {
45
46
  defaultMessage: 'Edit email template',
46
47
  })}
47
48
  </Crumb>
48
- <Crumb>
49
+ <Crumb isCurrent>
49
50
  {formatMessage({ id: getTrad(template.display), defaultMessage: template.display })}
50
51
  </Crumb>
51
52
  </Breadcrumbs>
@@ -1,20 +1,22 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useIntl } from 'react-intl';
2
+
4
3
  import {
4
+ Icon,
5
+ IconButton,
5
6
  Table,
6
- Thead,
7
7
  Tbody,
8
- Tr,
9
8
  Td,
10
9
  Th,
10
+ Thead,
11
+ Tr,
11
12
  Typography,
12
- IconButton,
13
- Icon,
14
13
  VisuallyHidden,
15
14
  } from '@strapi/design-system';
16
- import { Pencil, Refresh, Check } from '@strapi/icons';
17
15
  import { onRowClick, stopPropagation } from '@strapi/helper-plugin';
16
+ import { Check, Pencil, Refresh } from '@strapi/icons';
17
+ import PropTypes from 'prop-types';
18
+ import { useIntl } from 'react-intl';
19
+
18
20
  import { getTrad } from '../../../utils';
19
21
 
20
22
  const EmailTable = ({ canUpdate, onEditClick }) => {
@@ -1,22 +1,25 @@
1
1
  import React, { useMemo, useRef, useState } from 'react';
2
- import { useQuery, useMutation, useQueryClient } from 'react-query';
3
- import { useIntl } from 'react-intl';
2
+
3
+ import { ContentLayout, HeaderLayout, Main, useNotifyAT } from '@strapi/design-system';
4
4
  import {
5
+ CheckPagePermissions,
6
+ LoadingIndicatorPage,
5
7
  SettingsPageTitle,
6
- useTracking,
8
+ useFocusWhenNavigate,
7
9
  useNotification,
8
10
  useOverlayBlocker,
9
- CheckPagePermissions,
10
11
  useRBAC,
11
- useFocusWhenNavigate,
12
- LoadingIndicatorPage,
12
+ useTracking,
13
13
  } from '@strapi/helper-plugin';
14
- import { useNotifyAT, Main, ContentLayout, HeaderLayout } from '@strapi/design-system';
14
+ import { useIntl } from 'react-intl';
15
+ import { useMutation, useQuery, useQueryClient } from 'react-query';
16
+
15
17
  import pluginPermissions from '../../permissions';
16
18
  import { getTrad } from '../../utils';
17
- import { fetchData, putEmailTemplate } from './utils/api';
18
- import EmailTable from './components/EmailTable';
19
+
19
20
  import EmailForm from './components/EmailForm';
21
+ import EmailTable from './components/EmailTable';
22
+ import { fetchData, putEmailTemplate } from './utils/api';
20
23
 
21
24
  const ProtectedEmailTemplatesPage = () => (
22
25
  <CheckPagePermissions permissions={pluginPermissions.readEmailTemplates}>
@@ -1,4 +1,5 @@
1
1
  import { getFetchClient } from '@strapi/helper-plugin';
2
+
2
3
  import { getRequestURL } from '../../../utils';
3
4
 
4
5
  const fetchData = async () => {
@@ -1,5 +1,5 @@
1
- import * as yup from 'yup';
2
1
  import { translatedErrors } from '@strapi/helper-plugin';
2
+ import * as yup from 'yup';
3
3
 
4
4
  const schema = yup.object().shape({
5
5
  options: yup
@@ -1,43 +1,46 @@
1
1
  import React, { useMemo, useRef, useState } from 'react';
2
- import { useIntl } from 'react-intl';
3
- import {
4
- SettingsPageTitle,
5
- LoadingIndicatorPage,
6
- useTracking,
7
- useNotification,
8
- useOverlayBlocker,
9
- CheckPagePermissions,
10
- useRBAC,
11
- useFocusWhenNavigate,
12
- onRowClick,
13
- stopPropagation,
14
- } from '@strapi/helper-plugin';
15
- import has from 'lodash/has';
16
- import upperFirst from 'lodash/upperFirst';
2
+
17
3
  import {
4
+ ContentLayout,
18
5
  HeaderLayout,
6
+ IconButton,
19
7
  Layout,
20
- ContentLayout,
21
8
  Main,
22
- useNotifyAT,
23
9
  Table,
24
- Thead,
25
- Tr,
26
- Th,
27
10
  Tbody,
28
11
  Td,
12
+ Th,
13
+ Thead,
14
+ Tr,
29
15
  Typography,
30
- IconButton,
16
+ useNotifyAT,
31
17
  VisuallyHidden,
32
18
  } from '@strapi/design-system';
19
+ import {
20
+ CheckPagePermissions,
21
+ LoadingIndicatorPage,
22
+ onRowClick,
23
+ SettingsPageTitle,
24
+ stopPropagation,
25
+ useFocusWhenNavigate,
26
+ useNotification,
27
+ useOverlayBlocker,
28
+ useRBAC,
29
+ useTracking,
30
+ } from '@strapi/helper-plugin';
33
31
  import { Pencil } from '@strapi/icons';
34
- import { useQuery, useMutation, useQueryClient } from 'react-query';
35
- import forms from './utils/forms';
32
+ import has from 'lodash/has';
33
+ import upperFirst from 'lodash/upperFirst';
34
+ import { useIntl } from 'react-intl';
35
+ import { useMutation, useQuery, useQueryClient } from 'react-query';
36
+
37
+ import FormModal from '../../components/FormModal';
38
+ import pluginPermissions from '../../permissions';
39
+ import { getTrad } from '../../utils';
40
+
36
41
  import { fetchData, putProvider } from './utils/api';
37
42
  import createProvidersArray from './utils/createProvidersArray';
38
- import { getTrad } from '../../utils';
39
- import pluginPermissions from '../../permissions';
40
- import FormModal from '../../components/FormModal';
43
+ import forms from './utils/forms';
41
44
 
42
45
  export const ProvidersPage = () => {
43
46
  const { formatMessage } = useIntl();
@@ -1,4 +1,5 @@
1
1
  import { getFetchClient } from '@strapi/helper-plugin';
2
+
2
3
  import { getRequestURL } from '../../../utils';
3
4
 
4
5
  // eslint-disable-next-line import/prefer-default-export
@@ -1,5 +1,5 @@
1
- import * as yup from 'yup';
2
1
  import { translatedErrors } from '@strapi/helper-plugin';
2
+ import * as yup from 'yup';
3
3
 
4
4
  import { getTrad } from '../../../utils';
5
5
 
@@ -1,36 +1,39 @@
1
- import React, { useState, useRef } from 'react';
2
- import { useHistory } from 'react-router-dom';
1
+ import React, { useRef, useState } from 'react';
2
+
3
3
  import {
4
+ Box,
5
+ Button,
4
6
  ContentLayout,
7
+ Flex,
8
+ Grid,
9
+ GridItem,
5
10
  HeaderLayout,
6
11
  Main,
7
- Button,
8
- Flex,
9
- Box,
10
- TextInput,
11
12
  Textarea,
13
+ TextInput,
12
14
  Typography,
13
- GridItem,
14
- Grid,
15
15
  } from '@strapi/design-system';
16
- import { Check } from '@strapi/icons';
17
- import { Formik } from 'formik';
18
- import { useIntl } from 'react-intl';
19
16
  import {
20
- useOverlayBlocker,
17
+ Form,
21
18
  SettingsPageTitle,
22
19
  useFetchClient,
23
- useTracking,
24
- Form,
25
20
  useNotification,
21
+ useOverlayBlocker,
22
+ useTracking,
26
23
  } from '@strapi/helper-plugin';
27
- import UsersPermissions from '../../../components/UsersPermissions';
28
- import getTrad from '../../../utils/getTrad';
29
- import pluginId from '../../../pluginId';
30
- import { usePlugins } from '../../../hooks';
31
- import schema from './utils/schema';
24
+ import { Check } from '@strapi/icons';
25
+ import { Formik } from 'formik';
26
+ import { useIntl } from 'react-intl';
27
+ import { useHistory } from 'react-router-dom';
28
+
29
+ import UsersPermissions from '../../components/UsersPermissions';
30
+ import { usePlugins } from '../../hooks';
31
+ import pluginId from '../../pluginId';
32
+ import getTrad from '../../utils/getTrad';
33
+
34
+ import { createRoleSchema } from './constants';
32
35
 
33
- const EditPage = () => {
36
+ const CreatePage = () => {
34
37
  const { formatMessage } = useIntl();
35
38
  const [isSubmitting, setIsSubmitting] = useState(false);
36
39
  const toggleNotification = useNotification();
@@ -82,7 +85,7 @@ const EditPage = () => {
82
85
  enableReinitialize
83
86
  initialValues={{ name: '', description: '' }}
84
87
  onSubmit={handleCreateRoleSubmit}
85
- validationSchema={schema}
88
+ validationSchema={createRoleSchema}
86
89
  >
87
90
  {({ handleSubmit, values, handleChange, errors }) => (
88
91
  <Form noValidate onSubmit={handleSubmit}>
@@ -179,4 +182,4 @@ const EditPage = () => {
179
182
  );
180
183
  };
181
184
 
182
- export default EditPage;
185
+ export default CreatePage;
@@ -1,16 +1,5 @@
1
- import React, { useState, useRef } from 'react';
2
- import { Formik } from 'formik';
3
- import { useIntl } from 'react-intl';
4
- import { useRouteMatch } from 'react-router-dom';
5
- import {
6
- useFetchClient,
7
- useOverlayBlocker,
8
- SettingsPageTitle,
9
- LoadingIndicatorPage,
10
- Form,
11
- useNotification,
12
- Link,
13
- } from '@strapi/helper-plugin';
1
+ import React, { useRef, useState } from 'react';
2
+
14
3
  import {
15
4
  ContentLayout,
16
5
  HeaderLayout,
@@ -24,12 +13,26 @@ import {
24
13
  GridItem,
25
14
  Grid,
26
15
  } from '@strapi/design-system';
16
+ import {
17
+ useFetchClient,
18
+ useOverlayBlocker,
19
+ SettingsPageTitle,
20
+ LoadingIndicatorPage,
21
+ Form,
22
+ useNotification,
23
+ Link,
24
+ } from '@strapi/helper-plugin';
27
25
  import { ArrowLeft, Check } from '@strapi/icons';
28
- import UsersPermissions from '../../../components/UsersPermissions';
29
- import getTrad from '../../../utils/getTrad';
30
- import pluginId from '../../../pluginId';
31
- import { usePlugins, useFetchRole } from '../../../hooks';
32
- import schema from './utils/schema';
26
+ import { Formik } from 'formik';
27
+ import { useIntl } from 'react-intl';
28
+ import { useRouteMatch } from 'react-router-dom';
29
+
30
+ import UsersPermissions from '../../components/UsersPermissions';
31
+ import { usePlugins, useFetchRole } from '../../hooks';
32
+ import pluginId from '../../pluginId';
33
+ import getTrad from '../../utils/getTrad';
34
+
35
+ import { createRoleSchema } from './constants';
33
36
 
34
37
  const EditPage = () => {
35
38
  const { formatMessage } = useIntl();
@@ -87,7 +90,7 @@ const EditPage = () => {
87
90
  enableReinitialize
88
91
  initialValues={{ name: role.name, description: role.description }}
89
92
  onSubmit={handleEditRoleSubmit}
90
- validationSchema={schema}
93
+ validationSchema={createRoleSchema}
91
94
  >
92
95
  {({ handleSubmit, values, handleChange, errors }) => (
93
96
  <Form noValidate onSubmit={handleSubmit}>
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { IconButton, Typography, Flex, Tbody, Tr, Td } from '@strapi/design-system';
4
- import { Pencil, Trash } from '@strapi/icons';
2
+
3
+ import { Flex, IconButton, Tbody, Td, Tr, Typography } from '@strapi/design-system';
5
4
  import { CheckPermissions, onRowClick, stopPropagation } from '@strapi/helper-plugin';
5
+ import { Pencil, Trash } from '@strapi/icons';
6
+ import PropTypes from 'prop-types';
6
7
  import { useIntl } from 'react-intl';
7
8
  import { useHistory } from 'react-router-dom';
8
9
 
@@ -1,45 +1,47 @@
1
1
  import React, { useMemo, useState } from 'react';
2
+
2
3
  import {
4
+ ActionLayout,
3
5
  Button,
6
+ ContentLayout,
4
7
  HeaderLayout,
5
8
  Layout,
6
- ContentLayout,
7
- ActionLayout,
8
9
  Main,
9
10
  Table,
10
- Tr,
11
- Thead,
12
11
  Th,
12
+ Thead,
13
+ Tr,
13
14
  Typography,
14
15
  useNotifyAT,
15
16
  VisuallyHidden,
16
17
  } from '@strapi/design-system';
17
- import { Plus } from '@strapi/icons';
18
18
  import {
19
- useTracking,
20
- SettingsPageTitle,
21
19
  CheckPermissions,
22
- useNotification,
23
- useRBAC,
24
- NoPermissions,
20
+ ConfirmDialog,
21
+ EmptyStateLayout,
25
22
  LoadingIndicatorPage,
23
+ NoPermissions,
26
24
  SearchURLQuery,
25
+ SettingsPageTitle,
26
+ useCollator,
27
+ useFilter,
27
28
  useFocusWhenNavigate,
29
+ useNotification,
28
30
  useQueryParams,
29
- EmptyStateLayout,
30
- ConfirmDialog,
31
- useFilter,
32
- useCollator,
31
+ useRBAC,
32
+ useTracking,
33
33
  } from '@strapi/helper-plugin';
34
+ import { Plus } from '@strapi/icons';
34
35
  import { useIntl } from 'react-intl';
35
- import { useHistory } from 'react-router-dom';
36
36
  import { useMutation, useQuery, useQueryClient } from 'react-query';
37
+ import { useHistory } from 'react-router-dom';
37
38
 
38
- import { fetchData, deleteData } from './utils/api';
39
- import { getTrad } from '../../../utils';
40
- import pluginId from '../../../pluginId';
41
39
  import permissions from '../../../permissions';
40
+ import pluginId from '../../../pluginId';
41
+ import { getTrad } from '../../../utils';
42
+
42
43
  import TableBody from './components/TableBody';
44
+ import { deleteData, fetchData } from './utils/api';
43
45
 
44
46
  const RoleListPage = () => {
45
47
  const { trackUsage } = useTracking();
@@ -1,4 +1,5 @@
1
1
  import { getFetchClient } from '@strapi/helper-plugin';
2
+
2
3
  import { getRequestURL } from '../../../../utils';
3
4
 
4
5
  export const fetchData = async (toggleNotification, notifyStatus) => {
@@ -14,7 +15,7 @@ export const fetchData = async (toggleNotification, notifyStatus) => {
14
15
  message: { id: 'notification.error' },
15
16
  });
16
17
 
17
- throw new Error('error');
18
+ throw new Error(err);
18
19
  }
19
20
  };
20
21
 
@@ -1,7 +1,10 @@
1
1
  import React from 'react';
2
+
2
3
  import { CheckPagePermissions } from '@strapi/helper-plugin';
3
- import pluginPermissions from '../../../permissions';
4
- import RolesCreatePage from '../CreatePage';
4
+
5
+ import pluginPermissions from '../../permissions';
6
+
7
+ import RolesCreatePage from './CreatePage';
5
8
 
6
9
  const ProtectedRolesCreatePage = () => (
7
10
  <CheckPagePermissions permissions={pluginPermissions.createRole}>
@@ -1,7 +1,10 @@
1
1
  import React from 'react';
2
+
2
3
  import { CheckPagePermissions } from '@strapi/helper-plugin';
3
- import pluginPermissions from '../../../permissions';
4
- import RolesEditPage from '../EditPage';
4
+
5
+ import pluginPermissions from '../../permissions';
6
+
7
+ import RolesEditPage from './EditPage';
5
8
 
6
9
  const ProtectedRolesEditPage = () => (
7
10
  <CheckPagePermissions permissions={pluginPermissions.updateRole}>
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
+
2
3
  import { CheckPagePermissions } from '@strapi/helper-plugin';
3
- import pluginPermissions from '../../../permissions';
4
4
 
5
- import RolesListPage from '../ListPage';
5
+ import pluginPermissions from '../../permissions';
6
+
7
+ import RolesListPage from './ListPage';
6
8
 
7
9
  const ProtectedRolesListPage = () => {
8
10
  return (
@@ -1,9 +1,7 @@
1
- import * as yup from 'yup';
2
1
  import { translatedErrors } from '@strapi/helper-plugin';
2
+ import * as yup from 'yup';
3
3
 
4
- const schema = yup.object().shape({
4
+ export const createRoleSchema = yup.object().shape({
5
5
  name: yup.string().required(translatedErrors.required),
6
6
  description: yup.string().required(translatedErrors.required),
7
7
  });
8
-
9
- export default schema;
@@ -1,11 +1,14 @@
1
1
  import React from 'react';
2
- import { Switch, Route } from 'react-router-dom';
3
- import { CheckPagePermissions, AnErrorOccurred } from '@strapi/helper-plugin';
4
- import pluginId from '../../pluginId';
2
+
3
+ import { AnErrorOccurred, CheckPagePermissions } from '@strapi/helper-plugin';
4
+ import { Route, Switch } from 'react-router-dom';
5
+
5
6
  import pluginPermissions from '../../permissions';
6
- import ProtectedRolesListPage from './ProtectedListPage';
7
- import ProtectedRolesEditPage from './ProtectedEditPage';
7
+ import pluginId from '../../pluginId';
8
+
8
9
  import ProtectedRolesCreatePage from './ProtectedCreatePage';
10
+ import ProtectedRolesEditPage from './ProtectedEditPage';
11
+ import ProtectedRolesListPage from './ProtectedListPage';
9
12
 
10
13
  const Roles = () => {
11
14
  return (
@@ -1,4 +1,4 @@
1
1
  export { default as cleanPermissions } from './cleanPermissions';
2
+ export { default as formatPolicies } from './formatPolicies';
2
3
  export { default as getRequestURL } from './getRequestURL';
3
4
  export { default as getTrad } from './getTrad';
4
- export { default as formatPolicies } from './formatPolicies';
@@ -3,4 +3,5 @@
3
3
  module.exports = {
4
4
  preset: '../../../jest-preset.front.js',
5
5
  displayName: 'Users & Permissions plugin',
6
+ setupFilesAfterEnv: ['./tests/setup.js'],
6
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/plugin-users-permissions",
3
- "version": "4.11.1",
3
+ "version": "4.11.2",
4
4
  "description": "Protect your API with a full-authentication process based on JWT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,9 +30,9 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@strapi/design-system": "1.8.0",
33
- "@strapi/helper-plugin": "4.11.1",
33
+ "@strapi/helper-plugin": "4.11.2",
34
34
  "@strapi/icons": "1.8.0",
35
- "@strapi/utils": "4.11.1",
35
+ "@strapi/utils": "4.11.2",
36
36
  "bcryptjs": "2.4.3",
37
37
  "formik": "2.4.0",
38
38
  "grant-koa": "5.4.8",
@@ -54,7 +54,6 @@
54
54
  "@testing-library/dom": "9.2.0",
55
55
  "@testing-library/react": "14.0.0",
56
56
  "@testing-library/user-event": "14.4.3",
57
- "history": "^4.9.0",
58
57
  "msw": "1.2.1",
59
58
  "react": "^18.2.0",
60
59
  "react-dom": "^18.2.0",
@@ -78,5 +77,5 @@
78
77
  "required": true,
79
78
  "kind": "plugin"
80
79
  },
81
- "gitHead": "6cdb5a7737495ca0c7179076ade5361e182ea169"
80
+ "gitHead": "6f7c815c2bbe41dda7d77136eb8df736c028ff67"
82
81
  }
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const { castArray, map, every, pipe, isEmpty } = require('lodash/fp');
3
+ const { castArray, map, every, pipe } = require('lodash/fp');
4
4
  const { ForbiddenError, UnauthorizedError } = require('@strapi/utils').errors;
5
5
 
6
6
  const { getService } = require('../utils');
@@ -80,13 +80,6 @@ const authenticate = async (ctx) => {
80
80
  const verify = async (auth, config) => {
81
81
  const { credentials: user, ability } = auth;
82
82
 
83
- strapi.telemetry.send('didReceiveAPIRequest', {
84
- eventProperties: {
85
- authenticationMethod: auth?.strategy?.name,
86
- isAuthenticated: !isEmpty(user),
87
- },
88
- });
89
-
90
83
  if (!config.scope) {
91
84
  if (!user) {
92
85
  // A non authenticated user cannot access routes that do not have a scope
@@ -1,67 +0,0 @@
1
- import { useCallback, useEffect, useReducer } from 'react';
2
- import { useNotification, useFetchClient } from '@strapi/helper-plugin';
3
- import get from 'lodash/get';
4
- import init from './init';
5
- import pluginId from '../../pluginId';
6
- import { cleanPermissions } from '../../utils';
7
- import reducer, { initialState } from './reducer';
8
-
9
- const usePlugins = (shouldFetchData = true) => {
10
- const toggleNotification = useNotification();
11
- const [{ permissions, routes, isLoading }, dispatch] = useReducer(reducer, initialState, () =>
12
- init(initialState, shouldFetchData)
13
- );
14
- const fetchClient = useFetchClient();
15
-
16
- const fetchPlugins = useCallback(async () => {
17
- try {
18
- dispatch({
19
- type: 'GET_DATA',
20
- });
21
-
22
- const [{ permissions }, { routes }] = await Promise.all(
23
- [`/${pluginId}/permissions`, `/${pluginId}/routes`].map(async (endpoint) => {
24
- const res = await fetchClient.get(endpoint);
25
-
26
- return res.data;
27
- })
28
- );
29
-
30
- dispatch({
31
- type: 'GET_DATA_SUCCEEDED',
32
- permissions: cleanPermissions(permissions),
33
- routes,
34
- });
35
- } catch (err) {
36
- const message = get(err, ['response', 'payload', 'message'], 'An error occured');
37
-
38
- dispatch({
39
- type: 'GET_DATA_ERROR',
40
- });
41
-
42
- if (message !== 'Forbidden') {
43
- toggleNotification({
44
- type: 'warning',
45
- message,
46
- });
47
- }
48
- }
49
-
50
- // eslint-disable-next-line react-hooks/exhaustive-deps
51
- }, [toggleNotification]);
52
-
53
- useEffect(() => {
54
- if (shouldFetchData) {
55
- fetchPlugins();
56
- }
57
- }, [fetchPlugins, shouldFetchData]);
58
-
59
- return {
60
- permissions,
61
- routes,
62
- getData: fetchPlugins,
63
- isLoading,
64
- };
65
- };
66
-
67
- export default usePlugins;
@@ -1,5 +0,0 @@
1
- const init = (initialState, shouldFetchData) => {
2
- return { ...initialState, isLoading: shouldFetchData };
3
- };
4
-
5
- export default init;
@@ -1,34 +0,0 @@
1
- /* eslint-disable consistent-return */
2
- import produce from 'immer';
3
-
4
- export const initialState = {
5
- permissions: {},
6
- routes: {},
7
- isLoading: true,
8
- };
9
-
10
- const reducer = (state, action) =>
11
- produce(state, (draftState) => {
12
- switch (action.type) {
13
- case 'GET_DATA': {
14
- draftState.isLoading = true;
15
- draftState.permissions = {};
16
- draftState.routes = {};
17
- break;
18
- }
19
- case 'GET_DATA_SUCCEEDED': {
20
- draftState.permissions = action.permissions;
21
- draftState.routes = action.routes;
22
- draftState.isLoading = false;
23
- break;
24
- }
25
- case 'GET_DATA_ERROR': {
26
- draftState.isLoading = false;
27
- break;
28
- }
29
- default:
30
- return draftState;
31
- }
32
- });
33
-
34
- export default reducer;
@@ -1,9 +0,0 @@
1
- import * as yup from 'yup';
2
- import { translatedErrors } from '@strapi/helper-plugin';
3
-
4
- const schema = yup.object().shape({
5
- name: yup.string().required(translatedErrors.required),
6
- description: yup.string().required(translatedErrors.required),
7
- });
8
-
9
- export default schema;