@strapi/plugin-users-permissions 0.0.0-next.f426350b859ddae6592e9bfa99e6be94ae22e117 → 0.0.0-next.f4ec69568d980c6fee91ce2ee0f41c138347aa81
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/.eslintignore +1 -2
- package/.eslintrc +17 -0
- package/LICENSE +18 -3
- package/admin/src/components/BoundRoute/{index.js → index.jsx} +2 -2
- package/admin/src/components/FormModal/Input/{index.js → index.jsx} +32 -31
- package/admin/src/components/FormModal/index.jsx +115 -0
- package/admin/src/components/Permissions/PermissionRow/{CheckboxWrapper.js → CheckboxWrapper.jsx} +4 -3
- package/admin/src/components/Permissions/PermissionRow/{SubCategory.js → SubCategory.jsx} +13 -22
- package/admin/src/components/Permissions/index.jsx +47 -0
- package/admin/src/components/Permissions/reducer.js +1 -1
- package/admin/src/components/Policies/{index.js → index.jsx} +7 -5
- package/admin/src/components/UsersPermissions/{index.js → index.jsx} +15 -7
- package/admin/src/components/UsersPermissions/reducer.js +1 -1
- package/admin/src/index.js +19 -47
- package/admin/src/pages/AdvancedSettings/index.jsx +214 -0
- package/admin/src/pages/AdvancedSettings/utils/layout.js +20 -35
- package/admin/src/pages/AdvancedSettings/utils/schema.js +5 -2
- package/admin/src/pages/EmailTemplates/components/EmailForm.jsx +156 -0
- package/admin/src/pages/EmailTemplates/components/{EmailTable.js → EmailTable.jsx} +20 -17
- package/admin/src/pages/EmailTemplates/index.jsx +148 -0
- package/admin/src/pages/EmailTemplates/utils/schema.js +18 -6
- package/admin/src/pages/Providers/index.jsx +262 -0
- package/admin/src/pages/Providers/utils/forms.js +23 -11
- package/admin/src/pages/Roles/constants.js +3 -3
- package/admin/src/{hooks → pages/Roles/hooks}/usePlugins.js +19 -12
- package/admin/src/pages/Roles/index.jsx +24 -0
- package/admin/src/pages/Roles/pages/CreatePage.jsx +194 -0
- package/admin/src/pages/Roles/pages/EditPage.jsx +215 -0
- package/admin/src/pages/Roles/pages/ListPage/components/TableBody.jsx +119 -0
- package/admin/src/pages/Roles/{ListPage/index.js → pages/ListPage/index.jsx} +93 -65
- package/admin/src/translations/en.json +1 -1
- package/admin/src/translations/zh-Hans.json +80 -80
- package/admin/src/utils/prefixPluginTranslations.js +13 -0
- package/dist/_chunks/ar-BguGUqwK.js +44 -0
- package/dist/_chunks/ar-BguGUqwK.js.map +1 -0
- package/dist/_chunks/ar-CK8BRRXB.mjs +44 -0
- package/dist/_chunks/ar-CK8BRRXB.mjs.map +1 -0
- package/dist/_chunks/cs-BVigMk0l.mjs +50 -0
- package/dist/_chunks/cs-BVigMk0l.mjs.map +1 -0
- package/dist/_chunks/cs-BW8-K_GY.js +50 -0
- package/dist/_chunks/cs-BW8-K_GY.js.map +1 -0
- package/dist/_chunks/de-BKUdRFI4.mjs +62 -0
- package/dist/_chunks/de-BKUdRFI4.mjs.map +1 -0
- package/dist/_chunks/de-owXpVluI.js +62 -0
- package/dist/_chunks/de-owXpVluI.js.map +1 -0
- package/dist/_chunks/dk-BQiTK50l.mjs +86 -0
- package/dist/_chunks/dk-BQiTK50l.mjs.map +1 -0
- package/dist/_chunks/dk-LXAnbuBk.js +86 -0
- package/dist/_chunks/dk-LXAnbuBk.js.map +1 -0
- package/dist/_chunks/en-DOHtPf-2.mjs +86 -0
- package/dist/_chunks/en-DOHtPf-2.mjs.map +1 -0
- package/dist/_chunks/en-MHo5mcsU.js +86 -0
- package/dist/_chunks/en-MHo5mcsU.js.map +1 -0
- package/dist/_chunks/es-BwLCLXAQ.js +86 -0
- package/dist/_chunks/es-BwLCLXAQ.js.map +1 -0
- package/dist/_chunks/es-DNgOVMjD.mjs +86 -0
- package/dist/_chunks/es-DNgOVMjD.mjs.map +1 -0
- package/dist/_chunks/fr-DkgRugiU.mjs +50 -0
- package/dist/_chunks/fr-DkgRugiU.mjs.map +1 -0
- package/dist/_chunks/fr-DkhpSjjm.js +50 -0
- package/dist/_chunks/fr-DkhpSjjm.js.map +1 -0
- package/dist/_chunks/id-BTemOeTZ.js +62 -0
- package/dist/_chunks/id-BTemOeTZ.js.map +1 -0
- package/dist/_chunks/id-BdEsvnaF.mjs +62 -0
- package/dist/_chunks/id-BdEsvnaF.mjs.map +1 -0
- package/dist/_chunks/index-2awRBazk.js +281 -0
- package/dist/_chunks/index-2awRBazk.js.map +1 -0
- package/dist/_chunks/index-BAHBK68t.js +1172 -0
- package/dist/_chunks/index-BAHBK68t.js.map +1 -0
- package/dist/_chunks/index-BHbzbu1p.mjs +246 -0
- package/dist/_chunks/index-BHbzbu1p.mjs.map +1 -0
- package/dist/_chunks/index-Be4qNiZI.js +640 -0
- package/dist/_chunks/index-Be4qNiZI.js.map +1 -0
- package/dist/_chunks/index-C88EQQJQ-C4oUQUND.js +12026 -0
- package/dist/_chunks/index-C88EQQJQ-C4oUQUND.js.map +1 -0
- package/dist/_chunks/index-C88EQQJQ-DAZ1lfuF.mjs +12002 -0
- package/dist/_chunks/index-C88EQQJQ-DAZ1lfuF.mjs.map +1 -0
- package/dist/_chunks/index-CbKOY95_.mjs +344 -0
- package/dist/_chunks/index-CbKOY95_.mjs.map +1 -0
- package/dist/_chunks/index-CeweK3q9.mjs +617 -0
- package/dist/_chunks/index-CeweK3q9.mjs.map +1 -0
- package/dist/_chunks/index-QcDREbPt.mjs +262 -0
- package/dist/_chunks/index-QcDREbPt.mjs.map +1 -0
- package/dist/_chunks/index-YTFP-hNZ.js +245 -0
- package/dist/_chunks/index-YTFP-hNZ.js.map +1 -0
- package/dist/_chunks/index-YZkqoYZN.js +366 -0
- package/dist/_chunks/index-YZkqoYZN.js.map +1 -0
- package/dist/_chunks/index-mKh-etKG.mjs +1142 -0
- package/dist/_chunks/index-mKh-etKG.mjs.map +1 -0
- package/dist/_chunks/it-B-rv0E24.mjs +62 -0
- package/dist/_chunks/it-B-rv0E24.mjs.map +1 -0
- package/dist/_chunks/it-D1rH6V6_.js +62 -0
- package/dist/_chunks/it-D1rH6V6_.js.map +1 -0
- package/dist/_chunks/ja-C8K-VBPD.mjs +48 -0
- package/dist/_chunks/ja-C8K-VBPD.mjs.map +1 -0
- package/dist/_chunks/ja-DqShgTMf.js +48 -0
- package/dist/_chunks/ja-DqShgTMf.js.map +1 -0
- package/dist/_chunks/ko-B9DGEPWH.js +86 -0
- package/dist/_chunks/ko-B9DGEPWH.js.map +1 -0
- package/dist/_chunks/ko-Busb0wIY.mjs +86 -0
- package/dist/_chunks/ko-Busb0wIY.mjs.map +1 -0
- package/dist/_chunks/ms-ByvsQjRt.mjs +49 -0
- package/dist/_chunks/ms-ByvsQjRt.mjs.map +1 -0
- package/dist/_chunks/ms-CPBU3LWf.js +49 -0
- package/dist/_chunks/ms-CPBU3LWf.js.map +1 -0
- package/dist/_chunks/nl-5qO8Rpcy.mjs +48 -0
- package/dist/_chunks/nl-5qO8Rpcy.mjs.map +1 -0
- package/dist/_chunks/nl-CwNB6YoO.js +48 -0
- package/dist/_chunks/nl-CwNB6YoO.js.map +1 -0
- package/dist/_chunks/pl-BdIzifBE.mjs +86 -0
- package/dist/_chunks/pl-BdIzifBE.mjs.map +1 -0
- package/dist/_chunks/pl-Do9UD69f.js +86 -0
- package/dist/_chunks/pl-Do9UD69f.js.map +1 -0
- package/dist/_chunks/pt-BIO24ioG.mjs +48 -0
- package/dist/_chunks/pt-BIO24ioG.mjs.map +1 -0
- package/dist/_chunks/pt-BR-D7dZhxuP.js +44 -0
- package/dist/_chunks/pt-BR-D7dZhxuP.js.map +1 -0
- package/dist/_chunks/pt-BR-f0p23AQZ.mjs +44 -0
- package/dist/_chunks/pt-BR-f0p23AQZ.mjs.map +1 -0
- package/dist/_chunks/pt-fdvyOnUp.js +48 -0
- package/dist/_chunks/pt-fdvyOnUp.js.map +1 -0
- package/dist/_chunks/ru-C94rjPGA.js +86 -0
- package/dist/_chunks/ru-C94rjPGA.js.map +1 -0
- package/dist/_chunks/ru-VWy-IB7K.mjs +86 -0
- package/dist/_chunks/ru-VWy-IB7K.mjs.map +1 -0
- package/dist/_chunks/sk-BABEhykl.js +50 -0
- package/dist/_chunks/sk-BABEhykl.js.map +1 -0
- package/dist/_chunks/sk-B_LIcepm.mjs +50 -0
- package/dist/_chunks/sk-B_LIcepm.mjs.map +1 -0
- package/dist/_chunks/sv-ABLKOokl.mjs +86 -0
- package/dist/_chunks/sv-ABLKOokl.mjs.map +1 -0
- package/dist/_chunks/sv-Be43LhA9.js +86 -0
- package/dist/_chunks/sv-Be43LhA9.js.map +1 -0
- package/dist/_chunks/th-DKyP7ueR.mjs +60 -0
- package/dist/_chunks/th-DKyP7ueR.mjs.map +1 -0
- package/dist/_chunks/th-DgVhVLhL.js +60 -0
- package/dist/_chunks/th-DgVhVLhL.js.map +1 -0
- package/dist/_chunks/tr-B_idhkEs.js +85 -0
- package/dist/_chunks/tr-B_idhkEs.js.map +1 -0
- package/dist/_chunks/tr-qa1Q5UjC.mjs +85 -0
- package/dist/_chunks/tr-qa1Q5UjC.mjs.map +1 -0
- package/dist/_chunks/uk-BmRqbeQc.mjs +49 -0
- package/dist/_chunks/uk-BmRqbeQc.mjs.map +1 -0
- package/dist/_chunks/uk-LHOivnhP.js +49 -0
- package/dist/_chunks/uk-LHOivnhP.js.map +1 -0
- package/dist/_chunks/vi-CdVRdKDw.js +50 -0
- package/dist/_chunks/vi-CdVRdKDw.js.map +1 -0
- package/dist/_chunks/vi-HW-EdMea.mjs +50 -0
- package/dist/_chunks/vi-HW-EdMea.mjs.map +1 -0
- package/dist/_chunks/zh-5hKkVPA4.mjs +86 -0
- package/dist/_chunks/zh-5hKkVPA4.mjs.map +1 -0
- package/dist/_chunks/zh-Cuq8gMnF.js +86 -0
- package/dist/_chunks/zh-Cuq8gMnF.js.map +1 -0
- package/dist/_chunks/zh-Hans-BHilK-yc.mjs +86 -0
- package/dist/_chunks/zh-Hans-BHilK-yc.mjs.map +1 -0
- package/dist/_chunks/zh-Hans-GQDMKtY4.js +86 -0
- package/dist/_chunks/zh-Hans-GQDMKtY4.js.map +1 -0
- package/dist/admin/index.js +4 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +5 -0
- package/dist/admin/index.mjs.map +1 -0
- package/jest.config.front.js +1 -1
- package/package.json +46 -27
- package/packup.config.ts +22 -0
- package/server/bootstrap/index.js +18 -15
- package/server/bootstrap/users-permissions-actions.js +6 -0
- package/server/config.js +29 -0
- package/server/content-types/user/index.js +0 -1
- package/server/controllers/auth.js +74 -38
- package/server/controllers/content-manager-user.js +28 -30
- package/server/controllers/role.js +17 -4
- package/server/controllers/user.js +18 -8
- package/server/controllers/validation/auth.js +81 -25
- package/server/middlewares/rateLimit.js +1 -1
- package/server/register.js +1 -1
- package/server/services/jwt.js +3 -3
- package/server/services/permission.js +3 -7
- package/server/services/providers-registry.js +469 -261
- package/server/services/providers.js +10 -5
- package/server/services/role.js +15 -13
- package/server/services/user.js +56 -19
- package/server/services/users-permissions.js +15 -13
- package/server/utils/index.d.ts +2 -1
- package/server/utils/sanitize/sanitizers.js +7 -3
- package/server/utils/sanitize/visitors/remove-user-relation-from-role-entities.js +2 -2
- package/.eslintrc.js +0 -14
- package/admin/src/components/FormModal/index.js +0 -126
- package/admin/src/components/Permissions/index.js +0 -57
- package/admin/src/hooks/index.js +0 -5
- package/admin/src/hooks/useFetchRole/index.js +0 -67
- package/admin/src/hooks/useFetchRole/reducer.js +0 -31
- package/admin/src/hooks/useForm/index.js +0 -68
- package/admin/src/hooks/useForm/reducer.js +0 -40
- package/admin/src/hooks/useRolesList/index.js +0 -65
- package/admin/src/hooks/useRolesList/init.js +0 -5
- package/admin/src/hooks/useRolesList/reducer.js +0 -31
- package/admin/src/pages/AdvancedSettings/index.js +0 -242
- package/admin/src/pages/AdvancedSettings/utils/api.js +0 -16
- package/admin/src/pages/EmailTemplates/components/EmailForm.js +0 -176
- package/admin/src/pages/EmailTemplates/index.js +0 -159
- package/admin/src/pages/EmailTemplates/utils/api.js +0 -16
- package/admin/src/pages/Providers/index.js +0 -271
- package/admin/src/pages/Providers/reducer.js +0 -54
- package/admin/src/pages/Providers/utils/api.js +0 -24
- package/admin/src/pages/Providers/utils/createProvidersArray.js +0 -21
- package/admin/src/pages/Roles/CreatePage.js +0 -185
- package/admin/src/pages/Roles/EditPage.js +0 -197
- package/admin/src/pages/Roles/ListPage/components/TableBody.js +0 -93
- package/admin/src/pages/Roles/ListPage/utils/api.js +0 -30
- package/admin/src/pages/Roles/ProtectedCreatePage.js +0 -15
- package/admin/src/pages/Roles/ProtectedEditPage.js +0 -15
- package/admin/src/pages/Roles/ProtectedListPage.js +0 -17
- package/admin/src/pages/Roles/index.js +0 -30
- package/server/bootstrap/grant-config.js +0 -131
- package/strapi-admin.js +0 -3
- package/strapi-server.js +0 -3
- /package/admin/src/components/Permissions/PermissionRow/{index.js → index.jsx} +0 -0
- /package/admin/src/contexts/UsersPermissionsContext/{index.js → index.jsx} +0 -0
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
const _ = require('lodash');
|
|
9
9
|
const urlJoin = require('url-join');
|
|
10
10
|
|
|
11
|
-
const { getAbsoluteServerUrl } = require('@strapi/utils');
|
|
12
11
|
const { getService } = require('../utils');
|
|
13
12
|
|
|
14
13
|
module.exports = ({ strapi }) => {
|
|
@@ -60,7 +59,7 @@ module.exports = ({ strapi }) => {
|
|
|
60
59
|
throw new Error('Email was not available.');
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
const users = await strapi.query('plugin::users-permissions.user').findMany({
|
|
62
|
+
const users = await strapi.db.query('plugin::users-permissions.user').findMany({
|
|
64
63
|
where: { email },
|
|
65
64
|
});
|
|
66
65
|
|
|
@@ -83,7 +82,7 @@ module.exports = ({ strapi }) => {
|
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
// Retrieve default role.
|
|
86
|
-
const defaultRole = await strapi
|
|
85
|
+
const defaultRole = await strapi.db
|
|
87
86
|
.query('plugin::users-permissions.role')
|
|
88
87
|
.findOne({ where: { type: advancedSettings.default_role } });
|
|
89
88
|
|
|
@@ -96,7 +95,7 @@ module.exports = ({ strapi }) => {
|
|
|
96
95
|
confirmed: true,
|
|
97
96
|
};
|
|
98
97
|
|
|
99
|
-
const createdUser = await strapi
|
|
98
|
+
const createdUser = await strapi.db
|
|
100
99
|
.query('plugin::users-permissions.user')
|
|
101
100
|
.create({ data: newUser });
|
|
102
101
|
|
|
@@ -105,7 +104,13 @@ module.exports = ({ strapi }) => {
|
|
|
105
104
|
|
|
106
105
|
const buildRedirectUri = (provider = '') => {
|
|
107
106
|
const apiPrefix = strapi.config.get('api.rest.prefix');
|
|
108
|
-
return urlJoin(
|
|
107
|
+
return urlJoin(
|
|
108
|
+
strapi.config.get('server.absoluteUrl'),
|
|
109
|
+
apiPrefix,
|
|
110
|
+
'connect',
|
|
111
|
+
provider,
|
|
112
|
+
'callback'
|
|
113
|
+
);
|
|
109
114
|
};
|
|
110
115
|
|
|
111
116
|
return {
|
package/server/services/role.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = ({ strapi }) => ({
|
|
|
10
10
|
params.type = _.snakeCase(_.deburr(_.toLower(params.name)));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const role = await strapi
|
|
13
|
+
const role = await strapi.db
|
|
14
14
|
.query('plugin::users-permissions.role')
|
|
15
15
|
.create({ data: _.omit(params, ['users', 'permissions']) });
|
|
16
16
|
|
|
@@ -25,7 +25,7 @@ module.exports = ({ strapi }) => ({
|
|
|
25
25
|
const actionID = `${typeName}.${controllerName}.${actionName}`;
|
|
26
26
|
|
|
27
27
|
acc.push(
|
|
28
|
-
strapi
|
|
28
|
+
strapi.db
|
|
29
29
|
.query('plugin::users-permissions.permission')
|
|
30
30
|
.create({ data: { action: actionID, role: role.id } })
|
|
31
31
|
);
|
|
@@ -42,7 +42,7 @@ module.exports = ({ strapi }) => ({
|
|
|
42
42
|
},
|
|
43
43
|
|
|
44
44
|
async findOne(roleID) {
|
|
45
|
-
const role = await strapi
|
|
45
|
+
const role = await strapi.db
|
|
46
46
|
.query('plugin::users-permissions.role')
|
|
47
47
|
.findOne({ where: { id: roleID }, populate: ['permissions'] });
|
|
48
48
|
|
|
@@ -69,10 +69,12 @@ module.exports = ({ strapi }) => ({
|
|
|
69
69
|
},
|
|
70
70
|
|
|
71
71
|
async find() {
|
|
72
|
-
const roles = await strapi.
|
|
72
|
+
const roles = await strapi.db
|
|
73
|
+
.query('plugin::users-permissions.role')
|
|
74
|
+
.findMany({ sort: ['name'] });
|
|
73
75
|
|
|
74
76
|
for (const role of roles) {
|
|
75
|
-
role.nb_users = await strapi
|
|
77
|
+
role.nb_users = await strapi.db
|
|
76
78
|
.query('plugin::users-permissions.user')
|
|
77
79
|
.count({ where: { role: { id: role.id } } });
|
|
78
80
|
}
|
|
@@ -81,7 +83,7 @@ module.exports = ({ strapi }) => ({
|
|
|
81
83
|
},
|
|
82
84
|
|
|
83
85
|
async updateRole(roleID, data) {
|
|
84
|
-
const role = await strapi
|
|
86
|
+
const role = await strapi.db
|
|
85
87
|
.query('plugin::users-permissions.role')
|
|
86
88
|
.findOne({ where: { id: roleID }, populate: ['permissions'] });
|
|
87
89
|
|
|
@@ -89,7 +91,7 @@ module.exports = ({ strapi }) => ({
|
|
|
89
91
|
throw new NotFoundError('Role not found');
|
|
90
92
|
}
|
|
91
93
|
|
|
92
|
-
await strapi.query('plugin::users-permissions.role').update({
|
|
94
|
+
await strapi.db.query('plugin::users-permissions.role').update({
|
|
93
95
|
where: { id: roleID },
|
|
94
96
|
data: _.pick(data, ['name', 'description']),
|
|
95
97
|
});
|
|
@@ -129,7 +131,7 @@ module.exports = ({ strapi }) => ({
|
|
|
129
131
|
|
|
130
132
|
await Promise.all(
|
|
131
133
|
toDelete.map((permission) =>
|
|
132
|
-
strapi
|
|
134
|
+
strapi.db
|
|
133
135
|
.query('plugin::users-permissions.permission')
|
|
134
136
|
.delete({ where: { id: permission.id } })
|
|
135
137
|
)
|
|
@@ -137,13 +139,13 @@ module.exports = ({ strapi }) => ({
|
|
|
137
139
|
|
|
138
140
|
await Promise.all(
|
|
139
141
|
toCreate.map((permissionInfo) =>
|
|
140
|
-
strapi.query('plugin::users-permissions.permission').create({ data: permissionInfo })
|
|
142
|
+
strapi.db.query('plugin::users-permissions.permission').create({ data: permissionInfo })
|
|
141
143
|
)
|
|
142
144
|
);
|
|
143
145
|
},
|
|
144
146
|
|
|
145
147
|
async deleteRole(roleID, publicRoleID) {
|
|
146
|
-
const role = await strapi
|
|
148
|
+
const role = await strapi.db
|
|
147
149
|
.query('plugin::users-permissions.role')
|
|
148
150
|
.findOne({ where: { id: roleID }, populate: ['users', 'permissions'] });
|
|
149
151
|
|
|
@@ -154,7 +156,7 @@ module.exports = ({ strapi }) => ({
|
|
|
154
156
|
// Move users to guest role.
|
|
155
157
|
await Promise.all(
|
|
156
158
|
role.users.map((user) => {
|
|
157
|
-
return strapi.query('plugin::users-permissions.user').update({
|
|
159
|
+
return strapi.db.query('plugin::users-permissions.user').update({
|
|
158
160
|
where: { id: user.id },
|
|
159
161
|
data: { role: publicRoleID },
|
|
160
162
|
});
|
|
@@ -165,13 +167,13 @@ module.exports = ({ strapi }) => ({
|
|
|
165
167
|
// TODO: use delete many
|
|
166
168
|
await Promise.all(
|
|
167
169
|
role.permissions.map((permission) => {
|
|
168
|
-
return strapi.query('plugin::users-permissions.permission').delete({
|
|
170
|
+
return strapi.db.query('plugin::users-permissions.permission').delete({
|
|
169
171
|
where: { id: permission.id },
|
|
170
172
|
});
|
|
171
173
|
})
|
|
172
174
|
);
|
|
173
175
|
|
|
174
176
|
// Delete the role.
|
|
175
|
-
await strapi.query('plugin::users-permissions.role').delete({ where: { id: roleID } });
|
|
177
|
+
await strapi.db.query('plugin::users-permissions.role').delete({ where: { id: roleID } });
|
|
176
178
|
},
|
|
177
179
|
});
|
package/server/services/user.js
CHANGED
|
@@ -10,9 +10,12 @@ const crypto = require('crypto');
|
|
|
10
10
|
const bcrypt = require('bcryptjs');
|
|
11
11
|
const urlJoin = require('url-join');
|
|
12
12
|
|
|
13
|
-
const {
|
|
13
|
+
const { sanitize } = require('@strapi/utils');
|
|
14
|
+
const { toNumber, getOr } = require('lodash/fp');
|
|
14
15
|
const { getService } = require('../utils');
|
|
15
16
|
|
|
17
|
+
const USER_MODEL_UID = 'plugin::users-permissions.user';
|
|
18
|
+
|
|
16
19
|
module.exports = ({ strapi }) => ({
|
|
17
20
|
/**
|
|
18
21
|
* Promise to count users
|
|
@@ -21,22 +24,38 @@ module.exports = ({ strapi }) => ({
|
|
|
21
24
|
*/
|
|
22
25
|
|
|
23
26
|
count(params) {
|
|
24
|
-
return strapi.query(
|
|
27
|
+
return strapi.db.query(USER_MODEL_UID).count({ where: params });
|
|
25
28
|
},
|
|
26
29
|
|
|
27
30
|
/**
|
|
28
|
-
*
|
|
31
|
+
* Hashes password fields in the provided values object if they are present.
|
|
32
|
+
* It checks each key in the values object against the model's attributes and
|
|
33
|
+
* hashes it if the attribute type is 'password',
|
|
29
34
|
*
|
|
30
|
-
* @
|
|
35
|
+
* @param {object} values - The object containing the fields to be hashed.
|
|
36
|
+
* @return {object} The values object with hashed password fields if they were present.
|
|
31
37
|
*/
|
|
38
|
+
async ensureHashedPasswords(values) {
|
|
39
|
+
const attributes = strapi.getModel(USER_MODEL_UID).attributes;
|
|
40
|
+
|
|
41
|
+
for (const key in values) {
|
|
42
|
+
if (attributes[key] && attributes[key].type === 'password') {
|
|
43
|
+
// Check if a custom encryption.rounds has been set on the password attribute
|
|
44
|
+
const rounds = toNumber(getOr(10, 'encryption.rounds', attributes[key]));
|
|
45
|
+
values[key] = await bcrypt.hash(values[key], rounds);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return values;
|
|
50
|
+
},
|
|
32
51
|
|
|
33
52
|
/**
|
|
34
53
|
* Promise to add a/an user.
|
|
35
54
|
* @return {Promise}
|
|
36
55
|
*/
|
|
37
56
|
async add(values) {
|
|
38
|
-
return strapi.
|
|
39
|
-
data: values,
|
|
57
|
+
return strapi.db.query(USER_MODEL_UID).create({
|
|
58
|
+
data: await this.ensureHashedPasswords(values),
|
|
40
59
|
populate: ['role'],
|
|
41
60
|
});
|
|
42
61
|
},
|
|
@@ -48,8 +67,9 @@ module.exports = ({ strapi }) => ({
|
|
|
48
67
|
* @return {Promise}
|
|
49
68
|
*/
|
|
50
69
|
async edit(userId, params = {}) {
|
|
51
|
-
return strapi.
|
|
52
|
-
|
|
70
|
+
return strapi.db.query(USER_MODEL_UID).update({
|
|
71
|
+
where: { id: userId },
|
|
72
|
+
data: await this.ensureHashedPasswords(params),
|
|
53
73
|
populate: ['role'],
|
|
54
74
|
});
|
|
55
75
|
},
|
|
@@ -59,7 +79,14 @@ module.exports = ({ strapi }) => ({
|
|
|
59
79
|
* @return {Promise}
|
|
60
80
|
*/
|
|
61
81
|
fetch(id, params) {
|
|
62
|
-
|
|
82
|
+
const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});
|
|
83
|
+
|
|
84
|
+
return strapi.db.query(USER_MODEL_UID).findOne({
|
|
85
|
+
...query,
|
|
86
|
+
where: {
|
|
87
|
+
$and: [{ id }, query.where || {}],
|
|
88
|
+
},
|
|
89
|
+
});
|
|
63
90
|
},
|
|
64
91
|
|
|
65
92
|
/**
|
|
@@ -67,9 +94,7 @@ module.exports = ({ strapi }) => ({
|
|
|
67
94
|
* @return {Promise}
|
|
68
95
|
*/
|
|
69
96
|
fetchAuthenticatedUser(id) {
|
|
70
|
-
return strapi
|
|
71
|
-
.query('plugin::users-permissions.user')
|
|
72
|
-
.findOne({ where: { id }, populate: ['role'] });
|
|
97
|
+
return strapi.db.query(USER_MODEL_UID).findOne({ where: { id }, populate: ['role'] });
|
|
73
98
|
},
|
|
74
99
|
|
|
75
100
|
/**
|
|
@@ -77,7 +102,9 @@ module.exports = ({ strapi }) => ({
|
|
|
77
102
|
* @return {Promise}
|
|
78
103
|
*/
|
|
79
104
|
fetchAll(params) {
|
|
80
|
-
|
|
105
|
+
const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});
|
|
106
|
+
|
|
107
|
+
return strapi.db.query(USER_MODEL_UID).findMany(query);
|
|
81
108
|
},
|
|
82
109
|
|
|
83
110
|
/**
|
|
@@ -85,7 +112,7 @@ module.exports = ({ strapi }) => ({
|
|
|
85
112
|
* @return {Promise}
|
|
86
113
|
*/
|
|
87
114
|
async remove(params) {
|
|
88
|
-
return strapi.query(
|
|
115
|
+
return strapi.db.query(USER_MODEL_UID).delete({ where: params });
|
|
89
116
|
},
|
|
90
117
|
|
|
91
118
|
validatePassword(password, hash) {
|
|
@@ -95,14 +122,20 @@ module.exports = ({ strapi }) => ({
|
|
|
95
122
|
async sendConfirmationEmail(user) {
|
|
96
123
|
const userPermissionService = getService('users-permissions');
|
|
97
124
|
const pluginStore = await strapi.store({ type: 'plugin', name: 'users-permissions' });
|
|
98
|
-
const userSchema = strapi.getModel(
|
|
125
|
+
const userSchema = strapi.getModel(USER_MODEL_UID);
|
|
99
126
|
|
|
100
127
|
const settings = await pluginStore
|
|
101
128
|
.get({ key: 'email' })
|
|
102
129
|
.then((storeEmail) => storeEmail.email_confirmation.options);
|
|
103
130
|
|
|
104
131
|
// Sanitize the template's user information
|
|
105
|
-
const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput(
|
|
132
|
+
const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput(
|
|
133
|
+
{
|
|
134
|
+
schema: userSchema,
|
|
135
|
+
getModel: strapi.getModel.bind(strapi),
|
|
136
|
+
},
|
|
137
|
+
user
|
|
138
|
+
);
|
|
106
139
|
|
|
107
140
|
const confirmationToken = crypto.randomBytes(20).toString('hex');
|
|
108
141
|
|
|
@@ -112,9 +145,13 @@ module.exports = ({ strapi }) => ({
|
|
|
112
145
|
|
|
113
146
|
try {
|
|
114
147
|
settings.message = await userPermissionService.template(settings.message, {
|
|
115
|
-
URL: urlJoin(
|
|
116
|
-
|
|
117
|
-
|
|
148
|
+
URL: urlJoin(
|
|
149
|
+
strapi.config.get('server.absoluteUrl'),
|
|
150
|
+
apiPrefix,
|
|
151
|
+
'/auth/email-confirmation'
|
|
152
|
+
),
|
|
153
|
+
SERVER_URL: strapi.config.get('server.absoluteUrl'),
|
|
154
|
+
ADMIN_URL: strapi.config.get('admin.absoluteUrl'),
|
|
118
155
|
USER: sanitizedUserInfo,
|
|
119
156
|
CODE: confirmationToken,
|
|
120
157
|
});
|
|
@@ -6,7 +6,7 @@ const urlJoin = require('url-join');
|
|
|
6
6
|
const {
|
|
7
7
|
template: { createStrictInterpolationRegExp },
|
|
8
8
|
errors,
|
|
9
|
-
|
|
9
|
+
objects,
|
|
10
10
|
} = require('@strapi/utils');
|
|
11
11
|
|
|
12
12
|
const { getService } = require('../utils');
|
|
@@ -45,7 +45,7 @@ module.exports = ({ strapi }) => ({
|
|
|
45
45
|
return action[Symbol.for('__type__')].includes('content-api');
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
_.forEach(strapi.
|
|
48
|
+
_.forEach(strapi.apis, (api, apiName) => {
|
|
49
49
|
const controllers = _.reduce(
|
|
50
50
|
api.controllers,
|
|
51
51
|
(acc, controller, controllerName) => {
|
|
@@ -105,7 +105,7 @@ module.exports = ({ strapi }) => ({
|
|
|
105
105
|
async getRoutes() {
|
|
106
106
|
const routesMap = {};
|
|
107
107
|
|
|
108
|
-
_.forEach(strapi.
|
|
108
|
+
_.forEach(strapi.apis, (api, apiName) => {
|
|
109
109
|
const routes = _.flatMap(api.routes, (route) => {
|
|
110
110
|
if (_.has(route, 'routes')) {
|
|
111
111
|
return route.routes;
|
|
@@ -151,12 +151,12 @@ module.exports = ({ strapi }) => ({
|
|
|
151
151
|
},
|
|
152
152
|
|
|
153
153
|
async syncPermissions() {
|
|
154
|
-
const roles = await strapi.query('plugin::users-permissions.role').findMany();
|
|
155
|
-
const dbPermissions = await strapi.query('plugin::users-permissions.permission').findMany();
|
|
154
|
+
const roles = await strapi.db.query('plugin::users-permissions.role').findMany();
|
|
155
|
+
const dbPermissions = await strapi.db.query('plugin::users-permissions.permission').findMany();
|
|
156
156
|
|
|
157
157
|
const permissionsFoundInDB = _.uniq(_.map(dbPermissions, 'action'));
|
|
158
158
|
|
|
159
|
-
const appActions = _.flatMap(strapi.
|
|
159
|
+
const appActions = _.flatMap(strapi.apis, (api, apiName) => {
|
|
160
160
|
return _.flatMap(api.controllers, (controller, controllerName) => {
|
|
161
161
|
return _.keys(controller).map((actionName) => {
|
|
162
162
|
return `api::${apiName}.${controllerName}.${actionName}`;
|
|
@@ -178,7 +178,9 @@ module.exports = ({ strapi }) => ({
|
|
|
178
178
|
|
|
179
179
|
await Promise.all(
|
|
180
180
|
toDelete.map((action) => {
|
|
181
|
-
return strapi.
|
|
181
|
+
return strapi.db
|
|
182
|
+
.query('plugin::users-permissions.permission')
|
|
183
|
+
.delete({ where: { action } });
|
|
182
184
|
})
|
|
183
185
|
);
|
|
184
186
|
|
|
@@ -192,7 +194,7 @@ module.exports = ({ strapi }) => ({
|
|
|
192
194
|
|
|
193
195
|
await Promise.all(
|
|
194
196
|
toCreate.map((action) => {
|
|
195
|
-
return strapi.query('plugin::users-permissions.permission').create({
|
|
197
|
+
return strapi.db.query('plugin::users-permissions.permission').create({
|
|
196
198
|
data: {
|
|
197
199
|
action,
|
|
198
200
|
role: role.id,
|
|
@@ -205,10 +207,10 @@ module.exports = ({ strapi }) => ({
|
|
|
205
207
|
},
|
|
206
208
|
|
|
207
209
|
async initialize() {
|
|
208
|
-
const roleCount = await strapi.query('plugin::users-permissions.role').count();
|
|
210
|
+
const roleCount = await strapi.db.query('plugin::users-permissions.role').count();
|
|
209
211
|
|
|
210
212
|
if (roleCount === 0) {
|
|
211
|
-
await strapi.query('plugin::users-permissions.role').create({
|
|
213
|
+
await strapi.db.query('plugin::users-permissions.role').create({
|
|
212
214
|
data: {
|
|
213
215
|
name: 'Authenticated',
|
|
214
216
|
description: 'Default role given to authenticated user.',
|
|
@@ -216,7 +218,7 @@ module.exports = ({ strapi }) => ({
|
|
|
216
218
|
},
|
|
217
219
|
});
|
|
218
220
|
|
|
219
|
-
await strapi.query('plugin::users-permissions.role').create({
|
|
221
|
+
await strapi.db.query('plugin::users-permissions.role').create({
|
|
220
222
|
data: {
|
|
221
223
|
name: 'Public',
|
|
222
224
|
description: 'Default role given to unauthenticated user.',
|
|
@@ -229,13 +231,13 @@ module.exports = ({ strapi }) => ({
|
|
|
229
231
|
},
|
|
230
232
|
|
|
231
233
|
async updateUserRole(user, role) {
|
|
232
|
-
return strapi
|
|
234
|
+
return strapi.db
|
|
233
235
|
.query('plugin::users-permissions.user')
|
|
234
236
|
.update({ where: { id: user.id }, data: { role } });
|
|
235
237
|
},
|
|
236
238
|
|
|
237
239
|
template(layout, data) {
|
|
238
|
-
const allowedTemplateVariables = keysDeep(data);
|
|
240
|
+
const allowedTemplateVariables = objects.keysDeep(data);
|
|
239
241
|
|
|
240
242
|
// Create a strict interpolation RegExp based on possible variable names
|
|
241
243
|
const interpolate = createStrictInterpolationRegExp(allowedTemplateVariables, 'g');
|
package/server/utils/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import * as user from '../services/user';
|
|
|
3
3
|
import * as role from '../services/role';
|
|
4
4
|
import * as jwt from '../services/jwt';
|
|
5
5
|
import * as providers from '../services/providers';
|
|
6
|
+
import * as providersRegistry from '../services/providers-registry';
|
|
6
7
|
import * as permission from '../services/permission';
|
|
7
8
|
|
|
8
9
|
type S = {
|
|
@@ -11,7 +12,7 @@ type S = {
|
|
|
11
12
|
user: typeof user;
|
|
12
13
|
jwt: typeof jwt;
|
|
13
14
|
providers: typeof providers;
|
|
14
|
-
['providers-registry']: typeof
|
|
15
|
+
['providers-registry']: typeof providersRegistry;
|
|
15
16
|
permission: typeof permission;
|
|
16
17
|
};
|
|
17
18
|
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { curry } = require('lodash/fp');
|
|
4
|
-
const { traverseEntity,
|
|
4
|
+
const { traverseEntity, async } = require('@strapi/utils');
|
|
5
5
|
|
|
6
6
|
const { removeUserRelationFromRoleEntities } = require('./visitors');
|
|
7
7
|
|
|
8
8
|
const sanitizeUserRelationFromRoleEntities = curry((schema, entity) => {
|
|
9
|
-
return traverseEntity(
|
|
9
|
+
return traverseEntity(
|
|
10
|
+
removeUserRelationFromRoleEntities,
|
|
11
|
+
{ schema, getModel: strapi.getModel.bind(strapi) },
|
|
12
|
+
entity
|
|
13
|
+
);
|
|
10
14
|
});
|
|
11
15
|
|
|
12
16
|
const defaultSanitizeOutput = curry((schema, entity) => {
|
|
13
|
-
return
|
|
17
|
+
return async.pipe(sanitizeUserRelationFromRoleEntities(schema))(entity);
|
|
14
18
|
});
|
|
15
19
|
|
|
16
20
|
module.exports = {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module.exports = ({ schema, key, attribute }, { remove }) => {
|
|
4
4
|
if (
|
|
5
|
-
attribute
|
|
6
|
-
attribute
|
|
5
|
+
attribute?.type === 'relation' &&
|
|
6
|
+
attribute?.target === 'plugin::users-permissions.user' &&
|
|
7
7
|
schema.uid === 'plugin::users-permissions.role'
|
|
8
8
|
) {
|
|
9
9
|
remove(key);
|
package/.eslintrc.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* FormModal
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React from 'react';
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
Button,
|
|
11
|
-
Flex,
|
|
12
|
-
Grid,
|
|
13
|
-
GridItem,
|
|
14
|
-
ModalBody,
|
|
15
|
-
ModalFooter,
|
|
16
|
-
ModalHeader,
|
|
17
|
-
ModalLayout,
|
|
18
|
-
} from '@strapi/design-system';
|
|
19
|
-
import { Breadcrumbs, Crumb } from '@strapi/design-system/v2';
|
|
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
|
-
|
|
25
|
-
import Input from './Input';
|
|
26
|
-
|
|
27
|
-
const FormModal = ({
|
|
28
|
-
headerBreadcrumbs,
|
|
29
|
-
initialData,
|
|
30
|
-
isSubmiting,
|
|
31
|
-
layout,
|
|
32
|
-
isOpen,
|
|
33
|
-
onSubmit,
|
|
34
|
-
onToggle,
|
|
35
|
-
providerToEditName,
|
|
36
|
-
}) => {
|
|
37
|
-
const { formatMessage } = useIntl();
|
|
38
|
-
|
|
39
|
-
if (!isOpen) {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
<ModalLayout onClose={onToggle} labelledBy="title">
|
|
45
|
-
<ModalHeader>
|
|
46
|
-
<Breadcrumbs label={headerBreadcrumbs.join(', ')}>
|
|
47
|
-
{headerBreadcrumbs.map((crumb, index, arr) => (
|
|
48
|
-
<Crumb isCurrent={index === arr.length - 1} key={crumb}>
|
|
49
|
-
{crumb}
|
|
50
|
-
</Crumb>
|
|
51
|
-
))}
|
|
52
|
-
</Breadcrumbs>
|
|
53
|
-
</ModalHeader>
|
|
54
|
-
<Formik
|
|
55
|
-
onSubmit={(values) => onSubmit(values)}
|
|
56
|
-
initialValues={initialData}
|
|
57
|
-
validationSchema={layout.schema}
|
|
58
|
-
validateOnChange={false}
|
|
59
|
-
>
|
|
60
|
-
{({ errors, handleChange, values }) => {
|
|
61
|
-
return (
|
|
62
|
-
<Form>
|
|
63
|
-
<ModalBody>
|
|
64
|
-
<Flex direction="column" alignItems="stretch" gap={1}>
|
|
65
|
-
<Grid gap={5}>
|
|
66
|
-
{layout.form.map((row) => {
|
|
67
|
-
return row.map((input) => {
|
|
68
|
-
return (
|
|
69
|
-
<GridItem key={input.name} col={input.size} xs={12}>
|
|
70
|
-
<Input
|
|
71
|
-
{...input}
|
|
72
|
-
error={errors[input.name]}
|
|
73
|
-
onChange={handleChange}
|
|
74
|
-
value={values[input.name]}
|
|
75
|
-
providerToEditName={providerToEditName}
|
|
76
|
-
/>
|
|
77
|
-
</GridItem>
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
})}
|
|
81
|
-
</Grid>
|
|
82
|
-
</Flex>
|
|
83
|
-
</ModalBody>
|
|
84
|
-
<ModalFooter
|
|
85
|
-
startActions={
|
|
86
|
-
<Button variant="tertiary" onClick={onToggle} type="button">
|
|
87
|
-
{formatMessage({
|
|
88
|
-
id: 'app.components.Button.cancel',
|
|
89
|
-
defaultMessage: 'Cancel',
|
|
90
|
-
})}
|
|
91
|
-
</Button>
|
|
92
|
-
}
|
|
93
|
-
endActions={
|
|
94
|
-
<Button type="submit" loading={isSubmiting}>
|
|
95
|
-
{formatMessage({ id: 'global.save', defaultMessage: 'Save' })}
|
|
96
|
-
</Button>
|
|
97
|
-
}
|
|
98
|
-
/>
|
|
99
|
-
</Form>
|
|
100
|
-
);
|
|
101
|
-
}}
|
|
102
|
-
</Formik>
|
|
103
|
-
</ModalLayout>
|
|
104
|
-
);
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
FormModal.defaultProps = {
|
|
108
|
-
initialData: null,
|
|
109
|
-
providerToEditName: null,
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
FormModal.propTypes = {
|
|
113
|
-
headerBreadcrumbs: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
114
|
-
initialData: PropTypes.object,
|
|
115
|
-
layout: PropTypes.shape({
|
|
116
|
-
form: PropTypes.arrayOf(PropTypes.array),
|
|
117
|
-
schema: PropTypes.object,
|
|
118
|
-
}).isRequired,
|
|
119
|
-
isOpen: PropTypes.bool.isRequired,
|
|
120
|
-
isSubmiting: PropTypes.bool.isRequired,
|
|
121
|
-
onSubmit: PropTypes.func.isRequired,
|
|
122
|
-
onToggle: PropTypes.func.isRequired,
|
|
123
|
-
providerToEditName: PropTypes.string,
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
export default FormModal;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import React, { useReducer } from 'react';
|
|
2
|
-
|
|
3
|
-
import { Accordion, AccordionContent, AccordionToggle, Box, Flex } from '@strapi/design-system';
|
|
4
|
-
import { useIntl } from 'react-intl';
|
|
5
|
-
|
|
6
|
-
import { useUsersPermissions } from '../../contexts/UsersPermissionsContext';
|
|
7
|
-
import formatPluginName from '../../utils/formatPluginName';
|
|
8
|
-
|
|
9
|
-
import init from './init';
|
|
10
|
-
import PermissionRow from './PermissionRow';
|
|
11
|
-
import { initialState, reducer } from './reducer';
|
|
12
|
-
|
|
13
|
-
const Permissions = () => {
|
|
14
|
-
const { modifiedData } = useUsersPermissions();
|
|
15
|
-
const { formatMessage } = useIntl();
|
|
16
|
-
const [{ collapses }, dispatch] = useReducer(reducer, initialState, (state) =>
|
|
17
|
-
init(state, modifiedData)
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
const handleToggle = (index) =>
|
|
21
|
-
dispatch({
|
|
22
|
-
type: 'TOGGLE_COLLAPSE',
|
|
23
|
-
index,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<Flex direction="column" alignItems="stretch" gap={1}>
|
|
28
|
-
{collapses.map((collapse, index) => (
|
|
29
|
-
<Accordion
|
|
30
|
-
expanded={collapse.isOpen}
|
|
31
|
-
onToggle={() => handleToggle(index)}
|
|
32
|
-
key={collapse.name}
|
|
33
|
-
variant={index % 2 === 0 ? 'secondary' : undefined}
|
|
34
|
-
>
|
|
35
|
-
<AccordionToggle
|
|
36
|
-
title={formatPluginName(collapse.name)}
|
|
37
|
-
description={formatMessage(
|
|
38
|
-
{
|
|
39
|
-
id: 'users-permissions.Plugin.permissions.plugins.description',
|
|
40
|
-
defaultMessage: 'Define all allowed actions for the {name} plugin.',
|
|
41
|
-
},
|
|
42
|
-
{ name: collapse.name }
|
|
43
|
-
)}
|
|
44
|
-
variant={index % 2 ? 'primary' : 'secondary'}
|
|
45
|
-
/>
|
|
46
|
-
<AccordionContent>
|
|
47
|
-
<Box>
|
|
48
|
-
<PermissionRow permissions={modifiedData[collapse.name]} name={collapse.name} />
|
|
49
|
-
</Box>
|
|
50
|
-
</AccordionContent>
|
|
51
|
-
</Accordion>
|
|
52
|
-
))}
|
|
53
|
-
</Flex>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export default Permissions;
|
package/admin/src/hooks/index.js
DELETED