@strapi/plugin-users-permissions 0.0.0-next.ce51df0e18404afc8a1aa7f504c1006a7a221459 → 0.0.0-next.ce84fada19d58a7dfbdd553035e6558f8befcba4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/.eslintignore +1 -2
  2. package/.eslintrc +17 -0
  3. package/LICENSE +18 -3
  4. package/admin/src/components/BoundRoute/{index.js → index.jsx} +2 -2
  5. package/admin/src/components/FormModal/Input/{index.js → index.jsx} +32 -31
  6. package/admin/src/components/FormModal/index.jsx +115 -0
  7. package/admin/src/components/Permissions/PermissionRow/{CheckboxWrapper.js → CheckboxWrapper.jsx} +4 -3
  8. package/admin/src/components/Permissions/PermissionRow/{SubCategory.js → SubCategory.jsx} +13 -22
  9. package/admin/src/components/Permissions/index.jsx +47 -0
  10. package/admin/src/components/Permissions/reducer.js +1 -1
  11. package/admin/src/components/Policies/{index.js → index.jsx} +7 -5
  12. package/admin/src/components/UsersPermissions/{index.js → index.jsx} +15 -7
  13. package/admin/src/components/UsersPermissions/reducer.js +1 -1
  14. package/admin/src/index.js +14 -23
  15. package/admin/src/pages/AdvancedSettings/index.jsx +214 -0
  16. package/admin/src/pages/AdvancedSettings/utils/layout.js +20 -35
  17. package/admin/src/pages/AdvancedSettings/utils/schema.js +5 -2
  18. package/admin/src/pages/EmailTemplates/components/EmailForm.jsx +156 -0
  19. package/admin/src/pages/EmailTemplates/components/{EmailTable.js → EmailTable.jsx} +20 -17
  20. package/admin/src/pages/EmailTemplates/{index.js → index.jsx} +36 -62
  21. package/admin/src/pages/EmailTemplates/utils/schema.js +18 -6
  22. package/admin/src/pages/Providers/{index.js → index.jsx} +98 -113
  23. package/admin/src/pages/Providers/utils/forms.js +11 -11
  24. package/admin/src/pages/Roles/constants.js +3 -3
  25. package/admin/src/pages/Roles/hooks/usePlugins.js +4 -4
  26. package/admin/src/pages/Roles/index.jsx +24 -0
  27. package/admin/src/pages/Roles/pages/{CreatePage.js → CreatePage.jsx} +64 -60
  28. package/admin/src/pages/Roles/pages/{EditPage.js → EditPage.jsx} +73 -69
  29. package/admin/src/pages/Roles/pages/ListPage/components/{TableBody.js → TableBody.jsx} +27 -31
  30. package/admin/src/pages/Roles/pages/ListPage/{index.js → index.jsx} +81 -55
  31. package/admin/src/translations/en.json +1 -1
  32. package/admin/src/utils/prefixPluginTranslations.js +13 -0
  33. package/dist/_chunks/ar-BguGUqwK.js +44 -0
  34. package/dist/_chunks/ar-BguGUqwK.js.map +1 -0
  35. package/dist/_chunks/ar-CK8BRRXB.mjs +44 -0
  36. package/dist/_chunks/ar-CK8BRRXB.mjs.map +1 -0
  37. package/dist/_chunks/cs-BVigMk0l.mjs +50 -0
  38. package/dist/_chunks/cs-BVigMk0l.mjs.map +1 -0
  39. package/dist/_chunks/cs-BW8-K_GY.js +50 -0
  40. package/dist/_chunks/cs-BW8-K_GY.js.map +1 -0
  41. package/dist/_chunks/de-BKUdRFI4.mjs +62 -0
  42. package/dist/_chunks/de-BKUdRFI4.mjs.map +1 -0
  43. package/dist/_chunks/de-owXpVluI.js +62 -0
  44. package/dist/_chunks/de-owXpVluI.js.map +1 -0
  45. package/dist/_chunks/dk-BQiTK50l.mjs +86 -0
  46. package/dist/_chunks/dk-BQiTK50l.mjs.map +1 -0
  47. package/dist/_chunks/dk-LXAnbuBk.js +86 -0
  48. package/dist/_chunks/dk-LXAnbuBk.js.map +1 -0
  49. package/dist/_chunks/en-DOHtPf-2.mjs +86 -0
  50. package/dist/_chunks/en-DOHtPf-2.mjs.map +1 -0
  51. package/dist/_chunks/en-MHo5mcsU.js +86 -0
  52. package/dist/_chunks/en-MHo5mcsU.js.map +1 -0
  53. package/dist/_chunks/es-BwLCLXAQ.js +86 -0
  54. package/dist/_chunks/es-BwLCLXAQ.js.map +1 -0
  55. package/dist/_chunks/es-DNgOVMjD.mjs +86 -0
  56. package/dist/_chunks/es-DNgOVMjD.mjs.map +1 -0
  57. package/dist/_chunks/fr-DkgRugiU.mjs +50 -0
  58. package/dist/_chunks/fr-DkgRugiU.mjs.map +1 -0
  59. package/dist/_chunks/fr-DkhpSjjm.js +50 -0
  60. package/dist/_chunks/fr-DkhpSjjm.js.map +1 -0
  61. package/dist/_chunks/id-BTemOeTZ.js +62 -0
  62. package/dist/_chunks/id-BTemOeTZ.js.map +1 -0
  63. package/dist/_chunks/id-BdEsvnaF.mjs +62 -0
  64. package/dist/_chunks/id-BdEsvnaF.mjs.map +1 -0
  65. package/dist/_chunks/index-BOrMKeRw.mjs +249 -0
  66. package/dist/_chunks/index-BOrMKeRw.mjs.map +1 -0
  67. package/dist/_chunks/index-Belq5KbY.js +1173 -0
  68. package/dist/_chunks/index-Belq5KbY.js.map +1 -0
  69. package/dist/_chunks/index-Bz6iwjmq.mjs +615 -0
  70. package/dist/_chunks/index-Bz6iwjmq.mjs.map +1 -0
  71. package/dist/_chunks/index-CD4fcjMf.js +638 -0
  72. package/dist/_chunks/index-CD4fcjMf.js.map +1 -0
  73. package/dist/_chunks/index-CNonxjKA.js +281 -0
  74. package/dist/_chunks/index-CNonxjKA.js.map +1 -0
  75. package/dist/_chunks/index-CuNna9c6.mjs +262 -0
  76. package/dist/_chunks/index-CuNna9c6.mjs.map +1 -0
  77. package/dist/_chunks/index-D5NoyXgv.js +366 -0
  78. package/dist/_chunks/index-D5NoyXgv.js.map +1 -0
  79. package/dist/_chunks/index-DGJ3FzF4.js +248 -0
  80. package/dist/_chunks/index-DGJ3FzF4.js.map +1 -0
  81. package/dist/_chunks/index-DThn8eCU.mjs +1143 -0
  82. package/dist/_chunks/index-DThn8eCU.mjs.map +1 -0
  83. package/dist/_chunks/index-Dk2iD2AC.mjs +344 -0
  84. package/dist/_chunks/index-Dk2iD2AC.mjs.map +1 -0
  85. package/dist/_chunks/index-TfyEeDrd-BfJxOAzF.mjs +11845 -0
  86. package/dist/_chunks/index-TfyEeDrd-BfJxOAzF.mjs.map +1 -0
  87. package/dist/_chunks/index-TfyEeDrd-QiBdpWEj.js +11869 -0
  88. package/dist/_chunks/index-TfyEeDrd-QiBdpWEj.js.map +1 -0
  89. package/dist/_chunks/it-B-rv0E24.mjs +62 -0
  90. package/dist/_chunks/it-B-rv0E24.mjs.map +1 -0
  91. package/dist/_chunks/it-D1rH6V6_.js +62 -0
  92. package/dist/_chunks/it-D1rH6V6_.js.map +1 -0
  93. package/dist/_chunks/ja-C8K-VBPD.mjs +48 -0
  94. package/dist/_chunks/ja-C8K-VBPD.mjs.map +1 -0
  95. package/dist/_chunks/ja-DqShgTMf.js +48 -0
  96. package/dist/_chunks/ja-DqShgTMf.js.map +1 -0
  97. package/dist/_chunks/ko-B9DGEPWH.js +86 -0
  98. package/dist/_chunks/ko-B9DGEPWH.js.map +1 -0
  99. package/dist/_chunks/ko-Busb0wIY.mjs +86 -0
  100. package/dist/_chunks/ko-Busb0wIY.mjs.map +1 -0
  101. package/dist/_chunks/ms-ByvsQjRt.mjs +49 -0
  102. package/dist/_chunks/ms-ByvsQjRt.mjs.map +1 -0
  103. package/dist/_chunks/ms-CPBU3LWf.js +49 -0
  104. package/dist/_chunks/ms-CPBU3LWf.js.map +1 -0
  105. package/dist/_chunks/nl-5qO8Rpcy.mjs +48 -0
  106. package/dist/_chunks/nl-5qO8Rpcy.mjs.map +1 -0
  107. package/dist/_chunks/nl-CwNB6YoO.js +48 -0
  108. package/dist/_chunks/nl-CwNB6YoO.js.map +1 -0
  109. package/dist/_chunks/pl-BdIzifBE.mjs +86 -0
  110. package/dist/_chunks/pl-BdIzifBE.mjs.map +1 -0
  111. package/dist/_chunks/pl-Do9UD69f.js +86 -0
  112. package/dist/_chunks/pl-Do9UD69f.js.map +1 -0
  113. package/dist/_chunks/pt-BIO24ioG.mjs +48 -0
  114. package/dist/_chunks/pt-BIO24ioG.mjs.map +1 -0
  115. package/dist/_chunks/pt-BR-D7dZhxuP.js +44 -0
  116. package/dist/_chunks/pt-BR-D7dZhxuP.js.map +1 -0
  117. package/dist/_chunks/pt-BR-f0p23AQZ.mjs +44 -0
  118. package/dist/_chunks/pt-BR-f0p23AQZ.mjs.map +1 -0
  119. package/dist/_chunks/pt-fdvyOnUp.js +48 -0
  120. package/dist/_chunks/pt-fdvyOnUp.js.map +1 -0
  121. package/dist/_chunks/ru-C94rjPGA.js +86 -0
  122. package/dist/_chunks/ru-C94rjPGA.js.map +1 -0
  123. package/dist/_chunks/ru-VWy-IB7K.mjs +86 -0
  124. package/dist/_chunks/ru-VWy-IB7K.mjs.map +1 -0
  125. package/dist/_chunks/sk-BABEhykl.js +50 -0
  126. package/dist/_chunks/sk-BABEhykl.js.map +1 -0
  127. package/dist/_chunks/sk-B_LIcepm.mjs +50 -0
  128. package/dist/_chunks/sk-B_LIcepm.mjs.map +1 -0
  129. package/dist/_chunks/sv-ABLKOokl.mjs +86 -0
  130. package/dist/_chunks/sv-ABLKOokl.mjs.map +1 -0
  131. package/dist/_chunks/sv-Be43LhA9.js +86 -0
  132. package/dist/_chunks/sv-Be43LhA9.js.map +1 -0
  133. package/dist/_chunks/th-DKyP7ueR.mjs +60 -0
  134. package/dist/_chunks/th-DKyP7ueR.mjs.map +1 -0
  135. package/dist/_chunks/th-DgVhVLhL.js +60 -0
  136. package/dist/_chunks/th-DgVhVLhL.js.map +1 -0
  137. package/dist/_chunks/tr-B_idhkEs.js +85 -0
  138. package/dist/_chunks/tr-B_idhkEs.js.map +1 -0
  139. package/dist/_chunks/tr-qa1Q5UjC.mjs +85 -0
  140. package/dist/_chunks/tr-qa1Q5UjC.mjs.map +1 -0
  141. package/dist/_chunks/uk-BmRqbeQc.mjs +49 -0
  142. package/dist/_chunks/uk-BmRqbeQc.mjs.map +1 -0
  143. package/dist/_chunks/uk-LHOivnhP.js +49 -0
  144. package/dist/_chunks/uk-LHOivnhP.js.map +1 -0
  145. package/dist/_chunks/vi-CdVRdKDw.js +50 -0
  146. package/dist/_chunks/vi-CdVRdKDw.js.map +1 -0
  147. package/dist/_chunks/vi-HW-EdMea.mjs +50 -0
  148. package/dist/_chunks/vi-HW-EdMea.mjs.map +1 -0
  149. package/dist/_chunks/zh-5hKkVPA4.mjs +86 -0
  150. package/dist/_chunks/zh-5hKkVPA4.mjs.map +1 -0
  151. package/dist/_chunks/zh-Cuq8gMnF.js +86 -0
  152. package/dist/_chunks/zh-Cuq8gMnF.js.map +1 -0
  153. package/dist/_chunks/zh-Hans-BHilK-yc.mjs +86 -0
  154. package/dist/_chunks/zh-Hans-BHilK-yc.mjs.map +1 -0
  155. package/dist/_chunks/zh-Hans-GQDMKtY4.js +86 -0
  156. package/dist/_chunks/zh-Hans-GQDMKtY4.js.map +1 -0
  157. package/dist/admin/index.js +4 -0
  158. package/dist/admin/index.js.map +1 -0
  159. package/dist/admin/index.mjs +5 -0
  160. package/dist/admin/index.mjs.map +1 -0
  161. package/package.json +46 -27
  162. package/packup.config.ts +22 -0
  163. package/server/bootstrap/index.js +18 -50
  164. package/server/bootstrap/users-permissions-actions.js +6 -0
  165. package/server/config.js +29 -0
  166. package/server/content-types/user/index.js +0 -1
  167. package/server/controllers/auth.js +53 -60
  168. package/server/controllers/content-manager-user.js +28 -30
  169. package/server/controllers/role.js +1 -1
  170. package/server/controllers/user.js +8 -9
  171. package/server/middlewares/rateLimit.js +1 -1
  172. package/server/register.js +1 -1
  173. package/server/services/jwt.js +3 -3
  174. package/server/services/permission.js +3 -7
  175. package/server/services/providers-registry.js +469 -261
  176. package/server/services/providers.js +10 -5
  177. package/server/services/role.js +15 -13
  178. package/server/services/user.js +56 -19
  179. package/server/services/users-permissions.js +15 -13
  180. package/server/utils/index.d.ts +2 -1
  181. package/server/utils/sanitize/sanitizers.js +7 -3
  182. package/server/utils/sanitize/visitors/remove-user-relation-from-role-entities.js +2 -2
  183. package/.eslintrc.js +0 -14
  184. package/admin/src/components/FormModal/index.js +0 -126
  185. package/admin/src/components/Permissions/index.js +0 -55
  186. package/admin/src/pages/AdvancedSettings/index.js +0 -259
  187. package/admin/src/pages/EmailTemplates/components/EmailForm.js +0 -176
  188. package/admin/src/pages/Roles/index.js +0 -33
  189. package/admin/src/pages/Roles/pages/ListPage/utils/api.js +0 -30
  190. package/server/bootstrap/grant-config.js +0 -131
  191. package/strapi-admin.js +0 -3
  192. package/strapi-server.js +0 -3
  193. /package/admin/src/components/Permissions/PermissionRow/{index.js → index.jsx} +0 -0
  194. /package/admin/src/contexts/UsersPermissionsContext/{index.js → index.jsx} +0 -0
@@ -11,9 +11,6 @@ const crypto = require('crypto');
11
11
  const _ = require('lodash');
12
12
  const { concat, compact, isArray } = require('lodash/fp');
13
13
  const utils = require('@strapi/utils');
14
- const {
15
- contentTypes: { getNonWritableAttributes },
16
- } = require('@strapi/utils');
17
14
  const { getService } = require('../utils');
18
15
  const {
19
16
  validateCallbackBody,
@@ -25,14 +22,13 @@ const {
25
22
  validateChangePasswordBody,
26
23
  } = require('./validation/auth');
27
24
 
28
- const { getAbsoluteAdminUrl, getAbsoluteServerUrl, sanitize } = utils;
29
- const { ApplicationError, ValidationError } = utils.errors;
25
+ const { ApplicationError, ValidationError, ForbiddenError } = utils.errors;
30
26
 
31
27
  const sanitizeUser = (user, ctx) => {
32
28
  const { auth } = ctx.state;
33
29
  const userSchema = strapi.getModel('plugin::users-permissions.user');
34
30
 
35
- return sanitize.contentAPI.output(user, userSchema, { auth });
31
+ return strapi.contentAPI.sanitize.output(user, userSchema, { auth });
36
32
  };
37
33
 
38
34
  module.exports = {
@@ -55,7 +51,7 @@ module.exports = {
55
51
  const { identifier } = params;
56
52
 
57
53
  // Check if the user exists.
58
- const user = await strapi.query('plugin::users-permissions.user').findOne({
54
+ const user = await strapi.db.query('plugin::users-permissions.user').findOne({
59
55
  where: {
60
56
  provider,
61
57
  $or: [{ email: identifier.toLowerCase() }, { username: identifier }],
@@ -100,6 +96,10 @@ module.exports = {
100
96
  try {
101
97
  const user = await getService('providers').connect(provider, ctx.query);
102
98
 
99
+ if (user.blocked) {
100
+ throw new ForbiddenError('Your account has been blocked by an administrator');
101
+ }
102
+
103
103
  return ctx.send({
104
104
  jwt: getService('jwt').issue({ id: user.id }),
105
105
  user: await sanitizeUser(user, ctx),
@@ -116,10 +116,9 @@ module.exports = {
116
116
 
117
117
  const { currentPassword, password } = await validateChangePasswordBody(ctx.request.body);
118
118
 
119
- const user = await strapi.entityService.findOne(
120
- 'plugin::users-permissions.user',
121
- ctx.state.user.id
122
- );
119
+ const user = await strapi.db
120
+ .query('plugin::users-permissions.user')
121
+ .findOne({ where: { id: ctx.state.user.id } });
123
122
 
124
123
  const validPassword = await getService('user').validatePassword(currentPassword, user.password);
125
124
 
@@ -148,7 +147,7 @@ module.exports = {
148
147
  throw new ValidationError('Passwords do not match');
149
148
  }
150
149
 
151
- const user = await strapi
150
+ const user = await strapi.db
152
151
  .query('plugin::users-permissions.user')
153
152
  .findOne({ where: { resetPasswordToken: code } });
154
153
 
@@ -197,10 +196,28 @@ module.exports = {
197
196
  }
198
197
 
199
198
  // Ability to pass OAuth callback dynamically
200
- grantConfig[provider].callback =
201
- _.get(ctx, 'query.callback') ||
202
- _.get(ctx, 'session.grant.dynamic.callback') ||
203
- grantConfig[provider].callback;
199
+ const queryCustomCallback = _.get(ctx, 'query.callback');
200
+ const dynamicSessionCallback = _.get(ctx, 'session.grant.dynamic.callback');
201
+
202
+ const customCallback = queryCustomCallback ?? dynamicSessionCallback;
203
+
204
+ // The custom callback is validated to make sure it's not redirecting to an unwanted actor.
205
+ if (customCallback !== undefined) {
206
+ try {
207
+ // We're extracting the callback validator from the plugin config since it can be user-customized
208
+ const { validate: validateCallback } = strapi
209
+ .plugin('users-permissions')
210
+ .config('callback');
211
+
212
+ await validateCallback(customCallback, grantConfig[provider]);
213
+
214
+ grantConfig[provider].callback = customCallback;
215
+ } catch (e) {
216
+ throw new ValidationError('Invalid callback URL provided', { callback: customCallback });
217
+ }
218
+ }
219
+
220
+ // Build a valid redirect URI for the current provider
204
221
  grantConfig[provider].redirect_uri = getService('providers').buildRedirectUri(provider);
205
222
 
206
223
  return grant(grantConfig)(ctx, next);
@@ -215,7 +232,7 @@ module.exports = {
215
232
  const advancedSettings = await pluginStore.get({ key: 'advanced' });
216
233
 
217
234
  // Find the user by email.
218
- const user = await strapi
235
+ const user = await strapi.db
219
236
  .query('plugin::users-permissions.user')
220
237
  .findOne({ where: { email: email.toLowerCase() } });
221
238
 
@@ -233,8 +250,8 @@ module.exports = {
233
250
  resetPasswordSettings.message,
234
251
  {
235
252
  URL: advancedSettings.email_reset_password,
236
- SERVER_URL: getAbsoluteServerUrl(strapi.config),
237
- ADMIN_URL: getAbsoluteAdminUrl(strapi.config),
253
+ SERVER_URL: strapi.config.get('server.absoluteUrl'),
254
+ ADMIN_URL: strapi.config.get('admin.absoluteUrl'),
238
255
  USER: userInfo,
239
256
  TOKEN: resetPasswordToken,
240
257
  }
@@ -277,47 +294,22 @@ module.exports = {
277
294
  throw new ApplicationError('Register action is currently disabled');
278
295
  }
279
296
 
280
- const { register } = strapi.config.get('plugin.users-permissions');
297
+ const { register } = strapi.config.get('plugin::users-permissions');
281
298
  const alwaysAllowedKeys = ['username', 'password', 'email'];
282
- const userModel = strapi.contentTypes['plugin::users-permissions.user'];
283
- const { attributes } = userModel;
284
-
285
- const nonWritable = getNonWritableAttributes(userModel);
286
299
 
300
+ // Note that we intentionally do not filter allowedFields to allow a project to explicitly accept private or other Strapi field on registration
287
301
  const allowedKeys = compact(
288
- concat(
289
- alwaysAllowedKeys,
290
- isArray(register?.allowedFields)
291
- ? // Note that we do not filter allowedFields in case a user explicitly chooses to allow a private or otherwise omitted field on registration
292
- register.allowedFields // if null or undefined, compact will remove it
293
- : // to prevent breaking changes, if allowedFields is not set in config, we only remove private and known dangerous user schema fields
294
- // TODO V5: allowedFields defaults to [] when undefined and remove this case
295
- Object.keys(attributes).filter(
296
- (key) =>
297
- !nonWritable.includes(key) &&
298
- !attributes[key].private &&
299
- ![
300
- // many of these are included in nonWritable, but we'll list them again to be safe and since we're removing this code in v5 anyway
301
- // Strapi user schema fields
302
- 'confirmed',
303
- 'blocked',
304
- 'confirmationToken',
305
- 'resetPasswordToken',
306
- 'provider',
307
- 'id',
308
- 'role',
309
- // other Strapi fields that might be added
310
- 'createdAt',
311
- 'updatedAt',
312
- 'createdBy',
313
- 'updatedBy',
314
- 'publishedAt', // d&p
315
- 'strapi_reviewWorkflows_stage', // review workflows
316
- ].includes(key)
317
- )
318
- )
302
+ concat(alwaysAllowedKeys, isArray(register?.allowedFields) ? register.allowedFields : [])
319
303
  );
320
304
 
305
+ // Check if there are any keys in requestBody that are not in allowedKeys
306
+ const invalidKeys = Object.keys(ctx.request.body).filter((key) => !allowedKeys.includes(key));
307
+
308
+ if (invalidKeys.length > 0) {
309
+ // If there are invalid keys, throw an error
310
+ throw new ValidationError(`Invalid parameters: ${invalidKeys.join(', ')}`);
311
+ }
312
+
321
313
  const params = {
322
314
  ..._.pick(ctx.request.body, allowedKeys),
323
315
  provider: 'local',
@@ -325,7 +317,7 @@ module.exports = {
325
317
 
326
318
  await validateRegisterBody(params);
327
319
 
328
- const role = await strapi
320
+ const role = await strapi.db
329
321
  .query('plugin::users-permissions.role')
330
322
  .findOne({ where: { type: settings.default_role } });
331
323
 
@@ -344,7 +336,7 @@ module.exports = {
344
336
  ],
345
337
  };
346
338
 
347
- const conflictingUserCount = await strapi.query('plugin::users-permissions.user').count({
339
+ const conflictingUserCount = await strapi.db.query('plugin::users-permissions.user').count({
348
340
  where: { ...identifierFilter, provider },
349
341
  });
350
342
 
@@ -353,7 +345,7 @@ module.exports = {
353
345
  }
354
346
 
355
347
  if (settings.unique_email) {
356
- const conflictingUserCount = await strapi.query('plugin::users-permissions.user').count({
348
+ const conflictingUserCount = await strapi.db.query('plugin::users-permissions.user').count({
357
349
  where: { ...identifierFilter },
358
350
  });
359
351
 
@@ -378,7 +370,8 @@ module.exports = {
378
370
  try {
379
371
  await getService('user').sendConfirmationEmail(sanitizedUser);
380
372
  } catch (err) {
381
- throw new ApplicationError(err.message);
373
+ strapi.log.error(err);
374
+ throw new ApplicationError('Error sending confirmation email');
382
375
  }
383
376
 
384
377
  return ctx.send({ user: sanitizedUser });
@@ -423,7 +416,7 @@ module.exports = {
423
416
  async sendEmailConfirmation(ctx) {
424
417
  const { email } = await validateSendEmailConfirmationBody(ctx.request.body);
425
418
 
426
- const user = await strapi.query('plugin::users-permissions.user').findOne({
419
+ const user = await strapi.db.query('plugin::users-permissions.user').findOne({
427
420
  where: { email: email.toLowerCase() },
428
421
  });
429
422
 
@@ -17,24 +17,25 @@ const ACTIONS = {
17
17
  };
18
18
 
19
19
  const findEntityAndCheckPermissions = async (ability, action, model, id) => {
20
- const entity = await strapi.query(userModel).findOne({
21
- where: { id },
20
+ const doc = await strapi.service('plugin::content-manager.document-manager').findOne(id, model, {
22
21
  populate: [`${CREATED_BY_ATTRIBUTE}.roles`],
23
22
  });
24
23
 
25
- if (_.isNil(entity)) {
24
+ if (_.isNil(doc)) {
26
25
  throw new NotFoundError();
27
26
  }
28
27
 
29
- const pm = strapi.admin.services.permission.createPermissionsManager({ ability, action, model });
28
+ const pm = strapi
29
+ .service('admin::permission')
30
+ .createPermissionsManager({ ability, action, model });
30
31
 
31
- if (pm.ability.cannot(pm.action, pm.toSubject(entity))) {
32
+ if (pm.ability.cannot(pm.action, pm.toSubject(doc))) {
32
33
  throw new ForbiddenError();
33
34
  }
34
35
 
35
- const entityWithoutCreatorRoles = _.omit(entity, `${CREATED_BY_ATTRIBUTE}.roles`);
36
+ const docWithoutCreatorRoles = _.omit(doc, `${CREATED_BY_ATTRIBUTE}.roles`);
36
37
 
37
- return { pm, entity: entityWithoutCreatorRoles };
38
+ return { pm, doc: docWithoutCreatorRoles };
38
39
  };
39
40
 
40
41
  module.exports = {
@@ -48,7 +49,7 @@ module.exports = {
48
49
 
49
50
  const { email, username } = body;
50
51
 
51
- const pm = strapi.admin.services.permission.createPermissionsManager({
52
+ const pm = strapi.service('admin::permission').createPermissionsManager({
52
53
  ability: userAbility,
53
54
  action: ACTIONS.create,
54
55
  model: userModel,
@@ -66,7 +67,7 @@ module.exports = {
66
67
 
67
68
  await validateCreateUserBody(ctx.request.body);
68
69
 
69
- const userWithSameUsername = await strapi
70
+ const userWithSameUsername = await strapi.db
70
71
  .query('plugin::users-permissions.user')
71
72
  .findOne({ where: { username } });
72
73
 
@@ -75,7 +76,7 @@ module.exports = {
75
76
  }
76
77
 
77
78
  if (advanced.unique_email) {
78
- const userWithSameEmail = await strapi
79
+ const userWithSameEmail = await strapi.db
79
80
  .query('plugin::users-permissions.user')
80
81
  .findOne({ where: { email: email.toLowerCase() } });
81
82
 
@@ -93,18 +94,11 @@ module.exports = {
93
94
 
94
95
  user.email = _.toLower(user.email);
95
96
 
96
- if (!user.role) {
97
- const defaultRole = await strapi
98
- .query('plugin::users-permissions.role')
99
- .findOne({ where: { type: advanced.default_role } });
100
-
101
- user.role = defaultRole.id;
102
- }
103
-
104
97
  try {
105
98
  const data = await strapi
106
- .service('plugin::content-manager.entity-manager')
107
- .create(user, userModel);
99
+ .service('plugin::content-manager.document-manager')
100
+ .create(userModel, { data: user });
101
+
108
102
  const sanitizedData = await pm.sanitizeOutput(data, { action: ACTIONS.read });
109
103
 
110
104
  ctx.created(sanitizedData);
@@ -118,7 +112,7 @@ module.exports = {
118
112
  */
119
113
 
120
114
  async update(ctx) {
121
- const { id } = ctx.params;
115
+ const { id: documentId } = ctx.params;
122
116
  const { body } = ctx.request;
123
117
  const { user: admin, userAbility } = ctx.state;
124
118
 
@@ -128,13 +122,14 @@ module.exports = {
128
122
 
129
123
  const { email, username, password } = body;
130
124
 
131
- const { pm, entity } = await findEntityAndCheckPermissions(
125
+ const { pm, doc } = await findEntityAndCheckPermissions(
132
126
  userAbility,
133
127
  ACTIONS.edit,
134
128
  userModel,
135
- id
129
+ documentId
136
130
  );
137
- const user = entity;
131
+
132
+ const user = doc;
138
133
 
139
134
  await validateUpdateUserBody(ctx.request.body);
140
135
 
@@ -143,23 +138,24 @@ module.exports = {
143
138
  }
144
139
 
145
140
  if (_.has(body, 'username')) {
146
- const userWithSameUsername = await strapi
141
+ const userWithSameUsername = await strapi.db
147
142
  .query('plugin::users-permissions.user')
148
143
  .findOne({ where: { username } });
149
144
 
150
- if (userWithSameUsername && _.toString(userWithSameUsername.id) !== _.toString(id)) {
145
+ if (userWithSameUsername && _.toString(userWithSameUsername.id) !== _.toString(user.id)) {
151
146
  throw new ApplicationError('Username already taken');
152
147
  }
153
148
  }
154
149
 
155
150
  if (_.has(body, 'email') && advancedConfigs.unique_email) {
156
- const userWithSameEmail = await strapi
151
+ const userWithSameEmail = await strapi.db
157
152
  .query('plugin::users-permissions.user')
158
153
  .findOne({ where: { email: _.toLower(email) } });
159
154
 
160
- if (userWithSameEmail && _.toString(userWithSameEmail.id) !== _.toString(id)) {
155
+ if (userWithSameEmail && _.toString(userWithSameEmail.id) !== _.toString(user.id)) {
161
156
  throw new ApplicationError('Email already taken');
162
157
  }
158
+
163
159
  body.email = _.toLower(body.email);
164
160
  }
165
161
 
@@ -167,8 +163,10 @@ module.exports = {
167
163
  const updateData = _.omit({ ...sanitizedData, updatedBy: admin.id }, 'createdBy');
168
164
 
169
165
  const data = await strapi
170
- .service('plugin::content-manager.entity-manager')
171
- .update({ id }, updateData, userModel);
166
+ .service('plugin::content-manager.document-manager')
167
+ .update(documentId, userModel, {
168
+ data: updateData,
169
+ });
172
170
 
173
171
  ctx.body = await pm.sanitizeOutput(data, { action: ACTIONS.read });
174
172
  },
@@ -59,7 +59,7 @@ module.exports = {
59
59
  }
60
60
 
61
61
  // Fetch public role.
62
- const publicRole = await strapi
62
+ const publicRole = await strapi.db
63
63
  .query('plugin::users-permissions.role')
64
64
  .findOne({ where: { type: 'public' } });
65
65
 
@@ -11,28 +11,27 @@ const utils = require('@strapi/utils');
11
11
  const { getService } = require('../utils');
12
12
  const { validateCreateUserBody, validateUpdateUserBody } = require('./validation/user');
13
13
 
14
- const { sanitize, validate } = utils;
15
14
  const { ApplicationError, ValidationError, NotFoundError } = utils.errors;
16
15
 
17
16
  const sanitizeOutput = async (user, ctx) => {
18
17
  const schema = strapi.getModel('plugin::users-permissions.user');
19
18
  const { auth } = ctx.state;
20
19
 
21
- return sanitize.contentAPI.output(user, schema, { auth });
20
+ return strapi.contentAPI.sanitize.output(user, schema, { auth });
22
21
  };
23
22
 
24
23
  const validateQuery = async (query, ctx) => {
25
24
  const schema = strapi.getModel('plugin::users-permissions.user');
26
25
  const { auth } = ctx.state;
27
26
 
28
- return validate.contentAPI.query(query, schema, { auth });
27
+ return strapi.contentAPI.validate.query(query, schema, { auth });
29
28
  };
30
29
 
31
30
  const sanitizeQuery = async (query, ctx) => {
32
31
  const schema = strapi.getModel('plugin::users-permissions.user');
33
32
  const { auth } = ctx.state;
34
33
 
35
- return sanitize.contentAPI.query(query, schema, { auth });
34
+ return strapi.contentAPI.sanitize.query(query, schema, { auth });
36
35
  };
37
36
 
38
37
  module.exports = {
@@ -49,7 +48,7 @@ module.exports = {
49
48
 
50
49
  const { email, username, role } = ctx.request.body;
51
50
 
52
- const userWithSameUsername = await strapi
51
+ const userWithSameUsername = await strapi.db
53
52
  .query('plugin::users-permissions.user')
54
53
  .findOne({ where: { username } });
55
54
 
@@ -58,7 +57,7 @@ module.exports = {
58
57
  }
59
58
 
60
59
  if (advanced.unique_email) {
61
- const userWithSameEmail = await strapi
60
+ const userWithSameEmail = await strapi.db
62
61
  .query('plugin::users-permissions.user')
63
62
  .findOne({ where: { email: email.toLowerCase() } });
64
63
 
@@ -74,7 +73,7 @@ module.exports = {
74
73
  };
75
74
 
76
75
  if (!role) {
77
- const defaultRole = await strapi
76
+ const defaultRole = await strapi.db
78
77
  .query('plugin::users-permissions.role')
79
78
  .findOne({ where: { type: advanced.default_role } });
80
79
 
@@ -115,7 +114,7 @@ module.exports = {
115
114
  }
116
115
 
117
116
  if (_.has(ctx.request.body, 'username')) {
118
- const userWithSameUsername = await strapi
117
+ const userWithSameUsername = await strapi.db
119
118
  .query('plugin::users-permissions.user')
120
119
  .findOne({ where: { username } });
121
120
 
@@ -125,7 +124,7 @@ module.exports = {
125
124
  }
126
125
 
127
126
  if (_.has(ctx.request.body, 'email') && advancedConfigs.unique_email) {
128
- const userWithSameEmail = await strapi
127
+ const userWithSameEmail = await strapi.db
129
128
  .query('plugin::users-permissions.user')
130
129
  .findOne({ where: { email: email.toLowerCase() } });
131
130
 
@@ -9,7 +9,7 @@ const { RateLimitError } = utils.errors;
9
9
  module.exports =
10
10
  (config, { strapi }) =>
11
11
  async (ctx, next) => {
12
- let rateLimitConfig = strapi.config.get('plugin.users-permissions.ratelimit');
12
+ let rateLimitConfig = strapi.config.get('plugin::users-permissions.ratelimit');
13
13
 
14
14
  if (!rateLimitConfig) {
15
15
  rateLimitConfig = {
@@ -7,7 +7,7 @@ const authStrategy = require('./strategies/users-permissions');
7
7
  const sanitizers = require('./utils/sanitize/sanitizers');
8
8
 
9
9
  module.exports = ({ strapi }) => {
10
- strapi.container.get('auth').register('content-api', authStrategy);
10
+ strapi.get('auth').register('content-api', authStrategy);
11
11
  strapi.sanitizers.add('content-api.output', sanitizers.defaultSanitizeOutput);
12
12
 
13
13
  if (strapi.plugin('graphql')) {
@@ -29,10 +29,10 @@ module.exports = ({ strapi }) => ({
29
29
  },
30
30
 
31
31
  issue(payload, jwtOptions = {}) {
32
- _.defaults(jwtOptions, strapi.config.get('plugin.users-permissions.jwt'));
32
+ _.defaults(jwtOptions, strapi.config.get('plugin::users-permissions.jwt'));
33
33
  return jwt.sign(
34
34
  _.clone(payload.toJSON ? payload.toJSON() : payload),
35
- strapi.config.get('plugin.users-permissions.jwtSecret'),
35
+ strapi.config.get('plugin::users-permissions.jwtSecret'),
36
36
  jwtOptions
37
37
  );
38
38
  },
@@ -41,7 +41,7 @@ module.exports = ({ strapi }) => ({
41
41
  return new Promise((resolve, reject) => {
42
42
  jwt.verify(
43
43
  token,
44
- strapi.config.get('plugin.users-permissions.jwtSecret'),
44
+ strapi.config.get('plugin::users-permissions.jwtSecret'),
45
45
  {},
46
46
  (err, tokenPayload = {}) => {
47
47
  if (err) {
@@ -11,11 +11,7 @@ module.exports = ({ strapi }) => ({
11
11
  * @return {object[]}
12
12
  */
13
13
  async findRolePermissions(roleID) {
14
- return strapi.entityService.load(
15
- 'plugin::users-permissions.role',
16
- { id: roleID },
17
- 'permissions'
18
- );
14
+ return strapi.db.query('plugin::users-permissions.role').load({ id: roleID }, 'permissions');
19
15
  },
20
16
 
21
17
  /**
@@ -24,8 +20,8 @@ module.exports = ({ strapi }) => ({
24
20
  * @return {object[]}
25
21
  */
26
22
  async findPublicPermissions() {
27
- return strapi.entityService.findMany('plugin::users-permissions.permission', {
28
- filters: PUBLIC_ROLE_FILTER,
23
+ return strapi.db.query('plugin::users-permissions.permission').findMany({
24
+ where: PUBLIC_ROLE_FILTER,
29
25
  });
30
26
  },
31
27