@strapi/admin 4.7.2-exp.24dd7d95972fa822bf43e9b095b51027402c229e → 4.8.1
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/content-manager/components/ComponentInitializer/index.js +1 -1
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +3 -31
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +65 -134
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findAllAndReplace.js +85 -0
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/index.js +1 -2
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/schema.js +7 -1
- package/admin/src/content-manager/components/NonRepeatableComponent/index.js +1 -1
- package/admin/src/content-manager/components/RelationInput/RelationInput.js +1 -2
- package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +39 -33
- package/admin/src/content-manager/hooks/useRelation/useRelation.js +2 -2
- package/admin/src/content-manager/pages/EditView/Header/index.js +1 -1
- package/admin/src/content-manager/utils/createDefaultForm.js +0 -8
- package/admin/src/pages/AuthPage/components/Register/index.js +1 -1
- package/admin/src/pages/SettingsPage/components/Tokens/FormHead/index.js +1 -0
- package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +2 -2
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/schema.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Roles/CreatePage/index.js +266 -4
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/index.js +1 -2
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/index.js +2 -3
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/ActionRow/index.js +2 -3
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/SubActionRow/index.js +2 -3
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/GlobalActions/index.js +9 -4
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/PluginsAndSettings/SubCategory/index.js +3 -7
- package/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js +303 -124
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/schema.js +1 -1
- package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +18 -10
- package/admin/src/translations/ca.json +7 -13
- package/admin/src/translations/de.json +0 -6
- package/admin/src/translations/dk.json +0 -6
- package/admin/src/translations/en.json +0 -6
- package/admin/src/translations/es.json +0 -6
- package/admin/src/translations/eu.json +165 -171
- package/admin/src/translations/fr.json +0 -6
- package/admin/src/translations/gu.json +0 -6
- package/admin/src/translations/he.json +0 -6
- package/admin/src/translations/hi.json +0 -6
- package/admin/src/translations/hu.json +0 -6
- package/admin/src/translations/id.json +0 -6
- package/admin/src/translations/it.json +0 -6
- package/admin/src/translations/ja.json +0 -6
- package/admin/src/translations/ko.json +0 -6
- package/admin/src/translations/ml.json +0 -6
- package/admin/src/translations/nl.json +0 -6
- package/admin/src/translations/no.json +0 -6
- package/admin/src/translations/pl.json +0 -6
- package/admin/src/translations/pt-BR.json +0 -6
- package/admin/src/translations/ru.json +0 -6
- package/admin/src/translations/sa.json +0 -6
- package/admin/src/translations/sk.json +0 -6
- package/admin/src/translations/sv.json +0 -6
- package/admin/src/translations/th.json +0 -6
- package/admin/src/translations/tr.json +0 -6
- package/admin/src/translations/zh-Hans.json +0 -6
- package/admin/src/translations/zh.json +0 -6
- package/build/{4649.daa290f6.chunk.js → 4649.33220ac3.chunk.js} +2 -2
- package/build/{6891.ef7464be.chunk.js → 7112.2bf13da3.chunk.js} +6 -6
- package/build/7259.3675c199.chunk.js +1 -0
- package/build/{3094.1cac9087.chunk.js → 8580.0aa21940.chunk.js} +5 -5
- package/build/{Admin-authenticatedApp.884faefa.chunk.js → Admin-authenticatedApp.1f2fd68f.chunk.js} +4 -4
- package/build/Admin_settingsPage.caf3b9ab.chunk.js +9 -0
- package/build/{admin-app.d9d96db4.chunk.js → admin-app.4b313104.chunk.js} +2 -2
- package/build/admin-edit-roles-page.3b196317.chunk.js +216 -0
- package/build/{admin-edit-users.48031e30.chunk.js → admin-edit-users.af3b0f15.chunk.js} +1 -1
- package/build/admin-roles-list.0ad504a7.chunk.js +2 -0
- package/build/{admin-users.77b4188a.chunk.js → admin-users.af8c3123.chunk.js} +1 -1
- package/build/api-tokens-list-page.93f24348.chunk.js +16 -0
- package/build/ca-json.43e14418.chunk.js +1 -0
- package/build/content-manager.84afc839.chunk.js +1139 -0
- package/build/{content-type-builder.cdd117c3.chunk.js → content-type-builder.55dac849.chunk.js} +1 -1
- package/build/de-json.fcac7381.chunk.js +1 -0
- package/build/dk-json.e34cad0d.chunk.js +1 -0
- package/build/{en-json.e688dfe2.chunk.js → en-json.01a88a30.chunk.js} +1 -1
- package/build/es-json.715b6fd8.chunk.js +1 -0
- package/build/eu-json.fb17c8f9.chunk.js +1 -0
- package/build/fr-json.f66c3211.chunk.js +1 -0
- package/build/gu-json.4d667d0c.chunk.js +1 -0
- package/build/{he-json.f0de8cdb.chunk.js → he-json.3cf0b48a.chunk.js} +1 -1
- package/build/{hi-json.14a17920.chunk.js → hi-json.323be97d.chunk.js} +1 -1
- package/build/{hu-json.33172d09.chunk.js → hu-json.fe71e6c8.chunk.js} +1 -1
- package/build/id-json.41e07c46.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/it-json.bfe27ed8.chunk.js +1 -0
- package/build/ja-json.81b6d1e3.chunk.js +1 -0
- package/build/ko-json.4539f4ba.chunk.js +1 -0
- package/build/main.5b92c1d6.js +3809 -0
- package/build/{ml-json.3e69969b.chunk.js → ml-json.8988e374.chunk.js} +1 -1
- package/build/{nl-json.641782d5.chunk.js → nl-json.98345913.chunk.js} +1 -1
- package/build/{no-json.9b3cd181.chunk.js → no-json.19a2dbfa.chunk.js} +1 -1
- package/build/pl-json.59a5dab3.chunk.js +1 -0
- package/build/pt-BR-json.9410688b.chunk.js +1 -0
- package/build/{ru-json.c4a4f50b.chunk.js → ru-json.6a01cea6.chunk.js} +1 -1
- package/build/runtime~main.a3892432.js +2 -0
- package/build/sa-json.6359a11c.chunk.js +1 -0
- package/build/sk-json.2374f129.chunk.js +1 -0
- package/build/{sv-json.207afc0d.chunk.js → sv-json.ae6e71ea.chunk.js} +1 -1
- package/build/th-json.5f659396.chunk.js +1 -0
- package/build/{tr-json.f1a0d19d.chunk.js → tr-json.bac5dbd3.chunk.js} +1 -1
- package/build/transfer-tokens-list-page.ce37354b.chunk.js +16 -0
- package/build/zh-Hans-json.4c9706a6.chunk.js +1 -0
- package/build/{zh-json.085a34f4.chunk.js → zh-json.3529f1e5.chunk.js} +1 -1
- package/ee/server/controllers/index.js +0 -1
- package/ee/server/controllers/role.js +0 -39
- package/ee/server/controllers/user.js +1 -35
- package/ee/server/routes/index.js +0 -49
- package/ee/server/validation/role.js +28 -20
- package/package.json +13 -13
- package/server/bootstrap.js +0 -1
- package/server/controllers/api-token.js +4 -2
- package/server/controllers/permission.js +2 -4
- package/server/controllers/role.js +70 -23
- package/server/controllers/transfer/runner.js +5 -3
- package/server/domain/user.js +3 -0
- package/server/routes/roles.js +48 -0
- package/server/services/permission/permissions-manager/sanitize.js +2 -2
- package/server/services/permission/queries.js +1 -74
- package/server/strategies/data-transfer.js +3 -1
- package/server/validation/permission.js +1 -82
- package/server/validation/role.js +44 -0
- package/admin/src/assets/images/hot-air-balloon.png +0 -0
- package/admin/src/assets/images/upgrade-details.png +0 -0
- package/admin/src/components/UpgradePlanModal/index.js +0 -123
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +0 -51
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/recursivelyFindPathsBasedOnCondition.js +0 -79
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/utils/constants.js +0 -3
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/utils/constants.js +0 -3
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/ActionRow/utils/constants.js +0 -3
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/SubActionRow/utils/constants.js +0 -3
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/GlobalActions/utils/constants.js +0 -3
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/PluginsAndSettings/SubCategory/utils/constants.js +0 -3
- package/build/617f9c948fa79e6d73bd.png +0 -0
- package/build/6d21938306785f176538.png +0 -0
- package/build/7259.63e91b59.chunk.js +0 -1
- package/build/Admin_settingsPage.6814a96e.chunk.js +0 -177
- package/build/admin-edit-roles-page.bf130aaf.chunk.js +0 -1
- package/build/api-tokens-list-page.149903c8.chunk.js +0 -16
- package/build/ca-json.59c4502c.chunk.js +0 -1
- package/build/content-manager.d792c194.chunk.js +0 -1139
- package/build/de-json.dbc2cf1b.chunk.js +0 -1
- package/build/dk-json.52f67b15.chunk.js +0 -1
- package/build/es-json.c40c57dd.chunk.js +0 -1
- package/build/eu-json.6702a0d2.chunk.js +0 -1
- package/build/fr-json.ea9ec573.chunk.js +0 -1
- package/build/gu-json.94f0d242.chunk.js +0 -1
- package/build/id-json.e0d83d41.chunk.js +0 -1
- package/build/it-json.8be59205.chunk.js +0 -1
- package/build/ja-json.3008b720.chunk.js +0 -1
- package/build/ko-json.7d2f95b1.chunk.js +0 -1
- package/build/main.64fe0c37.js +0 -3928
- package/build/pl-json.05814145.chunk.js +0 -1
- package/build/pt-BR-json.d72350de.chunk.js +0 -1
- package/build/runtime~main.684b5fed.js +0 -2
- package/build/sa-json.e5e7ccaf.chunk.js +0 -1
- package/build/sk-json.3529b8aa.chunk.js +0 -1
- package/build/th-json.f664b96d.chunk.js +0 -1
- package/build/transfer-tokens-list-page.c6f8039a.chunk.js +0 -16
- package/build/zh-Hans-json.993d085f.chunk.js +0 -1
- package/ee/admin/pages/SettingsPage/pages/Roles/CreatePage/index.js +0 -270
- package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/utils/constants.js +0 -3
- package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ConditionsSelect/MenuList/utils/constants.js +0 -3
- package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/utils/constants.js +0 -3
- package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/ActionRow/utils/constants.js +0 -3
- package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/SubActionRow/utils/constants.js +0 -3
- package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/GlobalActions/utils/constants.js +0 -3
- package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/PluginsAndSettings/SubCategory/utils/constants.js +0 -3
- package/ee/admin/pages/SettingsPage/pages/Roles/ListPage/index.js +0 -376
- package/ee/admin/pages/SettingsPage/pages/Roles/ProtectedListPage/index.js +0 -12
- package/ee/server/controllers/permission.js +0 -21
- package/ee/server/validation/permission.js +0 -8
- package/server/domain/role.js +0 -29
- /package/{ee/admin → admin/src}/pages/SettingsPage/pages/Roles/CreatePage/utils/schema.js +0 -0
- /package/{ee/admin → admin/src}/pages/SettingsPage/pages/Roles/ListPage/reducer.js +0 -0
|
@@ -20,38 +20,46 @@ const rolesDeleteSchema = yup
|
|
|
20
20
|
.of(yup.strapiID())
|
|
21
21
|
.min(1)
|
|
22
22
|
.required()
|
|
23
|
-
.test(
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
.test(
|
|
24
|
+
'roles-deletion-checks',
|
|
25
|
+
'Roles deletion checks have failed',
|
|
26
|
+
async function rolesDeletionChecks(ids) {
|
|
27
|
+
try {
|
|
28
|
+
await strapi.admin.services.role.checkRolesIdForDeletion(ids);
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
if (features.isEnabled('sso')) {
|
|
31
|
+
await strapi.admin.services.role.ssoCheckRolesIdForDeletion(ids);
|
|
32
|
+
}
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return this.createError({ path: 'ids', message: e.message });
|
|
29
35
|
}
|
|
30
|
-
} catch (e) {
|
|
31
|
-
return this.createError({ path: 'ids', message: e.message });
|
|
32
|
-
}
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
),
|
|
36
40
|
})
|
|
37
41
|
.noUnknown();
|
|
38
42
|
|
|
39
43
|
const roleDeleteSchema = yup
|
|
40
44
|
.strapiID()
|
|
41
45
|
.required()
|
|
42
|
-
.test(
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
.test(
|
|
47
|
+
'no-admin-single-delete',
|
|
48
|
+
'Role deletion checks have failed',
|
|
49
|
+
async function noAdminSingleDelete(id) {
|
|
50
|
+
try {
|
|
51
|
+
await strapi.admin.services.role.checkRolesIdForDeletion([id]);
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
if (features.isEnabled('sso')) {
|
|
54
|
+
await strapi.admin.services.role.ssoCheckRolesIdForDeletion([id]);
|
|
55
|
+
}
|
|
56
|
+
} catch (e) {
|
|
57
|
+
return this.createError({ path: 'id', message: e.message });
|
|
48
58
|
}
|
|
49
|
-
} catch (e) {
|
|
50
|
-
return this.createError({ path: 'id', message: e.message });
|
|
51
|
-
}
|
|
52
59
|
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
);
|
|
55
63
|
|
|
56
64
|
module.exports = {
|
|
57
65
|
validateRoleCreateInput: validateYupSchema(roleCreateSchema),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/admin",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.1",
|
|
4
4
|
"description": "Strapi Admin",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,21 +46,21 @@
|
|
|
46
46
|
"@casl/ability": "^5.4.3",
|
|
47
47
|
"@fingerprintjs/fingerprintjs": "3.3.6",
|
|
48
48
|
"@pmmmwh/react-refresh-webpack-plugin": "0.5.10",
|
|
49
|
-
"@strapi/babel-plugin-switch-ee-ce": "4.
|
|
50
|
-
"@strapi/data-transfer": "4.
|
|
51
|
-
"@strapi/design-system": "1.6.
|
|
52
|
-
"@strapi/helper-plugin": "4.
|
|
53
|
-
"@strapi/icons": "1.6.
|
|
54
|
-
"@strapi/permissions": "4.
|
|
55
|
-
"@strapi/provider-audit-logs-local": "4.
|
|
56
|
-
"@strapi/typescript-utils": "4.
|
|
57
|
-
"@strapi/utils": "4.
|
|
49
|
+
"@strapi/babel-plugin-switch-ee-ce": "4.8.1",
|
|
50
|
+
"@strapi/data-transfer": "4.8.1",
|
|
51
|
+
"@strapi/design-system": "1.6.5",
|
|
52
|
+
"@strapi/helper-plugin": "4.8.1",
|
|
53
|
+
"@strapi/icons": "1.6.5",
|
|
54
|
+
"@strapi/permissions": "4.8.1",
|
|
55
|
+
"@strapi/provider-audit-logs-local": "4.8.1",
|
|
56
|
+
"@strapi/typescript-utils": "4.8.1",
|
|
57
|
+
"@strapi/utils": "4.8.1",
|
|
58
58
|
"axios": "1.2.2",
|
|
59
59
|
"babel-loader": "^9.1.2",
|
|
60
60
|
"babel-plugin-styled-components": "2.0.2",
|
|
61
61
|
"bcryptjs": "2.4.3",
|
|
62
62
|
"browserslist-to-esbuild": "1.2.0",
|
|
63
|
-
"chalk": "^4.1.
|
|
63
|
+
"chalk": "^4.1.2",
|
|
64
64
|
"chokidar": "^3.5.1",
|
|
65
65
|
"codemirror5": "npm:codemirror@^5.65.11",
|
|
66
66
|
"cross-env": "^7.0.3",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"react-redux": "8.0.5",
|
|
122
122
|
"react-refresh": "0.14.0",
|
|
123
123
|
"react-router-dom": "5.3.4",
|
|
124
|
-
"react-select": "5.
|
|
124
|
+
"react-select": "5.7.0",
|
|
125
125
|
"react-window": "1.8.7",
|
|
126
126
|
"redux": "^4.2.1",
|
|
127
127
|
"reselect": "^4.1.7",
|
|
@@ -166,5 +166,5 @@
|
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
},
|
|
169
|
-
"gitHead": "
|
|
169
|
+
"gitHead": "b3cb13cb14302ba2ccf2ab6fab774f08efe9f1b7"
|
|
170
170
|
}
|
package/server/bootstrap.js
CHANGED
|
@@ -85,7 +85,6 @@ module.exports = async () => {
|
|
|
85
85
|
await roleService.resetSuperAdminPermissions();
|
|
86
86
|
await roleService.displayWarningIfNoSuperAdmin();
|
|
87
87
|
|
|
88
|
-
await permissionService.ensureBoundPermissionsInDatabase();
|
|
89
88
|
await permissionService.cleanPermissionsInDatabase();
|
|
90
89
|
|
|
91
90
|
await userService.displayWarningIfUsersDontHaveRole();
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
|
|
3
|
+
const {
|
|
4
|
+
stringEquals,
|
|
5
|
+
errors: { ApplicationError },
|
|
6
|
+
} = require('@strapi/utils');
|
|
5
7
|
const { trim, has } = require('lodash/fp');
|
|
6
8
|
const { getService } = require('../utils');
|
|
7
9
|
const {
|
|
@@ -29,11 +29,9 @@ module.exports = {
|
|
|
29
29
|
* @param {KoaContext} ctx - koa context
|
|
30
30
|
*/
|
|
31
31
|
async getAll(ctx) {
|
|
32
|
-
const {
|
|
32
|
+
const { sectionsBuilder, actionProvider, conditionProvider } = getService('permission');
|
|
33
33
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const actions = await getService('action').getAllowedActionsForRole(roleId);
|
|
34
|
+
const actions = actionProvider.values();
|
|
37
35
|
const conditions = conditionProvider.values();
|
|
38
36
|
const sections = await sectionsBuilder.build(actions);
|
|
39
37
|
|
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { ApplicationError } = require('@strapi/utils').errors;
|
|
4
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
validateRoleUpdateInput,
|
|
6
|
+
validateRoleCreateInput,
|
|
7
|
+
validateRoleDeleteInput,
|
|
8
|
+
validateRolesDeleteInput,
|
|
9
|
+
} = require('../validation/role');
|
|
5
10
|
const { validatedUpdatePermissionsInput } = require('../validation/permission');
|
|
6
|
-
const {
|
|
11
|
+
const { SUPER_ADMIN_CODE } = require('../services/constants');
|
|
7
12
|
const { getService } = require('../utils');
|
|
8
13
|
|
|
9
14
|
module.exports = {
|
|
15
|
+
/**
|
|
16
|
+
* Create a new role
|
|
17
|
+
* @param {KoaContext} ctx - koa context
|
|
18
|
+
*/
|
|
19
|
+
async create(ctx) {
|
|
20
|
+
await validateRoleCreateInput(ctx.request.body);
|
|
21
|
+
|
|
22
|
+
const roleService = getService('role');
|
|
23
|
+
|
|
24
|
+
const role = await roleService.create(ctx.request.body);
|
|
25
|
+
const sanitizedRole = roleService.sanitizeRole(role);
|
|
26
|
+
|
|
27
|
+
ctx.created({ data: sanitizedRole });
|
|
28
|
+
},
|
|
29
|
+
|
|
10
30
|
/**
|
|
11
31
|
* Returns on role by id
|
|
12
32
|
* @param {KoaContext} ctx - koa context
|
|
@@ -99,10 +119,10 @@ module.exports = {
|
|
|
99
119
|
const { id } = ctx.params;
|
|
100
120
|
const { body: input } = ctx.request;
|
|
101
121
|
|
|
102
|
-
const
|
|
103
|
-
const
|
|
122
|
+
const roleService = getService('role');
|
|
123
|
+
const permissionService = getService('permission');
|
|
104
124
|
|
|
105
|
-
const role = await findOne({ id });
|
|
125
|
+
const role = await roleService.findOne({ id });
|
|
106
126
|
|
|
107
127
|
if (!role) {
|
|
108
128
|
return ctx.notFound('role.notFound');
|
|
@@ -112,30 +132,57 @@ module.exports = {
|
|
|
112
132
|
throw new ApplicationError("Super admin permissions can't be edited.");
|
|
113
133
|
}
|
|
114
134
|
|
|
115
|
-
await validatedUpdatePermissionsInput(input
|
|
135
|
+
await validatedUpdatePermissionsInput(input);
|
|
116
136
|
|
|
117
|
-
|
|
137
|
+
if (!role) {
|
|
138
|
+
return ctx.notFound('role.notFound');
|
|
139
|
+
}
|
|
118
140
|
|
|
119
|
-
|
|
120
|
-
permissionsToAssign = input.permissions.map((permission) => {
|
|
121
|
-
const action = actionProvider.get(permission.action);
|
|
141
|
+
const permissions = await roleService.assignPermissions(role.id, input.permissions);
|
|
122
142
|
|
|
123
|
-
|
|
124
|
-
return permission;
|
|
125
|
-
}
|
|
143
|
+
const sanitizedPermissions = permissions.map(permissionService.sanitizePermission);
|
|
126
144
|
|
|
127
|
-
|
|
145
|
+
ctx.body = {
|
|
146
|
+
data: sanitizedPermissions,
|
|
147
|
+
};
|
|
148
|
+
},
|
|
128
149
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Delete a role
|
|
152
|
+
* @param {KoaContext} ctx - koa context
|
|
153
|
+
*/
|
|
154
|
+
async deleteOne(ctx) {
|
|
155
|
+
const { id } = ctx.params;
|
|
134
156
|
|
|
135
|
-
|
|
157
|
+
await validateRoleDeleteInput(id);
|
|
136
158
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
159
|
+
const roleService = getService('role');
|
|
160
|
+
|
|
161
|
+
const roles = await roleService.deleteByIds([id]);
|
|
162
|
+
|
|
163
|
+
const sanitizedRole = roles.map((role) => roleService.sanitizeRole(role))[0] || null;
|
|
164
|
+
|
|
165
|
+
return ctx.deleted({
|
|
166
|
+
data: sanitizedRole,
|
|
167
|
+
});
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* delete several roles
|
|
172
|
+
* @param {KoaContext} ctx - koa context
|
|
173
|
+
*/
|
|
174
|
+
async deleteMany(ctx) {
|
|
175
|
+
const { body } = ctx.request;
|
|
176
|
+
|
|
177
|
+
await validateRolesDeleteInput(body);
|
|
178
|
+
|
|
179
|
+
const roleService = getService('role');
|
|
180
|
+
|
|
181
|
+
const roles = await roleService.deleteByIds(body.ids);
|
|
182
|
+
const sanitizedRoles = roles.map(roleService.sanitizeRole);
|
|
183
|
+
|
|
184
|
+
return ctx.deleted({
|
|
185
|
+
data: sanitizedRoles,
|
|
186
|
+
});
|
|
140
187
|
},
|
|
141
188
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const {
|
|
3
|
+
const { createTransferHandler } = require('@strapi/data-transfer').strapi.remote.handlers;
|
|
4
|
+
const {
|
|
5
|
+
errors: { UnauthorizedError },
|
|
6
|
+
} = require('@strapi/utils');
|
|
5
7
|
|
|
6
8
|
const dataTransferAuthStrategy = require('../../strategies/data-transfer');
|
|
7
9
|
|
|
@@ -20,5 +22,5 @@ const verify = async (ctx, scope) => {
|
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
module.exports = {
|
|
23
|
-
connect:
|
|
25
|
+
connect: createTransferHandler({ verify }),
|
|
24
26
|
};
|
package/server/domain/user.js
CHANGED
|
@@ -19,7 +19,10 @@ const hasSuperAdminRole = (user) => {
|
|
|
19
19
|
return user.roles.filter((role) => role.code === SUPER_ADMIN_CODE).length > 0;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
const ADMIN_USER_ALLOWED_FIELDS = ['id', 'firstname', 'lastname', 'username'];
|
|
23
|
+
|
|
22
24
|
module.exports = {
|
|
23
25
|
createUser,
|
|
24
26
|
hasSuperAdminRole,
|
|
27
|
+
ADMIN_USER_ALLOWED_FIELDS,
|
|
25
28
|
};
|
package/server/routes/roles.js
CHANGED
|
@@ -45,6 +45,22 @@ module.exports = [
|
|
|
45
45
|
],
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
method: 'POST',
|
|
50
|
+
path: '/roles',
|
|
51
|
+
handler: 'role.create',
|
|
52
|
+
config: {
|
|
53
|
+
policies: [
|
|
54
|
+
'admin::isAuthenticatedAdmin',
|
|
55
|
+
{
|
|
56
|
+
name: 'admin::hasPermissions',
|
|
57
|
+
config: {
|
|
58
|
+
actions: ['admin::roles.create'],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
48
64
|
{
|
|
49
65
|
method: 'PUT',
|
|
50
66
|
path: '/roles/:id',
|
|
@@ -56,4 +72,36 @@ module.exports = [
|
|
|
56
72
|
],
|
|
57
73
|
},
|
|
58
74
|
},
|
|
75
|
+
{
|
|
76
|
+
method: 'DELETE',
|
|
77
|
+
path: '/roles/:id',
|
|
78
|
+
handler: 'role.deleteOne',
|
|
79
|
+
config: {
|
|
80
|
+
policies: [
|
|
81
|
+
'admin::isAuthenticatedAdmin',
|
|
82
|
+
{
|
|
83
|
+
name: 'admin::hasPermissions',
|
|
84
|
+
config: {
|
|
85
|
+
actions: ['admin::roles.delete'],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
method: 'POST',
|
|
93
|
+
path: '/roles/batch-delete',
|
|
94
|
+
handler: 'role.deleteMany',
|
|
95
|
+
config: {
|
|
96
|
+
policies: [
|
|
97
|
+
'admin::isAuthenticatedAdmin',
|
|
98
|
+
{
|
|
99
|
+
name: 'admin::hasPermissions',
|
|
100
|
+
config: {
|
|
101
|
+
actions: ['admin::roles.delete'],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
59
107
|
];
|
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
|
|
22
22
|
const { contentTypes, traverseEntity, sanitize, pipeAsync, traverse } = require('@strapi/utils');
|
|
23
23
|
const { removePassword } = require('@strapi/utils/lib/sanitize/visitors');
|
|
24
|
+
const { ADMIN_USER_ALLOWED_FIELDS } = require('../../../domain/user');
|
|
24
25
|
|
|
25
26
|
const {
|
|
26
27
|
constants,
|
|
@@ -39,7 +40,6 @@ const {
|
|
|
39
40
|
|
|
40
41
|
const COMPONENT_FIELDS = ['__component'];
|
|
41
42
|
const STATIC_FIELDS = [ID_ATTRIBUTE];
|
|
42
|
-
const ADMIN_USER_ALLOWED_FIELDS = ['id', 'firstname', 'lastname', 'username'];
|
|
43
43
|
|
|
44
44
|
module.exports = ({ action, ability, model }) => {
|
|
45
45
|
const schema = strapi.getModel(model);
|
|
@@ -49,7 +49,7 @@ module.exports = ({ action, ability, model }) => {
|
|
|
49
49
|
const createSanitizeQuery = (options = {}) => {
|
|
50
50
|
const { fields } = options;
|
|
51
51
|
|
|
52
|
-
// TODO: sanitize relations to admin
|
|
52
|
+
// TODO: sanitize relations to admin users in all sanitizers
|
|
53
53
|
const permittedFields = fields.shouldIncludeAll ? null : getQueryFields(fields.permitted);
|
|
54
54
|
|
|
55
55
|
const sanitizeFilters = pipeAsync(
|
|
@@ -1,22 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
flatMap,
|
|
5
|
-
reject,
|
|
6
|
-
isNil,
|
|
7
|
-
isArray,
|
|
8
|
-
prop,
|
|
9
|
-
xor,
|
|
10
|
-
eq,
|
|
11
|
-
uniq,
|
|
12
|
-
map,
|
|
13
|
-
difference,
|
|
14
|
-
differenceWith,
|
|
15
|
-
pipe,
|
|
16
|
-
} = require('lodash/fp');
|
|
3
|
+
const { isNil, isArray, prop, xor, eq, map, differenceWith } = require('lodash/fp');
|
|
17
4
|
const pmap = require('p-map');
|
|
18
|
-
const { EDITOR_CODE } = require('../constants');
|
|
19
|
-
const { getBoundActionsBySubject, BOUND_ACTIONS_FOR_FIELDS } = require('../../domain/role');
|
|
20
5
|
const { getService } = require('../../utils');
|
|
21
6
|
const permissionDomain = require('../../domain/permission/index');
|
|
22
7
|
|
|
@@ -195,63 +180,6 @@ const cleanPermissionsInDatabase = async () => {
|
|
|
195
180
|
}
|
|
196
181
|
};
|
|
197
182
|
|
|
198
|
-
const ensureBoundPermissionsInDatabase = async () => {
|
|
199
|
-
if (strapi.EE) {
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const contentTypes = Object.values(strapi.contentTypes);
|
|
204
|
-
const editorRole = await strapi.query('admin::role').findOne({
|
|
205
|
-
where: { code: EDITOR_CODE },
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
if (isNil(editorRole)) {
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
for (const contentType of contentTypes) {
|
|
213
|
-
const boundActions = getBoundActionsBySubject(editorRole, contentType.uid);
|
|
214
|
-
|
|
215
|
-
const permissions = await findMany({
|
|
216
|
-
where: {
|
|
217
|
-
subject: contentType.uid,
|
|
218
|
-
action: boundActions,
|
|
219
|
-
role: { id: editorRole.id },
|
|
220
|
-
},
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
if (permissions.length === 0) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const fields = pipe(
|
|
228
|
-
flatMap(permissionDomain.getProperty('fields')),
|
|
229
|
-
reject(isNil),
|
|
230
|
-
uniq
|
|
231
|
-
)(permissions);
|
|
232
|
-
|
|
233
|
-
// Handle the scenario where permissions are missing
|
|
234
|
-
const missingActions = difference(map('action', permissions), boundActions);
|
|
235
|
-
|
|
236
|
-
if (missingActions.length > 0) {
|
|
237
|
-
const permissions = pipe(
|
|
238
|
-
// Create a permission skeleton from the action id
|
|
239
|
-
map((action) => ({ action, subject: contentType.uid, role: editorRole.id })),
|
|
240
|
-
// Use the permission domain to create a clean permission from the given object
|
|
241
|
-
map(permissionDomain.create),
|
|
242
|
-
// Adds the fields property if the permission action is eligible
|
|
243
|
-
map((permission) =>
|
|
244
|
-
BOUND_ACTIONS_FOR_FIELDS.includes(permission.action)
|
|
245
|
-
? permissionDomain.setProperty('fields', fields, permission)
|
|
246
|
-
: permission
|
|
247
|
-
)
|
|
248
|
-
)(missingActions);
|
|
249
|
-
|
|
250
|
-
await createMany(permissions);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
|
|
255
183
|
module.exports = {
|
|
256
184
|
createMany,
|
|
257
185
|
findMany,
|
|
@@ -259,5 +187,4 @@ module.exports = {
|
|
|
259
187
|
deleteByIds,
|
|
260
188
|
findUserPermissions,
|
|
261
189
|
cleanPermissionsInDatabase,
|
|
262
|
-
ensureBoundPermissionsInDatabase,
|
|
263
190
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
errors: { UnauthorizedError, ForbiddenError },
|
|
5
|
+
} = require('@strapi/utils');
|
|
4
6
|
const { castArray, isNil } = require('lodash/fp');
|
|
5
7
|
|
|
6
8
|
const { getService } = require('../utils');
|
|
@@ -1,83 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const _ = require('lodash');
|
|
4
3
|
const { yup, validateYupSchema } = require('@strapi/utils');
|
|
5
4
|
const { getService } = require('../utils');
|
|
6
|
-
const { AUTHOR_CODE, PUBLISH_ACTION } = require('../services/constants');
|
|
7
|
-
const {
|
|
8
|
-
BOUND_ACTIONS_FOR_FIELDS,
|
|
9
|
-
BOUND_ACTIONS,
|
|
10
|
-
getBoundActionsBySubject,
|
|
11
|
-
} = require('../domain/role');
|
|
12
5
|
const validators = require('./common-validators');
|
|
13
6
|
|
|
14
|
-
// validatedUpdatePermissionsInput
|
|
15
|
-
|
|
16
|
-
const actionFieldsAreEqual = (a, b) => {
|
|
17
|
-
const aFields = a.properties.fields || [];
|
|
18
|
-
const bFields = b.properties.fields || [];
|
|
19
|
-
|
|
20
|
-
return _.isEqual(aFields.sort(), bFields.sort());
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const haveSameFieldsAsOtherActions = (a, i, allActions) =>
|
|
24
|
-
allActions.slice(i + 1).every((b) => actionFieldsAreEqual(a, b));
|
|
25
|
-
|
|
26
|
-
const checkPermissionsAreBound = (role) =>
|
|
27
|
-
function (permissions) {
|
|
28
|
-
const permsBySubject = _.groupBy(
|
|
29
|
-
permissions.filter((perm) => BOUND_ACTIONS.includes(perm.action)),
|
|
30
|
-
'subject'
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
for (const [subject, perms] of Object.entries(permsBySubject)) {
|
|
34
|
-
const boundActions = getBoundActionsBySubject(role, subject);
|
|
35
|
-
const missingActions =
|
|
36
|
-
_.xor(
|
|
37
|
-
perms.map((p) => p.action),
|
|
38
|
-
boundActions
|
|
39
|
-
).length !== 0;
|
|
40
|
-
if (missingActions) return false;
|
|
41
|
-
|
|
42
|
-
const permsBoundByFields = perms.filter((p) => BOUND_ACTIONS_FOR_FIELDS.includes(p.action));
|
|
43
|
-
const everyActionsHaveSameFields = _.every(permsBoundByFields, haveSameFieldsAsOtherActions);
|
|
44
|
-
if (!everyActionsHaveSameFields) return false;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return true;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const noPublishPermissionForAuthorRole = (role) =>
|
|
51
|
-
function (permissions) {
|
|
52
|
-
const isAuthor = role.code === AUTHOR_CODE;
|
|
53
|
-
const hasPublishPermission = permissions.some((perm) => perm.action === PUBLISH_ACTION);
|
|
54
|
-
|
|
55
|
-
return !(isAuthor && hasPublishPermission);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const getUpdatePermissionsSchemas = (role) => [
|
|
59
|
-
validators.updatePermissions,
|
|
60
|
-
yup.object().shape({ permissions: actionsExistSchema.clone() }),
|
|
61
|
-
yup.object().shape({
|
|
62
|
-
permissions: yup
|
|
63
|
-
.array()
|
|
64
|
-
.test(
|
|
65
|
-
'author-no-publish',
|
|
66
|
-
'The author role cannot have the publish permission.',
|
|
67
|
-
noPublishPermissionForAuthorRole(role)
|
|
68
|
-
),
|
|
69
|
-
}),
|
|
70
|
-
yup.object().shape({
|
|
71
|
-
permissions: yup
|
|
72
|
-
.array()
|
|
73
|
-
.test(
|
|
74
|
-
'are-bond',
|
|
75
|
-
'Permissions have to be defined all together for a subject field or not at all',
|
|
76
|
-
checkPermissionsAreBound(role)
|
|
77
|
-
),
|
|
78
|
-
}),
|
|
79
|
-
];
|
|
80
|
-
|
|
81
7
|
const checkPermissionsSchema = yup.object().shape({
|
|
82
8
|
permissions: yup.array().of(
|
|
83
9
|
yup
|
|
@@ -91,13 +17,6 @@ const checkPermissionsSchema = yup.object().shape({
|
|
|
91
17
|
),
|
|
92
18
|
});
|
|
93
19
|
|
|
94
|
-
const validatedUpdatePermissionsInput = async (permissions, role) => {
|
|
95
|
-
const schemas = getUpdatePermissionsSchemas(role);
|
|
96
|
-
for (const schema of schemas) {
|
|
97
|
-
await validateYupSchema(schema)(permissions);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
20
|
// validatePermissionsExist
|
|
102
21
|
|
|
103
22
|
const checkPermissionsExist = function (permissions) {
|
|
@@ -131,7 +50,7 @@ const actionsExistSchema = yup
|
|
|
131
50
|
// exports
|
|
132
51
|
|
|
133
52
|
module.exports = {
|
|
134
|
-
validatedUpdatePermissionsInput,
|
|
53
|
+
validatedUpdatePermissionsInput: validateYupSchema(validators.updatePermissions),
|
|
135
54
|
validatePermissionsExist: validateYupSchema(actionsExistSchema),
|
|
136
55
|
validateCheckPermissionsInput: validateYupSchema(checkPermissionsSchema),
|
|
137
56
|
};
|
|
@@ -2,6 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
const { yup, validateYupSchema } = require('@strapi/utils');
|
|
4
4
|
|
|
5
|
+
const roleCreateSchema = yup
|
|
6
|
+
.object()
|
|
7
|
+
.shape({
|
|
8
|
+
name: yup.string().min(1).required(),
|
|
9
|
+
description: yup.string().nullable(),
|
|
10
|
+
})
|
|
11
|
+
.noUnknown();
|
|
12
|
+
|
|
13
|
+
const rolesDeleteSchema = yup
|
|
14
|
+
.object()
|
|
15
|
+
.shape({
|
|
16
|
+
ids: yup
|
|
17
|
+
.array()
|
|
18
|
+
.of(yup.strapiID())
|
|
19
|
+
.min(1)
|
|
20
|
+
.required()
|
|
21
|
+
.test('roles-deletion-checks', 'Roles deletion checks have failed', async function (ids) {
|
|
22
|
+
try {
|
|
23
|
+
await strapi.admin.services.role.checkRolesIdForDeletion(ids);
|
|
24
|
+
} catch (e) {
|
|
25
|
+
return this.createError({ path: 'ids', message: e.message });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return true;
|
|
29
|
+
}),
|
|
30
|
+
})
|
|
31
|
+
.noUnknown();
|
|
32
|
+
|
|
33
|
+
const roleDeleteSchema = yup
|
|
34
|
+
.strapiID()
|
|
35
|
+
.required()
|
|
36
|
+
.test('no-admin-single-delete', 'Role deletion checks have failed', async function (id) {
|
|
37
|
+
try {
|
|
38
|
+
await strapi.admin.services.role.checkRolesIdForDeletion([id]);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
return this.createError({ path: 'id', message: e.message });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return true;
|
|
44
|
+
});
|
|
45
|
+
|
|
5
46
|
const roleUpdateSchema = yup
|
|
6
47
|
.object()
|
|
7
48
|
.shape({
|
|
@@ -12,4 +53,7 @@ const roleUpdateSchema = yup
|
|
|
12
53
|
|
|
13
54
|
module.exports = {
|
|
14
55
|
validateRoleUpdateInput: validateYupSchema(roleUpdateSchema),
|
|
56
|
+
validateRoleCreateInput: validateYupSchema(roleCreateSchema),
|
|
57
|
+
validateRolesDeleteInput: validateYupSchema(rolesDeleteSchema),
|
|
58
|
+
validateRoleDeleteInput: validateYupSchema(roleDeleteSchema),
|
|
15
59
|
};
|
|
Binary file
|
|
Binary file
|