Created
November 27, 2025 18:20
-
-
Save leosantosw/2a2b1e82281653dc948ef51b013effa9 to your computer and use it in GitHub Desktop.
Middleware to fetches the users roles from FusionAuth and mapper with strapi roles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import axios from 'axios'; | |
| import { Context, Next } from 'koa'; | |
| interface StrapiRole { | |
| id: number; | |
| name: string; | |
| } | |
| interface StrapiUser { | |
| id: number; | |
| email: string; | |
| roles?: StrapiRole[]; | |
| } | |
| interface StrapiContext extends Context { | |
| state: { | |
| user: StrapiUser; | |
| }; | |
| body: { | |
| data?: { | |
| roles?: StrapiRole[]; | |
| }; | |
| error?: { | |
| status: number; | |
| name: string; | |
| message: string; | |
| }; | |
| }; | |
| } | |
| interface FusionAuthResponse { | |
| user: { | |
| registrations?: Array<{ | |
| roles?: string[]; | |
| }>; | |
| }; | |
| } | |
| export default () => { | |
| return async (ctx: StrapiContext, next: Next): Promise<void> => { | |
| await next(); | |
| if (ctx.request.url.includes('/admin/users/me') && ctx.status === 200) { | |
| try { | |
| const currentUser = ctx.state.user; | |
| const fusionRoles = await getFusionAuthRoles(currentUser.email); | |
| if (!fusionRoles || fusionRoles.length === 0) { | |
| ctx.status = 403; | |
| ctx.body = { | |
| error: { | |
| status: 403, | |
| name: 'ForbiddenError', | |
| message: 'Usuário não possui permissões no FusionAuth', | |
| } | |
| }; | |
| return; | |
| } | |
| const strapiRoles = await mapFusionRolesToStrapi(fusionRoles); | |
| const currentRoleIds = currentUser.roles?.map(r => r.id).sort(); | |
| const newRoleIds = strapiRoles.map(r => r.id).sort(); | |
| // update only when roles change | |
| if (JSON.stringify(currentRoleIds) !== JSON.stringify(newRoleIds)) { | |
| await strapi.query('admin::user').update({ | |
| where: { id: currentUser.id }, | |
| data: { | |
| roles: strapiRoles.map(r => r.id) | |
| } | |
| }); | |
| console.log('Role updated: ', strapiRoles.map(role => role.name)); | |
| } | |
| if (!ctx.body.data) { | |
| ctx.body.data = {}; | |
| } | |
| ctx.body.data.roles = strapiRoles; | |
| } catch (error) { | |
| console.error('❌ Erro ao processar roles:', error); | |
| ctx.status = 500; | |
| ctx.body = { | |
| error: { | |
| status: 500, | |
| name: 'InternalServerError', | |
| message: 'Erro ao validar permissões', | |
| } | |
| }; | |
| } | |
| } | |
| }; | |
| }; | |
| async function getFusionAuthRoles(email: string): Promise<string[]> { | |
| try { | |
| const { data } = await axios.get<FusionAuthResponse>( | |
| `${process.env.FUSIONAUTH_URL}/api/user`, | |
| { | |
| params: { email }, | |
| headers: { | |
| 'Authorization': process.env.FUSIONAUTH_API_KEY, | |
| }, | |
| } | |
| ); | |
| return data.user.registrations?.[0]?.roles || []; | |
| } catch (error) { | |
| console.error('Erro ao buscar roles do FusionAuth:', error); | |
| return []; | |
| } | |
| } | |
| async function mapFusionRolesToStrapi( | |
| fusionRoles: string[] | |
| ): Promise<StrapiRole[]> { | |
| const roleMapping: Record<string, string> = { | |
| 'admin': 'Super Admin', | |
| 'editor': 'Editor', | |
| 'viewer': 'Viewer', | |
| }; | |
| const strapiRoles: StrapiRole[] = []; | |
| const processedStrapiRoleNames = new Set<string>(); | |
| for (const fusionRole of fusionRoles) { | |
| const strapiRoleName = roleMapping[fusionRole.toLowerCase()]; | |
| if (!strapiRoleName) { | |
| console.warn(`⚠️ Role "${fusionRole}" do FusionAuth não está mapeada`); | |
| continue; | |
| } | |
| if (processedStrapiRoleNames.has(strapiRoleName)) { | |
| continue; | |
| } | |
| const strapiRole = await strapi.query('admin::role').findOne({ | |
| where: { name: strapiRoleName } | |
| }); | |
| if (!strapiRole) { | |
| console.error(`❌ Role "${strapiRoleName}" não existe no Strapi`); | |
| continue; | |
| } | |
| strapiRoles.push(strapiRole); | |
| processedStrapiRoleNames.add(strapiRoleName); | |
| } | |
| return strapiRoles; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment