mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-30 17:37:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			115 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const { castArray, map, every, pipe } = require('lodash/fp');
 | |
| const { ForbiddenError, UnauthorizedError } = require('@strapi/utils').errors;
 | |
| 
 | |
| const { getService } = require('../utils');
 | |
| 
 | |
| const getAdvancedSettings = () => {
 | |
|   return strapi.store({ type: 'plugin', name: 'users-permissions' }).get({ key: 'advanced' });
 | |
| };
 | |
| 
 | |
| const authenticate = async (ctx) => {
 | |
|   try {
 | |
|     const token = await getService('jwt').getToken(ctx);
 | |
| 
 | |
|     if (token) {
 | |
|       const { id } = token;
 | |
| 
 | |
|       // Invalid token
 | |
|       if (id === undefined) {
 | |
|         return { authenticated: false };
 | |
|       }
 | |
| 
 | |
|       const user = await getService('user').fetchAuthenticatedUser(id);
 | |
| 
 | |
|       // No user associated to the token
 | |
|       if (!user) {
 | |
|         return { error: 'Invalid credentials' };
 | |
|       }
 | |
| 
 | |
|       const advancedSettings = await getAdvancedSettings();
 | |
| 
 | |
|       // User not confirmed
 | |
|       if (advancedSettings.email_confirmation && !user.confirmed) {
 | |
|         return { error: 'Invalid credentials' };
 | |
|       }
 | |
| 
 | |
|       // User blocked
 | |
|       if (user.blocked) {
 | |
|         return { error: 'Invalid credentials' };
 | |
|       }
 | |
| 
 | |
|       // 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);
 | |
| 
 | |
|       ctx.state.user = user;
 | |
| 
 | |
|       return {
 | |
|         authenticated: true,
 | |
|         credentials: user,
 | |
|         ability,
 | |
|       };
 | |
|     }
 | |
| 
 | |
|     const publicPermissions = await getService('permission')
 | |
|       .findPublicPermissions()
 | |
|       .then(map(getService('permission').toContentAPIPermission));
 | |
| 
 | |
|     if (publicPermissions.length === 0) {
 | |
|       return { authenticated: false };
 | |
|     }
 | |
| 
 | |
|     const ability = await strapi.contentAPI.permissions.engine.generateAbility(publicPermissions);
 | |
| 
 | |
|     return {
 | |
|       authenticated: true,
 | |
|       credentials: null,
 | |
|       ability,
 | |
|     };
 | |
|   } catch (err) {
 | |
|     return { authenticated: false };
 | |
|   }
 | |
| };
 | |
| 
 | |
| const verify = async (auth, config) => {
 | |
|   const { credentials: user, ability } = auth;
 | |
| 
 | |
|   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;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // If no ability have been generated, then consider auth is missing
 | |
|   if (!ability) {
 | |
|     throw new UnauthorizedError();
 | |
|   }
 | |
| 
 | |
|   const isAllowed = pipe(
 | |
|     // Make sure we're dealing with an array
 | |
|     castArray,
 | |
|     // Transform the scope array into an action array
 | |
|     every((scope) => ability.can(scope))
 | |
|   )(config.scope);
 | |
| 
 | |
|   if (!isAllowed) {
 | |
|     throw new ForbiddenError();
 | |
|   }
 | |
| };
 | |
| 
 | |
| module.exports = {
 | |
|   name: 'users-permissions',
 | |
|   authenticate,
 | |
|   verify,
 | |
| };
 | 
