| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  | const { castArray, map, every, pipe } = require('lodash/fp'); | 
					
						
							| 
									
										
										
										
											2022-01-08 15:46:36 +00:00
										 |  |  | const { ForbiddenError, UnauthorizedError } = require('@strapi/utils').errors; | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | const { getService } = require('../utils'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const getAdvancedSettings = () => { | 
					
						
							| 
									
										
										
										
											2021-09-13 12:03:12 +02:00
										 |  |  |   return strapi.store({ type: 'plugin', name: 'users-permissions' }).get({ key: 'advanced' }); | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  | const authenticate = async (ctx) => { | 
					
						
							| 
									
										
										
										
											2021-11-15 17:54:17 +01:00
										 |  |  |   try { | 
					
						
							|  |  |  |     const token = await getService('jwt').getToken(ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (token) { | 
					
						
							|  |  |  |       const { id } = token; | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |       // Invalid token
 | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  |       if (id === undefined) { | 
					
						
							| 
									
										
										
										
											2021-09-16 14:36:54 +02:00
										 |  |  |         return { authenticated: false }; | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const user = await getService('user').fetchAuthenticatedUser(id); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |       // No user associated to the token
 | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       if (!user) { | 
					
						
							| 
									
										
										
										
											2021-09-17 14:07:39 +02:00
										 |  |  |         return { error: 'Invalid credentials' }; | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       const advancedSettings = await getAdvancedSettings(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |       // User not confirmed
 | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       if (advancedSettings.email_confirmation && !user.confirmed) { | 
					
						
							| 
									
										
										
										
											2021-09-17 14:07:39 +02:00
										 |  |  |         return { error: 'Invalid credentials' }; | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |       // User blocked
 | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       if (user.blocked) { | 
					
						
							| 
									
										
										
										
											2021-09-17 14:07:39 +02:00
										 |  |  |         return { error: 'Invalid credentials' }; | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |       // Fetch user's permissions
 | 
					
						
							|  |  |  |       const permissions = await Promise.resolve(user.role.id) | 
					
						
							|  |  |  |         .then(getService('permission').findRolePermissions) | 
					
						
							|  |  |  |         .then(map(getService('permission').toContentAPIPermission)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Generate an ability (content API engine) based on the given permissions
 | 
					
						
							|  |  |  |       const ability = await strapi.contentAPI.permissions.engine.generateAbility(permissions); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       ctx.state.user = user; | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       return { | 
					
						
							|  |  |  |         authenticated: true, | 
					
						
							|  |  |  |         credentials: user, | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |         ability, | 
					
						
							| 
									
										
										
										
											2021-09-08 16:16:16 +02:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |     const publicPermissions = await getService('permission') | 
					
						
							|  |  |  |       .findPublicPermissions() | 
					
						
							|  |  |  |       .then(map(getService('permission').toContentAPIPermission)); | 
					
						
							| 
									
										
										
										
											2021-11-15 17:54:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (publicPermissions.length === 0) { | 
					
						
							|  |  |  |       return { authenticated: false }; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |     const ability = await strapi.contentAPI.permissions.engine.generateAbility(publicPermissions); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-15 17:54:17 +01:00
										 |  |  |     return { | 
					
						
							|  |  |  |       authenticated: true, | 
					
						
							|  |  |  |       credentials: null, | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |       ability, | 
					
						
							| 
									
										
										
										
											2021-11-15 17:54:17 +01:00
										 |  |  |     }; | 
					
						
							|  |  |  |   } catch (err) { | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  |     return { authenticated: false }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const verify = async (auth, config) => { | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |   const { credentials: user, ability } = auth; | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-21 04:42:07 +00:00
										 |  |  |   if (!config.scope) { | 
					
						
							|  |  |  |     if (!user) { | 
					
						
							|  |  |  |       // A non authenticated user cannot access routes that do not have a scope
 | 
					
						
							|  |  |  |       throw new UnauthorizedError(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       // An authenticated user can access non scoped routes
 | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-08 15:46:36 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |   // If no ability have been generated, then consider auth is missing
 | 
					
						
							|  |  |  |   if (!ability) { | 
					
						
							|  |  |  |     throw new UnauthorizedError(); | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |   const isAllowed = pipe( | 
					
						
							|  |  |  |     // Make sure we're dealing with an array
 | 
					
						
							|  |  |  |     castArray, | 
					
						
							|  |  |  |     // Transform the scope array into an action array
 | 
					
						
							| 
									
										
										
										
											2022-08-18 12:18:09 +03:00
										 |  |  |     every((scope) => ability.can(scope)) | 
					
						
							| 
									
										
										
										
											2022-07-29 10:17:06 +02:00
										 |  |  |   )(config.scope); | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!isAllowed) { | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  |     throw new ForbiddenError(); | 
					
						
							| 
									
										
										
										
											2021-09-07 14:51:48 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = { | 
					
						
							|  |  |  |   name: 'users-permissions', | 
					
						
							|  |  |  |   authenticate, | 
					
						
							|  |  |  |   verify, | 
					
						
							|  |  |  | }; |