@strapi/plugin-users-permissions 4.0.0-next.6 → 4.0.0

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 (196) hide show
  1. package/admin/src/components/BoundRoute/getMethodColor.js +41 -0
  2. package/admin/src/components/BoundRoute/index.js +40 -24
  3. package/admin/src/components/FormModal/Input/index.js +121 -0
  4. package/admin/src/components/FormModal/index.js +123 -0
  5. package/admin/src/components/Permissions/PermissionRow/CheckboxWrapper.js +19 -26
  6. package/admin/src/components/Permissions/PermissionRow/SubCategory.js +118 -0
  7. package/admin/src/components/Permissions/PermissionRow/index.js +9 -48
  8. package/admin/src/components/Permissions/index.js +36 -24
  9. package/admin/src/components/Permissions/init.js +1 -6
  10. package/admin/src/components/Policies/index.js +46 -47
  11. package/admin/src/components/UsersPermissions/index.js +29 -26
  12. package/admin/src/components/UsersPermissions/init.js +1 -2
  13. package/admin/src/hooks/useFetchRole/index.js +17 -7
  14. package/admin/src/hooks/useForm/index.js +3 -29
  15. package/admin/src/hooks/useForm/reducer.js +2 -21
  16. package/admin/src/hooks/usePlugins/index.js +12 -21
  17. package/admin/src/hooks/usePlugins/reducer.js +0 -3
  18. package/admin/src/index.js +29 -34
  19. package/admin/src/pages/AdvancedSettings/index.js +210 -193
  20. package/admin/src/pages/AdvancedSettings/utils/api.js +13 -0
  21. package/admin/src/pages/AdvancedSettings/utils/layout.js +96 -0
  22. package/admin/src/pages/AdvancedSettings/utils/schema.js +22 -0
  23. package/admin/src/pages/EmailTemplates/components/EmailForm.js +173 -0
  24. package/admin/src/pages/EmailTemplates/components/EmailTable.js +116 -0
  25. package/admin/src/pages/EmailTemplates/index.js +125 -198
  26. package/admin/src/pages/EmailTemplates/utils/api.js +13 -0
  27. package/admin/src/pages/Providers/index.js +208 -216
  28. package/admin/src/pages/Providers/utils/api.js +21 -0
  29. package/admin/src/pages/Providers/utils/forms.js +168 -126
  30. package/admin/src/pages/Roles/CreatePage/index.js +155 -147
  31. package/admin/src/pages/Roles/EditPage/index.js +162 -134
  32. package/admin/src/pages/Roles/ListPage/components/TableBody.js +96 -0
  33. package/admin/src/pages/Roles/ListPage/index.js +176 -156
  34. package/admin/src/pages/Roles/ListPage/utils/api.js +28 -0
  35. package/admin/src/pages/Roles/index.js +14 -8
  36. package/admin/src/permissions.js +12 -14
  37. package/admin/src/translations/ar.json +0 -8
  38. package/admin/src/translations/cs.json +0 -8
  39. package/admin/src/translations/de.json +0 -8
  40. package/admin/src/translations/dk.json +0 -8
  41. package/admin/src/translations/en.json +33 -12
  42. package/admin/src/translations/es.json +0 -8
  43. package/admin/src/translations/fr.json +0 -8
  44. package/admin/src/translations/id.json +0 -8
  45. package/admin/src/translations/it.json +0 -8
  46. package/admin/src/translations/ja.json +0 -8
  47. package/admin/src/translations/ko.json +0 -8
  48. package/admin/src/translations/ms.json +0 -8
  49. package/admin/src/translations/nl.json +0 -8
  50. package/admin/src/translations/pl.json +0 -8
  51. package/admin/src/translations/pt-BR.json +0 -8
  52. package/admin/src/translations/pt.json +0 -8
  53. package/admin/src/translations/ru.json +0 -8
  54. package/admin/src/translations/sk.json +0 -8
  55. package/admin/src/translations/sv.json +0 -8
  56. package/admin/src/translations/th.json +0 -8
  57. package/admin/src/translations/tr.json +0 -8
  58. package/admin/src/translations/uk.json +0 -8
  59. package/admin/src/translations/vi.json +0 -8
  60. package/admin/src/translations/zh-Hans.json +5 -14
  61. package/admin/src/translations/zh.json +0 -8
  62. package/admin/src/utils/axiosInstance.js +36 -0
  63. package/admin/src/utils/formatPluginName.js +26 -0
  64. package/admin/src/utils/index.js +1 -0
  65. package/documentation/1.0.0/overrides/users-permissions-Role.json +6 -6
  66. package/documentation/1.0.0/overrides/users-permissions-User.json +7 -7
  67. package/package.json +30 -29
  68. package/{config/functions/bootstrap.js → server/bootstrap/index.js} +26 -33
  69. package/{config → server/bootstrap}/users-permissions-actions.js +0 -0
  70. package/server/config.js +23 -0
  71. package/server/content-types/index.js +11 -0
  72. package/server/content-types/permission/index.js +34 -0
  73. package/server/content-types/role/index.js +51 -0
  74. package/server/content-types/user/index.js +72 -0
  75. package/{models/User.config.js → server/content-types/user/schema-config.js} +0 -0
  76. package/server/controllers/auth.js +440 -0
  77. package/server/controllers/content-manager-user.js +183 -0
  78. package/server/controllers/index.js +17 -0
  79. package/server/controllers/permissions.js +26 -0
  80. package/server/controllers/role.js +77 -0
  81. package/server/controllers/settings.js +85 -0
  82. package/server/controllers/user.js +191 -0
  83. package/server/controllers/validation/auth.js +29 -0
  84. package/{controllers → server/controllers}/validation/email-template.js +0 -0
  85. package/server/controllers/validation/user.js +38 -0
  86. package/server/graphql/index.js +44 -0
  87. package/server/graphql/mutations/auth/email-confirmation.js +39 -0
  88. package/server/graphql/mutations/auth/forgot-password.js +38 -0
  89. package/server/graphql/mutations/auth/login.js +38 -0
  90. package/server/graphql/mutations/auth/register.js +39 -0
  91. package/server/graphql/mutations/auth/reset-password.js +41 -0
  92. package/server/graphql/mutations/crud/role/create-role.js +37 -0
  93. package/server/graphql/mutations/crud/role/delete-role.js +28 -0
  94. package/server/graphql/mutations/crud/role/update-role.js +38 -0
  95. package/server/graphql/mutations/crud/user/create-user.js +48 -0
  96. package/server/graphql/mutations/crud/user/delete-user.js +42 -0
  97. package/server/graphql/mutations/crud/user/update-user.js +49 -0
  98. package/server/graphql/mutations/index.js +42 -0
  99. package/server/graphql/queries/index.js +13 -0
  100. package/server/graphql/queries/me.js +17 -0
  101. package/server/graphql/resolvers-configs.js +37 -0
  102. package/server/graphql/types/create-role-payload.js +11 -0
  103. package/server/graphql/types/delete-role-payload.js +11 -0
  104. package/server/graphql/types/index.js +21 -0
  105. package/server/graphql/types/login-input.js +13 -0
  106. package/server/graphql/types/login-payload.js +12 -0
  107. package/server/graphql/types/me-role.js +14 -0
  108. package/server/graphql/types/me.js +16 -0
  109. package/server/graphql/types/password-payload.js +11 -0
  110. package/server/graphql/types/register-input.js +13 -0
  111. package/server/graphql/types/update-role-payload.js +11 -0
  112. package/server/graphql/utils.js +27 -0
  113. package/server/index.js +21 -0
  114. package/server/middlewares/index.js +7 -0
  115. package/{config/policies → server/middlewares}/rateLimit.js +4 -8
  116. package/server/register.js +11 -0
  117. package/server/routes/admin/index.js +10 -0
  118. package/server/routes/admin/permissions.js +20 -0
  119. package/server/routes/admin/role.js +79 -0
  120. package/server/routes/admin/settings.js +95 -0
  121. package/server/routes/content-api/auth.js +73 -0
  122. package/server/routes/content-api/index.js +11 -0
  123. package/server/routes/content-api/permissions.js +9 -0
  124. package/server/routes/content-api/role.js +29 -0
  125. package/server/routes/content-api/user.js +61 -0
  126. package/server/routes/index.js +6 -0
  127. package/server/services/index.js +15 -0
  128. package/server/services/jwt.js +55 -0
  129. package/server/services/providers.js +599 -0
  130. package/server/services/role.js +177 -0
  131. package/{services → server/services}/user.js +32 -35
  132. package/server/services/users-permissions.js +233 -0
  133. package/server/strategies/users-permissions.js +123 -0
  134. package/{utils → server/utils}/index.d.ts +6 -1
  135. package/server/utils/index.js +9 -0
  136. package/strapi-admin.js +3 -0
  137. package/strapi-server.js +3 -0
  138. package/admin/src/assets/images/logo.svg +0 -1
  139. package/admin/src/components/BaselineAlignement/index.js +0 -33
  140. package/admin/src/components/Bloc/index.js +0 -10
  141. package/admin/src/components/BoundRoute/Components.js +0 -78
  142. package/admin/src/components/ContainerFluid/index.js +0 -13
  143. package/admin/src/components/FormBloc/index.js +0 -61
  144. package/admin/src/components/IntlInput/index.js +0 -38
  145. package/admin/src/components/ListBaselineAlignment/index.js +0 -8
  146. package/admin/src/components/ListRow/Components.js +0 -74
  147. package/admin/src/components/ListRow/index.js +0 -35
  148. package/admin/src/components/ModalForm/Wrapper.js +0 -12
  149. package/admin/src/components/ModalForm/index.js +0 -59
  150. package/admin/src/components/Permissions/ListWrapper.js +0 -9
  151. package/admin/src/components/Permissions/PermissionRow/BaselineAlignment.js +0 -7
  152. package/admin/src/components/Permissions/PermissionRow/RowStyle.js +0 -28
  153. package/admin/src/components/Permissions/PermissionRow/SubCategory/ConditionsButtonWrapper.js +0 -13
  154. package/admin/src/components/Permissions/PermissionRow/SubCategory/PolicyWrapper.js +0 -8
  155. package/admin/src/components/Permissions/PermissionRow/SubCategory/SubCategoryWrapper.js +0 -26
  156. package/admin/src/components/Permissions/PermissionRow/SubCategory/index.js +0 -116
  157. package/admin/src/components/Policies/Components.js +0 -26
  158. package/admin/src/components/PrefixedIcon/index.js +0 -27
  159. package/admin/src/components/Roles/EmptyRole/BaselineAlignment.js +0 -7
  160. package/admin/src/components/Roles/EmptyRole/index.js +0 -27
  161. package/admin/src/components/Roles/RoleListWrapper/index.js +0 -17
  162. package/admin/src/components/Roles/RoleRow/RoleDescription.js +0 -9
  163. package/admin/src/components/Roles/RoleRow/index.js +0 -45
  164. package/admin/src/components/Roles/index.js +0 -3
  165. package/admin/src/components/SizedInput/index.js +0 -24
  166. package/admin/src/pages/AdvancedSettings/reducer.js +0 -65
  167. package/admin/src/pages/AdvancedSettings/utils/form.js +0 -52
  168. package/admin/src/pages/EmailTemplates/CustomTextInput.js +0 -105
  169. package/admin/src/pages/EmailTemplates/Wrapper.js +0 -36
  170. package/admin/src/pages/EmailTemplates/reducer.js +0 -58
  171. package/admin/src/pages/EmailTemplates/utils/forms.js +0 -81
  172. package/admin/src/pages/Roles/ListPage/BaselineAlignment.js +0 -8
  173. package/config/layout.js +0 -10
  174. package/config/policies/isAuthenticated.js +0 -9
  175. package/config/policies/permissions.js +0 -94
  176. package/config/request.json +0 -6
  177. package/config/routes.json +0 -381
  178. package/config/schema.graphql.js +0 -284
  179. package/config/security.json +0 -5
  180. package/controllers/auth.js +0 -596
  181. package/controllers/user/admin.js +0 -230
  182. package/controllers/user/api.js +0 -174
  183. package/controllers/user.js +0 -117
  184. package/controllers/users-permissions.js +0 -271
  185. package/middlewares/users-permissions/defaults.json +0 -5
  186. package/middlewares/users-permissions/index.js +0 -40
  187. package/models/Permission.js +0 -7
  188. package/models/Permission.settings.json +0 -45
  189. package/models/Role.js +0 -7
  190. package/models/Role.settings.json +0 -43
  191. package/models/User.js +0 -7
  192. package/models/User.settings.json +0 -63
  193. package/services/jwt.js +0 -65
  194. package/services/providers.js +0 -598
  195. package/services/users-permissions.js +0 -429
  196. package/utils/index.js +0 -11
@@ -0,0 +1,599 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Module dependencies.
5
+ */
6
+
7
+ // Public node modules.
8
+ const _ = require('lodash');
9
+ const jwt = require('jsonwebtoken');
10
+ const urlJoin = require('url-join');
11
+
12
+ const { getAbsoluteServerUrl } = require('@strapi/utils');
13
+
14
+ module.exports = ({ strapi }) => {
15
+ // lazy load heavy dependencies
16
+ const request = require('request');
17
+ // Purest strategies.
18
+ const purest = require('purest')({ request });
19
+ const purestConfig = require('@purest/providers');
20
+
21
+ /**
22
+ * Helper to get profiles
23
+ *
24
+ * @param {String} provider
25
+ * @param {Function} callback
26
+ */
27
+
28
+ const getProfile = async (provider, query, callback) => {
29
+ const access_token = query.access_token || query.code || query.oauth_token;
30
+
31
+ const providers = await strapi
32
+ .store({ type: 'plugin', name: 'users-permissions', key: 'grant' })
33
+ .get();
34
+
35
+ switch (provider) {
36
+ case 'discord': {
37
+ const discord = purest({
38
+ provider: 'discord',
39
+ config: {
40
+ discord: {
41
+ 'https://discordapp.com/api/': {
42
+ __domain: {
43
+ auth: {
44
+ auth: { bearer: '[0]' },
45
+ },
46
+ },
47
+ '{endpoint}': {
48
+ __path: {
49
+ alias: '__default',
50
+ },
51
+ },
52
+ },
53
+ },
54
+ },
55
+ });
56
+ discord
57
+ .query()
58
+ .get('users/@me')
59
+ .auth(access_token)
60
+ .request((err, res, body) => {
61
+ if (err) {
62
+ callback(err);
63
+ } else {
64
+ // Combine username and discriminator because discord username is not unique
65
+ var username = `${body.username}#${body.discriminator}`;
66
+ callback(null, {
67
+ username,
68
+ email: body.email,
69
+ });
70
+ }
71
+ });
72
+ break;
73
+ }
74
+ case 'cognito': {
75
+ // get the id_token
76
+ const idToken = query.id_token;
77
+ // decode the jwt token
78
+ const tokenPayload = jwt.decode(idToken);
79
+ if (!tokenPayload) {
80
+ callback(new Error('unable to decode jwt token'));
81
+ } else {
82
+ callback(null, {
83
+ username: tokenPayload['cognito:username'],
84
+ email: tokenPayload.email,
85
+ });
86
+ }
87
+ break;
88
+ }
89
+ case 'facebook': {
90
+ const facebook = purest({
91
+ provider: 'facebook',
92
+ config: purestConfig,
93
+ });
94
+
95
+ facebook
96
+ .query()
97
+ .get('me?fields=name,email')
98
+ .auth(access_token)
99
+ .request((err, res, body) => {
100
+ if (err) {
101
+ callback(err);
102
+ } else {
103
+ callback(null, {
104
+ username: body.name,
105
+ email: body.email,
106
+ });
107
+ }
108
+ });
109
+ break;
110
+ }
111
+ case 'google': {
112
+ const google = purest({ provider: 'google', config: purestConfig });
113
+
114
+ google
115
+ .query('oauth')
116
+ .get('tokeninfo')
117
+ .qs({ access_token })
118
+ .request((err, res, body) => {
119
+ if (err) {
120
+ callback(err);
121
+ } else {
122
+ callback(null, {
123
+ username: body.email.split('@')[0],
124
+ email: body.email,
125
+ });
126
+ }
127
+ });
128
+ break;
129
+ }
130
+ case 'github': {
131
+ const github = purest({
132
+ provider: 'github',
133
+ config: purestConfig,
134
+ defaults: {
135
+ headers: {
136
+ 'user-agent': 'strapi',
137
+ },
138
+ },
139
+ });
140
+
141
+ github
142
+ .query()
143
+ .get('user')
144
+ .auth(access_token)
145
+ .request((err, res, userbody) => {
146
+ if (err) {
147
+ return callback(err);
148
+ }
149
+
150
+ // This is the public email on the github profile
151
+ if (userbody.email) {
152
+ return callback(null, {
153
+ username: userbody.login,
154
+ email: userbody.email,
155
+ });
156
+ }
157
+
158
+ // Get the email with Github's user/emails API
159
+ github
160
+ .query()
161
+ .get('user/emails')
162
+ .auth(access_token)
163
+ .request((err, res, emailsbody) => {
164
+ if (err) {
165
+ return callback(err);
166
+ }
167
+
168
+ return callback(null, {
169
+ username: userbody.login,
170
+ email: Array.isArray(emailsbody)
171
+ ? emailsbody.find(email => email.primary === true).email
172
+ : null,
173
+ });
174
+ });
175
+ });
176
+ break;
177
+ }
178
+ case 'microsoft': {
179
+ const microsoft = purest({
180
+ provider: 'microsoft',
181
+ config: purestConfig,
182
+ });
183
+
184
+ microsoft
185
+ .query()
186
+ .get('me')
187
+ .auth(access_token)
188
+ .request((err, res, body) => {
189
+ if (err) {
190
+ callback(err);
191
+ } else {
192
+ callback(null, {
193
+ username: body.userPrincipalName,
194
+ email: body.userPrincipalName,
195
+ });
196
+ }
197
+ });
198
+ break;
199
+ }
200
+ case 'twitter': {
201
+ const twitter = purest({
202
+ provider: 'twitter',
203
+ config: purestConfig,
204
+ key: providers.twitter.key,
205
+ secret: providers.twitter.secret,
206
+ });
207
+
208
+ twitter
209
+ .query()
210
+ .get('account/verify_credentials')
211
+ .auth(access_token, query.access_secret)
212
+ .qs({ screen_name: query['raw[screen_name]'], include_email: 'true' })
213
+ .request((err, res, body) => {
214
+ if (err) {
215
+ callback(err);
216
+ } else {
217
+ callback(null, {
218
+ username: body.screen_name,
219
+ email: body.email,
220
+ });
221
+ }
222
+ });
223
+ break;
224
+ }
225
+ case 'instagram': {
226
+ const instagram = purest({
227
+ provider: 'instagram',
228
+ key: providers.instagram.key,
229
+ secret: providers.instagram.secret,
230
+ config: purestConfig,
231
+ });
232
+
233
+ instagram
234
+ .query()
235
+ .get('me')
236
+ .qs({ access_token, fields: 'id,username' })
237
+ .request((err, res, body) => {
238
+ if (err) {
239
+ callback(err);
240
+ } else {
241
+ callback(null, {
242
+ username: body.username,
243
+ email: `${body.username}@strapi.io`, // dummy email as Instagram does not provide user email
244
+ });
245
+ }
246
+ });
247
+ break;
248
+ }
249
+ case 'vk': {
250
+ const vk = purest({
251
+ provider: 'vk',
252
+ config: purestConfig,
253
+ });
254
+
255
+ vk.query()
256
+ .get('users.get')
257
+ .qs({ access_token, id: query.raw.user_id, v: '5.122' })
258
+ .request((err, res, body) => {
259
+ if (err) {
260
+ callback(err);
261
+ } else {
262
+ callback(null, {
263
+ username: `${body.response[0].last_name} ${body.response[0].first_name}`,
264
+ email: query.raw.email,
265
+ });
266
+ }
267
+ });
268
+ break;
269
+ }
270
+ case 'twitch': {
271
+ const twitch = purest({
272
+ provider: 'twitch',
273
+ config: {
274
+ twitch: {
275
+ 'https://api.twitch.tv': {
276
+ __domain: {
277
+ auth: {
278
+ headers: {
279
+ Authorization: 'Bearer [0]',
280
+ 'Client-ID': '[1]',
281
+ },
282
+ },
283
+ },
284
+ 'helix/{endpoint}': {
285
+ __path: {
286
+ alias: '__default',
287
+ },
288
+ },
289
+ 'oauth2/{endpoint}': {
290
+ __path: {
291
+ alias: 'oauth',
292
+ },
293
+ },
294
+ },
295
+ },
296
+ },
297
+ });
298
+
299
+ twitch
300
+ .get('users')
301
+ .auth(access_token, providers.twitch.key)
302
+ .request((err, res, body) => {
303
+ if (err) {
304
+ callback(err);
305
+ } else {
306
+ callback(null, {
307
+ username: body.data[0].login,
308
+ email: body.data[0].email,
309
+ });
310
+ }
311
+ });
312
+ break;
313
+ }
314
+ case 'linkedin': {
315
+ const linkedIn = purest({
316
+ provider: 'linkedin',
317
+ config: {
318
+ linkedin: {
319
+ 'https://api.linkedin.com': {
320
+ __domain: {
321
+ auth: [{ auth: { bearer: '[0]' } }],
322
+ },
323
+ '[version]/{endpoint}': {
324
+ __path: {
325
+ alias: '__default',
326
+ version: 'v2',
327
+ },
328
+ },
329
+ },
330
+ },
331
+ },
332
+ });
333
+ try {
334
+ const getDetailsRequest = () => {
335
+ return new Promise((resolve, reject) => {
336
+ linkedIn
337
+ .query()
338
+ .get('me')
339
+ .auth(access_token)
340
+ .request((err, res, body) => {
341
+ if (err) {
342
+ return reject(err);
343
+ }
344
+ resolve(body);
345
+ });
346
+ });
347
+ };
348
+
349
+ const getEmailRequest = () => {
350
+ return new Promise((resolve, reject) => {
351
+ linkedIn
352
+ .query()
353
+ .get('emailAddress?q=members&projection=(elements*(handle~))')
354
+ .auth(access_token)
355
+ .request((err, res, body) => {
356
+ if (err) {
357
+ return reject(err);
358
+ }
359
+ resolve(body);
360
+ });
361
+ });
362
+ };
363
+
364
+ const { localizedFirstName } = await getDetailsRequest();
365
+ const { elements } = await getEmailRequest();
366
+ const email = elements[0]['handle~'];
367
+
368
+ callback(null, {
369
+ username: localizedFirstName,
370
+ email: email.emailAddress,
371
+ });
372
+ } catch (err) {
373
+ callback(err);
374
+ }
375
+ break;
376
+ }
377
+ case 'reddit': {
378
+ const reddit = purest({
379
+ provider: 'reddit',
380
+ config: purestConfig,
381
+ defaults: {
382
+ headers: {
383
+ 'user-agent': 'strapi',
384
+ },
385
+ },
386
+ });
387
+
388
+ reddit
389
+ .query('auth')
390
+ .get('me')
391
+ .auth(access_token)
392
+ .request((err, res, body) => {
393
+ if (err) {
394
+ callback(err);
395
+ } else {
396
+ callback(null, {
397
+ username: body.name,
398
+ email: `${body.name}@strapi.io`, // dummy email as Reddit does not provide user email
399
+ });
400
+ }
401
+ });
402
+ break;
403
+ }
404
+ case 'auth0': {
405
+ const purestAuth0Conf = {};
406
+ purestAuth0Conf[`https://${providers.auth0.subdomain}.auth0.com`] = {
407
+ __domain: {
408
+ auth: {
409
+ auth: { bearer: '[0]' },
410
+ },
411
+ },
412
+ '{endpoint}': {
413
+ __path: {
414
+ alias: '__default',
415
+ },
416
+ },
417
+ };
418
+ const auth0 = purest({
419
+ provider: 'auth0',
420
+ config: {
421
+ auth0: purestAuth0Conf,
422
+ },
423
+ });
424
+
425
+ auth0
426
+ .get('userinfo')
427
+ .auth(access_token)
428
+ .request((err, res, body) => {
429
+ if (err) {
430
+ callback(err);
431
+ } else {
432
+ const username =
433
+ body.username || body.nickname || body.name || body.email.split('@')[0];
434
+ const email = body.email || `${username.replace(/\s+/g, '.')}@strapi.io`;
435
+
436
+ callback(null, {
437
+ username,
438
+ email,
439
+ });
440
+ }
441
+ });
442
+ break;
443
+ }
444
+ case 'cas': {
445
+ const provider_url = 'https://' + _.get(providers.cas, 'subdomain');
446
+ const cas = purest({
447
+ provider: 'cas',
448
+ config: {
449
+ cas: {
450
+ [provider_url]: {
451
+ __domain: {
452
+ auth: {
453
+ auth: { bearer: '[0]' },
454
+ },
455
+ },
456
+ '{endpoint}': {
457
+ __path: {
458
+ alias: '__default',
459
+ },
460
+ },
461
+ },
462
+ },
463
+ },
464
+ });
465
+ cas
466
+ .query()
467
+ .get('oidc/profile')
468
+ .auth(access_token)
469
+ .request((err, res, body) => {
470
+ if (err) {
471
+ callback(err);
472
+ } else {
473
+ // CAS attribute may be in body.attributes or "FLAT", depending on CAS config
474
+ const username = body.attributes
475
+ ? body.attributes.strapiusername || body.id || body.sub
476
+ : body.strapiusername || body.id || body.sub;
477
+ const email = body.attributes
478
+ ? body.attributes.strapiemail || body.attributes.email
479
+ : body.strapiemail || body.email;
480
+ if (!username || !email) {
481
+ strapi.log.warn(
482
+ 'CAS Response Body did not contain required attributes: ' + JSON.stringify(body)
483
+ );
484
+ }
485
+ callback(null, {
486
+ username,
487
+ email,
488
+ });
489
+ }
490
+ });
491
+ break;
492
+ }
493
+ default:
494
+ callback(new Error('Unknown provider.'));
495
+ break;
496
+ }
497
+ };
498
+
499
+ /**
500
+ * Connect thanks to a third-party provider.
501
+ *
502
+ *
503
+ * @param {String} provider
504
+ * @param {String} access_token
505
+ *
506
+ * @return {*}
507
+ */
508
+
509
+ const connect = (provider, query) => {
510
+ const access_token = query.access_token || query.code || query.oauth_token;
511
+
512
+ return new Promise((resolve, reject) => {
513
+ if (!access_token) {
514
+ return reject([null, { message: 'No access_token.' }]);
515
+ }
516
+
517
+ // Get the profile.
518
+ getProfile(provider, query, async (err, profile) => {
519
+ if (err) {
520
+ return reject([null, err]);
521
+ }
522
+
523
+ const email = _.toLower(profile.email);
524
+
525
+ // We need at least the mail.
526
+ if (!email) {
527
+ return reject([null, { message: 'Email was not available.' }]);
528
+ }
529
+
530
+ try {
531
+ const users = await strapi.query('plugin::users-permissions.user').findMany({
532
+ where: { email },
533
+ });
534
+
535
+ const advanced = await strapi
536
+ .store({ type: 'plugin', name: 'users-permissions', key: 'advanced' })
537
+ .get();
538
+
539
+ const user = _.find(users, { provider });
540
+
541
+ if (_.isEmpty(user) && !advanced.allow_register) {
542
+ return resolve([
543
+ null,
544
+ [{ messages: [{ id: 'Auth.advanced.allow_register' }] }],
545
+ 'Register action is actually not available.',
546
+ ]);
547
+ }
548
+
549
+ if (!_.isEmpty(user)) {
550
+ return resolve([user, null]);
551
+ }
552
+
553
+ if (
554
+ !_.isEmpty(_.find(users, user => user.provider !== provider)) &&
555
+ advanced.unique_email
556
+ ) {
557
+ return resolve([
558
+ null,
559
+ [{ messages: [{ id: 'Auth.form.error.email.taken' }] }],
560
+ 'Email is already taken.',
561
+ ]);
562
+ }
563
+
564
+ // Retrieve default role.
565
+ const defaultRole = await strapi
566
+ .query('plugin::users-permissions.role')
567
+ .findOne({ where: { type: advanced.default_role } });
568
+
569
+ // Create the new user.
570
+ const params = {
571
+ ...profile,
572
+ email, // overwrite with lowercased email
573
+ provider,
574
+ role: defaultRole.id,
575
+ confirmed: true,
576
+ };
577
+
578
+ const createdUser = await strapi
579
+ .query('plugin::users-permissions.user')
580
+ .create({ data: params });
581
+
582
+ return resolve([createdUser, null]);
583
+ } catch (err) {
584
+ reject([null, err]);
585
+ }
586
+ });
587
+ });
588
+ };
589
+
590
+ const buildRedirectUri = (provider = '') => {
591
+ const apiPrefix = strapi.config.get('api.rest.prefix');
592
+ return urlJoin(getAbsoluteServerUrl(strapi.config), apiPrefix, 'connect', provider, 'callback');
593
+ };
594
+
595
+ return {
596
+ connect,
597
+ buildRedirectUri,
598
+ };
599
+ };