@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.
- package/dist/_chunks/{index-gEkbV4F9.mjs → index--wWLZAMs.mjs} +2 -2
- package/dist/_chunks/{index-gEkbV4F9.mjs.map → index--wWLZAMs.mjs.map} +1 -1
- package/dist/_chunks/{index-TXvCramy.mjs → index-7jtnDf4p.mjs} +2 -2
- package/dist/_chunks/{index-TXvCramy.mjs.map → index-7jtnDf4p.mjs.map} +1 -1
- package/dist/_chunks/{index-b4wChiEY.js → index-8kzrt70D.js} +2 -2
- package/dist/_chunks/{index-b4wChiEY.js.map → index-8kzrt70D.js.map} +1 -1
- package/dist/_chunks/{index-eDOLWAV7.js → index-DiW6ewR1.js} +10 -10
- package/dist/_chunks/{index-eDOLWAV7.js.map → index-DiW6ewR1.js.map} +1 -1
- package/dist/_chunks/{index-6vUdu8my.js → index-JrkD5bN5.js} +2 -2
- package/dist/_chunks/{index-6vUdu8my.js.map → index-JrkD5bN5.js.map} +1 -1
- package/dist/_chunks/{index-KGe8mvqZ.js → index-UDmr9bPp.js} +2 -2
- package/dist/_chunks/{index-KGe8mvqZ.js.map → index-UDmr9bPp.js.map} +1 -1
- package/dist/_chunks/{index-gUNfzF88.mjs → index-l5A7Tjiq.mjs} +10 -10
- package/dist/_chunks/{index-gUNfzF88.mjs.map → index-l5A7Tjiq.mjs.map} +1 -1
- package/dist/_chunks/{index-_PJkAU_B.js → index-pEEKO4Ga.js} +2 -2
- package/dist/_chunks/{index-_PJkAU_B.js.map → index-pEEKO4Ga.js.map} +1 -1
- package/dist/_chunks/{index-oL1A5ghB.mjs → index-vRjKW1Li.mjs} +2 -2
- package/dist/_chunks/{index-oL1A5ghB.mjs.map → index-vRjKW1Li.mjs.map} +1 -1
- package/dist/_chunks/{index-rlXIaWJh.mjs → index-yYLeDDYr.mjs} +2 -2
- package/dist/_chunks/{index-rlXIaWJh.mjs.map → index-yYLeDDYr.mjs.map} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/package.json +6 -6
- package/server/bootstrap/index.js +13 -9
- package/server/services/providers-registry.js +468 -279
- package/server/utils/index.d.ts +2 -1
- 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
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
.
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
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
|
|
534
|
+
const apiPrefix = strapi.config.get('api.rest.prefix');
|
|
535
|
+
const baseURL = urljoin(strapi.config.server.url, apiPrefix, 'auth');
|
|
359
536
|
|
|
360
|
-
|
|
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
|
-
|
|
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
|
-
|
|
370
|
-
throw new Error('Unknown provider.');
|
|
371
|
-
}
|
|
560
|
+
const authProvider = authProviders[provider];
|
|
372
561
|
|
|
373
|
-
|
|
562
|
+
assert(authProvider, 'Unknown auth provider');
|
|
374
563
|
|
|
375
|
-
return
|
|
564
|
+
return authProvider.authCallback({ accessToken, query, providers, purest });
|
|
376
565
|
},
|
|
377
566
|
};
|
|
378
567
|
};
|