@strapi/plugin-users-permissions 5.50.2 → 5.51.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.
Files changed (59) hide show
  1. package/admin/src/pages/Roles/pages/EditPage.jsx +1 -1
  2. package/admin/src/translations/en.json +2 -0
  3. package/dist/admin/pages/Roles/pages/EditPage.js +1 -1
  4. package/dist/admin/pages/Roles/pages/EditPage.js.map +1 -1
  5. package/dist/admin/pages/Roles/pages/EditPage.mjs +1 -1
  6. package/dist/admin/pages/Roles/pages/EditPage.mjs.map +1 -1
  7. package/dist/admin/translations/en.json.js +1 -0
  8. package/dist/admin/translations/en.json.js.map +1 -1
  9. package/dist/admin/translations/en.json.mjs +1 -0
  10. package/dist/admin/translations/en.json.mjs.map +1 -1
  11. package/dist/server/_virtual/_node_crypto.js +10 -0
  12. package/dist/server/_virtual/_node_crypto.js.map +1 -0
  13. package/dist/server/_virtual/_node_crypto.mjs +7 -0
  14. package/dist/server/_virtual/_node_crypto.mjs.map +1 -0
  15. package/dist/server/_virtual/_node_url.js +10 -0
  16. package/dist/server/_virtual/_node_url.js.map +1 -0
  17. package/dist/server/_virtual/_node_url.mjs +7 -0
  18. package/dist/server/_virtual/_node_url.mjs.map +1 -0
  19. package/dist/server/controllers/auth.js +19 -19
  20. package/dist/server/controllers/auth.js.map +1 -1
  21. package/dist/server/controllers/auth.mjs +19 -18
  22. package/dist/server/controllers/auth.mjs.map +1 -1
  23. package/dist/server/services/providers-registry.js +121 -242
  24. package/dist/server/services/providers-registry.js.map +1 -1
  25. package/dist/server/services/providers-registry.mjs +121 -239
  26. package/dist/server/services/providers-registry.mjs.map +1 -1
  27. package/dist/server/utils/oauth-connect/index.js +236 -0
  28. package/dist/server/utils/oauth-connect/index.js.map +1 -0
  29. package/dist/server/utils/oauth-connect/index.mjs +230 -0
  30. package/dist/server/utils/oauth-connect/index.mjs.map +1 -0
  31. package/dist/server/utils/oauth-connect/oauth1.js +138 -0
  32. package/dist/server/utils/oauth-connect/oauth1.js.map +1 -0
  33. package/dist/server/utils/oauth-connect/oauth1.mjs +136 -0
  34. package/dist/server/utils/oauth-connect/oauth1.mjs.map +1 -0
  35. package/dist/server/utils/oauth-connect/oauth2.js +117 -0
  36. package/dist/server/utils/oauth-connect/oauth2.js.map +1 -0
  37. package/dist/server/utils/oauth-connect/oauth2.mjs +115 -0
  38. package/dist/server/utils/oauth-connect/oauth2.mjs.map +1 -0
  39. package/dist/server/utils/oauth-connect/providers.js +109 -0
  40. package/dist/server/utils/oauth-connect/providers.js.map +1 -0
  41. package/dist/server/utils/oauth-connect/providers.mjs +107 -0
  42. package/dist/server/utils/oauth-connect/providers.mjs.map +1 -0
  43. package/dist/server/utils/provider-http.js +52 -0
  44. package/dist/server/utils/provider-http.js.map +1 -0
  45. package/dist/server/utils/provider-http.mjs +50 -0
  46. package/dist/server/utils/provider-http.mjs.map +1 -0
  47. package/dist/server/utils/verify-jwt-with-jwks.js +60 -0
  48. package/dist/server/utils/verify-jwt-with-jwks.js.map +1 -0
  49. package/dist/server/utils/verify-jwt-with-jwks.mjs +54 -0
  50. package/dist/server/utils/verify-jwt-with-jwks.mjs.map +1 -0
  51. package/package.json +4 -7
  52. package/server/controllers/auth.js +13 -20
  53. package/server/services/providers-registry.js +137 -293
  54. package/server/utils/oauth-connect/index.js +256 -0
  55. package/server/utils/oauth-connect/oauth1.js +169 -0
  56. package/server/utils/oauth-connect/oauth2.js +123 -0
  57. package/server/utils/oauth-connect/providers.js +100 -0
  58. package/server/utils/provider-http.js +49 -0
  59. package/server/utils/verify-jwt-with-jwks.js +43 -0
@@ -1,18 +1,15 @@
1
1
  'use strict';
2
2
 
3
3
  var require$$0 = require('assert');
4
- var require$$1 = require('jsonwebtoken');
5
4
  var require$$2 = require('url-join');
6
- var require$$3 = require('jwk-to-pem');
7
- var require$$4 = require('purest');
5
+ var verifyJwtWithJwks = require('../utils/verify-jwt-with-jwks.js');
6
+ var providerHttp = require('../utils/provider-http.js');
7
+ var oauth1 = require('../utils/oauth-connect/oauth1.js');
8
8
 
9
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
 
11
11
  var require$$0__default = /*#__PURE__*/_interopDefault(require$$0);
12
- var require$$1__default = /*#__PURE__*/_interopDefault(require$$1);
13
12
  var require$$2__default = /*#__PURE__*/_interopDefault(require$$2);
14
- var require$$3__default = /*#__PURE__*/_interopDefault(require$$3);
15
- var require$$4__default = /*#__PURE__*/_interopDefault(require$$4);
16
13
 
17
14
  var providersRegistry;
18
15
  var hasRequiredProvidersRegistry;
@@ -20,53 +17,10 @@ function requireProvidersRegistry() {
20
17
  if (hasRequiredProvidersRegistry) return providersRegistry;
21
18
  hasRequiredProvidersRegistry = 1;
22
19
  const { strict: assert } = require$$0__default.default;
23
- const jwt = require$$1__default.default;
24
20
  const urljoin = require$$2__default.default;
25
- const jwkToPem = require$$3__default.default;
26
- const getCognitoPayload = async ({ idToken, jwksUrl, purest })=>{
27
- const { header: { kid }, payload } = jwt.decode(idToken, {
28
- complete: true
29
- });
30
- if (!payload || !kid) {
31
- throw new Error('The provided token is not valid');
32
- }
33
- const config = {
34
- cognito: {
35
- discovery: {
36
- origin: jwksUrl.origin,
37
- path: jwksUrl.pathname
38
- }
39
- }
40
- };
41
- try {
42
- const cognito = purest({
43
- provider: 'cognito',
44
- config
45
- });
46
- // get the JSON Web Key (JWK) for the user pool
47
- const { body: jwk } = await cognito('discovery').request();
48
- // Get the key with the same Key ID as the provided token
49
- const key = jwk.keys.find(({ kid: jwkKid })=>jwkKid === kid);
50
- const pem = jwkToPem(key);
51
- // https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html
52
- const decodedToken = await new Promise((resolve, reject)=>{
53
- jwt.verify(idToken, pem, {
54
- algorithms: [
55
- 'RS256'
56
- ]
57
- }, (err, decodedToken)=>{
58
- if (err) {
59
- reject();
60
- }
61
- resolve(decodedToken);
62
- });
63
- });
64
- return decodedToken;
65
- } catch (err) {
66
- throw new Error('There was an error verifying the token');
67
- }
68
- };
69
- const initProviders = ({ baseURL, purest })=>({
21
+ const { verifyJwtWithJwks: verifyJwtWithJwks$1 } = verifyJwtWithJwks.__require();
22
+ const { bearerGet, fetchJson } = providerHttp.__require();
23
+ const initProviders = ({ baseURL })=>({
70
24
  email: {
71
25
  enabled: true,
72
26
  icon: 'envelope',
@@ -85,17 +39,12 @@ function requireProvidersRegistry() {
85
39
  ]
86
40
  },
87
41
  async authCallback ({ accessToken }) {
88
- const discord = purest({
89
- provider: 'discord'
90
- });
91
- return discord.get('users/@me').auth(accessToken).request().then(({ body })=>{
92
- // Combine username and discriminator (if discriminator exists and not equal to 0)
93
- const username = body.discriminator && body.discriminator !== '0' ? `${body.username}#${body.discriminator}` : body.username;
94
- return {
95
- username,
96
- email: body.email
97
- };
98
- });
42
+ const { body } = await bearerGet('https://discord.com/api/users/@me', accessToken);
43
+ const username = body.discriminator && body.discriminator !== '0' ? `${body.username}#${body.discriminator}` : body.username;
44
+ return {
45
+ username,
46
+ email: body.email
47
+ };
99
48
  }
100
49
  },
101
50
  facebook: {
@@ -110,15 +59,15 @@ function requireProvidersRegistry() {
110
59
  ]
111
60
  },
112
61
  async authCallback ({ accessToken }) {
113
- const facebook = purest({
114
- provider: 'facebook'
62
+ const { body } = await bearerGet('https://graph.facebook.com/me', accessToken, {
63
+ qs: {
64
+ fields: 'name,email'
65
+ }
115
66
  });
116
- return facebook.get('me').auth(accessToken).qs({
117
- fields: 'name,email'
118
- }).request().then(({ body })=>({
119
- username: body.name,
120
- email: body.email
121
- }));
67
+ return {
68
+ username: body.name,
69
+ email: body.email
70
+ };
122
71
  }
123
72
  },
124
73
  google: {
@@ -133,15 +82,11 @@ function requireProvidersRegistry() {
133
82
  ]
134
83
  },
135
84
  async authCallback ({ accessToken }) {
136
- const google = purest({
137
- provider: 'google'
138
- });
139
- return google.query('oauth').get('tokeninfo').qs({
140
- accessToken
141
- }).request().then(({ body })=>({
142
- username: body.email.split('@')[0],
143
- email: body.email
144
- }));
85
+ const { body } = await fetchJson(`https://oauth2.googleapis.com/tokeninfo?access_token=${encodeURIComponent(accessToken)}`);
86
+ return {
87
+ username: body.email.split('@')[0],
88
+ email: body.email
89
+ };
145
90
  }
146
91
  },
147
92
  github: {
@@ -157,24 +102,22 @@ function requireProvidersRegistry() {
157
102
  ]
158
103
  },
159
104
  async authCallback ({ accessToken }) {
160
- const github = purest({
161
- provider: 'github',
162
- defaults: {
163
- headers: {
164
- 'user-agent': 'strapi'
165
- }
105
+ const { body: userBody } = await bearerGet('https://api.github.com/user', accessToken, {
106
+ headers: {
107
+ 'user-agent': 'strapi'
166
108
  }
167
109
  });
168
- const { body: userBody } = await github.get('user').auth(accessToken).request();
169
- // This is the public email on the github profile
170
110
  if (userBody.email) {
171
111
  return {
172
112
  username: userBody.login,
173
113
  email: userBody.email
174
114
  };
175
115
  }
176
- // Get the email with Github's user/emails API
177
- const { body: emailBody } = await github.get('user/emails').auth(accessToken).request();
116
+ const { body: emailBody } = await bearerGet('https://api.github.com/user/emails', accessToken, {
117
+ headers: {
118
+ 'user-agent': 'strapi'
119
+ }
120
+ });
178
121
  return {
179
122
  username: userBody.login,
180
123
  email: Array.isArray(emailBody) ? emailBody.find((email)=>email.primary === true).email : null
@@ -193,13 +136,11 @@ function requireProvidersRegistry() {
193
136
  ]
194
137
  },
195
138
  async authCallback ({ accessToken }) {
196
- const microsoft = purest({
197
- provider: 'microsoft'
198
- });
199
- return microsoft.get('me').auth(accessToken).request().then(({ body })=>({
200
- username: body.userPrincipalName,
201
- email: body.userPrincipalName
202
- }));
139
+ const { body } = await bearerGet('https://graph.microsoft.com/v1.0/me', accessToken);
140
+ return {
141
+ username: body.userPrincipalName,
142
+ email: body.userPrincipalName
143
+ };
203
144
  }
204
145
  },
205
146
  twitter: {
@@ -211,22 +152,22 @@ function requireProvidersRegistry() {
211
152
  callbackUrl: `${baseURL}/twitter/callback`
212
153
  },
213
154
  async authCallback ({ accessToken, query, providers }) {
214
- const twitter = purest({
215
- provider: 'twitter',
216
- defaults: {
217
- oauth: {
218
- consumer_key: providers.twitter.key,
219
- consumer_secret: providers.twitter.secret
220
- }
155
+ const { twitterGet } = oauth1.__require();
156
+ const { body } = await twitterGet({
157
+ url: 'https://api.twitter.com/1.1/account/verify_credentials.json',
158
+ accessToken,
159
+ accessCredential: query.access_secret,
160
+ consumerKey: providers.twitter.key,
161
+ clientCredential: providers.twitter.secret,
162
+ qs: {
163
+ include_email: 'true',
164
+ screen_name: query['raw[screen_name]']
221
165
  }
222
166
  });
223
- return twitter.get('account/verify_credentials').auth(accessToken, query.access_secret).qs({
224
- screen_name: query['raw[screen_name]'],
225
- include_email: 'true'
226
- }).request().then(({ body })=>({
227
- username: body.screen_name,
228
- email: body.email
229
- }));
167
+ return {
168
+ username: body.screen_name,
169
+ email: body.email
170
+ };
230
171
  }
231
172
  },
232
173
  instagram: {
@@ -241,15 +182,15 @@ function requireProvidersRegistry() {
241
182
  ]
242
183
  },
243
184
  async authCallback ({ accessToken }) {
244
- const instagram = purest({
245
- provider: 'instagram'
185
+ const { body } = await bearerGet('https://graph.instagram.com/me', accessToken, {
186
+ qs: {
187
+ fields: 'id,username'
188
+ }
246
189
  });
247
- return instagram.get('me').auth(accessToken).qs({
248
- fields: 'id,username'
249
- }).request().then(({ body })=>({
250
- username: body.username,
251
- email: `${body.username}@strapi.io`
252
- }));
190
+ return {
191
+ username: body.username,
192
+ email: `${body.username}@strapi.io`
193
+ };
253
194
  }
254
195
  },
255
196
  vk: {
@@ -264,16 +205,16 @@ function requireProvidersRegistry() {
264
205
  ]
265
206
  },
266
207
  async authCallback ({ accessToken, query }) {
267
- const vk = purest({
268
- provider: 'vk'
208
+ const { body } = await bearerGet('https://api.vk.com/method/users.get', accessToken, {
209
+ qs: {
210
+ user_ids: query.raw.user_id,
211
+ v: '5.122'
212
+ }
269
213
  });
270
- return vk.get('users').auth(accessToken).qs({
271
- id: query.raw.user_id,
272
- v: '5.122'
273
- }).request().then(({ body })=>({
274
- username: `${body.response[0].last_name} ${body.response[0].first_name}`,
275
- email: query.raw.email
276
- }));
214
+ return {
215
+ username: `${body.response[0].last_name} ${body.response[0].first_name}`,
216
+ email: query.raw.email
217
+ };
277
218
  }
278
219
  },
279
220
  twitch: {
@@ -288,25 +229,15 @@ function requireProvidersRegistry() {
288
229
  ]
289
230
  },
290
231
  async authCallback ({ accessToken, providers }) {
291
- const twitch = purest({
292
- provider: 'twitch',
293
- config: {
294
- twitch: {
295
- default: {
296
- origin: 'https://api.twitch.tv',
297
- path: 'helix/{path}',
298
- headers: {
299
- Authorization: 'Bearer {auth}',
300
- 'Client-Id': '{auth}'
301
- }
302
- }
303
- }
232
+ const { body } = await bearerGet('https://api.twitch.tv/helix/users', accessToken, {
233
+ headers: {
234
+ 'Client-Id': providers.twitch.key
304
235
  }
305
236
  });
306
- return twitch.get('users').auth(accessToken, providers.twitch.key).request().then(({ body })=>({
307
- username: body.data[0].login,
308
- email: body.data[0].email
309
- }));
237
+ return {
238
+ username: body.data[0].login,
239
+ email: body.data[0].email
240
+ };
310
241
  }
311
242
  },
312
243
  linkedin: {
@@ -322,14 +253,11 @@ function requireProvidersRegistry() {
322
253
  ]
323
254
  },
324
255
  async authCallback ({ accessToken }) {
325
- const linkedIn = purest({
326
- provider: 'linkedin'
327
- });
328
- const { body: { localizedFirstName } } = await linkedIn.get('me').auth(accessToken).request();
329
- const { body: { elements } } = await linkedIn.get('emailAddress?q=members&projection=(elements*(handle~))').auth(accessToken).request();
330
- const email = elements[0]['handle~'];
256
+ const { body: profileBody } = await bearerGet('https://api.linkedin.com/v2/me', accessToken);
257
+ const { body: emailBody } = await bearerGet('https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))', accessToken);
258
+ const email = emailBody.elements[0]['handle~'];
331
259
  return {
332
- username: localizedFirstName,
260
+ username: profileBody.localizedFirstName,
333
261
  email: email.emailAddress
334
262
  };
335
263
  }
@@ -351,10 +279,9 @@ function requireProvidersRegistry() {
351
279
  async authCallback ({ query, providers }) {
352
280
  const jwksUrl = new URL(providers.cognito.jwksurl);
353
281
  const idToken = query.id_token;
354
- const tokenPayload = await getCognitoPayload({
282
+ const tokenPayload = await verifyJwtWithJwks$1({
355
283
  idToken,
356
- jwksUrl,
357
- purest
284
+ jwksUrl
358
285
  });
359
286
  return {
360
287
  username: tokenPayload['cognito:username'],
@@ -374,26 +301,15 @@ function requireProvidersRegistry() {
374
301
  ]
375
302
  },
376
303
  async authCallback ({ accessToken }) {
377
- const reddit = purest({
378
- provider: 'reddit',
379
- config: {
380
- reddit: {
381
- default: {
382
- origin: 'https://oauth.reddit.com',
383
- path: 'api/{version}/{path}',
384
- version: 'v1',
385
- headers: {
386
- Authorization: 'Bearer {auth}',
387
- 'user-agent': 'strapi'
388
- }
389
- }
390
- }
304
+ const { body } = await bearerGet('https://oauth.reddit.com/api/v1/me', accessToken, {
305
+ headers: {
306
+ 'user-agent': 'strapi'
391
307
  }
392
308
  });
393
- return reddit.get('me').auth(accessToken).request().then(({ body })=>({
394
- username: body.name,
395
- email: `${body.name}@strapi.io`
396
- }));
309
+ return {
310
+ username: body.name,
311
+ email: `${body.name}@strapi.io`
312
+ };
397
313
  }
398
314
  },
399
315
  auth0: {
@@ -411,17 +327,13 @@ function requireProvidersRegistry() {
411
327
  ]
412
328
  },
413
329
  async authCallback ({ accessToken, providers }) {
414
- const auth0 = purest({
415
- provider: 'auth0'
416
- });
417
- return auth0.get('userinfo').subdomain(providers.auth0.subdomain).auth(accessToken).request().then(({ body })=>{
418
- const username = body.username || body.nickname || body.name || body.email.split('@')[0];
419
- const email = body.email || `${username.replace(/\s+/g, '.')}@strapi.io`;
420
- return {
421
- username,
422
- email
423
- };
424
- });
330
+ const { body } = await bearerGet(`https://${providers.auth0.subdomain}.auth0.com/userinfo`, accessToken);
331
+ const username = body.username || body.nickname || body.name || body.email.split('@')[0];
332
+ const email = body.email || `${username.replace(/\s+/g, '.')}@strapi.io`;
333
+ return {
334
+ username,
335
+ email
336
+ };
425
337
  }
426
338
  },
427
339
  cas: {
@@ -437,21 +349,16 @@ function requireProvidersRegistry() {
437
349
  subdomain: 'my.subdomain.com/cas'
438
350
  },
439
351
  async authCallback ({ accessToken, providers }) {
440
- const cas = purest({
441
- provider: 'cas'
442
- });
443
- return cas.get('oidc/profile').subdomain(providers.cas.subdomain).auth(accessToken).request().then(({ body })=>{
444
- // CAS attribute may be in body.attributes or "FLAT", depending on CAS config
445
- const username = body.attributes ? body.attributes.strapiusername || body.id || body.sub : body.strapiusername || body.id || body.sub;
446
- const email = body.attributes ? body.attributes.strapiemail || body.attributes.email : body.strapiemail || body.email;
447
- if (!username || !email) {
448
- strapi.log.warn(`CAS Response Body did not contain required attributes: ${JSON.stringify(body)}`);
449
- }
450
- return {
451
- username,
452
- email
453
- };
454
- });
352
+ const { body } = await bearerGet(`https://${providers.cas.subdomain}/oidc/profile`, accessToken);
353
+ const username = body.attributes ? body.attributes.strapiusername || body.id || body.sub : body.strapiusername || body.id || body.sub;
354
+ const email = body.attributes ? body.attributes.strapiemail || body.attributes.email : body.strapiemail || body.email;
355
+ if (!username || !email) {
356
+ strapi.log.warn(`CAS Response Body did not contain required attributes: ${JSON.stringify(body)}`);
357
+ }
358
+ return {
359
+ username,
360
+ email
361
+ };
455
362
  }
456
363
  },
457
364
  patreon: {
@@ -467,29 +374,12 @@ function requireProvidersRegistry() {
467
374
  ]
468
375
  },
469
376
  async authCallback ({ accessToken }) {
470
- const patreon = purest({
471
- provider: 'patreon',
472
- config: {
473
- patreon: {
474
- default: {
475
- origin: 'https://www.patreon.com',
476
- path: 'api/oauth2/{path}',
477
- headers: {
478
- authorization: 'Bearer {auth}'
479
- }
480
- }
481
- }
482
- }
483
- });
484
- return patreon.get('v2/identity').auth(accessToken).qs(new URLSearchParams({
485
- 'fields[user]': 'full_name,email'
486
- }).toString()).request().then(({ body })=>{
487
- const patreonData = body.data.attributes;
488
- return {
489
- username: patreonData.full_name,
490
- email: patreonData.email
491
- };
492
- });
377
+ const { body } = await bearerGet('https://www.patreon.com/api/oauth2/v2/identity?fields[user]=full_name,email', accessToken);
378
+ const patreonData = body.data.attributes;
379
+ return {
380
+ username: patreonData.full_name,
381
+ email: patreonData.email
382
+ };
493
383
  }
494
384
  },
495
385
  keycloak: {
@@ -507,29 +397,21 @@ function requireProvidersRegistry() {
507
397
  ]
508
398
  },
509
399
  async authCallback ({ accessToken, providers }) {
510
- const keycloak = purest({
511
- provider: 'keycloak'
512
- });
513
- return keycloak.subdomain(providers.keycloak.subdomain).get('protocol/openid-connect/userinfo').auth(accessToken).request().then(({ body })=>{
514
- return {
515
- username: body.preferred_username,
516
- email: body.email
517
- };
518
- });
400
+ const { body } = await bearerGet(`https://${providers.keycloak.subdomain}/protocol/openid-connect/userinfo`, accessToken);
401
+ return {
402
+ username: body.preferred_username,
403
+ email: body.email
404
+ };
519
405
  }
520
406
  }
521
407
  });
522
408
  providersRegistry = ()=>{
523
- const purest = require$$4__default.default;
524
409
  const apiPrefix = strapi.config.get('api.rest.prefix');
525
410
  const baseURL = urljoin(strapi.config.server.url, apiPrefix, 'auth');
526
411
  const authProviders = initProviders({
527
- baseURL,
528
- purest
412
+ baseURL
529
413
  });
530
- /**
531
- * @public
532
- */ return {
414
+ return {
533
415
  getAll () {
534
416
  return authProviders;
535
417
  },
@@ -542,16 +424,13 @@ function requireProvidersRegistry() {
542
424
  remove (name) {
543
425
  delete authProviders[name];
544
426
  },
545
- /**
546
- * @internal
547
- */ async run ({ provider, accessToken, query, providers }) {
427
+ async run ({ provider, accessToken, query, providers }) {
548
428
  const authProvider = authProviders[provider];
549
429
  assert(authProvider, 'Unknown auth provider');
550
430
  return authProvider.authCallback({
551
431
  accessToken,
552
432
  query,
553
- providers,
554
- purest
433
+ providers
555
434
  });
556
435
  }
557
436
  };