@strapi/plugin-users-permissions 4.0.0-next.9 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/src/components/BoundRoute/getMethodColor.js +41 -0
- package/admin/src/components/BoundRoute/index.js +40 -24
- package/admin/src/components/FormModal/Input/index.js +121 -0
- package/admin/src/components/FormModal/index.js +123 -0
- package/admin/src/components/Permissions/PermissionRow/CheckboxWrapper.js +19 -26
- package/admin/src/components/Permissions/PermissionRow/SubCategory.js +118 -0
- package/admin/src/components/Permissions/PermissionRow/index.js +9 -48
- package/admin/src/components/Permissions/index.js +36 -24
- package/admin/src/components/Permissions/init.js +1 -6
- package/admin/src/components/Policies/index.js +46 -47
- package/admin/src/components/UsersPermissions/index.js +29 -26
- package/admin/src/components/UsersPermissions/init.js +1 -2
- package/admin/src/hooks/useFetchRole/index.js +17 -7
- package/admin/src/hooks/useForm/index.js +3 -29
- package/admin/src/hooks/useForm/reducer.js +2 -21
- package/admin/src/hooks/usePlugins/index.js +12 -21
- package/admin/src/hooks/usePlugins/reducer.js +0 -3
- package/admin/src/index.js +0 -8
- package/admin/src/pages/AdvancedSettings/index.js +203 -193
- package/admin/src/pages/AdvancedSettings/utils/api.js +13 -0
- package/admin/src/pages/AdvancedSettings/utils/layout.js +96 -0
- package/admin/src/pages/AdvancedSettings/utils/schema.js +22 -0
- package/admin/src/pages/EmailTemplates/components/EmailForm.js +173 -0
- package/admin/src/pages/EmailTemplates/components/EmailTable.js +116 -0
- package/admin/src/pages/EmailTemplates/index.js +117 -197
- package/admin/src/pages/EmailTemplates/utils/api.js +13 -0
- package/admin/src/pages/Providers/index.js +206 -221
- package/admin/src/pages/Providers/utils/api.js +21 -0
- package/admin/src/pages/Providers/utils/forms.js +168 -126
- package/admin/src/pages/Roles/CreatePage/index.js +155 -147
- package/admin/src/pages/Roles/EditPage/index.js +162 -134
- package/admin/src/pages/Roles/ListPage/components/TableBody.js +96 -0
- package/admin/src/pages/Roles/ListPage/index.js +176 -156
- package/admin/src/pages/Roles/ListPage/utils/api.js +28 -0
- package/admin/src/translations/ar.json +0 -8
- package/admin/src/translations/cs.json +0 -8
- package/admin/src/translations/de.json +0 -8
- package/admin/src/translations/dk.json +0 -8
- package/admin/src/translations/en.json +33 -12
- package/admin/src/translations/es.json +0 -8
- package/admin/src/translations/fr.json +0 -8
- package/admin/src/translations/id.json +0 -8
- package/admin/src/translations/it.json +0 -8
- package/admin/src/translations/ja.json +0 -8
- package/admin/src/translations/ko.json +0 -8
- package/admin/src/translations/ms.json +0 -8
- package/admin/src/translations/nl.json +0 -8
- package/admin/src/translations/pl.json +0 -8
- package/admin/src/translations/pt-BR.json +0 -8
- package/admin/src/translations/pt.json +0 -8
- package/admin/src/translations/ru.json +0 -8
- package/admin/src/translations/sk.json +0 -8
- package/admin/src/translations/sv.json +0 -8
- package/admin/src/translations/th.json +0 -8
- package/admin/src/translations/tr.json +0 -8
- package/admin/src/translations/uk.json +0 -8
- package/admin/src/translations/vi.json +0 -8
- package/admin/src/translations/zh-Hans.json +5 -14
- package/admin/src/translations/zh.json +0 -8
- package/admin/src/utils/axiosInstance.js +36 -0
- package/admin/src/utils/formatPluginName.js +26 -0
- package/admin/src/utils/index.js +1 -0
- package/documentation/1.0.0/overrides/users-permissions-Role.json +6 -6
- package/documentation/1.0.0/overrides/users-permissions-User.json +7 -7
- package/package.json +30 -31
- package/server/bootstrap/index.js +19 -21
- package/server/config.js +3 -3
- package/server/content-types/index.js +3 -3
- package/server/content-types/permission/index.js +30 -3
- package/server/content-types/role/index.js +47 -3
- package/server/content-types/user/index.js +65 -4
- package/server/controllers/auth.js +81 -244
- package/server/controllers/content-manager-user.js +183 -0
- package/server/controllers/index.js +12 -6
- package/server/controllers/permissions.js +26 -0
- package/server/controllers/role.js +77 -0
- package/server/controllers/settings.js +85 -0
- package/server/controllers/user.js +118 -44
- package/server/controllers/validation/auth.js +29 -0
- package/server/controllers/validation/user.js +38 -0
- package/server/graphql/index.js +44 -0
- package/server/graphql/mutations/auth/email-confirmation.js +39 -0
- package/server/graphql/mutations/auth/forgot-password.js +38 -0
- package/server/graphql/mutations/auth/login.js +38 -0
- package/server/graphql/mutations/auth/register.js +39 -0
- package/server/graphql/mutations/auth/reset-password.js +41 -0
- package/server/graphql/mutations/crud/role/create-role.js +37 -0
- package/server/graphql/mutations/crud/role/delete-role.js +28 -0
- package/server/graphql/mutations/crud/role/update-role.js +38 -0
- package/server/graphql/mutations/crud/user/create-user.js +48 -0
- package/server/graphql/mutations/crud/user/delete-user.js +42 -0
- package/server/graphql/mutations/crud/user/update-user.js +49 -0
- package/server/graphql/mutations/index.js +42 -0
- package/server/graphql/queries/index.js +13 -0
- package/server/graphql/queries/me.js +17 -0
- package/server/graphql/resolvers-configs.js +37 -0
- package/server/graphql/types/create-role-payload.js +11 -0
- package/server/graphql/types/delete-role-payload.js +11 -0
- package/server/graphql/types/index.js +21 -0
- package/server/graphql/types/login-input.js +13 -0
- package/server/graphql/types/login-payload.js +12 -0
- package/server/graphql/types/me-role.js +14 -0
- package/server/graphql/types/me.js +16 -0
- package/server/graphql/types/password-payload.js +11 -0
- package/server/graphql/types/register-input.js +13 -0
- package/server/graphql/types/update-role-payload.js +11 -0
- package/server/graphql/utils.js +27 -0
- package/server/index.js +21 -0
- package/server/middlewares/index.js +2 -2
- package/server/{policies → middlewares}/rateLimit.js +3 -7
- package/server/register.js +11 -0
- package/server/routes/admin/index.js +10 -0
- package/server/routes/admin/permissions.js +20 -0
- package/server/routes/admin/role.js +79 -0
- package/server/routes/admin/settings.js +95 -0
- package/server/routes/content-api/auth.js +73 -0
- package/server/routes/content-api/index.js +11 -0
- package/server/routes/content-api/permissions.js +9 -0
- package/server/routes/content-api/role.js +29 -0
- package/server/routes/content-api/user.js +61 -0
- package/server/routes/index.js +4 -428
- package/server/services/index.js +10 -8
- package/server/services/jwt.js +9 -17
- package/server/services/providers.js +32 -33
- package/server/services/role.js +177 -0
- package/server/services/user.js +9 -15
- package/server/services/users-permissions.js +140 -338
- package/server/strategies/users-permissions.js +123 -0
- package/server/utils/index.d.ts +2 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +1 -19
- package/admin/src/assets/images/logo.svg +0 -1
- package/admin/src/components/BaselineAlignement/index.js +0 -33
- package/admin/src/components/Bloc/index.js +0 -10
- package/admin/src/components/BoundRoute/Components.js +0 -78
- package/admin/src/components/ContainerFluid/index.js +0 -13
- package/admin/src/components/FormBloc/index.js +0 -61
- package/admin/src/components/IntlInput/index.js +0 -38
- package/admin/src/components/ListBaselineAlignment/index.js +0 -8
- package/admin/src/components/ListRow/Components.js +0 -74
- package/admin/src/components/ListRow/index.js +0 -35
- package/admin/src/components/ModalForm/Wrapper.js +0 -12
- package/admin/src/components/ModalForm/index.js +0 -59
- package/admin/src/components/Permissions/ListWrapper.js +0 -9
- package/admin/src/components/Permissions/PermissionRow/BaselineAlignment.js +0 -7
- package/admin/src/components/Permissions/PermissionRow/RowStyle.js +0 -28
- package/admin/src/components/Permissions/PermissionRow/SubCategory/ConditionsButtonWrapper.js +0 -13
- package/admin/src/components/Permissions/PermissionRow/SubCategory/PolicyWrapper.js +0 -8
- package/admin/src/components/Permissions/PermissionRow/SubCategory/SubCategoryWrapper.js +0 -26
- package/admin/src/components/Permissions/PermissionRow/SubCategory/index.js +0 -116
- package/admin/src/components/Policies/Components.js +0 -26
- package/admin/src/components/PrefixedIcon/index.js +0 -27
- package/admin/src/components/Roles/EmptyRole/BaselineAlignment.js +0 -7
- package/admin/src/components/Roles/EmptyRole/index.js +0 -27
- package/admin/src/components/Roles/RoleListWrapper/index.js +0 -17
- package/admin/src/components/Roles/RoleRow/RoleDescription.js +0 -9
- package/admin/src/components/Roles/RoleRow/index.js +0 -45
- package/admin/src/components/Roles/index.js +0 -3
- package/admin/src/components/SizedInput/index.js +0 -24
- package/admin/src/pages/AdvancedSettings/reducer.js +0 -65
- package/admin/src/pages/AdvancedSettings/utils/form.js +0 -52
- package/admin/src/pages/EmailTemplates/CustomTextInput.js +0 -105
- package/admin/src/pages/EmailTemplates/Wrapper.js +0 -36
- package/admin/src/pages/EmailTemplates/reducer.js +0 -58
- package/admin/src/pages/EmailTemplates/utils/forms.js +0 -81
- package/admin/src/pages/Roles/ListPage/BaselineAlignment.js +0 -8
- package/server/content-types/permission/schema.json +0 -48
- package/server/content-types/role/schema.json +0 -46
- package/server/content-types/user/schema.json +0 -66
- package/server/controllers/user/admin.js +0 -230
- package/server/controllers/user/api.js +0 -174
- package/server/controllers/users-permissions.js +0 -271
- package/server/middlewares/users-permissions.js +0 -44
- package/server/policies/index.js +0 -11
- package/server/policies/isAuthenticated.js +0 -9
- package/server/policies/permissions.js +0 -94
- package/server/schema.graphql.js +0 -317
|
@@ -1,346 +1,198 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
|
-
const
|
|
4
|
+
const { filter, map, pipe, prop } = require('lodash/fp');
|
|
5
|
+
|
|
5
6
|
const { getService } = require('../utils');
|
|
6
7
|
|
|
7
8
|
const DEFAULT_PERMISSIONS = [
|
|
8
|
-
{ action: '
|
|
9
|
-
{ action: '
|
|
10
|
-
{ action: '
|
|
11
|
-
{ action: '
|
|
12
|
-
{ action: '
|
|
13
|
-
{ action: '
|
|
14
|
-
{ action: '
|
|
15
|
-
{
|
|
16
|
-
|
|
17
|
-
controller: 'auth',
|
|
18
|
-
type: 'users-permissions',
|
|
19
|
-
roleType: 'public',
|
|
20
|
-
},
|
|
21
|
-
{ action: 'me', controller: 'user', type: 'users-permissions', roleType: null },
|
|
9
|
+
{ action: 'plugin::users-permissions.auth.admincallback', roleType: 'public' },
|
|
10
|
+
{ action: 'plugin::users-permissions.auth.adminregister', roleType: 'public' },
|
|
11
|
+
{ action: 'plugin::users-permissions.auth.callback', roleType: 'public' },
|
|
12
|
+
{ action: 'plugin::users-permissions.auth.connect', roleType: null },
|
|
13
|
+
{ action: 'plugin::users-permissions.auth.forgotpassword', roleType: 'public' },
|
|
14
|
+
{ action: 'plugin::users-permissions.auth.resetpassword', roleType: 'public' },
|
|
15
|
+
{ action: 'plugin::users-permissions.auth.register', roleType: 'public' },
|
|
16
|
+
{ action: 'plugin::users-permissions.auth.emailconfirmation', roleType: 'public' },
|
|
17
|
+
{ action: 'plugin::users-permissions.user.me', roleType: null },
|
|
22
18
|
];
|
|
23
19
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
const transformRoutePrefixFor = pluginName => route => {
|
|
21
|
+
const prefix = route.config && route.config.prefix;
|
|
22
|
+
const path = prefix !== undefined ? `${prefix}${route.path}` : `/${pluginName}${route.path}`;
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
...route,
|
|
26
|
+
path,
|
|
27
|
+
};
|
|
32
28
|
};
|
|
33
29
|
|
|
34
30
|
module.exports = ({ strapi }) => ({
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
params.type = _.snakeCase(_.deburr(_.toLower(params.name)));
|
|
38
|
-
}
|
|
31
|
+
getActions({ defaultEnable = false } = {}) {
|
|
32
|
+
const actionMap = {};
|
|
39
33
|
|
|
40
|
-
const
|
|
41
|
-
.
|
|
42
|
-
|
|
34
|
+
const isContentApi = action => {
|
|
35
|
+
if (!_.has(action, Symbol.for('__type__'))) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
43
38
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
Object.keys(params.permissions[type].controllers[controller]).forEach(action => {
|
|
47
|
-
acc.push(
|
|
48
|
-
strapi.query('plugin::users-permissions.permission').create({
|
|
49
|
-
data: {
|
|
50
|
-
role: role.id,
|
|
51
|
-
type,
|
|
52
|
-
controller,
|
|
53
|
-
action: action.toLowerCase(),
|
|
54
|
-
...params.permissions[type].controllers[controller][action],
|
|
55
|
-
},
|
|
56
|
-
})
|
|
57
|
-
);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
39
|
+
return action[Symbol.for('__type__')].includes('content-api');
|
|
40
|
+
};
|
|
60
41
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
arrayOfPromises.push(
|
|
67
|
-
strapi.query('plugin::users-permissions.role').update({
|
|
68
|
-
where: {
|
|
69
|
-
id: role.id,
|
|
70
|
-
},
|
|
71
|
-
data: { users: params.users },
|
|
72
|
-
})
|
|
73
|
-
);
|
|
42
|
+
_.forEach(strapi.api, (api, apiName) => {
|
|
43
|
+
const controllers = _.reduce(
|
|
44
|
+
api.controllers,
|
|
45
|
+
(acc, controller, controllerName) => {
|
|
46
|
+
const contentApiActions = _.pickBy(controller, isContentApi);
|
|
74
47
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
async deleteRole(roleID, publicRoleID) {
|
|
79
|
-
const role = await strapi
|
|
80
|
-
.query('plugin::users-permissions.role')
|
|
81
|
-
.findOne({ where: { id: roleID }, populate: ['users', 'permissions'] });
|
|
48
|
+
if (_.isEmpty(contentApiActions)) {
|
|
49
|
+
return acc;
|
|
50
|
+
}
|
|
82
51
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
52
|
+
acc[controllerName] = _.mapValues(contentApiActions, () => {
|
|
53
|
+
return {
|
|
54
|
+
enabled: defaultEnable,
|
|
55
|
+
policy: '',
|
|
56
|
+
};
|
|
57
|
+
});
|
|
86
58
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
strapi.query('plugin::users-permissions.user').update({
|
|
91
|
-
where: {
|
|
92
|
-
id: user.id,
|
|
93
|
-
},
|
|
94
|
-
data: {
|
|
95
|
-
role: publicRoleID,
|
|
96
|
-
},
|
|
97
|
-
})
|
|
59
|
+
return acc;
|
|
60
|
+
},
|
|
61
|
+
{}
|
|
98
62
|
);
|
|
99
63
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// Remove permissions related to this role.
|
|
104
|
-
role.permissions.forEach(permission => {
|
|
105
|
-
arrayOfPromises.push(
|
|
106
|
-
strapi.query('plugin::users-permissions.permission').delete({
|
|
107
|
-
where: { id: permission.id },
|
|
108
|
-
})
|
|
109
|
-
);
|
|
64
|
+
if (!_.isEmpty(controllers)) {
|
|
65
|
+
actionMap[`api::${apiName}`] = { controllers };
|
|
66
|
+
}
|
|
110
67
|
});
|
|
111
68
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
69
|
+
_.forEach(strapi.plugins, (plugin, pluginName) => {
|
|
70
|
+
const controllers = _.reduce(
|
|
71
|
+
plugin.controllers,
|
|
72
|
+
(acc, controller, controllerName) => {
|
|
73
|
+
const contentApiActions = _.pickBy(controller, isContentApi);
|
|
116
74
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
getPlugins(lang = 'en') {
|
|
121
|
-
return new Promise(resolve => {
|
|
122
|
-
request(
|
|
123
|
-
{
|
|
124
|
-
uri: `https://marketplace.strapi.io/plugins?lang=${lang}`,
|
|
125
|
-
json: true,
|
|
126
|
-
timeout: 3000,
|
|
127
|
-
headers: {
|
|
128
|
-
'cache-control': 'max-age=3600',
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
(err, response, body) => {
|
|
132
|
-
if (err || response.statusCode !== 200) {
|
|
133
|
-
return resolve([]);
|
|
75
|
+
if (_.isEmpty(contentApiActions)) {
|
|
76
|
+
return acc;
|
|
134
77
|
}
|
|
135
78
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
getActions() {
|
|
143
|
-
const generateActions = data =>
|
|
144
|
-
Object.keys(data).reduce((acc, key) => {
|
|
145
|
-
if (_.isFunction(data[key])) {
|
|
146
|
-
acc[key] = { enabled: false, policy: '' };
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return acc;
|
|
150
|
-
}, {});
|
|
151
|
-
|
|
152
|
-
const appControllers = Object.keys(strapi.api || {})
|
|
153
|
-
.filter(key => !!strapi.api[key].controllers)
|
|
154
|
-
.reduce(
|
|
155
|
-
(acc, key) => {
|
|
156
|
-
Object.keys(strapi.api[key].controllers).forEach(controller => {
|
|
157
|
-
acc.controllers[controller] = generateActions(strapi.api[key].controllers[controller]);
|
|
79
|
+
acc[controllerName] = _.mapValues(contentApiActions, () => {
|
|
80
|
+
return {
|
|
81
|
+
enabled: defaultEnable,
|
|
82
|
+
policy: '',
|
|
83
|
+
};
|
|
158
84
|
});
|
|
159
85
|
|
|
160
86
|
return acc;
|
|
161
87
|
},
|
|
162
|
-
{
|
|
88
|
+
{}
|
|
163
89
|
);
|
|
164
90
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const pluginControllers = strapi.plugin(key).controllers;
|
|
171
|
-
acc[key] = Object.keys(pluginControllers).reduce((obj, k) => {
|
|
172
|
-
obj.controllers[k] = generateActions(pluginControllers[k]);
|
|
173
|
-
|
|
174
|
-
return obj;
|
|
175
|
-
}, initialState);
|
|
176
|
-
|
|
177
|
-
return acc;
|
|
178
|
-
}, {});
|
|
179
|
-
|
|
180
|
-
const permissions = {
|
|
181
|
-
application: {
|
|
182
|
-
controllers: appControllers.controllers,
|
|
183
|
-
},
|
|
184
|
-
};
|
|
91
|
+
if (!_.isEmpty(controllers)) {
|
|
92
|
+
actionMap[`plugin::${pluginName}`] = { controllers };
|
|
93
|
+
}
|
|
94
|
+
});
|
|
185
95
|
|
|
186
|
-
return
|
|
96
|
+
return actionMap;
|
|
187
97
|
},
|
|
188
98
|
|
|
189
|
-
async
|
|
190
|
-
const
|
|
191
|
-
.query('plugin::users-permissions.role')
|
|
192
|
-
.findOne({ where: { id: roleID }, populate: ['permissions'] });
|
|
99
|
+
async getRoutes() {
|
|
100
|
+
const routesMap = {};
|
|
193
101
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
102
|
+
_.forEach(strapi.api, (api, apiName) => {
|
|
103
|
+
const routes = _.flatMap(api.routes, route => {
|
|
104
|
+
if (_.has(route, 'routes')) {
|
|
105
|
+
return route.routes;
|
|
106
|
+
}
|
|
197
107
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
_.set(acc, `${permission.type}.controllers.${permission.controller}.${permission.action}`, {
|
|
201
|
-
enabled: _.toNumber(permission.enabled) == true,
|
|
202
|
-
policy: permission.policy,
|
|
203
|
-
});
|
|
108
|
+
return route;
|
|
109
|
+
}).filter(route => route.info.type === 'content-api');
|
|
204
110
|
|
|
205
|
-
if (
|
|
206
|
-
|
|
207
|
-
plugins.find(plugin => plugin.id === permission.type) || {};
|
|
111
|
+
if (routes.length === 0) {
|
|
112
|
+
return;
|
|
208
113
|
}
|
|
209
114
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
permissions,
|
|
216
|
-
};
|
|
217
|
-
},
|
|
218
|
-
|
|
219
|
-
async getRoles() {
|
|
220
|
-
const roles = await strapi.query('plugin::users-permissions.role').findMany({ sort: ['name'] });
|
|
221
|
-
|
|
222
|
-
for (let i = 0; i < roles.length; ++i) {
|
|
223
|
-
roles[i].nb_users = await strapi
|
|
224
|
-
.query('plugin::users-permissions.user')
|
|
225
|
-
.count({ where: { role: { id: roles[i].id } } });
|
|
226
|
-
}
|
|
115
|
+
routesMap[`api::${apiName}`] = routes.map(route => ({
|
|
116
|
+
...route,
|
|
117
|
+
path: `/api${route.path}`,
|
|
118
|
+
}));
|
|
119
|
+
});
|
|
227
120
|
|
|
228
|
-
|
|
229
|
-
|
|
121
|
+
_.forEach(strapi.plugins, (plugin, pluginName) => {
|
|
122
|
+
const transformPrefix = transformRoutePrefixFor(pluginName);
|
|
230
123
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const pluginsRoutes = Object.keys(strapi.plugins).reduce((acc, current) => {
|
|
236
|
-
const routes = strapi.plugin(current).routes.reduce((acc, curr) => {
|
|
237
|
-
const prefix = curr.config.prefix;
|
|
238
|
-
const path = prefix !== undefined ? `${prefix}${curr.path}` : `/${current}${curr.path}`;
|
|
239
|
-
_.set(curr, 'path', path);
|
|
124
|
+
const routes = _.flatMap(plugin.routes, route => {
|
|
125
|
+
if (_.has(route, 'routes')) {
|
|
126
|
+
return route.routes.map(transformPrefix);
|
|
127
|
+
}
|
|
240
128
|
|
|
241
|
-
return
|
|
242
|
-
}
|
|
129
|
+
return transformPrefix(route);
|
|
130
|
+
}).filter(route => route.info.type === 'content-api');
|
|
243
131
|
|
|
244
|
-
|
|
132
|
+
if (routes.length === 0) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
245
135
|
|
|
246
|
-
|
|
247
|
-
|
|
136
|
+
routesMap[`plugin::${pluginName}`] = routes.map(route => ({
|
|
137
|
+
...route,
|
|
138
|
+
path: `/api${route.path}`,
|
|
139
|
+
}));
|
|
140
|
+
});
|
|
248
141
|
|
|
249
|
-
return
|
|
142
|
+
return routesMap;
|
|
250
143
|
},
|
|
251
144
|
|
|
252
|
-
async
|
|
145
|
+
async syncPermissions() {
|
|
253
146
|
const roles = await strapi.query('plugin::users-permissions.role').findMany();
|
|
147
|
+
const dbPermissions = await strapi.query('plugin::users-permissions.permission').findMany();
|
|
254
148
|
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
const dbPermissions = await strapi
|
|
258
|
-
.query('plugin::users-permissions.permission')
|
|
259
|
-
.findMany({ populate: ['role'] });
|
|
260
|
-
|
|
261
|
-
let permissionsFoundInDB = dbPermissions.map(permission => {
|
|
262
|
-
const { type, controller, action, role } = permission;
|
|
263
|
-
return `${type}.${controller}.${action}.${role.id}`;
|
|
264
|
-
});
|
|
149
|
+
const permissionsFoundInDB = _.uniq(_.map(dbPermissions, 'action'));
|
|
265
150
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const actions = Object.keys(strapi.api[api].controllers[controller])
|
|
272
|
-
.filter(action => _.isFunction(strapi.api[api].controllers[controller][action]))
|
|
273
|
-
.map(action => `application.${controller}.${action.toLowerCase()}`);
|
|
274
|
-
|
|
275
|
-
acc = acc.concat(actions);
|
|
151
|
+
const appActions = _.flatMap(strapi.api, (api, apiName) => {
|
|
152
|
+
return _.flatMap(api.controllers, (controller, controllerName) => {
|
|
153
|
+
return _.keys(controller).map(actionName => {
|
|
154
|
+
return `api::${apiName}.${controllerName}.${actionName}`;
|
|
155
|
+
});
|
|
276
156
|
});
|
|
157
|
+
});
|
|
277
158
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const pluginControllers = strapi.plugin(plugin).controllers;
|
|
284
|
-
|
|
285
|
-
Object.keys(pluginControllers).forEach(controller => {
|
|
286
|
-
const controllerActions = pluginControllers[controller];
|
|
287
|
-
|
|
288
|
-
const actions = Object.keys(controllerActions)
|
|
289
|
-
.filter(action => _.isFunction(controllerActions[action]))
|
|
290
|
-
.map(action => `${plugin}.${controller}.${action.toLowerCase()}`);
|
|
291
|
-
|
|
292
|
-
acc = acc.concat(actions);
|
|
159
|
+
const pluginsActions = _.flatMap(strapi.plugins, (plugin, pluginName) => {
|
|
160
|
+
return _.flatMap(plugin.controllers, (controller, controllerName) => {
|
|
161
|
+
return _.keys(controller).map(actionName => {
|
|
162
|
+
return `plugin::${pluginName}.${controllerName}.${actionName}`;
|
|
163
|
+
});
|
|
293
164
|
});
|
|
165
|
+
});
|
|
294
166
|
|
|
295
|
-
|
|
296
|
-
}, []);
|
|
297
|
-
|
|
298
|
-
const actionsFoundInFiles = appActions.concat(pluginsActions);
|
|
167
|
+
const allActions = [...appActions, ...pluginsActions];
|
|
299
168
|
|
|
300
|
-
const
|
|
169
|
+
const toDelete = _.difference(permissionsFoundInDB, allActions);
|
|
301
170
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
// Compare to know if actions have been added or removed from controllers.
|
|
309
|
-
if (!_.isEqual(permissionsFoundInDB.sort(), permissionsFoundInFiles.sort())) {
|
|
310
|
-
const splitted = str => {
|
|
311
|
-
const [type, controller, action, roleId] = str.split('.');
|
|
312
|
-
|
|
313
|
-
return { type, controller, action, roleId };
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
// We have to know the difference to add or remove the permissions entries in the database.
|
|
317
|
-
const toRemove = _.difference(permissionsFoundInDB, permissionsFoundInFiles).map(splitted);
|
|
318
|
-
const toAdd = _.difference(permissionsFoundInFiles, permissionsFoundInDB).map(splitted);
|
|
319
|
-
|
|
320
|
-
const query = strapi.query('plugin::users-permissions.permission');
|
|
321
|
-
|
|
322
|
-
// Execute request to update entries in database for each role.
|
|
323
|
-
await Promise.all(
|
|
324
|
-
toAdd.map(permission => {
|
|
325
|
-
return query.create({
|
|
326
|
-
data: {
|
|
327
|
-
type: permission.type,
|
|
328
|
-
controller: permission.controller,
|
|
329
|
-
action: permission.action,
|
|
330
|
-
enabled: isEnabledByDefault(permission, rolesMap[permission.roleId]),
|
|
331
|
-
policy: '',
|
|
332
|
-
role: permission.roleId,
|
|
333
|
-
},
|
|
334
|
-
});
|
|
335
|
-
})
|
|
336
|
-
);
|
|
171
|
+
await Promise.all(
|
|
172
|
+
toDelete.map(action => {
|
|
173
|
+
return strapi.query('plugin::users-permissions.permission').delete({ where: { action } });
|
|
174
|
+
})
|
|
175
|
+
);
|
|
337
176
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
177
|
+
if (permissionsFoundInDB.length === 0) {
|
|
178
|
+
// create default permissions
|
|
179
|
+
for (const role of roles) {
|
|
180
|
+
const toCreate = pipe(
|
|
181
|
+
filter(({ roleType }) => roleType === role.type || roleType === null),
|
|
182
|
+
map(prop('action'))
|
|
183
|
+
)(DEFAULT_PERMISSIONS);
|
|
184
|
+
|
|
185
|
+
await Promise.all(
|
|
186
|
+
toCreate.map(action => {
|
|
187
|
+
return strapi.query('plugin::users-permissions.permission').create({
|
|
188
|
+
data: {
|
|
189
|
+
action,
|
|
190
|
+
role: role.id,
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
})
|
|
194
|
+
);
|
|
195
|
+
}
|
|
344
196
|
}
|
|
345
197
|
},
|
|
346
198
|
|
|
@@ -365,57 +217,7 @@ module.exports = ({ strapi }) => ({
|
|
|
365
217
|
});
|
|
366
218
|
}
|
|
367
219
|
|
|
368
|
-
return getService('users-permissions').
|
|
369
|
-
},
|
|
370
|
-
|
|
371
|
-
async updateRole(roleID, body) {
|
|
372
|
-
const [role, authenticated] = await Promise.all([
|
|
373
|
-
this.getRole(roleID, []),
|
|
374
|
-
strapi.query('plugin::users-permissions.role').findOne({ where: { type: 'authenticated' } }),
|
|
375
|
-
]);
|
|
376
|
-
|
|
377
|
-
await strapi.query('plugin::users-permissions.role').update({
|
|
378
|
-
where: { id: roleID },
|
|
379
|
-
data: _.pick(body, ['name', 'description']),
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
await Promise.all(
|
|
383
|
-
Object.keys(body.permissions || {}).reduce((acc, type) => {
|
|
384
|
-
Object.keys(body.permissions[type].controllers).forEach(controller => {
|
|
385
|
-
Object.keys(body.permissions[type].controllers[controller]).forEach(action => {
|
|
386
|
-
const bodyAction = body.permissions[type].controllers[controller][action];
|
|
387
|
-
const currentAction = _.get(
|
|
388
|
-
role.permissions,
|
|
389
|
-
`${type}.controllers.${controller}.${action}`,
|
|
390
|
-
{}
|
|
391
|
-
);
|
|
392
|
-
|
|
393
|
-
if (!_.isEqual(bodyAction, currentAction)) {
|
|
394
|
-
acc.push(
|
|
395
|
-
strapi.query('plugin::users-permissions.permission').update({
|
|
396
|
-
where: {
|
|
397
|
-
role: roleID,
|
|
398
|
-
type,
|
|
399
|
-
controller,
|
|
400
|
-
action: action.toLowerCase(),
|
|
401
|
-
},
|
|
402
|
-
data: bodyAction,
|
|
403
|
-
})
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
});
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
return acc;
|
|
410
|
-
}, [])
|
|
411
|
-
);
|
|
412
|
-
|
|
413
|
-
// Add user to this role.
|
|
414
|
-
const newUsers = _.differenceBy(body.users, role.users, 'id');
|
|
415
|
-
await Promise.all(newUsers.map(user => this.updateUserRole(user, roleID)));
|
|
416
|
-
|
|
417
|
-
const oldUsers = _.differenceBy(role.users, body.users, 'id');
|
|
418
|
-
await Promise.all(oldUsers.map(user => this.updateUserRole(user, authenticated.id)));
|
|
220
|
+
return getService('users-permissions').syncPermissions();
|
|
419
221
|
},
|
|
420
222
|
|
|
421
223
|
async updateUserRole(user, role) {
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { castArray, map } = require('lodash/fp');
|
|
4
|
+
const { ForbiddenError, UnauthorizedError } = require('@strapi/utils').errors;
|
|
5
|
+
|
|
6
|
+
const { getService } = require('../utils');
|
|
7
|
+
|
|
8
|
+
const getAdvancedSettings = () => {
|
|
9
|
+
return strapi.store({ type: 'plugin', name: 'users-permissions' }).get({ key: 'advanced' });
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const authenticate = async ctx => {
|
|
13
|
+
try {
|
|
14
|
+
const token = await getService('jwt').getToken(ctx);
|
|
15
|
+
|
|
16
|
+
if (token) {
|
|
17
|
+
const { id } = token;
|
|
18
|
+
|
|
19
|
+
if (id === undefined) {
|
|
20
|
+
return { authenticated: false };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// fetch authenticated user
|
|
24
|
+
const user = await getService('user').fetchAuthenticatedUser(id);
|
|
25
|
+
|
|
26
|
+
if (!user) {
|
|
27
|
+
return { error: 'Invalid credentials' };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const advancedSettings = await getAdvancedSettings();
|
|
31
|
+
|
|
32
|
+
if (advancedSettings.email_confirmation && !user.confirmed) {
|
|
33
|
+
return { error: 'Invalid credentials' };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (user.blocked) {
|
|
37
|
+
return { error: 'Invalid credentials' };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
ctx.state.user = user;
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
authenticated: true,
|
|
44
|
+
credentials: user,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const publicPermissions = await strapi.query('plugin::users-permissions.permission').findMany({
|
|
49
|
+
where: {
|
|
50
|
+
role: { type: 'public' },
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (publicPermissions.length === 0) {
|
|
55
|
+
return { authenticated: false };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
authenticated: true,
|
|
60
|
+
credentials: null,
|
|
61
|
+
};
|
|
62
|
+
} catch (err) {
|
|
63
|
+
return { authenticated: false };
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const verify = async (auth, config) => {
|
|
68
|
+
const { credentials: user } = auth;
|
|
69
|
+
|
|
70
|
+
// public accesss
|
|
71
|
+
if (!user) {
|
|
72
|
+
// test against public role
|
|
73
|
+
const publicPermissions = await strapi.query('plugin::users-permissions.permission').findMany({
|
|
74
|
+
where: {
|
|
75
|
+
role: { type: 'public' },
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const allowedActions = map('action', publicPermissions);
|
|
80
|
+
|
|
81
|
+
// A non authenticated user cannot access routes that do not have a scope
|
|
82
|
+
if (!config.scope) {
|
|
83
|
+
throw new UnauthorizedError();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const isAllowed = castArray(config.scope).every(scope => allowedActions.includes(scope));
|
|
87
|
+
|
|
88
|
+
if (!isAllowed) {
|
|
89
|
+
throw new ForbiddenError();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const permissions = await strapi.query('plugin::users-permissions.permission').findMany({
|
|
96
|
+
where: { role: user.role.id },
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const allowedActions = map('action', permissions);
|
|
100
|
+
|
|
101
|
+
// An authenticated user can access non scoped routes
|
|
102
|
+
if (!config.scope) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const isAllowed = castArray(config.scope).every(scope => allowedActions.includes(scope));
|
|
107
|
+
|
|
108
|
+
if (!isAllowed) {
|
|
109
|
+
throw new ForbiddenError();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// TODO: if we need to keep policies for u&p execution
|
|
113
|
+
// Execute the policies.
|
|
114
|
+
// if (permission.policy) {
|
|
115
|
+
// return await strapi.plugin('users-permissions').policy(permission.policy)(ctx, next);
|
|
116
|
+
// }
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
module.exports = {
|
|
120
|
+
name: 'users-permissions',
|
|
121
|
+
authenticate,
|
|
122
|
+
verify,
|
|
123
|
+
};
|
package/server/utils/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import * as usersPermissions from '../services/users-permissions';
|
|
2
2
|
import * as user from '../services/user';
|
|
3
|
+
import * as role from '../services/role';
|
|
3
4
|
import * as jwt from '../services/jwt';
|
|
4
5
|
import * as providers from '../services/providers';
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
type S = {
|
|
8
9
|
['users-permissions']: typeof usersPermissions;
|
|
10
|
+
['role']: typeof role;
|
|
9
11
|
user: typeof user;
|
|
10
12
|
jwt: typeof jwt;
|
|
11
13
|
providers: typeof providers;
|