@strapi/plugin-users-permissions 0.0.0-next.e21fe90bf2ab9906267ea6e6ca620bdcc729906c → 0.0.0-next.e326c69a49373b420f6566c30aca26f4b6274c6a

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 (101) hide show
  1. package/admin/src/pages/Providers/index.jsx +74 -76
  2. package/admin/src/pages/Roles/pages/CreatePage.jsx +3 -12
  3. package/admin/src/pages/Roles/pages/EditPage.jsx +3 -12
  4. package/admin/src/pages/Roles/pages/ListPage/index.jsx +91 -93
  5. package/admin/src/utils/formatPluginName.js +1 -1
  6. package/dist/admin/pages/Providers/index.js +84 -88
  7. package/dist/admin/pages/Providers/index.js.map +1 -1
  8. package/dist/admin/pages/Providers/index.mjs +84 -88
  9. package/dist/admin/pages/Providers/index.mjs.map +1 -1
  10. package/dist/admin/pages/Roles/pages/CreatePage.js +1 -1
  11. package/dist/admin/pages/Roles/pages/CreatePage.js.map +1 -1
  12. package/dist/admin/pages/Roles/pages/CreatePage.mjs +2 -2
  13. package/dist/admin/pages/Roles/pages/CreatePage.mjs.map +1 -1
  14. package/dist/admin/pages/Roles/pages/EditPage.js +1 -1
  15. package/dist/admin/pages/Roles/pages/EditPage.js.map +1 -1
  16. package/dist/admin/pages/Roles/pages/EditPage.mjs +2 -2
  17. package/dist/admin/pages/Roles/pages/EditPage.mjs.map +1 -1
  18. package/dist/admin/pages/Roles/pages/ListPage/index.js +95 -99
  19. package/dist/admin/pages/Roles/pages/ListPage/index.js.map +1 -1
  20. package/dist/admin/pages/Roles/pages/ListPage/index.mjs +95 -99
  21. package/dist/admin/pages/Roles/pages/ListPage/index.mjs.map +1 -1
  22. package/dist/admin/utils/formatPluginName.js +1 -1
  23. package/dist/admin/utils/formatPluginName.js.map +1 -1
  24. package/dist/admin/utils/formatPluginName.mjs +1 -1
  25. package/dist/admin/utils/formatPluginName.mjs.map +1 -1
  26. package/dist/server/bootstrap/index.js +28 -7
  27. package/dist/server/bootstrap/index.js.map +1 -1
  28. package/dist/server/bootstrap/index.mjs +28 -7
  29. package/dist/server/bootstrap/index.mjs.map +1 -1
  30. package/dist/server/config.js +16 -0
  31. package/dist/server/config.js.map +1 -1
  32. package/dist/server/config.mjs +16 -0
  33. package/dist/server/config.mjs.map +1 -1
  34. package/dist/server/controllers/auth.js +198 -3
  35. package/dist/server/controllers/auth.js.map +1 -1
  36. package/dist/server/controllers/auth.mjs +198 -3
  37. package/dist/server/controllers/auth.mjs.map +1 -1
  38. package/dist/server/controllers/content-manager-user.js +3 -3
  39. package/dist/server/controllers/content-manager-user.js.map +1 -1
  40. package/dist/server/controllers/content-manager-user.mjs +3 -3
  41. package/dist/server/controllers/content-manager-user.mjs.map +1 -1
  42. package/dist/server/controllers/validation/user.js +6 -1
  43. package/dist/server/controllers/validation/user.js.map +1 -1
  44. package/dist/server/controllers/validation/user.mjs +6 -1
  45. package/dist/server/controllers/validation/user.mjs.map +1 -1
  46. package/dist/server/routes/content-api/auth.js +155 -91
  47. package/dist/server/routes/content-api/auth.js.map +1 -1
  48. package/dist/server/routes/content-api/auth.mjs +155 -91
  49. package/dist/server/routes/content-api/auth.mjs.map +1 -1
  50. package/dist/server/routes/content-api/index.js +11 -9
  51. package/dist/server/routes/content-api/index.js.map +1 -1
  52. package/dist/server/routes/content-api/index.mjs +11 -9
  53. package/dist/server/routes/content-api/index.mjs.map +1 -1
  54. package/dist/server/routes/content-api/permissions.js +14 -7
  55. package/dist/server/routes/content-api/permissions.js.map +1 -1
  56. package/dist/server/routes/content-api/permissions.mjs +14 -7
  57. package/dist/server/routes/content-api/permissions.mjs.map +1 -1
  58. package/dist/server/routes/content-api/role.js +61 -27
  59. package/dist/server/routes/content-api/role.js.map +1 -1
  60. package/dist/server/routes/content-api/role.mjs +61 -27
  61. package/dist/server/routes/content-api/role.mjs.map +1 -1
  62. package/dist/server/routes/content-api/user.js +119 -57
  63. package/dist/server/routes/content-api/user.js.map +1 -1
  64. package/dist/server/routes/content-api/user.mjs +119 -57
  65. package/dist/server/routes/content-api/user.mjs.map +1 -1
  66. package/dist/server/routes/content-api/validation.js +217 -0
  67. package/dist/server/routes/content-api/validation.js.map +1 -0
  68. package/dist/server/routes/content-api/validation.mjs +215 -0
  69. package/dist/server/routes/content-api/validation.mjs.map +1 -0
  70. package/dist/server/services/constants.js +19 -0
  71. package/dist/server/services/constants.js.map +1 -0
  72. package/dist/server/services/constants.mjs +17 -0
  73. package/dist/server/services/constants.mjs.map +1 -0
  74. package/dist/server/services/jwt.js +45 -2
  75. package/dist/server/services/jwt.js.map +1 -1
  76. package/dist/server/services/jwt.mjs +45 -2
  77. package/dist/server/services/jwt.mjs.map +1 -1
  78. package/dist/server/services/user.js +29 -20
  79. package/dist/server/services/user.js.map +1 -1
  80. package/dist/server/services/user.mjs +29 -20
  81. package/dist/server/services/user.mjs.map +1 -1
  82. package/dist/server/services/users-permissions.js +4 -3
  83. package/dist/server/services/users-permissions.js.map +1 -1
  84. package/dist/server/services/users-permissions.mjs +4 -3
  85. package/dist/server/services/users-permissions.mjs.map +1 -1
  86. package/package.json +8 -7
  87. package/server/bootstrap/index.js +31 -0
  88. package/server/config.js +22 -0
  89. package/server/controllers/auth.js +232 -8
  90. package/server/controllers/content-manager-user.js +3 -4
  91. package/server/controllers/validation/user.js +12 -1
  92. package/server/routes/content-api/auth.js +119 -71
  93. package/server/routes/content-api/index.js +11 -4
  94. package/server/routes/content-api/permissions.js +14 -7
  95. package/server/routes/content-api/role.js +57 -27
  96. package/server/routes/content-api/user.js +108 -51
  97. package/server/routes/content-api/validation.js +250 -0
  98. package/server/services/constants.js +9 -0
  99. package/server/services/jwt.js +50 -2
  100. package/server/services/user.js +11 -0
  101. package/server/services/users-permissions.js +4 -2
package/server/config.js CHANGED
@@ -1,11 +1,33 @@
1
1
  'use strict';
2
2
 
3
+ const {
4
+ DEFAULT_ACCESS_TOKEN_LIFESPAN,
5
+ DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN,
6
+ DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN,
7
+ DEFAULT_MAX_SESSION_LIFESPAN,
8
+ DEFAULT_IDLE_SESSION_LIFESPAN,
9
+ } = require('./services/constants');
10
+
3
11
  module.exports = {
4
12
  default: ({ env }) => ({
5
13
  jwtSecret: env('JWT_SECRET'),
6
14
  jwt: {
7
15
  expiresIn: '30d',
8
16
  },
17
+ /**
18
+ * JWT management mode for the Content API authentication
19
+ * - "legacy-support": use plugin JWTs (backward compatible)
20
+ * - "refresh": use SessionManager (access/refresh tokens)
21
+ */
22
+ jwtManagement: 'legacy-support',
23
+ sessions: {
24
+ accessTokenLifespan: DEFAULT_ACCESS_TOKEN_LIFESPAN,
25
+ maxRefreshTokenLifespan: DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN,
26
+ idleRefreshTokenLifespan: DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN,
27
+ maxSessionLifespan: DEFAULT_MAX_SESSION_LIFESPAN,
28
+ idleSessionLifespan: DEFAULT_IDLE_SESSION_LIFESPAN,
29
+ httpOnly: false,
30
+ },
9
31
  ratelimit: {
10
32
  interval: 60000,
11
33
  max: 10,
@@ -31,6 +31,12 @@ const sanitizeUser = (user, ctx) => {
31
31
  return strapi.contentAPI.sanitize.output(user, userSchema, { auth });
32
32
  };
33
33
 
34
+ const extractDeviceId = (requestBody) => {
35
+ const { deviceId } = requestBody || {};
36
+
37
+ return typeof deviceId === 'string' && deviceId.length > 0 ? deviceId : undefined;
38
+ };
39
+
34
40
  module.exports = ({ strapi }) => ({
35
41
  async callback(ctx) {
36
42
  const provider = ctx.params.provider || 'local';
@@ -86,6 +92,45 @@ module.exports = ({ strapi }) => ({
86
92
  throw new ApplicationError('Your account has been blocked by an administrator');
87
93
  }
88
94
 
95
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
96
+ if (mode === 'refresh') {
97
+ const deviceId = extractDeviceId(ctx.request.body);
98
+
99
+ const refresh = await strapi
100
+ .sessionManager('users-permissions')
101
+ .generateRefreshToken(String(user.id), deviceId, { type: 'refresh' });
102
+
103
+ const access = await strapi
104
+ .sessionManager('users-permissions')
105
+ .generateAccessToken(refresh.token);
106
+ if ('error' in access) {
107
+ throw new ApplicationError('Invalid credentials');
108
+ }
109
+
110
+ const upSessions = strapi.config.get('plugin::users-permissions.sessions');
111
+ const requestHttpOnly = ctx.request.header['x-strapi-refresh-cookie'] === 'httpOnly';
112
+ if (upSessions?.httpOnly || requestHttpOnly) {
113
+ const cookieName = upSessions.cookie?.name || 'strapi_up_refresh';
114
+ const cookieOptions = {
115
+ httpOnly: true,
116
+ secure: Boolean(upSessions.cookie?.secure),
117
+ sameSite: upSessions.cookie?.sameSite ?? 'lax',
118
+ path: upSessions.cookie?.path ?? '/',
119
+ domain: upSessions.cookie?.domain,
120
+ overwrite: true,
121
+ };
122
+
123
+ ctx.cookies.set(cookieName, refresh.token, cookieOptions);
124
+ return ctx.send({ jwt: access.token, user: await sanitizeUser(user, ctx) });
125
+ }
126
+
127
+ return ctx.send({
128
+ jwt: access.token,
129
+ refreshToken: refresh.token,
130
+ user: await sanitizeUser(user, ctx),
131
+ });
132
+ }
133
+
89
134
  return ctx.send({
90
135
  jwt: getService('jwt').issue({ id: user.id }),
91
136
  user: await sanitizeUser(user, ctx),
@@ -100,6 +145,43 @@ module.exports = ({ strapi }) => ({
100
145
  throw new ForbiddenError('Your account has been blocked by an administrator');
101
146
  }
102
147
 
148
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
149
+ if (mode === 'refresh') {
150
+ const deviceId = extractDeviceId(ctx.request.body);
151
+
152
+ const refresh = await strapi
153
+ .sessionManager('users-permissions')
154
+ .generateRefreshToken(String(user.id), deviceId, { type: 'refresh' });
155
+
156
+ const access = await strapi
157
+ .sessionManager('users-permissions')
158
+ .generateAccessToken(refresh.token);
159
+ if ('error' in access) {
160
+ throw new ApplicationError('Invalid credentials');
161
+ }
162
+
163
+ const upSessions = strapi.config.get('plugin::users-permissions.sessions');
164
+ const requestHttpOnly = ctx.request.header['x-strapi-refresh-cookie'] === 'httpOnly';
165
+ if (upSessions?.httpOnly || requestHttpOnly) {
166
+ const cookieName = upSessions.cookie?.name || 'strapi_up_refresh';
167
+ const cookieOptions = {
168
+ httpOnly: true,
169
+ secure: Boolean(upSessions.cookie?.secure),
170
+ sameSite: upSessions.cookie?.sameSite ?? 'lax',
171
+ path: upSessions.cookie?.path ?? '/',
172
+ domain: upSessions.cookie?.domain,
173
+ overwrite: true,
174
+ };
175
+ ctx.cookies.set(cookieName, refresh.token, cookieOptions);
176
+ return ctx.send({ jwt: access.token, user: await sanitizeUser(user, ctx) });
177
+ }
178
+ return ctx.send({
179
+ jwt: access.token,
180
+ refreshToken: refresh.token,
181
+ user: await sanitizeUser(user, ctx),
182
+ });
183
+ }
184
+
103
185
  return ctx.send({
104
186
  jwt: getService('jwt').issue({ id: user.id }),
105
187
  user: await sanitizeUser(user, ctx),
@@ -137,7 +219,37 @@ module.exports = ({ strapi }) => ({
137
219
 
138
220
  await getService('user').edit(user.id, { password });
139
221
 
140
- ctx.send({
222
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
223
+ if (mode === 'refresh') {
224
+ const deviceId = extractDeviceId(ctx.request.body);
225
+
226
+ if (deviceId) {
227
+ // Invalidate sessions: specific device if deviceId provided
228
+ await strapi
229
+ .sessionManager('users-permissions')
230
+ .invalidateRefreshToken(String(user.id), deviceId);
231
+ }
232
+
233
+ const newDeviceId = deviceId || crypto.randomUUID();
234
+ const refresh = await strapi
235
+ .sessionManager('users-permissions')
236
+ .generateRefreshToken(String(user.id), newDeviceId, { type: 'refresh' });
237
+
238
+ const access = await strapi
239
+ .sessionManager('users-permissions')
240
+ .generateAccessToken(refresh.token);
241
+ if ('error' in access) {
242
+ throw new ApplicationError('Invalid credentials');
243
+ }
244
+
245
+ return ctx.send({
246
+ jwt: access.token,
247
+ refreshToken: refresh.token,
248
+ user: await sanitizeUser(user, ctx),
249
+ });
250
+ }
251
+
252
+ return ctx.send({
141
253
  jwt: getService('jwt').issue({ id: user.id }),
142
254
  user: await sanitizeUser(user, ctx),
143
255
  });
@@ -168,13 +280,111 @@ module.exports = ({ strapi }) => ({
168
280
  password,
169
281
  });
170
282
 
171
- // Update the user.
172
- ctx.send({
283
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
284
+ if (mode === 'refresh') {
285
+ const deviceId = extractDeviceId(ctx.request.body);
286
+
287
+ if (deviceId) {
288
+ // Invalidate sessions: specific device if deviceId provided
289
+ await strapi
290
+ .sessionManager('users-permissions')
291
+ .invalidateRefreshToken(String(user.id), deviceId);
292
+ }
293
+
294
+ const newDeviceId = deviceId || crypto.randomUUID();
295
+ const refresh = await strapi
296
+ .sessionManager('users-permissions')
297
+ .generateRefreshToken(String(user.id), newDeviceId, { type: 'refresh' });
298
+
299
+ const access = await strapi
300
+ .sessionManager('users-permissions')
301
+ .generateAccessToken(refresh.token);
302
+ if ('error' in access) {
303
+ throw new ApplicationError('Invalid credentials');
304
+ }
305
+
306
+ return ctx.send({
307
+ jwt: access.token,
308
+ refreshToken: refresh.token,
309
+ user: await sanitizeUser(user, ctx),
310
+ });
311
+ }
312
+
313
+ return ctx.send({
173
314
  jwt: getService('jwt').issue({ id: user.id }),
174
315
  user: await sanitizeUser(user, ctx),
175
316
  });
176
317
  },
318
+ async refresh(ctx) {
319
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
320
+ if (mode !== 'refresh') {
321
+ return ctx.notFound();
322
+ }
323
+
324
+ const { refreshToken } = ctx.request.body || {};
325
+ if (!refreshToken || typeof refreshToken !== 'string') {
326
+ return ctx.badRequest('Missing refresh token');
327
+ }
328
+
329
+ const rotation = await strapi
330
+ .sessionManager('users-permissions')
331
+ .rotateRefreshToken(refreshToken);
332
+ if ('error' in rotation) {
333
+ return ctx.unauthorized('Invalid refresh token');
334
+ }
335
+
336
+ const result = await strapi
337
+ .sessionManager('users-permissions')
338
+ .generateAccessToken(rotation.token);
339
+ if ('error' in result) {
340
+ return ctx.unauthorized('Invalid refresh token');
341
+ }
342
+
343
+ const upSessions = strapi.config.get('plugin::users-permissions.sessions');
344
+ const requestHttpOnly = ctx.request.header['x-strapi-refresh-cookie'] === 'httpOnly';
345
+ if (upSessions?.httpOnly || requestHttpOnly) {
346
+ const cookieName = upSessions.cookie?.name || 'strapi_up_refresh';
347
+ const cookieOptions = {
348
+ httpOnly: true,
349
+ secure: Boolean(upSessions.cookie?.secure),
350
+ sameSite: upSessions.cookie?.sameSite ?? 'lax',
351
+ path: upSessions.cookie?.path ?? '/',
352
+ domain: upSessions.cookie?.domain,
353
+ overwrite: true,
354
+ };
355
+ ctx.cookies.set(cookieName, rotation.token, cookieOptions);
356
+ return ctx.send({ jwt: result.token });
357
+ }
358
+ return ctx.send({ jwt: result.token, refreshToken: rotation.token });
359
+ },
360
+ async logout(ctx) {
361
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
362
+ if (mode !== 'refresh') {
363
+ return ctx.notFound();
364
+ }
365
+
366
+ // Invalidate all sessions for the authenticated user, or by deviceId if provided
367
+ if (!ctx.state.user) {
368
+ return ctx.unauthorized('Missing authentication');
369
+ }
370
+
371
+ const deviceId = extractDeviceId(ctx.request.body);
372
+ try {
373
+ await strapi
374
+ .sessionManager('users-permissions')
375
+ .invalidateRefreshToken(String(ctx.state.user.id), deviceId);
376
+ } catch (err) {
377
+ strapi.log.error('UP logout failed', err);
378
+ }
177
379
 
380
+ const upSessions = strapi.config.get('plugin::users-permissions.sessions');
381
+ const requestHttpOnly = ctx.request.header['x-strapi-refresh-cookie'] === 'httpOnly';
382
+ if (upSessions?.httpOnly || requestHttpOnly) {
383
+ const cookieName = upSessions.cookie?.name || 'strapi_up_refresh';
384
+ ctx.cookies.set(cookieName, '', { expires: new Date(0) });
385
+ }
386
+ return ctx.send({ ok: true });
387
+ },
178
388
  async connect(ctx, next) {
179
389
  const grant = require('grant').koa();
180
390
 
@@ -387,12 +597,26 @@ module.exports = ({ strapi }) => ({
387
597
  return ctx.send({ user: sanitizedUser });
388
598
  }
389
599
 
390
- const jwt = getService('jwt').issue(_.pick(user, ['id']));
600
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
601
+ if (mode === 'refresh') {
602
+ const deviceId = extractDeviceId(ctx.request.body) || crypto.randomUUID();
391
603
 
392
- return ctx.send({
393
- jwt,
394
- user: sanitizedUser,
395
- });
604
+ const refresh = await strapi
605
+ .sessionManager('users-permissions')
606
+ .generateRefreshToken(String(user.id), deviceId, { type: 'refresh' });
607
+
608
+ const access = await strapi
609
+ .sessionManager('users-permissions')
610
+ .generateAccessToken(refresh.token);
611
+ if ('error' in access) {
612
+ throw new ApplicationError('Invalid credentials');
613
+ }
614
+
615
+ return ctx.send({ jwt: access.token, refreshToken: refresh.token, user: sanitizedUser });
616
+ }
617
+
618
+ const jwt = getService('jwt').issue(_.pick(user, ['id']));
619
+ return ctx.send({ jwt, user: sanitizedUser });
396
620
  },
397
621
 
398
622
  async emailConfirmation(ctx, next, returnUser) {
@@ -2,8 +2,7 @@
2
2
 
3
3
  const _ = require('lodash');
4
4
  const { contentTypes: contentTypesUtils } = require('@strapi/utils');
5
- const { ApplicationError, ValidationError, NotFoundError, ForbiddenError } =
6
- require('@strapi/utils').errors;
5
+ const { ApplicationError, NotFoundError, ForbiddenError } = require('@strapi/utils').errors;
7
6
  const { validateCreateUserBody, validateUpdateUserBody } = require('./validation/user');
8
7
 
9
8
  const { UPDATED_BY_ATTRIBUTE, CREATED_BY_ATTRIBUTE } = contentTypesUtils.constants;
@@ -133,8 +132,8 @@ module.exports = {
133
132
 
134
133
  await validateUpdateUserBody(ctx.request.body);
135
134
 
136
- if (_.has(body, 'password') && !password && user.provider === 'local') {
137
- throw new ValidationError('password.notNull');
135
+ if (_.has(body, 'password') && (password == null || password === '')) {
136
+ delete body.password;
138
137
  }
139
138
 
140
139
  if (_.has(body, 'username')) {
@@ -29,7 +29,18 @@ const createUserBodySchema = yup.object().shape({
29
29
  const updateUserBodySchema = yup.object().shape({
30
30
  email: yup.string().email().min(1),
31
31
  username: yup.string().min(1),
32
- password: yup.string().min(1),
32
+ password: yup
33
+ .mixed()
34
+ .test(
35
+ 'password-validation',
36
+ 'Password must be at least 1 character',
37
+ function validatePassword(value) {
38
+ if (value == null || value === '') {
39
+ return true;
40
+ }
41
+ return typeof value === 'string' && value.length >= 1;
42
+ }
43
+ ),
33
44
  role: yup.lazy((value) =>
34
45
  typeof value === 'object'
35
46
  ? yup.object().shape({
@@ -1,82 +1,130 @@
1
1
  'use strict';
2
2
 
3
- module.exports = [
4
- {
5
- method: 'GET',
6
- path: '/connect/(.*)',
7
- handler: 'auth.connect',
8
- config: {
9
- middlewares: ['plugin::users-permissions.rateLimit'],
10
- prefix: '',
3
+ const { UsersPermissionsRouteValidator } = require('./validation');
4
+
5
+ module.exports = (strapi) => {
6
+ const validator = new UsersPermissionsRouteValidator(strapi);
7
+
8
+ return [
9
+ {
10
+ method: 'GET',
11
+ path: '/connect/(.*)',
12
+ handler: 'auth.connect',
13
+ config: {
14
+ middlewares: ['plugin::users-permissions.rateLimit'],
15
+ prefix: '',
16
+ },
17
+ },
18
+ {
19
+ method: 'POST',
20
+ path: '/auth/local',
21
+ handler: 'auth.callback',
22
+ config: {
23
+ middlewares: ['plugin::users-permissions.rateLimit'],
24
+ prefix: '',
25
+ },
26
+ request: {
27
+ body: { 'application/json': validator.loginBodySchema },
28
+ },
29
+ response: validator.authResponseSchema,
30
+ },
31
+ {
32
+ method: 'POST',
33
+ path: '/auth/local/register',
34
+ handler: 'auth.register',
35
+ config: {
36
+ middlewares: ['plugin::users-permissions.rateLimit'],
37
+ prefix: '',
38
+ },
39
+ request: {
40
+ body: { 'application/json': validator.registerBodySchema },
41
+ },
42
+ response: validator.authRegisterResponseSchema,
11
43
  },
12
- },
13
- {
14
- method: 'POST',
15
- path: '/auth/local',
16
- handler: 'auth.callback',
17
- config: {
18
- middlewares: ['plugin::users-permissions.rateLimit'],
19
- prefix: '',
44
+ {
45
+ method: 'GET',
46
+ path: '/auth/:provider/callback',
47
+ handler: 'auth.callback',
48
+ config: {
49
+ prefix: '',
50
+ },
51
+ request: {
52
+ params: {
53
+ provider: validator.providerParam,
54
+ },
55
+ },
56
+ response: validator.authResponseSchema,
20
57
  },
21
- },
22
- {
23
- method: 'POST',
24
- path: '/auth/local/register',
25
- handler: 'auth.register',
26
- config: {
27
- middlewares: ['plugin::users-permissions.rateLimit'],
28
- prefix: '',
58
+ {
59
+ method: 'POST',
60
+ path: '/auth/forgot-password',
61
+ handler: 'auth.forgotPassword',
62
+ config: {
63
+ middlewares: ['plugin::users-permissions.rateLimit'],
64
+ prefix: '',
65
+ },
66
+ request: {
67
+ body: { 'application/json': validator.forgotPasswordBodySchema },
68
+ },
69
+ response: validator.forgotPasswordResponseSchema,
29
70
  },
30
- },
31
- {
32
- method: 'GET',
33
- path: '/auth/:provider/callback',
34
- handler: 'auth.callback',
35
- config: {
36
- prefix: '',
71
+ {
72
+ method: 'POST',
73
+ path: '/auth/reset-password',
74
+ handler: 'auth.resetPassword',
75
+ config: {
76
+ middlewares: ['plugin::users-permissions.rateLimit'],
77
+ prefix: '',
78
+ },
79
+ request: {
80
+ body: { 'application/json': validator.resetPasswordBodySchema },
81
+ },
82
+ response: validator.authResponseSchema,
37
83
  },
38
- },
39
- {
40
- method: 'POST',
41
- path: '/auth/forgot-password',
42
- handler: 'auth.forgotPassword',
43
- config: {
44
- middlewares: ['plugin::users-permissions.rateLimit'],
45
- prefix: '',
84
+ {
85
+ method: 'GET',
86
+ path: '/auth/email-confirmation',
87
+ handler: 'auth.emailConfirmation',
88
+ config: {
89
+ prefix: '',
90
+ },
46
91
  },
47
- },
48
- {
49
- method: 'POST',
50
- path: '/auth/reset-password',
51
- handler: 'auth.resetPassword',
52
- config: {
53
- middlewares: ['plugin::users-permissions.rateLimit'],
54
- prefix: '',
92
+ {
93
+ method: 'POST',
94
+ path: '/auth/send-email-confirmation',
95
+ handler: 'auth.sendEmailConfirmation',
96
+ config: {
97
+ prefix: '',
98
+ },
99
+ request: {
100
+ body: { 'application/json': validator.sendEmailConfirmationBodySchema },
101
+ },
102
+ response: validator.sendEmailConfirmationResponseSchema,
55
103
  },
56
- },
57
- {
58
- method: 'GET',
59
- path: '/auth/email-confirmation',
60
- handler: 'auth.emailConfirmation',
61
- config: {
62
- prefix: '',
104
+ {
105
+ method: 'POST',
106
+ path: '/auth/change-password',
107
+ handler: 'auth.changePassword',
108
+ config: {
109
+ middlewares: ['plugin::users-permissions.rateLimit'],
110
+ prefix: '',
111
+ },
112
+ request: {
113
+ body: { 'application/json': validator.changePasswordBodySchema },
114
+ },
115
+ response: validator.authResponseSchema,
63
116
  },
64
- },
65
- {
66
- method: 'POST',
67
- path: '/auth/send-email-confirmation',
68
- handler: 'auth.sendEmailConfirmation',
69
- config: {
70
- prefix: '',
117
+ {
118
+ method: 'POST',
119
+ path: '/auth/refresh',
120
+ handler: 'auth.refresh',
121
+ config: { prefix: '' },
71
122
  },
72
- },
73
- {
74
- method: 'POST',
75
- path: '/auth/change-password',
76
- handler: 'auth.changePassword',
77
- config: {
78
- middlewares: ['plugin::users-permissions.rateLimit'],
79
- prefix: '',
123
+ {
124
+ method: 'POST',
125
+ path: '/auth/logout',
126
+ handler: 'auth.logout',
127
+ config: { prefix: '' },
80
128
  },
81
- },
82
- ];
129
+ ];
130
+ };
@@ -1,11 +1,18 @@
1
1
  'use strict';
2
2
 
3
+ const { createContentApiRoutesFactory } = require('@strapi/utils');
3
4
  const authRoutes = require('./auth');
4
5
  const userRoutes = require('./user');
5
6
  const roleRoutes = require('./role');
6
7
  const permissionsRoutes = require('./permissions');
7
8
 
8
- module.exports = {
9
- type: 'content-api',
10
- routes: [...authRoutes, ...userRoutes, ...roleRoutes, ...permissionsRoutes],
11
- };
9
+ const createContentApiRoutes = createContentApiRoutesFactory(() => {
10
+ return [
11
+ ...authRoutes(strapi),
12
+ ...userRoutes(strapi),
13
+ ...roleRoutes(strapi),
14
+ ...permissionsRoutes(strapi),
15
+ ];
16
+ });
17
+
18
+ module.exports = createContentApiRoutes;
@@ -1,9 +1,16 @@
1
1
  'use strict';
2
2
 
3
- module.exports = [
4
- {
5
- method: 'GET',
6
- path: '/permissions',
7
- handler: 'permissions.getPermissions',
8
- },
9
- ];
3
+ const { UsersPermissionsRouteValidator } = require('./validation');
4
+
5
+ module.exports = (strapi) => {
6
+ const validator = new UsersPermissionsRouteValidator(strapi);
7
+
8
+ return [
9
+ {
10
+ method: 'GET',
11
+ path: '/permissions',
12
+ handler: 'permissions.getPermissions',
13
+ response: validator.permissionsResponseSchema,
14
+ },
15
+ ];
16
+ };