@strapi/plugin-users-permissions 4.7.0 → 4.7.2-exp.24dd7d95972fa822bf43e9b095b51027402c229e
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.
- package/admin/src/components/BoundRoute/index.js +5 -5
- package/admin/src/components/FormModal/index.js +3 -3
- package/admin/src/components/Permissions/index.js +3 -3
- package/admin/src/components/Policies/index.js +5 -5
- package/admin/src/components/UsersPermissions/index.js +5 -5
- package/admin/src/pages/AdvancedSettings/index.js +3 -3
- package/admin/src/pages/Roles/CreatePage/index.js +5 -5
- package/admin/src/pages/Roles/EditPage/index.js +5 -5
- package/package.json +25 -10
- package/server/content-types/user/index.js +3 -0
- package/server/controllers/user.js +17 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
|
-
import {
|
|
3
|
+
import { Flex, Box, Typography } from '@strapi/design-system';
|
|
4
4
|
import map from 'lodash/map';
|
|
5
5
|
import tail from 'lodash/tail';
|
|
6
6
|
import { useIntl } from 'react-intl';
|
|
@@ -21,7 +21,7 @@ function BoundRoute({ route }) {
|
|
|
21
21
|
const colors = getMethodColor(route.method);
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
|
-
<
|
|
24
|
+
<Flex direction="column" alignItems="stretch" gap={2}>
|
|
25
25
|
<Typography variant="delta" as="h3">
|
|
26
26
|
{formatMessage({
|
|
27
27
|
id: 'users-permissions.BoundRoute.title',
|
|
@@ -33,7 +33,7 @@ function BoundRoute({ route }) {
|
|
|
33
33
|
.{action}
|
|
34
34
|
</Typography>
|
|
35
35
|
</Typography>
|
|
36
|
-
<
|
|
36
|
+
<Flex hasRadius background="neutral0" borderColor="neutral200" gap={0}>
|
|
37
37
|
<MethodBox background={colors.background} borderColor={colors.border} padding={2}>
|
|
38
38
|
<Typography fontWeight="bold" textColor={colors.text}>
|
|
39
39
|
{method}
|
|
@@ -46,8 +46,8 @@ function BoundRoute({ route }) {
|
|
|
46
46
|
</Typography>
|
|
47
47
|
))}
|
|
48
48
|
</Box>
|
|
49
|
-
</
|
|
50
|
-
</
|
|
49
|
+
</Flex>
|
|
50
|
+
</Flex>
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -8,7 +8,7 @@ import React from 'react';
|
|
|
8
8
|
import { useIntl } from 'react-intl';
|
|
9
9
|
import {
|
|
10
10
|
Button,
|
|
11
|
-
|
|
11
|
+
Flex,
|
|
12
12
|
Breadcrumbs,
|
|
13
13
|
Crumb,
|
|
14
14
|
Grid,
|
|
@@ -58,7 +58,7 @@ const FormModal = ({
|
|
|
58
58
|
return (
|
|
59
59
|
<Form>
|
|
60
60
|
<ModalBody>
|
|
61
|
-
<
|
|
61
|
+
<Flex direction="column" alignItems="stretch" gap={1}>
|
|
62
62
|
<Grid gap={5}>
|
|
63
63
|
{layout.form.map((row) => {
|
|
64
64
|
return row.map((input) => {
|
|
@@ -76,7 +76,7 @@ const FormModal = ({
|
|
|
76
76
|
});
|
|
77
77
|
})}
|
|
78
78
|
</Grid>
|
|
79
|
-
</
|
|
79
|
+
</Flex>
|
|
80
80
|
</ModalBody>
|
|
81
81
|
<ModalFooter
|
|
82
82
|
startActions={
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useReducer } from 'react';
|
|
2
|
-
import { Accordion, AccordionToggle, AccordionContent, Box,
|
|
2
|
+
import { Accordion, AccordionToggle, AccordionContent, Box, Flex } from '@strapi/design-system';
|
|
3
3
|
import { useIntl } from 'react-intl';
|
|
4
4
|
import { useUsersPermissions } from '../../contexts/UsersPermissionsContext';
|
|
5
5
|
import formatPluginName from '../../utils/formatPluginName';
|
|
@@ -21,7 +21,7 @@ const Permissions = () => {
|
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
|
-
<
|
|
24
|
+
<Flex direction="column" alignItems="stretch" gap={1}>
|
|
25
25
|
{collapses.map((collapse, index) => (
|
|
26
26
|
<Accordion
|
|
27
27
|
expanded={collapse.isOpen}
|
|
@@ -47,7 +47,7 @@ const Permissions = () => {
|
|
|
47
47
|
</AccordionContent>
|
|
48
48
|
</Accordion>
|
|
49
49
|
))}
|
|
50
|
-
</
|
|
50
|
+
</Flex>
|
|
51
51
|
);
|
|
52
52
|
};
|
|
53
53
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useIntl } from 'react-intl';
|
|
3
|
-
import { Typography,
|
|
3
|
+
import { Typography, Flex, GridItem } from '@strapi/design-system';
|
|
4
4
|
import { get, isEmpty, without } from 'lodash';
|
|
5
5
|
import { useUsersPermissions } from '../../contexts/UsersPermissionsContext';
|
|
6
6
|
import BoundRoute from '../BoundRoute';
|
|
@@ -28,14 +28,14 @@ const Policies = () => {
|
|
|
28
28
|
style={{ minHeight: '100%' }}
|
|
29
29
|
>
|
|
30
30
|
{selectedAction ? (
|
|
31
|
-
<
|
|
31
|
+
<Flex direction="column" alignItems="stretch" gap={2}>
|
|
32
32
|
{displayedRoutes.map((route, key) => (
|
|
33
33
|
// eslint-disable-next-line react/no-array-index-key
|
|
34
34
|
<BoundRoute key={key} route={route} />
|
|
35
35
|
))}
|
|
36
|
-
</
|
|
36
|
+
</Flex>
|
|
37
37
|
) : (
|
|
38
|
-
<
|
|
38
|
+
<Flex direction="column" alignItems="stretch" gap={2}>
|
|
39
39
|
<Typography variant="delta" as="h3">
|
|
40
40
|
{formatMessage({
|
|
41
41
|
id: 'users-permissions.Policies.header.title',
|
|
@@ -49,7 +49,7 @@ const Policies = () => {
|
|
|
49
49
|
"Select the application's actions or the plugin's actions and click on the cog icon to display the bound route",
|
|
50
50
|
})}
|
|
51
51
|
</Typography>
|
|
52
|
-
</
|
|
52
|
+
</Flex>
|
|
53
53
|
)}
|
|
54
54
|
</GridItem>
|
|
55
55
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { memo, useReducer, forwardRef, useImperativeHandle } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { Typography,
|
|
3
|
+
import { Typography, Flex, Grid, GridItem } from '@strapi/design-system';
|
|
4
4
|
import { useIntl } from 'react-intl';
|
|
5
5
|
import getTrad from '../../utils/getTrad';
|
|
6
6
|
import Policies from '../Policies';
|
|
@@ -60,8 +60,8 @@ const UsersPermissions = forwardRef(({ permissions, routes }, ref) => {
|
|
|
60
60
|
<UsersPermissionsProvider value={providerValue}>
|
|
61
61
|
<Grid gap={0} shadow="filterShadow" hasRadius background="neutral0">
|
|
62
62
|
<GridItem col={7} paddingTop={6} paddingBottom={6} paddingLeft={7} paddingRight={7}>
|
|
63
|
-
<
|
|
64
|
-
<
|
|
63
|
+
<Flex direction="column" alignItems="stretch" gap={6}>
|
|
64
|
+
<Flex direction="column" alignItems="stretch" gap={2}>
|
|
65
65
|
<Typography variant="delta" as="h2">
|
|
66
66
|
{formatMessage({
|
|
67
67
|
id: getTrad('Plugins.header.title'),
|
|
@@ -74,9 +74,9 @@ const UsersPermissions = forwardRef(({ permissions, routes }, ref) => {
|
|
|
74
74
|
defaultMessage: 'Only actions bound by a route are listed below.',
|
|
75
75
|
})}
|
|
76
76
|
</Typography>
|
|
77
|
-
</
|
|
77
|
+
</Flex>
|
|
78
78
|
<Permissions />
|
|
79
|
-
</
|
|
79
|
+
</Flex>
|
|
80
80
|
</GridItem>
|
|
81
81
|
<Policies />
|
|
82
82
|
</Grid>
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
ContentLayout,
|
|
21
21
|
Button,
|
|
22
22
|
Box,
|
|
23
|
-
|
|
23
|
+
Flex,
|
|
24
24
|
Select,
|
|
25
25
|
Option,
|
|
26
26
|
Typography,
|
|
@@ -173,7 +173,7 @@ const AdvancedSettingsPage = () => {
|
|
|
173
173
|
paddingLeft={7}
|
|
174
174
|
paddingRight={7}
|
|
175
175
|
>
|
|
176
|
-
<
|
|
176
|
+
<Flex direction="column" alignItems="stretch" gap={4}>
|
|
177
177
|
<Typography variant="delta" as="h2">
|
|
178
178
|
{formatMessage({
|
|
179
179
|
id: 'global.settings',
|
|
@@ -229,7 +229,7 @@ const AdvancedSettingsPage = () => {
|
|
|
229
229
|
);
|
|
230
230
|
})}
|
|
231
231
|
</Grid>
|
|
232
|
-
</
|
|
232
|
+
</Flex>
|
|
233
233
|
</Box>
|
|
234
234
|
</ContentLayout>
|
|
235
235
|
</Form>
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
HeaderLayout,
|
|
6
6
|
Main,
|
|
7
7
|
Button,
|
|
8
|
-
|
|
8
|
+
Flex,
|
|
9
9
|
Box,
|
|
10
10
|
TextInput,
|
|
11
11
|
Textarea,
|
|
@@ -107,7 +107,7 @@ const EditPage = () => {
|
|
|
107
107
|
})}
|
|
108
108
|
/>
|
|
109
109
|
<ContentLayout>
|
|
110
|
-
<
|
|
110
|
+
<Flex direction="column" alignItems="stretch" gap={7}>
|
|
111
111
|
<Box
|
|
112
112
|
background="neutral0"
|
|
113
113
|
hasRadius
|
|
@@ -117,7 +117,7 @@ const EditPage = () => {
|
|
|
117
117
|
paddingLeft={7}
|
|
118
118
|
paddingRight={7}
|
|
119
119
|
>
|
|
120
|
-
<
|
|
120
|
+
<Flex direction="column" alignItems="stretch" gap={4}>
|
|
121
121
|
<Typography variant="delta" as="h2">
|
|
122
122
|
{formatMessage({
|
|
123
123
|
id: getTrad('EditPage.form.roles'),
|
|
@@ -161,7 +161,7 @@ const EditPage = () => {
|
|
|
161
161
|
/>
|
|
162
162
|
</GridItem>
|
|
163
163
|
</Grid>
|
|
164
|
-
</
|
|
164
|
+
</Flex>
|
|
165
165
|
</Box>
|
|
166
166
|
{!isLoadingPlugins && (
|
|
167
167
|
<UsersPermissions
|
|
@@ -170,7 +170,7 @@ const EditPage = () => {
|
|
|
170
170
|
routes={routes}
|
|
171
171
|
/>
|
|
172
172
|
)}
|
|
173
|
-
</
|
|
173
|
+
</Flex>
|
|
174
174
|
</ContentLayout>
|
|
175
175
|
</Form>
|
|
176
176
|
)}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
HeaderLayout,
|
|
17
17
|
Main,
|
|
18
18
|
Button,
|
|
19
|
-
|
|
19
|
+
Flex,
|
|
20
20
|
Box,
|
|
21
21
|
TextInput,
|
|
22
22
|
Textarea,
|
|
@@ -119,7 +119,7 @@ const EditPage = () => {
|
|
|
119
119
|
}
|
|
120
120
|
/>
|
|
121
121
|
<ContentLayout>
|
|
122
|
-
<
|
|
122
|
+
<Flex direction="column" alignItems="stretch" gap={7}>
|
|
123
123
|
<Box
|
|
124
124
|
background="neutral0"
|
|
125
125
|
hasRadius
|
|
@@ -129,7 +129,7 @@ const EditPage = () => {
|
|
|
129
129
|
paddingLeft={7}
|
|
130
130
|
paddingRight={7}
|
|
131
131
|
>
|
|
132
|
-
<
|
|
132
|
+
<Flex direction="column" alignItems="stretch" gap={4}>
|
|
133
133
|
<Typography variant="delta" as="h2">
|
|
134
134
|
{formatMessage({
|
|
135
135
|
id: getTrad('EditPage.form.roles'),
|
|
@@ -173,7 +173,7 @@ const EditPage = () => {
|
|
|
173
173
|
/>
|
|
174
174
|
</GridItem>
|
|
175
175
|
</Grid>
|
|
176
|
-
</
|
|
176
|
+
</Flex>
|
|
177
177
|
</Box>
|
|
178
178
|
{!isLoadingPlugins && (
|
|
179
179
|
<UsersPermissions
|
|
@@ -182,7 +182,7 @@ const EditPage = () => {
|
|
|
182
182
|
routes={routes}
|
|
183
183
|
/>
|
|
184
184
|
)}
|
|
185
|
-
</
|
|
185
|
+
</Flex>
|
|
186
186
|
</ContentLayout>
|
|
187
187
|
</Form>
|
|
188
188
|
)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/plugin-users-permissions",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.2-exp.24dd7d95972fa822bf43e9b095b51027402c229e",
|
|
4
4
|
"description": "Protect your API with a full-authentication process based on JWT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,31 +27,46 @@
|
|
|
27
27
|
"test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@strapi/
|
|
31
|
-
"@strapi/
|
|
30
|
+
"@strapi/design-system": "1.6.3",
|
|
31
|
+
"@strapi/helper-plugin": "4.7.2-exp.24dd7d95972fa822bf43e9b095b51027402c229e",
|
|
32
|
+
"@strapi/icons": "1.6.3",
|
|
33
|
+
"@strapi/utils": "4.7.2-exp.24dd7d95972fa822bf43e9b095b51027402c229e",
|
|
32
34
|
"bcryptjs": "2.4.3",
|
|
35
|
+
"formik": "2.2.9",
|
|
33
36
|
"grant-koa": "5.4.8",
|
|
37
|
+
"immer": "9.0.19",
|
|
34
38
|
"jsonwebtoken": "9.0.0",
|
|
35
39
|
"jwk-to-pem": "2.0.5",
|
|
36
40
|
"koa": "^2.13.4",
|
|
37
41
|
"koa2-ratelimit": "^1.1.2",
|
|
38
42
|
"lodash": "4.17.21",
|
|
43
|
+
"match-sorter": "^4.0.2",
|
|
44
|
+
"prop-types": "^15.7.2",
|
|
39
45
|
"purest": "4.0.2",
|
|
40
|
-
"react": "^17.0.2",
|
|
41
|
-
"react-dom": "^17.0.2",
|
|
42
46
|
"react-intl": "6.2.8",
|
|
47
|
+
"react-query": "3.24.3",
|
|
43
48
|
"react-redux": "8.0.5",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"url-join": "4.0.1"
|
|
49
|
+
"url-join": "4.0.1",
|
|
50
|
+
"yup": "^0.32.9"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
53
|
"@testing-library/dom": "8.19.0",
|
|
50
54
|
"@testing-library/react": "12.1.4",
|
|
51
55
|
"@testing-library/react-hooks": "8.0.1",
|
|
52
56
|
"@testing-library/user-event": "14.4.3",
|
|
57
|
+
"history": "^4.9.0",
|
|
53
58
|
"msw": "1.0.1",
|
|
54
|
-
"react
|
|
59
|
+
"react": "^17.0.2",
|
|
60
|
+
"react-dom": "^17.0.2",
|
|
61
|
+
"react-router-dom": "5.3.4",
|
|
62
|
+
"react-test-renderer": "^17.0.2",
|
|
63
|
+
"styled-components": "5.3.3"
|
|
64
|
+
},
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"react": "^17.0.2",
|
|
67
|
+
"react-dom": "^17.0.2",
|
|
68
|
+
"react-router-dom": "5.3.4",
|
|
69
|
+
"styled-components": "5.3.3"
|
|
55
70
|
},
|
|
56
71
|
"engines": {
|
|
57
72
|
"node": ">=14.19.1 <=18.x.x",
|
|
@@ -64,5 +79,5 @@
|
|
|
64
79
|
"required": true,
|
|
65
80
|
"kind": "plugin"
|
|
66
81
|
},
|
|
67
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "24dd7d95972fa822bf43e9b095b51027402c229e"
|
|
68
83
|
}
|
|
@@ -38,16 +38,19 @@ module.exports = {
|
|
|
38
38
|
minLength: 6,
|
|
39
39
|
configurable: false,
|
|
40
40
|
private: true,
|
|
41
|
+
searchable: false,
|
|
41
42
|
},
|
|
42
43
|
resetPasswordToken: {
|
|
43
44
|
type: 'string',
|
|
44
45
|
configurable: false,
|
|
45
46
|
private: true,
|
|
47
|
+
searchable: false,
|
|
46
48
|
},
|
|
47
49
|
confirmationToken: {
|
|
48
50
|
type: 'string',
|
|
49
51
|
configurable: false,
|
|
50
52
|
private: true,
|
|
53
|
+
searchable: false,
|
|
51
54
|
},
|
|
52
55
|
confirmed: {
|
|
53
56
|
type: 'boolean',
|
|
@@ -14,13 +14,20 @@ const { validateCreateUserBody, validateUpdateUserBody } = require('./validation
|
|
|
14
14
|
const { sanitize } = utils;
|
|
15
15
|
const { ApplicationError, ValidationError, NotFoundError } = utils.errors;
|
|
16
16
|
|
|
17
|
-
const sanitizeOutput = (user, ctx) => {
|
|
17
|
+
const sanitizeOutput = async (user, ctx) => {
|
|
18
18
|
const schema = strapi.getModel('plugin::users-permissions.user');
|
|
19
19
|
const { auth } = ctx.state;
|
|
20
20
|
|
|
21
21
|
return sanitize.contentAPI.output(user, schema, { auth });
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
const sanitizeParams = async (params, ctx) => {
|
|
25
|
+
const schema = strapi.getModel('plugin::users-permissions.user');
|
|
26
|
+
const { auth } = ctx.state;
|
|
27
|
+
|
|
28
|
+
return sanitize.contentAPI.params(params, schema, { auth });
|
|
29
|
+
};
|
|
30
|
+
|
|
24
31
|
module.exports = {
|
|
25
32
|
/**
|
|
26
33
|
* Create a/an user record.
|
|
@@ -136,7 +143,8 @@ module.exports = {
|
|
|
136
143
|
* @return {Object|Array}
|
|
137
144
|
*/
|
|
138
145
|
async find(ctx) {
|
|
139
|
-
const
|
|
146
|
+
const sanitizedParams = await sanitizeParams(ctx.query, ctx);
|
|
147
|
+
const users = await getService('user').fetchAll(sanitizedParams);
|
|
140
148
|
|
|
141
149
|
ctx.body = await Promise.all(users.map((user) => sanitizeOutput(user, ctx)));
|
|
142
150
|
},
|
|
@@ -147,9 +155,9 @@ module.exports = {
|
|
|
147
155
|
*/
|
|
148
156
|
async findOne(ctx) {
|
|
149
157
|
const { id } = ctx.params;
|
|
150
|
-
const
|
|
158
|
+
const sanitizedParams = await sanitizeParams(ctx.query, ctx);
|
|
151
159
|
|
|
152
|
-
let data = await getService('user').fetch(id,
|
|
160
|
+
let data = await getService('user').fetch(id, sanitizedParams);
|
|
153
161
|
|
|
154
162
|
if (data) {
|
|
155
163
|
data = await sanitizeOutput(data, ctx);
|
|
@@ -163,7 +171,9 @@ module.exports = {
|
|
|
163
171
|
* @return {Number}
|
|
164
172
|
*/
|
|
165
173
|
async count(ctx) {
|
|
166
|
-
|
|
174
|
+
const sanitizedParams = await sanitizeParams(ctx.query, ctx);
|
|
175
|
+
|
|
176
|
+
ctx.body = await getService('user').count(sanitizedParams);
|
|
167
177
|
},
|
|
168
178
|
|
|
169
179
|
/**
|
|
@@ -191,7 +201,8 @@ module.exports = {
|
|
|
191
201
|
return ctx.unauthorized();
|
|
192
202
|
}
|
|
193
203
|
|
|
194
|
-
const
|
|
204
|
+
const sanitizedParams = await sanitizeParams(query, ctx);
|
|
205
|
+
const user = await getService('user').fetch(authUser.id, sanitizedParams);
|
|
195
206
|
|
|
196
207
|
ctx.body = await sanitizeOutput(user, ctx);
|
|
197
208
|
},
|