@strapi/plugin-users-permissions 4.0.0-next.6 → 4.0.0

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 (196) hide show
  1. package/admin/src/components/BoundRoute/getMethodColor.js +41 -0
  2. package/admin/src/components/BoundRoute/index.js +40 -24
  3. package/admin/src/components/FormModal/Input/index.js +121 -0
  4. package/admin/src/components/FormModal/index.js +123 -0
  5. package/admin/src/components/Permissions/PermissionRow/CheckboxWrapper.js +19 -26
  6. package/admin/src/components/Permissions/PermissionRow/SubCategory.js +118 -0
  7. package/admin/src/components/Permissions/PermissionRow/index.js +9 -48
  8. package/admin/src/components/Permissions/index.js +36 -24
  9. package/admin/src/components/Permissions/init.js +1 -6
  10. package/admin/src/components/Policies/index.js +46 -47
  11. package/admin/src/components/UsersPermissions/index.js +29 -26
  12. package/admin/src/components/UsersPermissions/init.js +1 -2
  13. package/admin/src/hooks/useFetchRole/index.js +17 -7
  14. package/admin/src/hooks/useForm/index.js +3 -29
  15. package/admin/src/hooks/useForm/reducer.js +2 -21
  16. package/admin/src/hooks/usePlugins/index.js +12 -21
  17. package/admin/src/hooks/usePlugins/reducer.js +0 -3
  18. package/admin/src/index.js +29 -34
  19. package/admin/src/pages/AdvancedSettings/index.js +210 -193
  20. package/admin/src/pages/AdvancedSettings/utils/api.js +13 -0
  21. package/admin/src/pages/AdvancedSettings/utils/layout.js +96 -0
  22. package/admin/src/pages/AdvancedSettings/utils/schema.js +22 -0
  23. package/admin/src/pages/EmailTemplates/components/EmailForm.js +173 -0
  24. package/admin/src/pages/EmailTemplates/components/EmailTable.js +116 -0
  25. package/admin/src/pages/EmailTemplates/index.js +125 -198
  26. package/admin/src/pages/EmailTemplates/utils/api.js +13 -0
  27. package/admin/src/pages/Providers/index.js +208 -216
  28. package/admin/src/pages/Providers/utils/api.js +21 -0
  29. package/admin/src/pages/Providers/utils/forms.js +168 -126
  30. package/admin/src/pages/Roles/CreatePage/index.js +155 -147
  31. package/admin/src/pages/Roles/EditPage/index.js +162 -134
  32. package/admin/src/pages/Roles/ListPage/components/TableBody.js +96 -0
  33. package/admin/src/pages/Roles/ListPage/index.js +176 -156
  34. package/admin/src/pages/Roles/ListPage/utils/api.js +28 -0
  35. package/admin/src/pages/Roles/index.js +14 -8
  36. package/admin/src/permissions.js +12 -14
  37. package/admin/src/translations/ar.json +0 -8
  38. package/admin/src/translations/cs.json +0 -8
  39. package/admin/src/translations/de.json +0 -8
  40. package/admin/src/translations/dk.json +0 -8
  41. package/admin/src/translations/en.json +33 -12
  42. package/admin/src/translations/es.json +0 -8
  43. package/admin/src/translations/fr.json +0 -8
  44. package/admin/src/translations/id.json +0 -8
  45. package/admin/src/translations/it.json +0 -8
  46. package/admin/src/translations/ja.json +0 -8
  47. package/admin/src/translations/ko.json +0 -8
  48. package/admin/src/translations/ms.json +0 -8
  49. package/admin/src/translations/nl.json +0 -8
  50. package/admin/src/translations/pl.json +0 -8
  51. package/admin/src/translations/pt-BR.json +0 -8
  52. package/admin/src/translations/pt.json +0 -8
  53. package/admin/src/translations/ru.json +0 -8
  54. package/admin/src/translations/sk.json +0 -8
  55. package/admin/src/translations/sv.json +0 -8
  56. package/admin/src/translations/th.json +0 -8
  57. package/admin/src/translations/tr.json +0 -8
  58. package/admin/src/translations/uk.json +0 -8
  59. package/admin/src/translations/vi.json +0 -8
  60. package/admin/src/translations/zh-Hans.json +5 -14
  61. package/admin/src/translations/zh.json +0 -8
  62. package/admin/src/utils/axiosInstance.js +36 -0
  63. package/admin/src/utils/formatPluginName.js +26 -0
  64. package/admin/src/utils/index.js +1 -0
  65. package/documentation/1.0.0/overrides/users-permissions-Role.json +6 -6
  66. package/documentation/1.0.0/overrides/users-permissions-User.json +7 -7
  67. package/package.json +30 -29
  68. package/{config/functions/bootstrap.js → server/bootstrap/index.js} +26 -33
  69. package/{config → server/bootstrap}/users-permissions-actions.js +0 -0
  70. package/server/config.js +23 -0
  71. package/server/content-types/index.js +11 -0
  72. package/server/content-types/permission/index.js +34 -0
  73. package/server/content-types/role/index.js +51 -0
  74. package/server/content-types/user/index.js +72 -0
  75. package/{models/User.config.js → server/content-types/user/schema-config.js} +0 -0
  76. package/server/controllers/auth.js +440 -0
  77. package/server/controllers/content-manager-user.js +183 -0
  78. package/server/controllers/index.js +17 -0
  79. package/server/controllers/permissions.js +26 -0
  80. package/server/controllers/role.js +77 -0
  81. package/server/controllers/settings.js +85 -0
  82. package/server/controllers/user.js +191 -0
  83. package/server/controllers/validation/auth.js +29 -0
  84. package/{controllers → server/controllers}/validation/email-template.js +0 -0
  85. package/server/controllers/validation/user.js +38 -0
  86. package/server/graphql/index.js +44 -0
  87. package/server/graphql/mutations/auth/email-confirmation.js +39 -0
  88. package/server/graphql/mutations/auth/forgot-password.js +38 -0
  89. package/server/graphql/mutations/auth/login.js +38 -0
  90. package/server/graphql/mutations/auth/register.js +39 -0
  91. package/server/graphql/mutations/auth/reset-password.js +41 -0
  92. package/server/graphql/mutations/crud/role/create-role.js +37 -0
  93. package/server/graphql/mutations/crud/role/delete-role.js +28 -0
  94. package/server/graphql/mutations/crud/role/update-role.js +38 -0
  95. package/server/graphql/mutations/crud/user/create-user.js +48 -0
  96. package/server/graphql/mutations/crud/user/delete-user.js +42 -0
  97. package/server/graphql/mutations/crud/user/update-user.js +49 -0
  98. package/server/graphql/mutations/index.js +42 -0
  99. package/server/graphql/queries/index.js +13 -0
  100. package/server/graphql/queries/me.js +17 -0
  101. package/server/graphql/resolvers-configs.js +37 -0
  102. package/server/graphql/types/create-role-payload.js +11 -0
  103. package/server/graphql/types/delete-role-payload.js +11 -0
  104. package/server/graphql/types/index.js +21 -0
  105. package/server/graphql/types/login-input.js +13 -0
  106. package/server/graphql/types/login-payload.js +12 -0
  107. package/server/graphql/types/me-role.js +14 -0
  108. package/server/graphql/types/me.js +16 -0
  109. package/server/graphql/types/password-payload.js +11 -0
  110. package/server/graphql/types/register-input.js +13 -0
  111. package/server/graphql/types/update-role-payload.js +11 -0
  112. package/server/graphql/utils.js +27 -0
  113. package/server/index.js +21 -0
  114. package/server/middlewares/index.js +7 -0
  115. package/{config/policies → server/middlewares}/rateLimit.js +4 -8
  116. package/server/register.js +11 -0
  117. package/server/routes/admin/index.js +10 -0
  118. package/server/routes/admin/permissions.js +20 -0
  119. package/server/routes/admin/role.js +79 -0
  120. package/server/routes/admin/settings.js +95 -0
  121. package/server/routes/content-api/auth.js +73 -0
  122. package/server/routes/content-api/index.js +11 -0
  123. package/server/routes/content-api/permissions.js +9 -0
  124. package/server/routes/content-api/role.js +29 -0
  125. package/server/routes/content-api/user.js +61 -0
  126. package/server/routes/index.js +6 -0
  127. package/server/services/index.js +15 -0
  128. package/server/services/jwt.js +55 -0
  129. package/server/services/providers.js +599 -0
  130. package/server/services/role.js +177 -0
  131. package/{services → server/services}/user.js +32 -35
  132. package/server/services/users-permissions.js +233 -0
  133. package/server/strategies/users-permissions.js +123 -0
  134. package/{utils → server/utils}/index.d.ts +6 -1
  135. package/server/utils/index.js +9 -0
  136. package/strapi-admin.js +3 -0
  137. package/strapi-server.js +3 -0
  138. package/admin/src/assets/images/logo.svg +0 -1
  139. package/admin/src/components/BaselineAlignement/index.js +0 -33
  140. package/admin/src/components/Bloc/index.js +0 -10
  141. package/admin/src/components/BoundRoute/Components.js +0 -78
  142. package/admin/src/components/ContainerFluid/index.js +0 -13
  143. package/admin/src/components/FormBloc/index.js +0 -61
  144. package/admin/src/components/IntlInput/index.js +0 -38
  145. package/admin/src/components/ListBaselineAlignment/index.js +0 -8
  146. package/admin/src/components/ListRow/Components.js +0 -74
  147. package/admin/src/components/ListRow/index.js +0 -35
  148. package/admin/src/components/ModalForm/Wrapper.js +0 -12
  149. package/admin/src/components/ModalForm/index.js +0 -59
  150. package/admin/src/components/Permissions/ListWrapper.js +0 -9
  151. package/admin/src/components/Permissions/PermissionRow/BaselineAlignment.js +0 -7
  152. package/admin/src/components/Permissions/PermissionRow/RowStyle.js +0 -28
  153. package/admin/src/components/Permissions/PermissionRow/SubCategory/ConditionsButtonWrapper.js +0 -13
  154. package/admin/src/components/Permissions/PermissionRow/SubCategory/PolicyWrapper.js +0 -8
  155. package/admin/src/components/Permissions/PermissionRow/SubCategory/SubCategoryWrapper.js +0 -26
  156. package/admin/src/components/Permissions/PermissionRow/SubCategory/index.js +0 -116
  157. package/admin/src/components/Policies/Components.js +0 -26
  158. package/admin/src/components/PrefixedIcon/index.js +0 -27
  159. package/admin/src/components/Roles/EmptyRole/BaselineAlignment.js +0 -7
  160. package/admin/src/components/Roles/EmptyRole/index.js +0 -27
  161. package/admin/src/components/Roles/RoleListWrapper/index.js +0 -17
  162. package/admin/src/components/Roles/RoleRow/RoleDescription.js +0 -9
  163. package/admin/src/components/Roles/RoleRow/index.js +0 -45
  164. package/admin/src/components/Roles/index.js +0 -3
  165. package/admin/src/components/SizedInput/index.js +0 -24
  166. package/admin/src/pages/AdvancedSettings/reducer.js +0 -65
  167. package/admin/src/pages/AdvancedSettings/utils/form.js +0 -52
  168. package/admin/src/pages/EmailTemplates/CustomTextInput.js +0 -105
  169. package/admin/src/pages/EmailTemplates/Wrapper.js +0 -36
  170. package/admin/src/pages/EmailTemplates/reducer.js +0 -58
  171. package/admin/src/pages/EmailTemplates/utils/forms.js +0 -81
  172. package/admin/src/pages/Roles/ListPage/BaselineAlignment.js +0 -8
  173. package/config/layout.js +0 -10
  174. package/config/policies/isAuthenticated.js +0 -9
  175. package/config/policies/permissions.js +0 -94
  176. package/config/request.json +0 -6
  177. package/config/routes.json +0 -381
  178. package/config/schema.graphql.js +0 -284
  179. package/config/security.json +0 -5
  180. package/controllers/auth.js +0 -596
  181. package/controllers/user/admin.js +0 -230
  182. package/controllers/user/api.js +0 -174
  183. package/controllers/user.js +0 -117
  184. package/controllers/users-permissions.js +0 -271
  185. package/middlewares/users-permissions/defaults.json +0 -5
  186. package/middlewares/users-permissions/index.js +0 -40
  187. package/models/Permission.js +0 -7
  188. package/models/Permission.settings.json +0 -45
  189. package/models/Role.js +0 -7
  190. package/models/Role.settings.json +0 -43
  191. package/models/User.js +0 -7
  192. package/models/User.settings.json +0 -63
  193. package/services/jwt.js +0 -65
  194. package/services/providers.js +0 -598
  195. package/services/users-permissions.js +0 -429
  196. package/utils/index.js +0 -11
@@ -4,20 +4,12 @@
4
4
  // Here's the file: strapi/docs/3.0.0-beta.x/guides/registering-a-field-in-admin.md
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
- import React from 'react';
8
- import { CheckPagePermissions, prefixPluginTranslations } from '@strapi/helper-plugin';
7
+ import { prefixPluginTranslations } from '@strapi/helper-plugin';
9
8
  import pluginPkg from '../../package.json';
10
- import pluginLogo from './assets/images/logo.svg';
11
9
  import pluginPermissions from './permissions';
12
10
  import pluginId from './pluginId';
13
- import RolesPage from './pages/Roles';
14
- import ProvidersPage from './pages/Providers';
15
- import EmailTemplatesPage from './pages/EmailTemplates';
16
- import AdvancedSettingsPage from './pages/AdvancedSettings';
17
11
  import getTrad from './utils/getTrad';
18
12
 
19
- const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
20
- const icon = pluginPkg.strapi.icon;
21
13
  const name = pluginPkg.strapi.name;
22
14
 
23
15
  export default {
@@ -39,11 +31,13 @@ export default {
39
31
  },
40
32
  id: 'roles',
41
33
  to: `/settings/${pluginId}/roles`,
42
- Component: () => (
43
- <CheckPagePermissions permissions={pluginPermissions.accessRoles}>
44
- <RolesPage />
45
- </CheckPagePermissions>
46
- ),
34
+ Component: async () => {
35
+ const component = await import(
36
+ /* webpackChunkName: "users-roles-settings-page" */ './pages/Roles'
37
+ );
38
+
39
+ return component;
40
+ },
47
41
  permissions: pluginPermissions.accessRoles,
48
42
  },
49
43
  {
@@ -53,11 +47,13 @@ export default {
53
47
  },
54
48
  id: 'providers',
55
49
  to: `/settings/${pluginId}/providers`,
56
- Component: () => (
57
- <CheckPagePermissions permissions={pluginPermissions.readProviders}>
58
- <ProvidersPage />
59
- </CheckPagePermissions>
60
- ),
50
+ Component: async () => {
51
+ const component = await import(
52
+ /* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'
53
+ );
54
+
55
+ return component;
56
+ },
61
57
  permissions: pluginPermissions.readProviders,
62
58
  },
63
59
  {
@@ -67,11 +63,13 @@ export default {
67
63
  },
68
64
  id: 'email-templates',
69
65
  to: `/settings/${pluginId}/email-templates`,
70
- Component: () => (
71
- <CheckPagePermissions permissions={pluginPermissions.readEmailTemplates}>
72
- <EmailTemplatesPage />
73
- </CheckPagePermissions>
74
- ),
66
+ Component: async () => {
67
+ const component = await import(
68
+ /* webpackChunkName: "users-email-settings-page" */ './pages/EmailTemplates'
69
+ );
70
+
71
+ return component;
72
+ },
75
73
  permissions: pluginPermissions.readEmailTemplates,
76
74
  },
77
75
  {
@@ -81,24 +79,21 @@ export default {
81
79
  },
82
80
  id: 'advanced-settings',
83
81
  to: `/settings/${pluginId}/advanced-settings`,
84
- Component: () => (
85
- <CheckPagePermissions permissions={pluginPermissions.readAdvancedSettings}>
86
- <AdvancedSettingsPage />
87
- </CheckPagePermissions>
88
- ),
82
+ Component: async () => {
83
+ const component = await import(
84
+ /* webpackChunkName: "users-advanced-settings-page" */ './pages/AdvancedSettings'
85
+ );
86
+
87
+ return component;
88
+ },
89
89
  permissions: pluginPermissions.readAdvancedSettings,
90
90
  },
91
91
  ]
92
92
  );
93
93
 
94
94
  app.registerPlugin({
95
- description: pluginDescription,
96
- icon,
97
95
  id: pluginId,
98
- isReady: true,
99
- isRequired: pluginPkg.strapi.required || false,
100
96
  name,
101
- pluginLogo,
102
97
  });
103
98
  },
104
99
  bootstrap() {},
@@ -1,220 +1,237 @@
1
- import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';
1
+ import React, { useMemo } from 'react';
2
+ import { useQuery, useMutation, useQueryClient } from 'react-query';
2
3
  import { useIntl } from 'react-intl';
3
- import { Header } from '@buffetjs/custom';
4
- import { isEqual } from 'lodash';
4
+ import { Formik } from 'formik';
5
5
  import {
6
- FormBloc,
7
- PopUpWarning,
6
+ CheckPagePermissions,
7
+ Form,
8
+ GenericInput,
9
+ LoadingIndicatorPage,
8
10
  SettingsPageTitle,
9
- SizedInput,
10
- useRBAC,
11
- request,
11
+ useFocusWhenNavigate,
12
12
  useNotification,
13
13
  useOverlayBlocker,
14
+ useRBAC,
14
15
  } from '@strapi/helper-plugin';
16
+ import { useNotifyAT } from '@strapi/design-system/LiveRegions';
17
+ import { Main } from '@strapi/design-system/Main';
18
+ import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
19
+ import { Button } from '@strapi/design-system/Button';
20
+ import { Box } from '@strapi/design-system/Box';
21
+ import { Stack } from '@strapi/design-system/Stack';
22
+ import { Select, Option } from '@strapi/design-system/Select';
23
+ import { Typography } from '@strapi/design-system/Typography';
24
+ import { Grid, GridItem } from '@strapi/design-system/Grid';
25
+ import Check from '@strapi/icons/Check';
15
26
  import pluginPermissions from '../../permissions';
16
- import { getTrad, getRequestURL } from '../../utils';
17
- import ListBaselineAlignment from '../../components/ListBaselineAlignment';
18
- import form from './utils/form';
19
- import reducer, { initialState } from './reducer';
27
+ import { getTrad } from '../../utils';
28
+ import layout from './utils/layout';
29
+ import schema from './utils/schema';
30
+ import { fetchData, putAdvancedSettings } from './utils/api';
31
+
32
+ const ProtectedAdvancedSettingsPage = () => (
33
+ <CheckPagePermissions permissions={pluginPermissions.readAdvancedSettings}>
34
+ <AdvancedSettingsPage />
35
+ </CheckPagePermissions>
36
+ );
20
37
 
21
38
  const AdvancedSettingsPage = () => {
22
39
  const { formatMessage } = useIntl();
23
40
  const toggleNotification = useNotification();
24
41
  const { lockApp, unlockApp } = useOverlayBlocker();
25
- const [showModalWarning, setShowModalWarning] = useState(false);
26
- const pageTitle = formatMessage({ id: getTrad('HeaderNav.link.advancedSettings') });
27
- const formTitle = formatMessage({
28
- id: getTrad('Form.title.advancedSettings'),
29
- defaultMessage: 'Settings',
30
- });
42
+ const { notifyStatus } = useNotifyAT();
43
+ const queryClient = useQueryClient();
44
+ useFocusWhenNavigate();
31
45
 
32
- const updatePermissions = useMemo(() => {
33
- return { update: pluginPermissions.updateAdvancedSettings };
34
- }, []);
46
+ const updatePermissions = useMemo(
47
+ () => ({ update: pluginPermissions.updateAdvancedSettings }),
48
+ []
49
+ );
35
50
  const {
36
51
  isLoading: isLoadingForPermissions,
37
52
  allowedActions: { canUpdate },
38
53
  } = useRBAC(updatePermissions);
39
- const [
40
- { initialData, isConfirmButtonLoading, isLoading, modifiedData, roles },
41
- dispatch,
42
- ] = useReducer(reducer, initialState);
43
- const isMounted = useRef(true);
44
- const abortController = new AbortController();
45
- const { signal } = abortController;
46
-
47
- useEffect(() => {
48
- const getData = async () => {
49
- try {
50
- dispatch({
51
- type: 'GET_DATA',
52
- });
53
-
54
- const data = await request(getRequestURL('advanced'), { method: 'GET', signal });
55
-
56
- dispatch({
57
- type: 'GET_DATA_SUCCEEDED',
58
- data,
59
- });
60
- } catch (err) {
61
- if (isMounted.current) {
62
- dispatch({
63
- type: 'GET_DATA_ERROR',
64
- });
65
- console.error(err);
66
- toggleNotification({
67
- type: 'warning',
68
- message: { id: 'notification.error' },
69
- });
70
- }
71
- }
72
- };
73
-
74
- if (!isLoadingForPermissions) {
75
- getData();
76
- }
77
-
78
- return () => {
79
- abortController.abort();
80
- isMounted.current = false;
81
- };
82
-
83
- // eslint-disable-next-line react-hooks/exhaustive-deps
84
- }, [isLoadingForPermissions]);
85
-
86
- const handleChange = useCallback(({ target }) => {
87
- dispatch({
88
- type: 'ON_CHANGE',
89
- keys: target.name,
90
- value: target.value,
91
- });
92
- }, []);
93
-
94
- const handleSubmit = useCallback(
95
- async e => {
96
- e.preventDefault();
97
-
98
- try {
99
- dispatch({
100
- type: 'ON_SUBMIT',
101
- });
102
-
103
- lockApp();
104
- await request(getRequestURL('advanced'), { method: 'PUT', body: modifiedData });
105
-
106
- dispatch({
107
- type: 'ON_SUBMIT_SUCCEEDED',
108
- });
109
-
110
- toggleNotification({
111
- type: 'success',
112
- message: { id: getTrad('notification.success.submit') },
113
- });
114
- } catch (err) {
115
- dispatch({
116
- type: 'ON_SUBMIT_ERROR',
117
- });
118
- console.error(err);
119
- toggleNotification({
120
- type: 'warning',
121
- message: { id: 'notification.error' },
122
- });
123
- }
54
+
55
+ const { status: isLoadingData, data } = useQuery('advanced', () => fetchData(), {
56
+ onSuccess: () => {
57
+ notifyStatus(
58
+ formatMessage({
59
+ id: getTrad('Form.advancedSettings.data.loaded'),
60
+ defaultMessage: 'Advanced settings data has been loaded',
61
+ })
62
+ );
63
+ },
64
+ onError: () => {
65
+ toggleNotification({
66
+ type: 'warning',
67
+ message: { id: getTrad('notification.error'), defaultMessage: 'An error occured' },
68
+ });
69
+ },
70
+ });
71
+
72
+ const isLoading = isLoadingForPermissions || isLoadingData !== 'success';
73
+
74
+ const submitMutation = useMutation(body => putAdvancedSettings(body), {
75
+ onSuccess: async () => {
76
+ await queryClient.invalidateQueries('advanced');
77
+ toggleNotification({
78
+ type: 'success',
79
+ message: { id: getTrad('notification.success.saved'), defaultMessage: 'Saved' },
80
+ });
124
81
 
125
82
  unlockApp();
126
83
  },
127
- [lockApp, modifiedData, toggleNotification, unlockApp]
128
- );
84
+ onError: () => {
85
+ toggleNotification({
86
+ type: 'warning',
87
+ message: { id: getTrad('notification.error'), defaultMessage: 'An error occured' },
88
+ });
89
+ unlockApp();
90
+ },
91
+ refetchActive: true,
92
+ });
129
93
 
130
- const handleConfirmReset = useCallback(() => {
131
- dispatch({
132
- type: 'ON_RESET',
133
- });
134
-
135
- setShowModalWarning(false);
136
- }, []);
137
-
138
- const handleToggleModal = useCallback(() => {
139
- setShowModalWarning(prev => !prev);
140
- }, []);
141
-
142
- const headerActions = useMemo(() => {
143
- const isDisabled = isEqual(initialData, modifiedData);
144
-
145
- return [
146
- {
147
- disabled: isDisabled,
148
- onClick: () => {
149
- handleToggleModal();
150
- },
151
- color: 'cancel',
152
- label: formatMessage({
153
- id: 'app.components.Button.reset',
154
- }),
155
-
156
- type: 'button',
157
- style: {
158
- paddingLeft: 15,
159
- paddingRight: 15,
160
- fontWeight: 600,
161
- },
162
- },
163
- {
164
- disabled: isDisabled,
165
- color: 'success',
166
- label: formatMessage({
167
- id: 'app.components.Button.save',
168
- }),
169
- isLoading: isConfirmButtonLoading,
170
- type: 'submit',
171
- style: {
172
- minWidth: 150,
173
- fontWeight: 600,
174
- },
175
- },
176
- ];
177
- }, [initialData, isConfirmButtonLoading, modifiedData, formatMessage, handleToggleModal]);
178
-
179
- const showLoader = isLoadingForPermissions || isLoading;
94
+ const { isLoading: isSubmittingForm } = submitMutation;
95
+
96
+ const handleSubmit = async body => {
97
+ lockApp();
98
+
99
+ const urlConfirmation = body.email_confirmation ? body.email_confirmation_redirection : '';
100
+
101
+ await submitMutation.mutateAsync({ ...body, email_confirmation_redirection: urlConfirmation });
102
+ };
103
+
104
+ if (isLoading) {
105
+ return (
106
+ <Main aria-busy="true">
107
+ <SettingsPageTitle
108
+ name={formatMessage({
109
+ id: getTrad('HeaderNav.link.advancedSettings'),
110
+ defaultMessage: 'Advanced Settings',
111
+ })}
112
+ />
113
+ <HeaderLayout
114
+ title={formatMessage({
115
+ id: getTrad('HeaderNav.link.advancedSettings'),
116
+ defaultMessage: 'Advanced Settings',
117
+ })}
118
+ />
119
+ <ContentLayout>
120
+ <LoadingIndicatorPage />
121
+ </ContentLayout>
122
+ </Main>
123
+ );
124
+ }
180
125
 
181
126
  return (
182
- <>
183
- <SettingsPageTitle name={pageTitle} />
184
- <div>
185
- <form onSubmit={handleSubmit}>
186
- <Header actions={headerActions} title={{ label: pageTitle }} isLoading={showLoader} />
187
- <ListBaselineAlignment />
188
- <FormBloc title={formTitle} isLoading={showLoader}>
189
- {form.map(input => {
190
- return (
191
- <SizedInput
192
- key={input.name}
193
- {...input}
194
- disabled={!canUpdate}
195
- onChange={handleChange}
196
- options={roles}
197
- value={modifiedData[input.name]}
198
- />
199
- );
200
- })}
201
- </FormBloc>
202
- </form>
203
- </div>
204
- <PopUpWarning
205
- isOpen={showModalWarning}
206
- toggleModal={handleToggleModal}
207
- content={{
208
- title: getTrad('popUpWarning.title'),
209
- message: getTrad('popUpWarning.warning.cancel'),
210
- cancel: getTrad('popUpWarning.button.cancel'),
211
- confirm: getTrad('popUpWarning.button.confirm'),
212
- }}
213
- popUpWarningType="danger"
214
- onConfirm={handleConfirmReset}
127
+ <Main aria-busy={isSubmittingForm}>
128
+ <SettingsPageTitle
129
+ name={formatMessage({
130
+ id: getTrad('HeaderNav.link.advancedSettings'),
131
+ defaultMessage: 'Advanced Settings',
132
+ })}
215
133
  />
216
- </>
134
+ <Formik
135
+ onSubmit={handleSubmit}
136
+ initialValues={data.settings}
137
+ validateOnChange={false}
138
+ validationSchema={schema}
139
+ enableReinitialize
140
+ >
141
+ {({ errors, values, handleChange, isSubmitting }) => {
142
+ return (
143
+ <Form>
144
+ <HeaderLayout
145
+ title={formatMessage({
146
+ id: getTrad('HeaderNav.link.advancedSettings'),
147
+ defaultMessage: 'Advanced Settings',
148
+ })}
149
+ primaryAction={
150
+ <Button
151
+ loading={isSubmitting}
152
+ type="submit"
153
+ disabled={!canUpdate}
154
+ startIcon={<Check />}
155
+ size="L"
156
+ >
157
+ {formatMessage({ id: getTrad('Form.save'), defaultMessage: 'Save' })}
158
+ </Button>
159
+ }
160
+ />
161
+ <ContentLayout>
162
+ <Box
163
+ background="neutral0"
164
+ hasRadius
165
+ shadow="filterShadow"
166
+ paddingTop={6}
167
+ paddingBottom={6}
168
+ paddingLeft={7}
169
+ paddingRight={7}
170
+ >
171
+ <Stack size={4}>
172
+ <Typography variant="delta" as="h2">
173
+ {formatMessage({
174
+ id: getTrad('Form.title.advancedSettings'),
175
+ defaultMessage: 'Settings',
176
+ })}
177
+ </Typography>
178
+ <Grid gap={6}>
179
+ <GridItem col={6} s={12}>
180
+ <Select
181
+ label={formatMessage({
182
+ id: getTrad('EditForm.inputSelect.label.role'),
183
+ defaultMessage: 'Default role for authenticated users',
184
+ })}
185
+ value={values.default_role}
186
+ hint={formatMessage({
187
+ id: getTrad('EditForm.inputSelect.description.role'),
188
+ defaultMessage:
189
+ 'It will attach the new authenticated user to the selected role.',
190
+ })}
191
+ onChange={e =>
192
+ handleChange({ target: { name: 'default_role', value: e } })}
193
+ >
194
+ {data.roles.map(role => {
195
+ return (
196
+ <Option key={role.type} value={role.type}>
197
+ {role.name}
198
+ </Option>
199
+ );
200
+ })}
201
+ </Select>
202
+ </GridItem>
203
+ {layout.map(input => {
204
+ let value = values[input.name];
205
+
206
+ if (!value) {
207
+ value = input.type === 'bool' ? false : '';
208
+ }
209
+
210
+ return (
211
+ <GridItem key={input.name} {...input.size}>
212
+ <GenericInput
213
+ {...input}
214
+ value={value}
215
+ error={errors[input.name]}
216
+ disabled={
217
+ input.name === 'email_confirmation_redirection' &&
218
+ values.email_confirmation === false
219
+ }
220
+ onChange={handleChange}
221
+ />
222
+ </GridItem>
223
+ );
224
+ })}
225
+ </Grid>
226
+ </Stack>
227
+ </Box>
228
+ </ContentLayout>
229
+ </Form>
230
+ );
231
+ }}
232
+ </Formik>
233
+ </Main>
217
234
  );
218
235
  };
219
236
 
220
- export default AdvancedSettingsPage;
237
+ export default ProtectedAdvancedSettingsPage;
@@ -0,0 +1,13 @@
1
+ import { axiosInstance, getRequestURL } from '../../../utils';
2
+
3
+ const fetchData = async () => {
4
+ const { data } = await axiosInstance.get(getRequestURL('advanced'));
5
+
6
+ return data;
7
+ };
8
+
9
+ const putAdvancedSettings = body => {
10
+ return axiosInstance.put(getRequestURL('advanced'), body);
11
+ };
12
+
13
+ export { fetchData, putAdvancedSettings };
@@ -0,0 +1,96 @@
1
+ import { getTrad } from '../../../utils';
2
+
3
+ const layout = [
4
+ {
5
+ intlLabel: {
6
+ id: getTrad('EditForm.inputToggle.label.email'),
7
+ defaultMessage: 'One account per email address',
8
+ },
9
+ description: {
10
+ id: getTrad('EditForm.inputToggle.description.email'),
11
+ defaultMessage:
12
+ 'Disallow the user to create multiple accounts using the same email address with different authentication providers.',
13
+ },
14
+ name: 'unique_email',
15
+ type: 'bool',
16
+ size: {
17
+ col: 12,
18
+ xs: 12,
19
+ },
20
+ },
21
+ {
22
+ intlLabel: {
23
+ id: getTrad('EditForm.inputToggle.label.sign-up'),
24
+ defaultMessage: 'Enable sign-ups',
25
+ },
26
+ description: {
27
+ id: getTrad('EditForm.inputToggle.description.sign-up'),
28
+ defaultMessage:
29
+ 'When disabled (OFF), the registration process is forbidden. No one can subscribe anymore no matter the used provider.',
30
+ },
31
+ name: 'allow_register',
32
+ type: 'bool',
33
+ size: {
34
+ col: 12,
35
+ xs: 12,
36
+ },
37
+ },
38
+ {
39
+ intlLabel: {
40
+ id: getTrad('EditForm.inputToggle.label.email-reset-password'),
41
+ defaultMessage: 'Reset password page',
42
+ },
43
+ description: {
44
+ id: getTrad('EditForm.inputToggle.description.email-reset-password'),
45
+ defaultMessage: "URL of your application's reset password page.",
46
+ },
47
+ placeholder: {
48
+ id: getTrad('EditForm.inputToggle.placeholder.email-reset-password'),
49
+ defaultMessage: 'ex: https://youtfrontend.com/reset-password',
50
+ },
51
+ name: 'email_reset_password',
52
+ type: 'text',
53
+ size: {
54
+ col: 6,
55
+ xs: 12,
56
+ },
57
+ },
58
+ {
59
+ intlLabel: {
60
+ id: getTrad('EditForm.inputToggle.label.email-confirmation'),
61
+ defaultMessage: 'Enable email confirmation',
62
+ },
63
+ description: {
64
+ id: getTrad('EditForm.inputToggle.description.email-confirmation'),
65
+ defaultMessage: 'When enabled (ON), new registered users receive a confirmation email.',
66
+ },
67
+ name: 'email_confirmation',
68
+ type: 'bool',
69
+ size: {
70
+ col: 12,
71
+ xs: 12,
72
+ },
73
+ },
74
+ {
75
+ intlLabel: {
76
+ id: getTrad('EditForm.inputToggle.label.email-confirmation-redirection'),
77
+ defaultMessage: 'Redirection url',
78
+ },
79
+ description: {
80
+ id: getTrad('EditForm.inputToggle.description.email-confirmation-redirection'),
81
+ defaultMessage: 'After you confirmed your email, choose where you will be redirected.',
82
+ },
83
+ placeholder: {
84
+ id: getTrad('EditForm.inputToggle.placeholder.email-reset-password'),
85
+ defaultMessage: 'ex: https://youtfrontend.com/reset-password',
86
+ },
87
+ name: 'email_confirmation_redirection',
88
+ type: 'text',
89
+ size: {
90
+ col: 6,
91
+ xs: 12,
92
+ },
93
+ },
94
+ ];
95
+
96
+ export default layout;
@@ -0,0 +1,22 @@
1
+ import * as yup from 'yup';
2
+ import { translatedErrors } from '@strapi/helper-plugin';
3
+
4
+ const URL_REGEX = new RegExp('(^$)|((https?://.*)(d*)/?(.*))');
5
+
6
+ const schema = yup.object().shape({
7
+ email_confirmation_redirection: yup
8
+ .string(translatedErrors.string)
9
+ .matches(URL_REGEX, translatedErrors.regex)
10
+ .nullable()
11
+ .when('email_confirmation', {
12
+ is: true,
13
+ then: yup.string().required(translatedErrors.required),
14
+ otherwise: yup.string(),
15
+ }),
16
+ email_reset_password: yup
17
+ .string(translatedErrors.string)
18
+ .matches(URL_REGEX, translatedErrors.regex)
19
+ .nullable(),
20
+ });
21
+
22
+ export default schema;