logto-nextjs/src/graphql/features/Role/permissionService.ts
2025-07-28 15:37:21 +02:00

132 lines
4.6 KiB
TypeScript

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<boolean> {
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<boolean> {
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" },
});
}
}