import axios from "axios"; import { GraphQLError } from "graphql"; import { GraphQLContext } from "../../context/types"; import { getLogtoAccessToken } from "../User/resolver"; function getAccessTokenFromContext(context: GraphQLContext): string | null { return context.accessToken || null; } export async function listPermissions(context: GraphQLContext) { const token = getAccessTokenFromContext(context) || (await getLogtoAccessToken()); try { const response = await axios.get(`${process.env.LOGTO_ENDPOINT}/api/permissions`, { headers: { Authorization: `Bearer ${token}` }, }); return response.data; } catch (e) { throw new GraphQLError("Erreur lors de la récupération des permissions", { extensions: { code: "PERMISSIONS_FETCH_FAILED" }, }); } } export async function createPermission(name: string, description: string | null, context: GraphQLContext) { const token = getAccessTokenFromContext(context) || (await getLogtoAccessToken()); try { const response = await axios.post( `${process.env.LOGTO_ENDPOINT}/api/permissions`, { name, description }, { headers: { Authorization: `Bearer ${token}` } } ); return response.data; } catch (e) { throw new GraphQLError("Erreur lors de la création de la permission", { extensions: { code: "CREATE_PERMISSION_FAILED" }, }); } } export async function deletePermission(id: string, context: GraphQLContext) { const token = getAccessTokenFromContext(context) || (await getLogtoAccessToken()); try { await axios.delete(`${process.env.LOGTO_ENDPOINT}/api/scopes/${id}`, { headers: { Authorization: `Bearer ${token}` }, }); return true; } catch (e) { throw new GraphQLError("Erreur lors de la suppression de la permission", { extensions: { code: "DELETE_PERMISSION_FAILED" }, }); } } export async function assignPermissionToRole(roleId: string, permissionId: string, context: GraphQLContext) { // permissionId est un scopeId (ResourceScope) // Pour compatibilité avec l'API Logto actuelle, on envoie scopeIds const token = getAccessTokenFromContext(context) || (await getLogtoAccessToken()); try { const res = await axios.post( `${process.env.LOGTO_ENDPOINT}/api/roles/${roleId}/scopes`, { scopeIds: [permissionId] }, { headers: { Authorization: `Bearer ${token}` } } ); // eslint-disable-next-line no-console console.log("[DEBUG assignPermissionToRole] Logto response:", res.data); return true; } catch (e: any) { // Si l'erreur est que la permission existe déjà, on considère comme succès if (e?.response?.data?.code === "role.scope_exists") { return true; } console.error("[ERROR assignPermissionToRole]", e?.response?.data || e); throw new GraphQLError("Erreur lors de l'assignation du scope au rôle", { extensions: { code: "ASSIGN_SCOPE_TO_ROLE_FAILED" }, }); } } export async function removePermissionFromRole(roleId: string, permissionId: string, context: GraphQLContext) { // permissionId est en fait un scopeId (ResourceScope) const token = getAccessTokenFromContext(context) || (await getLogtoAccessToken()); try { await axios.delete(`${process.env.LOGTO_ENDPOINT}/api/roles/${roleId}/scopes/${permissionId}`, { headers: { Authorization: `Bearer ${token}` }, }); return true; } catch { throw new GraphQLError("Erreur lors de la suppression du scope du rôle", { extensions: { code: "REMOVE_SCOPE_FROM_ROLE_FAILED" }, }); } } export async function assignScopeToResource( resourceId: string, name: string, description: string | null, context: GraphQLContext ): Promise { const token = getAccessTokenFromContext(context) || (await getLogtoAccessToken()); try { await axios.post( `${process.env.LOGTO_ENDPOINT}/api/resources/${resourceId}/scopes`, { name, description }, { headers: { Authorization: `Bearer ${token}` } } ); return true; } catch { throw new GraphQLError("Erreur lors de l'assignation du scope à la ressource", { extensions: { code: "ASSIGN_SCOPE_FAILED" }, }); } } export async function removeScopeFromResource( resourceId: string, scope: string, context: GraphQLContext ): Promise { const token = getAccessTokenFromContext(context) || (await getLogtoAccessToken()); try { await axios.delete(`${process.env.LOGTO_ENDPOINT}/api/resources/${resourceId}/scopes/${scope}`, { headers: { Authorization: `Bearer ${token}` }, }); return true; } catch { throw new GraphQLError("Erreur lors de la suppression du scope de la ressource", { extensions: { code: "REMOVE_SCOPE_FAILED" }, }); } }