@strapi/plugin-users-permissions 4.0.0-next.9 → 4.0.3

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 (178) 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 +0 -8
  19. package/admin/src/pages/AdvancedSettings/index.js +203 -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 +21 -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 +117 -197
  26. package/admin/src/pages/EmailTemplates/utils/api.js +13 -0
  27. package/admin/src/pages/Providers/index.js +206 -221
  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/translations/ar.json +0 -8
  36. package/admin/src/translations/cs.json +0 -8
  37. package/admin/src/translations/de.json +0 -8
  38. package/admin/src/translations/dk.json +0 -8
  39. package/admin/src/translations/en.json +33 -12
  40. package/admin/src/translations/es.json +0 -8
  41. package/admin/src/translations/fr.json +0 -8
  42. package/admin/src/translations/id.json +0 -8
  43. package/admin/src/translations/it.json +0 -8
  44. package/admin/src/translations/ja.json +0 -8
  45. package/admin/src/translations/ko.json +93 -54
  46. package/admin/src/translations/ms.json +0 -8
  47. package/admin/src/translations/nl.json +0 -8
  48. package/admin/src/translations/pl.json +0 -8
  49. package/admin/src/translations/pt-BR.json +0 -8
  50. package/admin/src/translations/pt.json +0 -8
  51. package/admin/src/translations/ru.json +0 -8
  52. package/admin/src/translations/sk.json +0 -8
  53. package/admin/src/translations/sv.json +0 -8
  54. package/admin/src/translations/th.json +0 -8
  55. package/admin/src/translations/tr.json +0 -8
  56. package/admin/src/translations/uk.json +0 -8
  57. package/admin/src/translations/vi.json +0 -8
  58. package/admin/src/translations/zh-Hans.json +5 -14
  59. package/admin/src/translations/zh.json +0 -8
  60. package/admin/src/utils/axiosInstance.js +36 -0
  61. package/admin/src/utils/formatPluginName.js +26 -0
  62. package/admin/src/utils/index.js +1 -0
  63. package/documentation/1.0.0/overrides/users-permissions-Role.json +6 -6
  64. package/documentation/1.0.0/overrides/users-permissions-User.json +7 -7
  65. package/jest.config.front.js +10 -0
  66. package/package.json +36 -33
  67. package/server/bootstrap/index.js +19 -21
  68. package/server/config.js +3 -3
  69. package/server/content-types/index.js +3 -3
  70. package/server/content-types/permission/index.js +30 -3
  71. package/server/content-types/role/index.js +47 -3
  72. package/server/content-types/user/index.js +65 -4
  73. package/server/controllers/auth.js +82 -245
  74. package/server/controllers/content-manager-user.js +183 -0
  75. package/server/controllers/index.js +12 -6
  76. package/server/controllers/permissions.js +26 -0
  77. package/server/controllers/role.js +77 -0
  78. package/server/controllers/settings.js +85 -0
  79. package/server/controllers/user.js +119 -45
  80. package/server/controllers/validation/auth.js +29 -0
  81. package/server/controllers/validation/user.js +38 -0
  82. package/server/graphql/index.js +44 -0
  83. package/server/graphql/mutations/auth/email-confirmation.js +39 -0
  84. package/server/graphql/mutations/auth/forgot-password.js +38 -0
  85. package/server/graphql/mutations/auth/login.js +38 -0
  86. package/server/graphql/mutations/auth/register.js +39 -0
  87. package/server/graphql/mutations/auth/reset-password.js +41 -0
  88. package/server/graphql/mutations/crud/role/create-role.js +37 -0
  89. package/server/graphql/mutations/crud/role/delete-role.js +28 -0
  90. package/server/graphql/mutations/crud/role/update-role.js +38 -0
  91. package/server/graphql/mutations/crud/user/create-user.js +48 -0
  92. package/server/graphql/mutations/crud/user/delete-user.js +42 -0
  93. package/server/graphql/mutations/crud/user/update-user.js +49 -0
  94. package/server/graphql/mutations/index.js +42 -0
  95. package/server/graphql/queries/index.js +13 -0
  96. package/server/graphql/queries/me.js +17 -0
  97. package/server/graphql/resolvers-configs.js +37 -0
  98. package/server/graphql/types/create-role-payload.js +11 -0
  99. package/server/graphql/types/delete-role-payload.js +11 -0
  100. package/server/graphql/types/index.js +21 -0
  101. package/server/graphql/types/login-input.js +13 -0
  102. package/server/graphql/types/login-payload.js +12 -0
  103. package/server/graphql/types/me-role.js +14 -0
  104. package/server/graphql/types/me.js +16 -0
  105. package/server/graphql/types/password-payload.js +11 -0
  106. package/server/graphql/types/register-input.js +13 -0
  107. package/server/graphql/types/update-role-payload.js +11 -0
  108. package/server/graphql/utils.js +27 -0
  109. package/server/index.js +21 -0
  110. package/server/middlewares/index.js +2 -2
  111. package/server/{policies → middlewares}/rateLimit.js +3 -7
  112. package/server/register.js +11 -0
  113. package/server/routes/admin/index.js +10 -0
  114. package/server/routes/admin/permissions.js +20 -0
  115. package/server/routes/admin/role.js +79 -0
  116. package/server/routes/admin/settings.js +95 -0
  117. package/server/routes/content-api/auth.js +73 -0
  118. package/server/routes/content-api/index.js +11 -0
  119. package/server/routes/content-api/permissions.js +9 -0
  120. package/server/routes/content-api/role.js +29 -0
  121. package/server/routes/content-api/user.js +61 -0
  122. package/server/routes/index.js +4 -428
  123. package/server/services/index.js +10 -8
  124. package/server/services/jwt.js +9 -17
  125. package/server/services/providers.js +32 -33
  126. package/server/services/role.js +177 -0
  127. package/server/services/user.js +23 -22
  128. package/server/services/users-permissions.js +140 -338
  129. package/server/strategies/users-permissions.js +123 -0
  130. package/server/utils/index.d.ts +2 -0
  131. package/strapi-admin.js +3 -0
  132. package/strapi-server.js +1 -19
  133. package/admin/src/assets/images/logo.svg +0 -1
  134. package/admin/src/components/BaselineAlignement/index.js +0 -33
  135. package/admin/src/components/Bloc/index.js +0 -10
  136. package/admin/src/components/BoundRoute/Components.js +0 -78
  137. package/admin/src/components/ContainerFluid/index.js +0 -13
  138. package/admin/src/components/FormBloc/index.js +0 -61
  139. package/admin/src/components/IntlInput/index.js +0 -38
  140. package/admin/src/components/ListBaselineAlignment/index.js +0 -8
  141. package/admin/src/components/ListRow/Components.js +0 -74
  142. package/admin/src/components/ListRow/index.js +0 -35
  143. package/admin/src/components/ModalForm/Wrapper.js +0 -12
  144. package/admin/src/components/ModalForm/index.js +0 -59
  145. package/admin/src/components/Permissions/ListWrapper.js +0 -9
  146. package/admin/src/components/Permissions/PermissionRow/BaselineAlignment.js +0 -7
  147. package/admin/src/components/Permissions/PermissionRow/RowStyle.js +0 -28
  148. package/admin/src/components/Permissions/PermissionRow/SubCategory/ConditionsButtonWrapper.js +0 -13
  149. package/admin/src/components/Permissions/PermissionRow/SubCategory/PolicyWrapper.js +0 -8
  150. package/admin/src/components/Permissions/PermissionRow/SubCategory/SubCategoryWrapper.js +0 -26
  151. package/admin/src/components/Permissions/PermissionRow/SubCategory/index.js +0 -116
  152. package/admin/src/components/Policies/Components.js +0 -26
  153. package/admin/src/components/PrefixedIcon/index.js +0 -27
  154. package/admin/src/components/Roles/EmptyRole/BaselineAlignment.js +0 -7
  155. package/admin/src/components/Roles/EmptyRole/index.js +0 -27
  156. package/admin/src/components/Roles/RoleListWrapper/index.js +0 -17
  157. package/admin/src/components/Roles/RoleRow/RoleDescription.js +0 -9
  158. package/admin/src/components/Roles/RoleRow/index.js +0 -45
  159. package/admin/src/components/Roles/index.js +0 -3
  160. package/admin/src/components/SizedInput/index.js +0 -24
  161. package/admin/src/pages/AdvancedSettings/reducer.js +0 -65
  162. package/admin/src/pages/AdvancedSettings/utils/form.js +0 -52
  163. package/admin/src/pages/EmailTemplates/CustomTextInput.js +0 -105
  164. package/admin/src/pages/EmailTemplates/Wrapper.js +0 -36
  165. package/admin/src/pages/EmailTemplates/reducer.js +0 -58
  166. package/admin/src/pages/EmailTemplates/utils/forms.js +0 -81
  167. package/admin/src/pages/Roles/ListPage/BaselineAlignment.js +0 -8
  168. package/server/content-types/permission/schema.json +0 -48
  169. package/server/content-types/role/schema.json +0 -46
  170. package/server/content-types/user/schema.json +0 -66
  171. package/server/controllers/user/admin.js +0 -230
  172. package/server/controllers/user/api.js +0 -174
  173. package/server/controllers/users-permissions.js +0 -271
  174. package/server/middlewares/users-permissions.js +0 -44
  175. package/server/policies/index.js +0 -11
  176. package/server/policies/isAuthenticated.js +0 -9
  177. package/server/policies/permissions.js +0 -94
  178. package/server/schema.graphql.js +0 -317
@@ -1,23 +1,33 @@
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
- CheckPagePermissions,
14
+ useRBAC,
15
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';
16
26
  import pluginPermissions from '../../permissions';
17
- import { getTrad, getRequestURL } from '../../utils';
18
- import ListBaselineAlignment from '../../components/ListBaselineAlignment';
19
- import form from './utils/form';
20
- 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';
21
31
 
22
32
  const ProtectedAdvancedSettingsPage = () => (
23
33
  <CheckPagePermissions permissions={pluginPermissions.readAdvancedSettings}>
@@ -29,198 +39,198 @@ const AdvancedSettingsPage = () => {
29
39
  const { formatMessage } = useIntl();
30
40
  const toggleNotification = useNotification();
31
41
  const { lockApp, unlockApp } = useOverlayBlocker();
32
- const [showModalWarning, setShowModalWarning] = useState(false);
33
- const pageTitle = formatMessage({ id: getTrad('HeaderNav.link.advancedSettings') });
34
- const formTitle = formatMessage({
35
- id: getTrad('Form.title.advancedSettings'),
36
- defaultMessage: 'Settings',
37
- });
42
+ const { notifyStatus } = useNotifyAT();
43
+ const queryClient = useQueryClient();
44
+ useFocusWhenNavigate();
38
45
 
39
- const updatePermissions = useMemo(() => {
40
- return { update: pluginPermissions.updateAdvancedSettings };
41
- }, []);
46
+ const updatePermissions = useMemo(
47
+ () => ({ update: pluginPermissions.updateAdvancedSettings }),
48
+ []
49
+ );
42
50
  const {
43
51
  isLoading: isLoadingForPermissions,
44
52
  allowedActions: { canUpdate },
45
53
  } = useRBAC(updatePermissions);
46
- const [
47
- { initialData, isConfirmButtonLoading, isLoading, modifiedData, roles },
48
- dispatch,
49
- ] = useReducer(reducer, initialState);
50
- const isMounted = useRef(true);
51
- const abortController = new AbortController();
52
- const { signal } = abortController;
53
-
54
- useEffect(() => {
55
- const getData = async () => {
56
- try {
57
- dispatch({
58
- type: 'GET_DATA',
59
- });
60
-
61
- const data = await request(getRequestURL('advanced'), { method: 'GET', signal });
62
-
63
- dispatch({
64
- type: 'GET_DATA_SUCCEEDED',
65
- data,
66
- });
67
- } catch (err) {
68
- if (isMounted.current) {
69
- dispatch({
70
- type: 'GET_DATA_ERROR',
71
- });
72
- console.error(err);
73
- toggleNotification({
74
- type: 'warning',
75
- message: { id: 'notification.error' },
76
- });
77
- }
78
- }
79
- };
80
-
81
- if (!isLoadingForPermissions) {
82
- getData();
83
- }
84
-
85
- return () => {
86
- abortController.abort();
87
- isMounted.current = false;
88
- };
89
-
90
- // eslint-disable-next-line react-hooks/exhaustive-deps
91
- }, [isLoadingForPermissions]);
92
-
93
- const handleChange = useCallback(({ target }) => {
94
- dispatch({
95
- type: 'ON_CHANGE',
96
- keys: target.name,
97
- value: target.value,
98
- });
99
- }, []);
100
-
101
- const handleSubmit = useCallback(
102
- async e => {
103
- e.preventDefault();
104
-
105
- try {
106
- dispatch({
107
- type: 'ON_SUBMIT',
108
- });
109
-
110
- lockApp();
111
- await request(getRequestURL('advanced'), { method: 'PUT', body: modifiedData });
112
-
113
- dispatch({
114
- type: 'ON_SUBMIT_SUCCEEDED',
115
- });
116
-
117
- toggleNotification({
118
- type: 'success',
119
- message: { id: getTrad('notification.success.submit') },
120
- });
121
- } catch (err) {
122
- dispatch({
123
- type: 'ON_SUBMIT_ERROR',
124
- });
125
- console.error(err);
126
- toggleNotification({
127
- type: 'warning',
128
- message: { id: 'notification.error' },
129
- });
130
- }
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
+ });
131
81
 
132
82
  unlockApp();
133
83
  },
134
- [lockApp, modifiedData, toggleNotification, unlockApp]
135
- );
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
+ });
136
93
 
137
- const handleConfirmReset = useCallback(() => {
138
- dispatch({
139
- type: 'ON_RESET',
140
- });
141
-
142
- setShowModalWarning(false);
143
- }, []);
144
-
145
- const handleToggleModal = useCallback(() => {
146
- setShowModalWarning(prev => !prev);
147
- }, []);
148
-
149
- const headerActions = useMemo(() => {
150
- const isDisabled = isEqual(initialData, modifiedData);
151
-
152
- return [
153
- {
154
- disabled: isDisabled,
155
- onClick: () => {
156
- handleToggleModal();
157
- },
158
- color: 'cancel',
159
- label: formatMessage({
160
- id: 'app.components.Button.reset',
161
- }),
162
-
163
- type: 'button',
164
- style: {
165
- paddingLeft: 15,
166
- paddingRight: 15,
167
- fontWeight: 600,
168
- },
169
- },
170
- {
171
- disabled: isDisabled,
172
- color: 'success',
173
- label: formatMessage({
174
- id: 'app.components.Button.save',
175
- }),
176
- isLoading: isConfirmButtonLoading,
177
- type: 'submit',
178
- style: {
179
- minWidth: 150,
180
- fontWeight: 600,
181
- },
182
- },
183
- ];
184
- }, [initialData, isConfirmButtonLoading, modifiedData, formatMessage, handleToggleModal]);
185
-
186
- 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
+ }
187
125
 
188
126
  return (
189
- <>
190
- <SettingsPageTitle name={pageTitle} />
191
- <div>
192
- <form onSubmit={handleSubmit}>
193
- <Header actions={headerActions} title={{ label: pageTitle }} isLoading={showLoader} />
194
- <ListBaselineAlignment />
195
- <FormBloc title={formTitle} isLoading={showLoader}>
196
- {form.map(input => {
197
- return (
198
- <SizedInput
199
- key={input.name}
200
- {...input}
201
- disabled={!canUpdate}
202
- onChange={handleChange}
203
- options={roles}
204
- value={modifiedData[input.name]}
205
- />
206
- );
207
- })}
208
- </FormBloc>
209
- </form>
210
- </div>
211
- <PopUpWarning
212
- isOpen={showModalWarning}
213
- toggleModal={handleToggleModal}
214
- content={{
215
- title: getTrad('popUpWarning.title'),
216
- message: getTrad('popUpWarning.warning.cancel'),
217
- cancel: getTrad('popUpWarning.button.cancel'),
218
- confirm: getTrad('popUpWarning.button.confirm'),
219
- }}
220
- popUpWarningType="danger"
221
- onConfirm={handleConfirmReset}
127
+ <Main aria-busy={isSubmittingForm}>
128
+ <SettingsPageTitle
129
+ name={formatMessage({
130
+ id: getTrad('HeaderNav.link.advancedSettings'),
131
+ defaultMessage: 'Advanced Settings',
132
+ })}
222
133
  />
223
- </>
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>
224
234
  );
225
235
  };
226
236
 
@@ -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,21 @@
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.mixed().when('email_confirmation', {
8
+ is: true,
9
+ then: yup
10
+ .string()
11
+ .matches(URL_REGEX)
12
+ .required(),
13
+ otherwise: yup.string().nullable(),
14
+ }),
15
+ email_reset_password: yup
16
+ .string(translatedErrors.string)
17
+ .matches(URL_REGEX, translatedErrors.regex)
18
+ .nullable(),
19
+ });
20
+
21
+ export default schema;