@strapi/plugin-users-permissions 4.25.22 → 4.25.23

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 (27) hide show
  1. package/dist/_chunks/{index-gEkbV4F9.mjs → index--wWLZAMs.mjs} +2 -2
  2. package/dist/_chunks/{index-gEkbV4F9.mjs.map → index--wWLZAMs.mjs.map} +1 -1
  3. package/dist/_chunks/{index-TXvCramy.mjs → index-7jtnDf4p.mjs} +2 -2
  4. package/dist/_chunks/{index-TXvCramy.mjs.map → index-7jtnDf4p.mjs.map} +1 -1
  5. package/dist/_chunks/{index-b4wChiEY.js → index-8kzrt70D.js} +2 -2
  6. package/dist/_chunks/{index-b4wChiEY.js.map → index-8kzrt70D.js.map} +1 -1
  7. package/dist/_chunks/{index-eDOLWAV7.js → index-DiW6ewR1.js} +10 -10
  8. package/dist/_chunks/{index-eDOLWAV7.js.map → index-DiW6ewR1.js.map} +1 -1
  9. package/dist/_chunks/{index-6vUdu8my.js → index-JrkD5bN5.js} +2 -2
  10. package/dist/_chunks/{index-6vUdu8my.js.map → index-JrkD5bN5.js.map} +1 -1
  11. package/dist/_chunks/{index-KGe8mvqZ.js → index-UDmr9bPp.js} +2 -2
  12. package/dist/_chunks/{index-KGe8mvqZ.js.map → index-UDmr9bPp.js.map} +1 -1
  13. package/dist/_chunks/{index-gUNfzF88.mjs → index-l5A7Tjiq.mjs} +10 -10
  14. package/dist/_chunks/{index-gUNfzF88.mjs.map → index-l5A7Tjiq.mjs.map} +1 -1
  15. package/dist/_chunks/{index-_PJkAU_B.js → index-pEEKO4Ga.js} +2 -2
  16. package/dist/_chunks/{index-_PJkAU_B.js.map → index-pEEKO4Ga.js.map} +1 -1
  17. package/dist/_chunks/{index-oL1A5ghB.mjs → index-vRjKW1Li.mjs} +2 -2
  18. package/dist/_chunks/{index-oL1A5ghB.mjs.map → index-vRjKW1Li.mjs.map} +1 -1
  19. package/dist/_chunks/{index-rlXIaWJh.mjs → index-yYLeDDYr.mjs} +2 -2
  20. package/dist/_chunks/{index-rlXIaWJh.mjs.map → index-yYLeDDYr.mjs.map} +1 -1
  21. package/dist/admin/index.js +1 -1
  22. package/dist/admin/index.mjs +1 -1
  23. package/package.json +6 -6
  24. package/server/bootstrap/index.js +13 -9
  25. package/server/services/providers-registry.js +468 -279
  26. package/server/utils/index.d.ts +2 -1
  27. package/server/bootstrap/grant-config.js +0 -140
@@ -2,6 +2,7 @@
2
2
 
3
3
  const { strict: assert } = require('assert');
4
4
  const jwt = require('jsonwebtoken');
5
+ const urljoin = require('url-join');
5
6
  const jwkToPem = require('jwk-to-pem');
6
7
 
7
8
  const getCognitoPayload = async ({ idToken, jwksUrl, purest }) => {
@@ -45,334 +46,522 @@ const getCognitoPayload = async ({ idToken, jwksUrl, purest }) => {
45
46
  }
46
47
  };
47
48
 
48
- const getInitialProviders = ({ purest }) => ({
49
- async discord({ accessToken }) {
50
- const discord = purest({ provider: 'discord' });
51
-
52
- return discord
53
- .get('users/@me')
54
- .auth(accessToken)
55
- .request()
56
- .then(({ body }) => {
57
- // Combine username and discriminator (if discriminator exists and not equal to 0)
58
- const username =
59
- body.discriminator && body.discriminator !== '0'
60
- ? `${body.username}#${body.discriminator}`
61
- : body.username;
62
- return {
63
- username,
64
- email: body.email,
65
- };
66
- });
49
+ const initProviders = ({ baseURL, purest }) => ({
50
+ email: {
51
+ enabled: true,
52
+ icon: 'envelope',
53
+ grantConfig: {},
67
54
  },
68
- async cognito({ query, providers }) {
69
- const jwksUrl = new URL(providers.cognito.jwksurl);
70
- const idToken = query.id_token;
71
- const tokenPayload = await getCognitoPayload({ idToken, jwksUrl, purest });
72
- return {
73
- username: tokenPayload['cognito:username'],
74
- email: tokenPayload.email,
75
- };
55
+ discord: {
56
+ enabled: false,
57
+ icon: 'discord',
58
+ grantConfig: {
59
+ key: '',
60
+ secret: '',
61
+ callbackUrl: `${baseURL}/discord/callback`,
62
+ scope: ['identify', 'email'],
63
+ },
64
+ async authCallback({ accessToken }) {
65
+ const discord = purest({ provider: 'discord' });
66
+
67
+ return discord
68
+ .get('users/@me')
69
+ .auth(accessToken)
70
+ .request()
71
+ .then(({ body }) => {
72
+ // Combine username and discriminator (if discriminator exists and not equal to 0)
73
+ const username =
74
+ body.discriminator && body.discriminator !== '0'
75
+ ? `${body.username}#${body.discriminator}`
76
+ : body.username;
77
+ return {
78
+ username,
79
+ email: body.email,
80
+ };
81
+ });
82
+ },
76
83
  },
77
- async facebook({ accessToken }) {
78
- const facebook = purest({ provider: 'facebook' });
79
-
80
- return facebook
81
- .get('me')
82
- .auth(accessToken)
83
- .qs({ fields: 'name,email' })
84
- .request()
85
- .then(({ body }) => ({
86
- username: body.name,
87
- email: body.email,
88
- }));
84
+ facebook: {
85
+ enabled: false,
86
+ icon: 'facebook-square',
87
+ grantConfig: {
88
+ key: '',
89
+ secret: '',
90
+ callbackUrl: `${baseURL}/facebook/callback`,
91
+ scope: ['email'],
92
+ },
93
+ async authCallback({ accessToken }) {
94
+ const facebook = purest({ provider: 'facebook' });
95
+
96
+ return facebook
97
+ .get('me')
98
+ .auth(accessToken)
99
+ .qs({ fields: 'name,email' })
100
+ .request()
101
+ .then(({ body }) => ({
102
+ username: body.name,
103
+ email: body.email,
104
+ }));
105
+ },
89
106
  },
90
- async google({ accessToken }) {
91
- const google = purest({ provider: 'google' });
92
-
93
- return google
94
- .query('oauth')
95
- .get('tokeninfo')
96
- .qs({ accessToken })
97
- .request()
98
- .then(({ body }) => ({
99
- username: body.email.split('@')[0],
100
- email: body.email,
101
- }));
107
+ google: {
108
+ enabled: false,
109
+ icon: 'google',
110
+ grantConfig: {
111
+ key: '',
112
+ secret: '',
113
+ callbackUrl: `${baseURL}/google/callback`,
114
+ scope: ['email'],
115
+ },
116
+ async authCallback({ accessToken }) {
117
+ const google = purest({ provider: 'google' });
118
+
119
+ return google
120
+ .query('oauth')
121
+ .get('tokeninfo')
122
+ .qs({ accessToken })
123
+ .request()
124
+ .then(({ body }) => ({
125
+ username: body.email.split('@')[0],
126
+ email: body.email,
127
+ }));
128
+ },
102
129
  },
103
- async github({ accessToken }) {
104
- const github = purest({
105
- provider: 'github',
106
- defaults: {
107
- headers: {
108
- 'user-agent': 'strapi',
130
+ github: {
131
+ enabled: false,
132
+ icon: 'github',
133
+ grantConfig: {
134
+ key: '',
135
+ secret: '',
136
+ callbackUrl: `${baseURL}/github/callback`,
137
+ scope: ['user', 'user:email'],
138
+ },
139
+ async authCallback({ accessToken }) {
140
+ const github = purest({
141
+ provider: 'github',
142
+ defaults: {
143
+ headers: {
144
+ 'user-agent': 'strapi',
145
+ },
109
146
  },
110
- },
111
- });
147
+ });
148
+
149
+ const { body: userBody } = await github.get('user').auth(accessToken).request();
112
150
 
113
- const { body: userBody } = await github.get('user').auth(accessToken).request();
151
+ // This is the public email on the github profile
152
+ if (userBody.email) {
153
+ return {
154
+ username: userBody.login,
155
+ email: userBody.email,
156
+ };
157
+ }
158
+ // Get the email with Github's user/emails API
159
+ const { body: emailBody } = await github.get('user/emails').auth(accessToken).request();
114
160
 
115
- // This is the public email on the github profile
116
- if (userBody.email) {
117
161
  return {
118
162
  username: userBody.login,
119
- email: userBody.email,
163
+ email: Array.isArray(emailBody)
164
+ ? emailBody.find((email) => email.primary === true).email
165
+ : null,
120
166
  };
121
- }
122
- // Get the email with Github's user/emails API
123
- const { body: emailBody } = await github.get('user/emails').auth(accessToken).request();
124
-
125
- return {
126
- username: userBody.login,
127
- email: Array.isArray(emailBody)
128
- ? emailBody.find((email) => email.primary === true).email
129
- : null,
130
- };
167
+ },
131
168
  },
132
- async microsoft({ accessToken }) {
133
- const microsoft = purest({ provider: 'microsoft' });
134
-
135
- return microsoft
136
- .get('me')
137
- .auth(accessToken)
138
- .request()
139
- .then(({ body }) => ({
140
- username: body.userPrincipalName,
141
- email: body.userPrincipalName,
142
- }));
169
+ microsoft: {
170
+ enabled: false,
171
+ icon: 'windows',
172
+ grantConfig: {
173
+ key: '',
174
+ secret: '',
175
+ callbackUrl: `${baseURL}/microsoft/callback`,
176
+ scope: ['user.read'],
177
+ },
178
+ async authCallback({ accessToken }) {
179
+ const microsoft = purest({ provider: 'microsoft' });
180
+
181
+ return microsoft
182
+ .get('me')
183
+ .auth(accessToken)
184
+ .request()
185
+ .then(({ body }) => ({
186
+ username: body.userPrincipalName,
187
+ email: body.userPrincipalName,
188
+ }));
189
+ },
143
190
  },
144
- async twitter({ accessToken, query, providers }) {
145
- const twitter = purest({
146
- provider: 'twitter',
147
- defaults: {
148
- oauth: {
149
- consumer_key: providers.twitter.key,
150
- consumer_secret: providers.twitter.secret,
191
+
192
+ twitter: {
193
+ enabled: false,
194
+ icon: 'twitter',
195
+ grantConfig: {
196
+ key: '',
197
+ secret: '',
198
+ callbackUrl: `${baseURL}/twitter/callback`,
199
+ },
200
+ async authCallback({ accessToken, query, providers }) {
201
+ const twitter = purest({
202
+ provider: 'twitter',
203
+ defaults: {
204
+ oauth: {
205
+ consumer_key: providers.twitter.key,
206
+ consumer_secret: providers.twitter.secret,
207
+ },
151
208
  },
152
- },
153
- });
209
+ });
154
210
 
155
- return twitter
156
- .get('account/verify_credentials')
157
- .auth(accessToken, query.access_secret)
158
- .qs({ screen_name: query['raw[screen_name]'], include_email: 'true' })
159
- .request()
160
- .then(({ body }) => ({
161
- username: body.screen_name,
162
- email: body.email,
163
- }));
211
+ return twitter
212
+ .get('account/verify_credentials')
213
+ .auth(accessToken, query.access_secret)
214
+ .qs({ screen_name: query['raw[screen_name]'], include_email: 'true' })
215
+ .request()
216
+ .then(({ body }) => ({
217
+ username: body.screen_name,
218
+ email: body.email,
219
+ }));
220
+ },
164
221
  },
165
- async instagram({ accessToken }) {
166
- const instagram = purest({ provider: 'instagram' });
167
-
168
- return instagram
169
- .get('me')
170
- .auth(accessToken)
171
- .qs({ fields: 'id,username' })
172
- .request()
173
- .then(({ body }) => ({
174
- username: body.username,
175
- email: `${body.username}@strapi.io`, // dummy email as Instagram does not provide user email
176
- }));
222
+ instagram: {
223
+ enabled: false,
224
+ icon: 'instagram',
225
+ grantConfig: {
226
+ key: '',
227
+ secret: '',
228
+ callbackUrl: `${baseURL}/instagram/callback`,
229
+ scope: ['user_profile'],
230
+ },
231
+ async authCallback({ accessToken }) {
232
+ const instagram = purest({ provider: 'instagram' });
233
+
234
+ return instagram
235
+ .get('me')
236
+ .auth(accessToken)
237
+ .qs({ fields: 'id,username' })
238
+ .request()
239
+ .then(({ body }) => ({
240
+ username: body.username,
241
+ email: `${body.username}@strapi.io`, // dummy email as Instagram does not provide user email
242
+ }));
243
+ },
177
244
  },
178
- async vk({ accessToken, query }) {
179
- const vk = purest({ provider: 'vk' });
180
-
181
- return vk
182
- .get('users')
183
- .auth(accessToken)
184
- .qs({ id: query.raw.user_id, v: '5.122' })
185
- .request()
186
- .then(({ body }) => ({
187
- username: `${body.response[0].last_name} ${body.response[0].first_name}`,
188
- email: query.raw.email,
189
- }));
245
+ vk: {
246
+ enabled: false,
247
+ icon: 'vk',
248
+ grantConfig: {
249
+ key: '',
250
+ secret: '',
251
+ callbackUrl: `${baseURL}/vk/callback`,
252
+ scope: ['email'],
253
+ },
254
+ async authCallback({ accessToken, query }) {
255
+ const vk = purest({ provider: 'vk' });
256
+
257
+ return vk
258
+ .get('users')
259
+ .auth(accessToken)
260
+ .qs({ id: query.raw.user_id, v: '5.122' })
261
+ .request()
262
+ .then(({ body }) => ({
263
+ username: `${body.response[0].last_name} ${body.response[0].first_name}`,
264
+ email: query.raw.email,
265
+ }));
266
+ },
190
267
  },
191
- async twitch({ accessToken, providers }) {
192
- const twitch = purest({
193
- provider: 'twitch',
194
- config: {
195
- twitch: {
196
- default: {
197
- origin: 'https://api.twitch.tv',
198
- path: 'helix/{path}',
199
- headers: {
200
- Authorization: 'Bearer {auth}',
201
- 'Client-Id': '{auth}',
268
+
269
+ twitch: {
270
+ enabled: false,
271
+ icon: 'twitch',
272
+ grantConfig: {
273
+ key: '',
274
+ secret: '',
275
+ callbackUrl: `${baseURL}/twitch/callback`,
276
+ scope: ['user:read:email'],
277
+ },
278
+ async authCallback({ accessToken, providers }) {
279
+ const twitch = purest({
280
+ provider: 'twitch',
281
+ config: {
282
+ twitch: {
283
+ default: {
284
+ origin: 'https://api.twitch.tv',
285
+ path: 'helix/{path}',
286
+ headers: {
287
+ Authorization: 'Bearer {auth}',
288
+ 'Client-Id': '{auth}',
289
+ },
202
290
  },
203
291
  },
204
292
  },
205
- },
206
- });
293
+ });
207
294
 
208
- return twitch
209
- .get('users')
210
- .auth(accessToken, providers.twitch.key)
211
- .request()
212
- .then(({ body }) => ({
213
- username: body.data[0].login,
214
- email: body.data[0].email,
215
- }));
295
+ return twitch
296
+ .get('users')
297
+ .auth(accessToken, providers.twitch.key)
298
+ .request()
299
+ .then(({ body }) => ({
300
+ username: body.data[0].login,
301
+ email: body.data[0].email,
302
+ }));
303
+ },
216
304
  },
217
- async linkedin({ accessToken }) {
218
- const linkedIn = purest({ provider: 'linkedin' });
219
- const {
220
- body: { localizedFirstName },
221
- } = await linkedIn.get('me').auth(accessToken).request();
222
- const {
223
- body: { elements },
224
- } = await linkedIn
225
- .get('emailAddress?q=members&projection=(elements*(handle~))')
226
- .auth(accessToken)
227
- .request();
228
-
229
- const email = elements[0]['handle~'];
230
-
231
- return {
232
- username: localizedFirstName,
233
- email: email.emailAddress,
234
- };
305
+
306
+ linkedin: {
307
+ enabled: false,
308
+ icon: 'linkedin',
309
+ grantConfig: {
310
+ key: '',
311
+ secret: '',
312
+ callbackUrl: `${baseURL}/linkedin/callback`,
313
+ scope: ['r_liteprofile', 'r_emailaddress'],
314
+ },
315
+ async authCallback({ accessToken }) {
316
+ const linkedIn = purest({ provider: 'linkedin' });
317
+ const {
318
+ body: { localizedFirstName },
319
+ } = await linkedIn.get('me').auth(accessToken).request();
320
+ const {
321
+ body: { elements },
322
+ } = await linkedIn
323
+ .get('emailAddress?q=members&projection=(elements*(handle~))')
324
+ .auth(accessToken)
325
+ .request();
326
+
327
+ const email = elements[0]['handle~'];
328
+
329
+ return {
330
+ username: localizedFirstName,
331
+ email: email.emailAddress,
332
+ };
333
+ },
334
+ },
335
+
336
+ cognito: {
337
+ enabled: false,
338
+ icon: 'aws',
339
+ grantConfig: {
340
+ key: '',
341
+ secret: '',
342
+ subdomain: 'my.subdomain.com',
343
+ callback: `${baseURL}/cognito/callback`,
344
+ scope: ['email', 'openid', 'profile'],
345
+ },
346
+ async authCallback({ query, providers }) {
347
+ const jwksUrl = new URL(providers.cognito.jwksurl);
348
+ const idToken = query.id_token;
349
+ const tokenPayload = await getCognitoPayload({ idToken, jwksUrl, purest });
350
+ return {
351
+ username: tokenPayload['cognito:username'],
352
+ email: tokenPayload.email,
353
+ };
354
+ },
235
355
  },
236
- async reddit({ accessToken }) {
237
- const reddit = purest({
238
- provider: 'reddit',
239
- config: {
240
- reddit: {
241
- default: {
242
- origin: 'https://oauth.reddit.com',
243
- path: 'api/{version}/{path}',
244
- version: 'v1',
245
- headers: {
246
- Authorization: 'Bearer {auth}',
247
- 'user-agent': 'strapi',
356
+
357
+ reddit: {
358
+ enabled: false,
359
+ icon: 'reddit',
360
+ grantConfig: {
361
+ key: '',
362
+ secret: '',
363
+ callback: `${baseURL}/reddit/callback`,
364
+ scope: ['identity'],
365
+ },
366
+ async authCallback({ accessToken }) {
367
+ const reddit = purest({
368
+ provider: 'reddit',
369
+ config: {
370
+ reddit: {
371
+ default: {
372
+ origin: 'https://oauth.reddit.com',
373
+ path: 'api/{version}/{path}',
374
+ version: 'v1',
375
+ headers: {
376
+ Authorization: 'Bearer {auth}',
377
+ 'user-agent': 'strapi',
378
+ },
248
379
  },
249
380
  },
250
381
  },
251
- },
252
- });
382
+ });
253
383
 
254
- return reddit
255
- .get('me')
256
- .auth(accessToken)
257
- .request()
258
- .then(({ body }) => ({
259
- username: body.name,
260
- email: `${body.name}@strapi.io`, // dummy email as Reddit does not provide user email
261
- }));
384
+ return reddit
385
+ .get('me')
386
+ .auth(accessToken)
387
+ .request()
388
+ .then(({ body }) => ({
389
+ username: body.name,
390
+ email: `${body.name}@strapi.io`, // dummy email as Reddit does not provide user email
391
+ }));
392
+ },
262
393
  },
263
- async auth0({ accessToken, providers }) {
264
- const auth0 = purest({ provider: 'auth0' });
265
-
266
- return auth0
267
- .get('userinfo')
268
- .subdomain(providers.auth0.subdomain)
269
- .auth(accessToken)
270
- .request()
271
- .then(({ body }) => {
272
- const username = body.username || body.nickname || body.name || body.email.split('@')[0];
273
- const email = body.email || `${username.replace(/\s+/g, '.')}@strapi.io`;
274
394
 
275
- return {
276
- username,
277
- email,
278
- };
279
- });
395
+ auth0: {
396
+ enabled: false,
397
+ icon: '',
398
+ grantConfig: {
399
+ key: '',
400
+ secret: '',
401
+ subdomain: 'my-tenant.eu',
402
+ callback: `${baseURL}/auth0/callback`,
403
+ scope: ['openid', 'email', 'profile'],
404
+ },
405
+ async authCallback({ accessToken, providers }) {
406
+ const auth0 = purest({ provider: 'auth0' });
407
+
408
+ return auth0
409
+ .get('userinfo')
410
+ .subdomain(providers.auth0.subdomain)
411
+ .auth(accessToken)
412
+ .request()
413
+ .then(({ body }) => {
414
+ const username = body.username || body.nickname || body.name || body.email.split('@')[0];
415
+ const email = body.email || `${username.replace(/\s+/g, '.')}@strapi.io`;
416
+
417
+ return {
418
+ username,
419
+ email,
420
+ };
421
+ });
422
+ },
280
423
  },
281
- async cas({ accessToken, providers }) {
282
- const cas = purest({ provider: 'cas' });
283
-
284
- return cas
285
- .get('oidc/profile')
286
- .subdomain(providers.cas.subdomain)
287
- .auth(accessToken)
288
- .request()
289
- .then(({ body }) => {
290
- // CAS attribute may be in body.attributes or "FLAT", depending on CAS config
291
- const username = body.attributes
292
- ? body.attributes.strapiusername || body.id || body.sub
293
- : body.strapiusername || body.id || body.sub;
294
- const email = body.attributes
295
- ? body.attributes.strapiemail || body.attributes.email
296
- : body.strapiemail || body.email;
297
- if (!username || !email) {
298
- strapi.log.warn(
299
- `CAS Response Body did not contain required attributes: ${JSON.stringify(body)}`
300
- );
301
- }
302
- return {
303
- username,
304
- email,
305
- };
306
- });
424
+
425
+ cas: {
426
+ enabled: false,
427
+ icon: 'book',
428
+ grantConfig: {
429
+ key: '',
430
+ secret: '',
431
+ callback: `${baseURL}/cas/callback`,
432
+ scope: ['openid email'], // scopes should be space delimited
433
+ subdomain: 'my.subdomain.com/cas',
434
+ },
435
+ async authCallback({ accessToken, providers }) {
436
+ const cas = purest({ provider: 'cas' });
437
+
438
+ return cas
439
+ .get('oidc/profile')
440
+ .subdomain(providers.cas.subdomain)
441
+ .auth(accessToken)
442
+ .request()
443
+ .then(({ body }) => {
444
+ // CAS attribute may be in body.attributes or "FLAT", depending on CAS config
445
+ const username = body.attributes
446
+ ? body.attributes.strapiusername || body.id || body.sub
447
+ : body.strapiusername || body.id || body.sub;
448
+ const email = body.attributes
449
+ ? body.attributes.strapiemail || body.attributes.email
450
+ : body.strapiemail || body.email;
451
+ if (!username || !email) {
452
+ strapi.log.warn(
453
+ `CAS Response Body did not contain required attributes: ${JSON.stringify(body)}`
454
+ );
455
+ }
456
+ return {
457
+ username,
458
+ email,
459
+ };
460
+ });
461
+ },
307
462
  },
308
- async patreon({ accessToken }) {
309
- const patreon = purest({
310
- provider: 'patreon',
311
- config: {
312
- patreon: {
313
- default: {
314
- origin: 'https://www.patreon.com',
315
- path: 'api/oauth2/{path}',
316
- headers: {
317
- 'user-agent': 'strapi',
318
- authorization: 'Bearer {auth}',
463
+
464
+ patreon: {
465
+ enabled: false,
466
+ icon: '',
467
+ grantConfig: {
468
+ key: '',
469
+ secret: '',
470
+ callback: `${baseURL}/patreon/callback`,
471
+ scope: ['identity', 'identity[email]'],
472
+ },
473
+ async authCallback({ accessToken }) {
474
+ const patreon = purest({
475
+ provider: 'patreon',
476
+ config: {
477
+ patreon: {
478
+ default: {
479
+ origin: 'https://www.patreon.com',
480
+ path: 'api/oauth2/{path}',
481
+ headers: {
482
+ authorization: 'Bearer {auth}',
483
+ },
319
484
  },
320
485
  },
321
486
  },
322
- },
323
- });
324
-
325
- return patreon
326
- .get('v2/identity')
327
- .auth(accessToken)
328
- .qs(new URLSearchParams({ 'fields[user]': 'full_name,email' }).toString())
329
- .request()
330
- .then(({ body }) => {
331
- const patreonData = body.data.attributes;
332
- return {
333
- username: patreonData.full_name,
334
- email: patreonData.email,
335
- };
336
487
  });
488
+
489
+ return patreon
490
+ .get('v2/identity')
491
+ .auth(accessToken)
492
+ .qs(new URLSearchParams({ 'fields[user]': 'full_name,email' }).toString())
493
+ .request()
494
+ .then(({ body }) => {
495
+ const patreonData = body.data.attributes;
496
+ return {
497
+ username: patreonData.full_name,
498
+ email: patreonData.email,
499
+ };
500
+ });
501
+ },
337
502
  },
338
- async keycloak({ accessToken, providers }) {
339
- const keycloak = purest({ provider: 'keycloak' });
340
-
341
- return keycloak
342
- .subdomain(providers.keycloak.subdomain)
343
- .get('protocol/openid-connect/userinfo')
344
- .auth(accessToken)
345
- .request()
346
- .then(({ body }) => {
347
- return {
348
- username: body.preferred_username,
349
- email: body.email,
350
- };
351
- });
503
+ keycloak: {
504
+ enabled: false,
505
+ icon: '',
506
+ grantConfig: {
507
+ key: '',
508
+ secret: '',
509
+ subdomain: 'myKeycloakProvider.com/realms/myrealm',
510
+ callback: `${baseURL}/keycloak/callback`,
511
+ scope: ['openid', 'email', 'profile'],
512
+ },
513
+ async authCallback({ accessToken, providers }) {
514
+ const keycloak = purest({ provider: 'keycloak' });
515
+
516
+ return keycloak
517
+ .subdomain(providers.keycloak.subdomain)
518
+ .get('protocol/openid-connect/userinfo')
519
+ .auth(accessToken)
520
+ .request()
521
+ .then(({ body }) => {
522
+ return {
523
+ username: body.preferred_username,
524
+ email: body.email,
525
+ };
526
+ });
527
+ },
352
528
  },
353
529
  });
354
530
 
355
531
  module.exports = () => {
356
532
  const purest = require('purest');
357
533
 
358
- const providersCallbacks = getInitialProviders({ purest });
534
+ const apiPrefix = strapi.config.get('api.rest.prefix');
535
+ const baseURL = urljoin(strapi.config.server.url, apiPrefix, 'auth');
359
536
 
360
- return {
361
- register(providerName, provider) {
362
- assert(typeof providerName === 'string', 'Provider name must be a string');
363
- assert(typeof provider === 'function', 'Provider callback must be a function');
537
+ const authProviders = initProviders({ baseURL, purest });
364
538
 
365
- providersCallbacks[providerName] = provider({ purest });
539
+ /**
540
+ * @public
541
+ */
542
+ return {
543
+ getAll() {
544
+ return authProviders;
545
+ },
546
+ get(name) {
547
+ return authProviders[name];
548
+ },
549
+ add(name, config) {
550
+ authProviders[name] = config;
551
+ },
552
+ remove(name) {
553
+ delete authProviders[name];
366
554
  },
367
555
 
556
+ /**
557
+ * @internal
558
+ */
368
559
  async run({ provider, accessToken, query, providers }) {
369
- if (!providersCallbacks[provider]) {
370
- throw new Error('Unknown provider.');
371
- }
560
+ const authProvider = authProviders[provider];
372
561
 
373
- const providerCb = providersCallbacks[provider];
562
+ assert(authProvider, 'Unknown auth provider');
374
563
 
375
- return providerCb({ accessToken, query, providers });
564
+ return authProvider.authCallback({ accessToken, query, providers, purest });
376
565
  },
377
566
  };
378
567
  };