From 02bcbd60b6bd5e5ed94b7676d67af3fcf4ed48b4 Mon Sep 17 00:00:00 2001 From: this-is-tobi Date: Mon, 22 May 2023 00:03:45 +0200 Subject: [PATCH] refactor: :loud_sound: harmonize api logs --- apps/server/package.json | 1 - apps/server/src/connect.js | 5 +- .../src/controllers/admin/organizations.js | 72 ++--- apps/server/src/controllers/admin/project.js | 26 +- apps/server/src/controllers/admin/user.js | 20 +- apps/server/src/controllers/environment.js | 174 +++++++---- apps/server/src/controllers/organization.js | 19 +- apps/server/src/controllers/permission.js | 116 +++++--- apps/server/src/controllers/project.js | 244 ++++++++++------ apps/server/src/controllers/repository.js | 276 +++++++++++------- apps/server/src/controllers/service.js | 21 +- apps/server/src/controllers/user.js | 207 +++++++------ .../src/generate-files/generate-ci-files.js | 19 +- .../src/routes/admin/organization.spec.js | 12 +- apps/server/src/routes/admin/user.spec.js | 2 +- apps/server/src/routes/organization.spec.js | 2 +- .../src/routes/project-environment.spec.js | 20 +- .../src/routes/project-permission.spec.js | 14 +- .../src/routes/project-repository.spec.js | 4 +- apps/server/src/routes/project-user.spec.js | 12 +- apps/server/src/routes/project.spec.js | 22 +- apps/server/src/utils/logger.js | 38 ++- pnpm-lock.yaml | 6 +- 23 files changed, 798 insertions(+), 534 deletions(-) diff --git a/apps/server/package.json b/apps/server/package.json index 9bb41d167..dc40d39ba 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -22,7 +22,6 @@ "dotenv": "^16.0.3", "fastify": "^4.17.0", "fastify-keycloak-adapter": "^2.0.1", - "lodash.kebabcase": "^4.1.1", "mustache": "^4.2.0", "nanoid": "4.0.2", "node-vault-client": "^0.6.1", diff --git a/apps/server/src/connect.js b/apps/server/src/connect.js index 90fd2010d..a94eb2a44 100644 --- a/apps/server/src/connect.js +++ b/apps/server/src/connect.js @@ -138,7 +138,10 @@ export const synchroniseModels = async () => { } catch (error) { app.log.error({ message: 'Models synchronisation with database failed.', - error: JSON.stringify(error), + error: { + message: error?.message, + trace: error?.trace, + }, }) } } diff --git a/apps/server/src/controllers/admin/organizations.js b/apps/server/src/controllers/admin/organizations.js index 0decb7791..9dbba4cc9 100644 --- a/apps/server/src/controllers/admin/organizations.js +++ b/apps/server/src/controllers/admin/organizations.js @@ -7,29 +7,28 @@ import { } from '../../models/queries/organization-queries.js' import { organizationSchema } from 'shared/src/schemas/organization.js' import { adminGroupPath } from 'shared/src/utils/const.js' -import { getLogInfos } from '../../utils/logger.js' +import { addReqLogs } from '../../utils/logger.js' import { sendOk, sendCreated, sendNotFound, sendBadRequest, sendForbidden } from '../../utils/response.js' // GET export const getAllOrganizationsController = async (req, res) => { - if (!req.session.user.groups?.includes(adminGroupPath)) sendForbidden(res, 'Vous n\'avez pas les droits administrateurs') + if (!req.session.user.groups?.includes(adminGroupPath)) sendForbidden(res, 'Vous n\'avez pas les droits administrateur') try { const organizations = await getOrganizations() - req.log.info({ - ...getLogInfos(), + addReqLogs({ + req, description: 'Organisations récupérées avec succès', }) sendOk(res, organizations) } catch (error) { - const message = 'Echec de récupération des organisations' - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération des organisations' + addReqLogs({ + req, + description, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } @@ -37,7 +36,7 @@ export const getAllOrganizationsController = async (req, res) => { export const createOrganizationController = async (req, res) => { const data = req.body - if (!req.session.user.groups?.includes(adminGroupPath)) sendForbidden(res, 'Vous n\'avez pas les droits administrateurs') + if (!req.session.user.groups?.includes(adminGroupPath)) sendForbidden(res, 'Vous n\'avez pas les droits administrateur') try { await organizationSchema.validateAsync(data) @@ -46,21 +45,23 @@ export const createOrganizationController = async (req, res) => { if (isNameTaken) throw new Error('Cette organisation existe déjà') const organization = await createOrganization(data) - req.log.info({ - ...getLogInfos({ + + addReqLogs({ + req, + description: 'Organisation créée avec succès', + extras: { organizationId: organization.id, - }), - description: 'L\'organisation a bien été enregistrée en base', + }, }) sendCreated(res, organization) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec d\'enregistrement de l\'organisation', - error: error.message, - trace: error.trace, + const description = 'Echec de la création de l\'organisation' + addReqLogs({ + req, + description, + error, }) - sendBadRequest(res, error.message) + sendBadRequest(res, description) } } @@ -69,7 +70,7 @@ export const updateOrganizationController = async (req, res) => { const name = req.params.orgName const { active, label } = req.body - if (!req.session.user.groups?.includes(adminGroupPath)) sendForbidden(res, 'Vous n\'avez pas les droits administrateurs') + if (!req.session.user.groups?.includes(adminGroupPath)) sendForbidden(res, 'Vous n\'avez pas les droits administrateur') try { if (active !== undefined) { await updateActiveOrganization({ name, active }) @@ -78,20 +79,25 @@ export const updateOrganizationController = async (req, res) => { await updateLabelOrganization({ name, label }) } const organization = await getOrganizationByName(name) - req.log.info({ - ...getLogInfos({ + + addReqLogs({ + req, + description: 'Organisation mise à jour avec succès', + extras: { organizationId: organization.id, - }), - description: 'L\'organisation a bien été mise à jour', + }, }) sendCreated(res, organization) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec de mise à jour de l\'organisation', - error: error.message, - trace: error.trace, + const description = 'Echec de la mise à jour de l\'organisation' + addReqLogs({ + req, + description, + extras: { + organizationName: name, + }, + error, }) - sendBadRequest(res, error.message) + sendBadRequest(res, description) } } diff --git a/apps/server/src/controllers/admin/project.js b/apps/server/src/controllers/admin/project.js index 83fd35618..5e68ec700 100644 --- a/apps/server/src/controllers/admin/project.js +++ b/apps/server/src/controllers/admin/project.js @@ -1,24 +1,24 @@ -import { getAllProjects } from '../models/queries/project-queries.js' -import { getLogInfos } from '../utils/logger.js' -import { sendOk, sendNotFound } from '../utils/response.js' +import { addReqLogs } from '../../utils/logger.js' +import { getAllProjects } from '../../models/queries/project-queries.js' +import { sendOk, sendNotFound } from '../../utils/response.js' import { adminGroupPath } from 'shared/src/utils/const.js' export const getAllProjectsController = async (req, res) => { try { - if (!req.session.user.groups?.includes(adminGroupPath)) throw new Error('Vous n\'avez pas les droits administrateurs') + if (!req.session.user.groups?.includes(adminGroupPath)) throw new Error('Vous n\'avez pas les droits administrateur') const projects = await getAllProjects() - req.log.info({ - ...getLogInfos(), - description: 'Projects récupérés avec succès', + addReqLogs({ + req, + description: 'Ensemble des projets récupérés avec succès', }) return sendOk(res, projects) } catch (error) { - const message = 'Projets non trouvés' - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, + const description = 'Echec de la récupération de l\'ensemble des projets' + addReqLogs({ + req, + description, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } diff --git a/apps/server/src/controllers/admin/user.js b/apps/server/src/controllers/admin/user.js index 97866402c..0ae2bf68b 100644 --- a/apps/server/src/controllers/admin/user.js +++ b/apps/server/src/controllers/admin/user.js @@ -4,22 +4,24 @@ import { import { adminGroupPath } from 'shared/src/utils/const.js' import { sendNotFound, sendOk } from '../../utils/response.js' -import { getLogInfos } from '../../utils/logger.js' +import { addReqLogs } from '../../utils/logger.js' export const getUsersController = async (req, res) => { try { - if (!req.session.user.groups?.includes(adminGroupPath)) throw new Error('Vous n\'avez pas les droits administrateurs') + if (!req.session.user.groups?.includes(adminGroupPath)) throw new Error('Vous n\'avez pas les droits administrateur') const users = await getUsers() - req.log.info({ - ...getLogInfos(), - description: 'Utilisateurs récupérés avec succès', + + addReqLogs({ + req, + description: 'Ensemble des utilisateurs récupérés avec succès', }) sendOk(res, users) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec de récupération des utilisateurs', - error: error.message, + const description = 'Echec de la récupération de l\'ensemble des utilisateurs' + addReqLogs({ + req, + description, + error, }) sendNotFound(res, error.message) } diff --git a/apps/server/src/controllers/environment.js b/apps/server/src/controllers/environment.js index 166d40935..1d9ee353c 100644 --- a/apps/server/src/controllers/environment.js +++ b/apps/server/src/controllers/environment.js @@ -16,7 +16,7 @@ import { getRoleByUserIdAndProjectId, getSingleOwnerByProjectId, } from '../models/queries/users-projects-queries.js' -import { getLogInfos } from '../utils/logger.js' +import { addReqLogs } from '../utils/logger.js' import { sendOk, sendCreated, sendNotFound, sendBadRequest, sendForbidden } from '../utils/response.js' import hooksFns from '../plugins/index.js' import { addLogs } from '../models/queries/log-queries.js' @@ -39,21 +39,27 @@ export const getEnvironmentByIdController = async (req, res) => { if (!role) throw new Error('Vous n\'êtes pas membre du projet') if (role.role !== 'owner' && !userPermissionLevel) throw new Error('Vous n\'êtes pas souscripteur et n\'avez pas accès à cet environnement') - req.log.info({ - ...getLogInfos({ - environmentId: env.id, - }), - description: 'Environment successfully retrieved', + addReqLogs({ + req, + description: 'Environnement récupéré avec succès', + extras: { + environmentId, + projectId, + }, }) sendOk(res, env) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: `Environnement non trouvé: ${error.message}`, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération de l\'environnement' + addReqLogs({ + req, + description, + extras: { + environmentId, + projectId, + }, + error, }) - return sendNotFound(res, error.message) + return sendNotFound(res, description) } } @@ -84,21 +90,26 @@ export const initializeEnvironmentController = async (req, res) => { await lockProject(projectId) owner = await getSingleOwnerByProjectId(projectId) - req.log.info({ - ...getLogInfos({ - projectId: project.id, - }), - description: 'Environment successfully created in database', + addReqLogs({ + req, + description: 'Environnement créé avec succès', + extras: { + environmentId: env.id, + projectId, + }, }) sendCreated(res, env) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Environnement non créé', - error: error.message, - trace: error.trace, + const description = 'Echec de la création de l\'environnement' + addReqLogs({ + req, + description, + extras: { + projectId, + }, + error, }) - return sendBadRequest(res, error.message) + return sendBadRequest(res, description) } // Process api call to external service @@ -125,14 +136,24 @@ export const initializeEnvironmentController = async (req, res) => { const results = await hooksFns.initializeEnvironment(envData) await addLogs('Create Environment', results, userId) if (results.failed) throw new Error('Echec services à la création de l\'environnement') - isServicesCallOk = true + addReqLogs({ + req, + description: 'Environnement créé avec succès par les plugins', + extras: { + environmentId: env.id, + projectId, + }, + }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: `Echec requête ${req.id} : ${error.message}`, - error: JSON.stringify(error), - trace: error.trace, + addReqLogs({ + req, + description: 'Echec de création de l\'environnement par les plugins', + extras: { + environmentId: env.id, + projectId, + }, + error, }) isServicesCallOk = false } @@ -160,16 +181,23 @@ export const initializeEnvironmentController = async (req, res) => { } await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ projectId: env.id }), - description: 'Projet déverrouillé', + addReqLogs({ + req, + description: 'Projet dévérouillé avec succès après la création de l\'environnement', + extras: { + environmentId: env.id, + projectId, + }, }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec, projet verrouillé', - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec du déverrouillage du projet après la création de l\'environnement', + extras: { + environmentId: env.id, + projectId, + }, + error, }) } } @@ -195,20 +223,26 @@ export const deleteEnvironmentController = async (req, res) => { await updateEnvironmentDeleting(environmentId) await lockProject(projectId) - req.log.info({ - ...getLogInfos({ + addReqLogs({ + req, + description: 'Statut de l\'environnement mis à jour avec succès, environnement en cours de suppression', + extras: { + environmentId, projectId, - }), - description: 'Environment status successfully updated in database', + }, }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Cannot update environment status', - error: error.message, - trace: error.trace, + const description = 'Echec de la suppression de l\'environnement' + addReqLogs({ + req, + description, + extras: { + environmentId, + projectId, + }, + error, }) - return sendForbidden(res, error.message) + return sendForbidden(res, description) } try { @@ -233,17 +267,24 @@ export const deleteEnvironmentController = async (req, res) => { await deleteEnvironment(environmentId) await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ environmentId }), - description: 'Environment successfully deleted', + addReqLogs({ + req, + description: 'Environnement supprimé avec succès', + extras: { + environmentId, + projectId, + }, }) return } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Cannot delete environment', - error: JSON.stringify(error), - trace: error.trace, + addReqLogs({ + req, + description: 'Erreur de la suppression de l\'environnement', + extras: { + environmentId, + projectId, + }, + error, }) } @@ -251,16 +292,23 @@ export const deleteEnvironmentController = async (req, res) => { await updateEnvironmentFailed(environmentId) await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ environmentId }), - description: 'Environment status successfully updated to failed in database', + addReqLogs({ + req, + description: 'Statut de l\'environnement mis à jour avec succès, échec de la suppression de l\'environnement', + extras: { + environmentId, + projectId, + }, }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Cannot update environment status to failed', - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec de la mise à jour de l\'environnement', + extras: { + environmentId, + projectId, + }, + error, }) } } diff --git a/apps/server/src/controllers/organization.js b/apps/server/src/controllers/organization.js index dd4afc065..f5f7a6ddf 100644 --- a/apps/server/src/controllers/organization.js +++ b/apps/server/src/controllers/organization.js @@ -1,26 +1,25 @@ import { getActiveOrganizations, } from '../models/queries/organization-queries.js' -import { getLogInfos } from '../utils/logger.js' +import { addReqLogs } from '../utils/logger.js' import { sendOk, sendNotFound } from '../utils/response.js' // GET export const getActiveOrganizationsController = async (req, res) => { try { const organizations = await getActiveOrganizations() - req.log.info({ - ...getLogInfos(), + addReqLogs({ + req, description: 'Organisations récupérées avec succès', }) sendOk(res, organizations) } catch (error) { - const message = 'Echec de récupération des organisations' - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération des organisations' + addReqLogs({ + req, + description, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } diff --git a/apps/server/src/controllers/permission.js b/apps/server/src/controllers/permission.js index 5f8cd553f..99b7cdde9 100644 --- a/apps/server/src/controllers/permission.js +++ b/apps/server/src/controllers/permission.js @@ -9,7 +9,7 @@ import { getRoleByUserIdAndProjectId, getSingleOwnerByProjectId, } from '../models/queries/users-projects-queries.js' -import { getLogInfos } from '../utils/logger.js' +import { addReqLogs } from '../utils/logger.js' import { sendOk, sendCreated, sendNotFound, sendBadRequest, sendForbidden } from '../utils/response.js' // import hooksFns from '../plugins/index.js' @@ -24,20 +24,28 @@ export const getEnvironmentPermissionsController = async (req, res) => { if (!role) throw new Error('Vous n\'êtes pas membre du projet') const permissions = await getEnvironmentPermissions(environmentId) - req.log.info({ - ...getLogInfos(), - description: 'Permissions récupérées', + + addReqLogs({ + req, + description: 'Permissions de l\'environnement récupérées avec succès', + extras: { + projectId, + environmentId, + }, }) sendOk(res, permissions) } catch (error) { - const message = `Permissions non trouvées: ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération des permissions de l\'environnement' + addReqLogs({ + req, + description, + extras: { + projectId, + environmentId, + }, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } @@ -57,20 +65,28 @@ export const setPermissionController = async (req, res) => { // if (data.level === 0) await removeMembers([data.userId], [permission.Environment.name]) // if (data.level === 10) await removeMembers([data.userId], [permission.Environment.name]) && await addMembers([data.userId], [permission.Environment.name]) // if (data.level === 20) await addMembers([data.userId], [permission.Environment.name]) - req.log.info({ - ...getLogInfos(), - description: 'Permission enregistrée', + addReqLogs({ + req, + description: 'Permission créée avec succès', + extras: { + permissionId: permission.id, + projectId, + environmentId, + }, }) sendCreated(res, permission) } catch (error) { - const message = `Permissions non créées : ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la création d\'une permission' + addReqLogs({ + req, + description, + extras: { + projectId, + environmentId, + }, + error, }) - sendBadRequest(res, message) + sendBadRequest(res, description) } } @@ -92,20 +108,29 @@ export const updatePermissionController = async (req, res) => { if (data.userId === owner.id) throw new Error('La permission du owner du projet ne peut être modifiée') const permission = await updatePermission({ userId: data.userId, environmentId, level: data.level }) - req.log.info({ - ...getLogInfos(), - description: 'Permission mise à jour', + + addReqLogs({ + req, + description: 'Permission mise à jour avec succès', + extras: { + permissionId: permission.id, + projectId, + environmentId, + }, }) sendOk(res, permission) } catch (error) { - const message = `Permission non modifiée : ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la mise à jour de la permission' + addReqLogs({ + req, + description, + extras: { + projectId, + environmentId, + }, + error, }) - sendBadRequest(res, message) + sendBadRequest(res, description) } } @@ -128,20 +153,27 @@ export const deletePermissionController = async (req, res) => { const permission = await deletePermission(userId, environmentId) - const message = 'Permission supprimée' - req.log.info({ - ...getLogInfos({ permission }), - description: message, + addReqLogs({ + req, + description: 'Permissions supprimée avec succès', + extras: { + permissionId: permission.id, + projectId, + environmentId, + }, }) sendOk(res, permission) } catch (error) { - const message = `Permission non supprimée : ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la suppression de la permission' + addReqLogs({ + req, + description, + extras: { + projectId, + environmentId, + }, + error, }) - sendForbidden(res, message) + sendForbidden(res, description) } } diff --git a/apps/server/src/controllers/project.js b/apps/server/src/controllers/project.js index 7c964b53f..34f004cb4 100644 --- a/apps/server/src/controllers/project.js +++ b/apps/server/src/controllers/project.js @@ -36,7 +36,7 @@ import { deletePermissionById, } from '../models/queries/permission-queries.js' import { filterObjectByKeys, lowercaseFirstLetter, replaceNestedKeys } from '../utils/queries-tools.js' -import { getLogInfos } from '../utils/logger.js' +import { addReqLogs } from '../utils/logger.js' import { sendOk, sendCreated, sendUnprocessableContent, sendNotFound, sendBadRequest, sendForbidden } from '../utils/response.js' import { projectSchema } from 'shared/src/schemas/project.js' import { calcProjectNameMaxLength } from 'shared/src/utils/functions.js' @@ -54,9 +54,13 @@ export const getUserProjectsController = async (req, res) => { if (!user) return sendOk(res, []) let projects = await getUserProjects(user) - req.log.info({ - ...getLogInfos(), - description: 'Projets récupérés', + + addReqLogs({ + req, + description: 'Projets de l\'utilisateur récupérés avec succès', + extras: { + userId: requestor.id, + }, }) if (!projects.length) return sendOk(res, []) @@ -67,14 +71,16 @@ export const getUserProjectsController = async (req, res) => { sendOk(res, projects) } catch (error) { - const message = `Projets non trouvés: ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération des projets de l\'utilisateur' + addReqLogs({ + req, + description, + extras: { + userId: requestor.id, + }, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } @@ -87,20 +93,27 @@ export const getProjectByIdController = async (req, res) => { const role = await getRoleByUserIdAndProjectId(userId, projectId) if (!role) throw new Error('Vous n\'êtes pas membre du projet') - req.log.info({ - ...getLogInfos({ projectId }), - description: 'Projet récupéré', + addReqLogs({ + req, + description: 'Projet de l\'utilisateur récupéré avec succès', + extras: { + projectId, + userId, + }, }) sendOk(res, project) } catch (error) { - const message = `Projet non trouvé: ${error.message}` - req.log.error({ - ...getLogInfos({ projectId }), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de récupération du projet de l\'utilisateur' + addReqLogs({ + req, + description, + extras: { + projectId, + userId, + }, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } @@ -113,20 +126,23 @@ export const getProjectOwnerController = async (req, res) => { if (!role) throw new Error('Vous n\'êtes pas membre du projet') const owner = await getSingleOwnerByProjectId(projectId) - req.log.info({ - ...getLogInfos({ owner }), - description: 'Propriétaire du projet récupéré avec succès', + + addReqLogs({ + req, + description: 'Souscripteur du projet récupéré avec succès', + extras: { + ownerId: owner.id, + }, }) sendOk(res, owner) } catch (error) { - const message = `Projet non trouvé: ${error.message}` - req.log.error({ - ...getLogInfos({ projectId }), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération du souscripteur du projet' + addReqLogs({ + req, + description, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } @@ -150,7 +166,15 @@ export const createProjectController = async (req, res) => { .map(({ status }) => status?.message) .join('; ') sendUnprocessableContent(res, reasons) - req.log.error(reasons) + + addReqLogs({ + req, + description: 'Echec de la validation des prérequis de création du projet par les services externes', + extras: { + reasons, + }, + error: new Error('Failed to validate project creation'), + }) addLogs('Create Project Validation', { reasons }, user.id) return } @@ -169,22 +193,22 @@ export const createProjectController = async (req, res) => { await addUserToProject({ project, user: owner, role: 'owner' }) project = { ...project.get({ plain: true }) } - req.log.info({ - ...getLogInfos({ + addReqLogs({ + req, + description: 'Projet créé avec succès', + extras: { projectId: project.id, - }), - description: 'Projet créé en base de données', + }, }) sendCreated(res, project) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: `Projet non créé: ${error.message}`, - error: error.message, - stack: error.stack, - data: error.request, + const description = 'Echec de la création du projet' + addReqLogs({ + req, + description, + error, }) - return sendBadRequest(res, error.message) + return sendBadRequest(res, description) } // Process api call to external service @@ -200,7 +224,7 @@ export const createProjectController = async (req, res) => { const results = await hooksFns.createProject(projectData) await addLogs('Create Project', results, owner.id) - if (results.failed) throw new Error('Echec des services lors de la création du projet') + if (results.failed) throw new Error('Failed to create project by external servcices') // enregistrement des ids GitLab et Harbor const { gitlab, registry } = results @@ -213,14 +237,22 @@ export const createProjectController = async (req, res) => { }, } await updateProjectServices(project.id, services) - isServicesCallOk = true + addReqLogs({ + req, + description: 'Projet créé avec succès par les plugins', + extras: { + projectId: project.id, + }, + }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: `Echec requête ${req.id} : ${error.message}`, - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec de la création du projet par les plugins', + extras: { + projectId: project.id, + }, + error, }) isServicesCallOk = false } @@ -234,16 +266,20 @@ export const createProjectController = async (req, res) => { } await unlockProject(project.id) - req.log.info({ - ...getLogInfos({ projectId: project.id }), - description: 'Projet déverrouillé', + addReqLogs({ + req, + description: 'Projet déverrouillé avec succès après création par les plugins', + extras: { + projectId: project.id, + }, }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec, projet verrouillé', - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec du déverrouillage du projet après création par les plugins', + extras: { + projectId: project.id, + }, }) } } @@ -278,20 +314,25 @@ export const updateProjectController = async (req, res) => { await updateProject(projectId, data) await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ projectId }), - description: 'Project déverrouillé', + addReqLogs({ + req, + description: 'Projet mis à jour avec succès', + extras: { + projectId, + }, }) sendOk(res, projectId) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: `Description du projet non mise à jour : ${error.message}`, - error: error.message, - stack: error.stack, - data: error.request, + const description = 'Echec de la mise à jour du projet' + addReqLogs({ + req, + description, + extras: { + projectId, + }, + error, }) - return sendBadRequest(res, error.message) + return sendBadRequest(res, description) } } @@ -328,21 +369,26 @@ export const archiveProjectController = async (req, res) => { environments?.forEach(async environment => { await updateEnvironmentDeleting(environment.id) }) - req.log.info({ - ...getLogInfos({ - projectId, - }), + + addReqLogs({ + req, description: 'Projet en cours de suppression', + extras: { + projectId, + }, }) sendOk(res, projectId) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: `Echec de suppression du projet : ${error.message}`, - error: error.message, - trace: error.trace, + const description = 'Echec de la suppression du projet' + addReqLogs({ + req, + description, + extras: { + projectId, + }, + error, }) - return sendForbidden(res, error.message) + return sendForbidden(res, description) } // Process api call to external service @@ -382,15 +428,23 @@ export const archiveProjectController = async (req, res) => { delete projectData.name const results = await hooksFns.archiveProject(projectData) await addLogs('Delete Project', results, userId) - if (results.failed) throw new Error('Echec des services à la suppression du projet') - + if (results.failed) throw new Error('Echec de la suppression du projet par les services externes') isServicesCallOk = true + addReqLogs({ + req, + description: 'Projet supprimé avec succès par les plugins', + extras: { + projectId: project.id, + }, + }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: `Echec requête ${req.id} : ${error.message}`, - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec de la suppression du projet par les plugins', + extras: { + projectId, + }, + error, }) isServicesCallOk = false } @@ -416,15 +470,21 @@ export const archiveProjectController = async (req, res) => { } await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ projectId }), - description: 'Project déverrouillé', + addReqLogs({ + req, + description: 'Déverrouillage du projet avec succès après suppression', + extras: { + projectId, + }, }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec, projet verrouillé', - error: error.message, + addReqLogs({ + req, + description: 'Echec du déverrouillage du projet après suprpession', + extras: { + projectId, + }, + error, }) } } diff --git a/apps/server/src/controllers/repository.js b/apps/server/src/controllers/repository.js index dbea68855..e4a016e29 100644 --- a/apps/server/src/controllers/repository.js +++ b/apps/server/src/controllers/repository.js @@ -20,7 +20,7 @@ import { getEnvironmentsByProjectId, } from '../models/queries/environment-queries.js' import { filterObjectByKeys } from '../utils/queries-tools.js' -import { getLogInfos } from '../utils/logger.js' +import { addReqLogs } from '../utils/logger.js' import { sendOk, sendCreated, sendUnprocessableContent, sendNotFound, sendBadRequest, sendForbidden } from '../utils/response.js' import { getOrganizationById } from '../models/queries/organization-queries.js' import { addLogs } from '../models/queries/log-queries.js' @@ -38,20 +38,27 @@ export const getRepositoryByIdController = async (req, res) => { const role = await getRoleByUserIdAndProjectId(userId, projectId) if (!role) throw new Error('Vous n\'êtes pas membre du projet') - req.log.info({ - ...getLogInfos({ repositoryId }), - description: 'Dépôt récupéré', + addReqLogs({ + req, + description: 'Dépôt récupéré avec succès', + extras: { + repositoryId, + projectId, + }, }) sendOk(res, repo) } catch (error) { - const message = 'Dépôt non trouvé' - req.log.error({ - ...getLogInfos({ repositoryId }), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération du dépôt' + addReqLogs({ + req, + description, + extras: { + repositoryId, + projectId, + }, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } @@ -63,20 +70,26 @@ export const getProjectRepositoriesController = async (req, res) => { const role = await getRoleByUserIdAndProjectId(userId, projectId) if (!role) throw new Error('Vous n\'êtes pas membre du projet') - req.log.info({ - ...getLogInfos({ projectId }), - description: 'Dépôts récupérés', + addReqLogs({ + req, + description: 'Dépôts du projet récupérés avec succès', + extras: { + projectId, + repositoriesId: repos.map(({ id }) => id), + }, }) sendOk(res, repos) } catch (error) { - const message = 'Dépôts non trouvés' - req.log.error({ - ...getLogInfos({ projectId }), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération des dépôt du projet' + addReqLogs({ + req, + description, + extras: { + projectId, + }, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } @@ -98,7 +111,15 @@ export const createRepositoryController = async (req, res) => { .map(({ status }) => status?.message) .join('; ') sendUnprocessableContent(res, reasons) - req.log.error(reasons) + + addReqLogs({ + req, + description: 'Dépôt récupéré avec succès', + extras: { + reasons, + }, + error: new Error('Failed to validation repository creation'), + }) addLogs('Create Project Validation', { reasons }, user.id) return } @@ -115,21 +136,26 @@ export const createRepositoryController = async (req, res) => { await lockProject(projectId) repo = await initializeRepository(data) - const message = 'Dépôt créé avec succès' - req.log.info({ - ...getLogInfos({ repositoryId: repo.id }), - description: message, + addReqLogs({ + req, + description: 'Dépôt créé avec succès', + extras: { + projectId, + repositoryId: repo.id, + }, }) sendCreated(res, repo) } catch (error) { - const message = 'Dépôt non créé' - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la création du dépôt' + addReqLogs({ + req, + description, + extras: { + projectId, + }, + error, }) - return sendBadRequest(res, message) + return sendBadRequest(res, description) } // Process api call to external service @@ -156,13 +182,23 @@ export const createRepositoryController = async (req, res) => { await addLogs('Create Repository', results, user.id) if (results.failed) throw new Error('Echec des services lors de la création du dépôt') isServicesCallOk = true + addReqLogs({ + req, + description: 'Dépôt créé avec succès par les plugins', + extras: { + projectId, + repositoryId: repo.id, + }, + }) } catch (error) { - const message = `Echec requête ${req.id} : ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la création du dépôt par les plugins' + addReqLogs({ + req, + description, + extras: { + projectId, + repositoryId: repo.id, + }, }) isServicesCallOk = false } @@ -176,16 +212,23 @@ export const createRepositoryController = async (req, res) => { } await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ repositoryId: repo.id }), - description: 'Statut du dépôt mis à jour, projet déverrouillé', + addReqLogs({ + req, + description: 'Déverrouillage du projet avec succès après la mise à jour du statut du dépôt', + extras: { + projectId, + repositoryId: repo.id, + }, }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec de mise à jour du statut du dépôt, projet verrouillé', - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec du déverrouillage du projet après la mise à jour du statut du dépôt', + extras: { + projectId, + repositoryId: repo.id, + }, + error, }) } } @@ -220,22 +263,29 @@ export const updateRepositoryController = async (req, res) => { await updateRepository(repositoryId, data.info) repo = await getRepositoryById(repositoryId) - - const message = 'Dépôt mis à jour' - req.log.info({ - ...getLogInfos({ repositoryId }), - description: message, + const description = 'Dépôt mis à jour avec succès' + + addReqLogs({ + req, + description, + extras: { + projectId, + repositoryId, + }, }) - sendOk(res, message) + sendOk(res, description) } catch (error) { - const message = 'Dépôt non mis à jour' - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la mise à jour du dépôt' + addReqLogs({ + req, + description, + extras: { + projectId, + repositoryId, + }, + error, }) - return sendBadRequest(res, message) + return sendBadRequest(res, description) } // Process api call to external service @@ -258,12 +308,14 @@ export const updateRepositoryController = async (req, res) => { if (results.failed) throw new Error('Echec des services associés au dépôt') isServicesCallOk = true } catch (error) { - const message = `Echec requête ${req.id} : ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la mise à jour du dépôt par les services externes' + addReqLogs({ + req, + description, + extras: { + repositoryId: repo.id, + }, + error, }) isServicesCallOk = false } @@ -275,17 +327,24 @@ export const updateRepositoryController = async (req, res) => { } await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ repositoryId: repo.id }), - description: 'Statut du dépôt mis à jour, projet déverrouillé', + addReqLogs({ + req, + description: 'Déverrouillage du projet avec succès après mise à jour du statut du dépôt', + extras: { + projectId, + repositoryId: repo.id, + }, }) return } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec de mise à jour du statut du dépôt, projet verrouillé', - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec du déverrouillage du projet après la mise à jour du statut du dépôt', + extras: { + projectId, + repositoryId: repo.id, + }, + error, }) } } @@ -308,21 +367,28 @@ export const deleteRepositoryController = async (req, res) => { await lockProject(projectId) await updateRepositoryDeleting(repositoryId) - const message = 'Dépôt en cours de suppression' - req.log.info({ - ...getLogInfos({ repositoryId }), - description: message, + const description = 'Dépôt en cours de suppression' + addReqLogs({ + req, + description, + extras: { + projectId, + repositoryId: repo.id, + }, }) - sendOk(res, message) + sendOk(res, description) } catch (error) { - const message = 'Dépôt non supprimé' - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la suppression du dépôt' + addReqLogs({ + req, + description, + extras: { + projectId, + repositoryId: repo.id, + }, + error, }) - return sendForbidden(res, message) + return sendForbidden(res, description) } // Process api call to external service @@ -346,11 +412,14 @@ export const deleteRepositoryController = async (req, res) => { if (results.failed) throw new Error('Echec des opérations') isServicesCallOk = true } catch (error) { - req.log.error({ - ...getLogInfos(), - description: error.message, - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec de la suppresion du dépôt par les plugins', + extras: { + projectId, + repositoryId: repo.id, + }, + error, }) isServicesCallOk = false } @@ -363,18 +432,23 @@ export const deleteRepositoryController = async (req, res) => { await updateRepositoryFailed(repo.id) } await unlockProject(projectId) - - req.log.info({ - ...getLogInfos({ repositoryId: repo.id }), - description: 'Projet déverrouillé', + addReqLogs({ + req, + description: 'Déverrouillage du projet avec succès après la suppression du dépôt par les plugins', + extras: { + projectId, + repositoryId: repo.id, + }, }) - return } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec, projet verrouillé', - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec du déverrouillage du projet après la suppression du dépôt par les plugins', + extras: { + projectId, + repositoryId: repo.id, + }, + error, }) } } diff --git a/apps/server/src/controllers/service.js b/apps/server/src/controllers/service.js index 9d3f2da36..6d1b67282 100644 --- a/apps/server/src/controllers/service.js +++ b/apps/server/src/controllers/service.js @@ -1,6 +1,6 @@ import { URL } from 'node:url' import axios from 'axios' -import { getLogInfos } from '../utils/logger.js' +import { addReqLogs } from '../utils/logger.js' import { sendOk, sendBadRequest } from '../utils/response.js' import { allServices } from '../utils/services.js' import { getUserById } from '../models/queries/user-queries.js' @@ -33,16 +33,19 @@ export const checkServicesHealthController = async (req, res) => { } } })) + addReqLogs({ + req, + description: 'Etats des services récupérés avec succès', + }) sendOk(res, serviceData) } catch (error) { - let message = `Erreur : ${error.message}` - if (error.message.match(/^Failed to parse URL from/)) message = 'Url de service invalide' - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - stack: error.stack, + let description = 'Echec de la récupération de l\'état des services' + if (error.message.match(/^Failed to parse URL from/)) description = 'Url de service invalide' + addReqLogs({ + req, + description, + error, }) - sendBadRequest(res, message) + sendBadRequest(res, description) } } diff --git a/apps/server/src/controllers/user.js b/apps/server/src/controllers/user.js index 9822cb1dc..0dd459b00 100644 --- a/apps/server/src/controllers/user.js +++ b/apps/server/src/controllers/user.js @@ -19,7 +19,7 @@ import { import { deletePermission } from '../models/queries/permission-queries.js' import { getEnvironmentsByProjectId } from '../models/queries/environment-queries.js' import { sendOk, sendCreated, sendNotFound, sendBadRequest, sendForbidden } from '../utils/response.js' -import { getLogInfos } from '../utils/logger.js' +import { addReqLogs } from '../utils/logger.js' // import hooksFns from '../plugins/index.js' // GET @@ -33,44 +33,28 @@ export const getProjectUsersController = async (req, res) => { const users = await getProjectUsers(projectId) - req.log.info({ - ...getLogInfos(), - description: 'Membres du projet récupérés', + addReqLogs({ + req, + description: 'Membres du projet récupérés avec succès', + extras: { + projectId, + }, }) sendOk(res, users) } catch (error) { - const message = `Echec de récupération des membres du projet: ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la récupération des membres du projet' + addReqLogs({ + req, + description, + extras: { + projectId, + }, + error, }) - sendNotFound(res, message) + sendNotFound(res, description) } } -// TODO : conditionner possibilité de récupérer tous les utilisateurs selon les droits de l'utilisateur -// export const getUsersController = async (req, res) => { -// try { -// const users = await getUsers() -// req.log.info({ -// ...getLogInfos(), -// description: 'Users successfully retreived', -// }) -// sendOk(res, users) -// } catch (error) { -// const message = 'Utilisateurs non trouvés' -// req.log.error({ -// ...getLogInfos(), -// description: message, -// error: error.message, -// trace: error.trace, -// }) -// sendNotFound(res, message) -// } -// } - // CREATE export const addUserToProjectController = async (req, res) => { const userId = req.session?.user?.id @@ -94,21 +78,27 @@ export const addUserToProjectController = async (req, res) => { await lockProject(projectId) await addUserToProject({ project, user: userToAdd, role: 'user' }) - const message = 'Utilisateur ajouté au projet' - req.log.info({ - ...getLogInfos({ projectId }), - description: message, + const description = 'Utilisateur ajouté au projet avec succès' + addReqLogs({ + req, + description, + extras: { + projectId, + userId: userToAdd.id, + }, }) - sendCreated(res, message) + sendCreated(res, description) } catch (error) { - const message = `Utilisateur non ajouté au projet : ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de l\'ajout de l\'utilisateur au projet' + addReqLogs({ + req, + description, + extras: { + projectId, + }, + error, }) - return sendBadRequest(res, message) + return sendBadRequest(res, description) } // Process api call to external service @@ -116,16 +106,21 @@ export const addUserToProjectController = async (req, res) => { try { await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ projectId }), - description: 'Projet déverrouillé', + addReqLogs({ + req, + description: 'Projet déverrouillé avec succès après l\'ajout de l\'utilisateur au projet', + extras: { + projectId, + }, }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec, projet verrouillé', - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec du déverrouillage du projet après l\'ajout de l\'utilisateur au projet', + extras: { + projectId, + }, + error, }) } } @@ -135,22 +130,23 @@ export const createUserController = async (req, res) => { try { const user = await createUser(data) - req.log.info({ - ...getLogInfos({ + + addReqLogs({ + req, + description: 'Utilisateur créé avec succès', + extras: { userId: user.id, - }), - description: 'Utilisateur enregistré en base', + }, }) sendCreated(res, user) } catch (error) { - const message = 'Utilisateur non enregistré' - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la création de l\'utilisateur' + addReqLogs({ + req, + description, + error, }) - sendBadRequest(res, message) + sendBadRequest(res, description) } } @@ -174,21 +170,28 @@ export const updateUserProjectRoleController = async (req, res) => { await updateUserProjectRole(projectId, userToUpdateId, data.role) - const message = 'Rôle de l\'utilisateur mis à jour' - req.log.info({ - ...getLogInfos({ userToUpdateRole }), - description: message, + const description = 'Rôle de l\'utilisateur mis à jour avec succès' + addReqLogs({ + req, + description, + extras: { + projectId, + userId: userToUpdateId, + }, }) - sendOk(res, message) + sendOk(res, description) } catch (error) { - const message = `Le rôle de l'utilisateur ne peut pas être modifié : ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la mise à jour du rôle de l\'utilisateur' + addReqLogs({ + req, + description, + extras: { + projectId, + userId: userToUpdateId, + }, + error, }) - sendBadRequest(res, message) + sendBadRequest(res, description) } } @@ -221,21 +224,28 @@ export const removeUserFromProjectController = async (req, res) => { }) await deleteRoleByUserIdAndProjectId(userToRemoveId, projectId) - const message = 'Utilisateur retiré du projet' - req.log.info({ - ...getLogInfos({ projectId }), - description: message, + const description = 'Utilisateur supprimé dans le projet avec succès' + addReqLogs({ + req, + description, + extras: { + projectId, + userId: userToRemoveId, + }, }) - sendOk(res, message) + sendOk(res, description) } catch (error) { - const message = `L'utilisateur ne peut être retiré du projet : ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la suppression de l\'utilisateur dans le projet' + addReqLogs({ + req, + description, + extras: { + projectId, + userId: userToRemoveId, + }, + error, }) - return sendForbidden(res, message) + return sendForbidden(res, description) } // Process api call to external service @@ -243,16 +253,23 @@ export const removeUserFromProjectController = async (req, res) => { try { await unlockProject(projectId) - req.log.info({ - ...getLogInfos({ projectId }), - description: 'Projet déverrouillé', + addReqLogs({ + req, + description: 'Projet déverrouillé avec succès après suppression de l\'utilisateur dans le projet', + extras: { + projectId, + userId: userToRemoveId, + }, }) } catch (error) { - req.log.error({ - ...getLogInfos(), - description: 'Echec, projet verrouillé', - error: error.message, - trace: error.trace, + addReqLogs({ + req, + description: 'Echec du déverrouillage du projet après suppression de l\'utilisateur dans le projet', + extras: { + projectId, + userId: userToRemoveId, + }, + error, }) } } diff --git a/apps/server/src/generate-files/generate-ci-files.js b/apps/server/src/generate-files/generate-ci-files.js index 4b3d91c5b..4c2de99fd 100644 --- a/apps/server/src/generate-files/generate-ci-files.js +++ b/apps/server/src/generate-files/generate-ci-files.js @@ -2,7 +2,7 @@ import * as fs from 'node:fs/promises' import Mustache from 'mustache' import path from 'node:path' -import { getLogInfos } from '../utils/logger.js' +import { addReqLogs } from '../utils/logger.js' import { sendCreated, sendServerError } from '../utils/response.js' export const generateCIFiles = async (req, res) => { @@ -48,15 +48,18 @@ export const generateCIFiles = async (req, res) => { content.node = Mustache.render(node.toString()) } + addReqLogs({ + req, + description: 'Fichiers de gitlab-ci créés avec succès', + }) sendCreated(res, content) } catch (error) { - const message = `Cannot generate files: ${error.message}` - req.log.error({ - ...getLogInfos(), - description: message, - error: error.message, - trace: error.trace, + const description = 'Echec de la création des fichiers de gitlab-ci' + addReqLogs({ + req, + description, + error, }) - return sendServerError(res, message) + return sendServerError(res, description) } } diff --git a/apps/server/src/routes/admin/organization.spec.js b/apps/server/src/routes/admin/organization.spec.js index fa7bcffa3..5559e1c44 100644 --- a/apps/server/src/routes/admin/organization.spec.js +++ b/apps/server/src/routes/admin/organization.spec.js @@ -76,7 +76,7 @@ describe('Organizations routes', () => { .end() expect(response.statusCode).toEqual(404) - expect(response.body).toEqual('Echec de récupération des organisations') + expect(response.body).toEqual('Echec de la récupération des organisations') }) it('Should return an error if requestor is not admin', async () => { @@ -87,7 +87,7 @@ describe('Organizations routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('Vous n\'avez pas les droits administrateurs') + expect(response.body).toEqual('Vous n\'avez pas les droits administrateur') }) }) @@ -122,7 +122,7 @@ describe('Organizations routes', () => { .end() expect(response.statusCode).toEqual(400) - expect(response.body).toEqual('"name" length must be less than or equal to 10 characters long') + expect(response.body).toEqual('Echec de la création de l\'organisation') }) it('Should return an error if organization already exists', async () => { @@ -139,7 +139,7 @@ describe('Organizations routes', () => { .end() expect(response.statusCode).toEqual(400) - expect(response.body).toEqual('Cette organisation existe déjà') + expect(response.body).toEqual('Echec de la création de l\'organisation') }) it('Should return an error if requestor is not admin', async () => { @@ -156,7 +156,7 @@ describe('Organizations routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('Vous n\'avez pas les droits administrateurs') + expect(response.body).toEqual('Vous n\'avez pas les droits administrateur') }) }) @@ -228,7 +228,7 @@ describe('Organizations routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('Vous n\'avez pas les droits administrateurs') + expect(response.body).toEqual('Vous n\'avez pas les droits administrateur') }) }) }) diff --git a/apps/server/src/routes/admin/user.spec.js b/apps/server/src/routes/admin/user.spec.js index 1ffdbd092..eb9afd0f6 100644 --- a/apps/server/src/routes/admin/user.spec.js +++ b/apps/server/src/routes/admin/user.spec.js @@ -87,7 +87,7 @@ describe('Admin Users routes', () => { .get('/') .end() expect(response.statusCode).toEqual(404) - expect(response.body).toEqual('Vous n\'avez pas les droits administrateurs') + expect(response.body).toEqual('Vous n\'avez pas les droits administrateur') }) }) }) diff --git a/apps/server/src/routes/organization.spec.js b/apps/server/src/routes/organization.spec.js index 7a2fbc57a..638f50af1 100644 --- a/apps/server/src/routes/organization.spec.js +++ b/apps/server/src/routes/organization.spec.js @@ -90,7 +90,7 @@ describe('Organizations routes', () => { .end() expect(response.statusCode).toEqual(404) - expect(response.body).toEqual('Echec de récupération des organisations') + expect(response.body).toEqual('Echec de la récupération des organisations') }) }) }) diff --git a/apps/server/src/routes/project-environment.spec.js b/apps/server/src/routes/project-environment.spec.js index 92223d1e4..efbcd1d5a 100644 --- a/apps/server/src/routes/project-environment.spec.js +++ b/apps/server/src/routes/project-environment.spec.js @@ -98,7 +98,7 @@ describe('User routes', () => { expect(response.json()).toEqual(randomDbSetup.project.environments[0]) }) - it('Should not retreive an environment if Vous n\'êtes pas membre du projet', async () => { + it('Should not retreive an environment if not project member', async () => { const randomDbSetup = createRandomDbSetup({}) const owner = randomDbSetup.project.users.find(user => user.role === 'owner') @@ -112,7 +112,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(404) expect(response.body).toBeDefined() - expect(response.body).toEqual('Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la récupération de l\'environnement') }) it('Should not retreive an environment if requestor has no permission', async () => { @@ -131,7 +131,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(404) expect(response.body).toBeDefined() - expect(response.body).toEqual('Vous n\'êtes pas souscripteur et n\'avez pas accès à cet environnement') + expect(response.body).toEqual('Echec de la récupération de l\'environnement') }) }) @@ -169,7 +169,7 @@ describe('User routes', () => { expect(response.json()).toMatchObject(newEnvironment) }) - it('Should not create an environment if Vous n\'êtes pas membre du projet', async () => { + it('Should not create an environment if not project member', async () => { const randomDbSetup = createRandomDbSetup({}) const newEnvironment = getRandomEnv('dev', randomDbSetup.project.id) delete newEnvironment.id @@ -193,7 +193,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual('Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la création de l\'environnement') }) it('Should not create an environment if name already present', async () => { @@ -222,7 +222,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual('Requested environment already exists for this project') + expect(response.body).toEqual('Echec de la création de l\'environnement') }) }) @@ -248,7 +248,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(200) }) - it('Should not delete an environment if Vous n\'êtes pas membre du projet', async () => { + it('Should not delete an environment if not project member', async () => { const randomDbSetup = createRandomDbSetup({}) const environmentToDelete = randomDbSetup.project.environments[0] const owner = randomDbSetup.project.users.find(user => user.role === 'owner') @@ -263,10 +263,10 @@ describe('User routes', () => { expect(response.statusCode).toEqual(403) expect(response.body).toBeDefined() - expect(response.body).toEqual('Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la suppression de l\'environnement') }) - it('Should not delete an environment if Vous n\'êtes pas souscripteur du projet', async () => { + it('Should not delete an environment if not project member', async () => { const randomDbSetup = createRandomDbSetup({}) const environmentToDelete = randomDbSetup.project.environments[0] const owner = randomDbSetup.project.users.find(user => user.role === 'owner') @@ -283,7 +283,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(403) expect(response.body).toBeDefined() - expect(response.body).toEqual('Vous n\'êtes pas souscripteur du projet') + expect(response.body).toEqual('Echec de la suppression de l\'environnement') }) }) }) diff --git a/apps/server/src/routes/project-permission.spec.js b/apps/server/src/routes/project-permission.spec.js index e061011e3..29ee84ef1 100644 --- a/apps/server/src/routes/project-permission.spec.js +++ b/apps/server/src/routes/project-permission.spec.js @@ -99,7 +99,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(404) - expect(response.body).toEqual('Permissions non trouvées: Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la récupération des permissions de l\'environnement') }) }) @@ -130,7 +130,7 @@ describe('Project routes', () => { expect(response.json()).toMatchObject(newPermission) }) - it('Should not set a permission if Vous n\'êtes pas membre du projet', async () => { + it('Should not set a permission if not project member', async () => { const randomDbSetup = createRandomDbSetup({}) const newPermission = randomDbSetup.project.environments[0].permissions[0] const owner = randomDbSetup.project.users.find(user => user.role === 'owner') @@ -146,7 +146,7 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual('Permissions non créées : Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la création d\'une permission') }) }) @@ -201,7 +201,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(400) - expect(response.body).toEqual('Permission non modifiée : La permission du owner du projet ne peut être modifiée') + expect(response.body).toEqual('Echec de la mise à jour de la permission') }) it('Should not update a permission if not permitted on given environment', async () => { @@ -222,7 +222,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(400) - expect(response.body).toEqual('Permission non modifiée : Le requérant doit avoir des droits sur l\'environnement pour modifier des permissions') + expect(response.body).toEqual('Echec de la mise à jour de la permission') }) }) @@ -274,7 +274,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('Permission non supprimée : La permission du owner du projet ne peut être supprimée') + expect(response.body).toEqual('Echec de la suppression de la permission') }) it('Should not delete permission if not permitted on given environment', async () => { @@ -294,7 +294,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('Permission non supprimée : Le requérant doit avoir des droits sur l\'environnement pour supprimer des permissions') + expect(response.body).toEqual('Echec de la suppression de la permission') }) }) }) diff --git a/apps/server/src/routes/project-repository.spec.js b/apps/server/src/routes/project-repository.spec.js index 0ab3879d9..a2abf96b6 100644 --- a/apps/server/src/routes/project-repository.spec.js +++ b/apps/server/src/routes/project-repository.spec.js @@ -154,7 +154,7 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(200) expect(response.body).toBeDefined() - expect(response.body).toEqual('Dépôt mis à jour') + expect(response.body).toEqual('Dépôt mis à jour avec succès') }) it('Should should not update a repository if invalid keys', async () => { @@ -179,7 +179,7 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual('Dépôt non mis à jour') + expect(response.body).toEqual('Echec de la mise à jour du dépôt') }) }) diff --git a/apps/server/src/routes/project-user.spec.js b/apps/server/src/routes/project-user.spec.js index e2d81d66b..e2d368bd6 100644 --- a/apps/server/src/routes/project-user.spec.js +++ b/apps/server/src/routes/project-user.spec.js @@ -95,7 +95,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(404) expect(response.body).toBeDefined() - expect(response.body).toEqual('Echec de récupération des membres du projet: Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la récupération des membres du projet') }) }) @@ -149,7 +149,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual('Utilisateur non ajouté au projet : L\'utilisateur est déjà membre du projet') + expect(response.body).toEqual('Echec de l\'ajout de l\'utilisateur au projet') }) it('Should not add an user if project is missing', async () => { @@ -167,7 +167,7 @@ describe('User routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual('Utilisateur non ajouté au projet : Projet introuvable') + expect(response.body).toEqual('Echec de l\'ajout de l\'utilisateur au projet') }) }) @@ -245,7 +245,7 @@ describe('User routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('L\'utilisateur ne peut être retiré du projet : Projet introuvable') + expect(response.body).toEqual('Echec de la suppression de l\'utilisateur dans le projet') }) it('Should not remove an user if requestor is not member himself', async () => { @@ -263,7 +263,7 @@ describe('User routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('L\'utilisateur ne peut être retiré du projet : Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la suppression de l\'utilisateur dans le projet') }) it('Should not remove an user if user is not member', async () => { @@ -283,7 +283,7 @@ describe('User routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('L\'utilisateur ne peut être retiré du projet : L\'utilisateur n\'est pas membre du projet') + expect(response.body).toEqual('Echec de la suppression de l\'utilisateur dans le projet') }) }) }) diff --git a/apps/server/src/routes/project.spec.js b/apps/server/src/routes/project.spec.js index 86711428e..b5a2e6b62 100644 --- a/apps/server/src/routes/project.spec.js +++ b/apps/server/src/routes/project.spec.js @@ -110,7 +110,7 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(404) expect(response.body.json).not.toBeDefined() expect(response.body).toBeDefined() - expect(response.body).toEqual('Projets non trouvés: error message') + expect(response.body).toEqual('Echec de la récupération des projets de l\'utilisateur') }) }) @@ -142,10 +142,10 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(404) expect(response.body.json).not.toBeDefined() expect(response.body).toBeDefined() - expect(response.body).toEqual('Projet non trouvé: custom error message') + expect(response.body).toEqual('Echec de récupération du projet de l\'utilisateur') }) - it('Should not retreive a project when Vous n\'êtes pas membre du projet', async () => { + it('Should not retreive a project when not project member', async () => { const randomDbSetup = createRandomDbSetup({}) const owner = randomDbSetup.project.users.find(user => user.role === 'owner') @@ -160,7 +160,7 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(404) expect(response.body.json).not.toBeDefined() expect(response.body).toBeDefined() - expect(response.body).toEqual('Projet non trouvé: Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de récupération du projet de l\'utilisateur') }) }) @@ -255,7 +255,7 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual(`"${removedKey}" is required`) + expect(response.body).toEqual('Echec de la création du projet') }) it('Should not create a project if name already exists', async () => { @@ -284,7 +284,7 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual(`"${newProject.name}" existe déjà`) + expect(response.body).toEqual('Echec de la création du projet') }) it('Should not create a project if name exists in archives', async () => { @@ -314,7 +314,7 @@ describe('Project routes', () => { expect(response.statusCode).toEqual(400) expect(response.body).toBeDefined() - expect(response.body).toEqual(`"${newProject.name}" est archivé et n'est plus disponible`) + expect(response.body).toEqual('Echec de la création du projet') }) }) @@ -363,7 +363,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(400) - expect(response.body).toEqual('Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la mise à jour du projet') }) it('Should not update a project description if description is invalid', async () => { @@ -382,7 +382,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(400) - expect(response.body).toEqual(`"description" length must be less than or equal to ${descriptionMaxLength} characters long`) + expect(response.body).toEqual('Echec de la mise à jour du projet') }) }) @@ -430,7 +430,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('Vous n\'êtes pas membre du projet') + expect(response.body).toEqual('Echec de la suppression du projet') }) it('Should not archive a project if requestor is not owner', async () => { @@ -447,7 +447,7 @@ describe('Project routes', () => { .end() expect(response.statusCode).toEqual(403) - expect(response.body).toEqual('Vous n\'êtes pas souscripteur du projet') + expect(response.body).toEqual('Echec de la suppression du projet') }) }) }) diff --git a/apps/server/src/utils/logger.js b/apps/server/src/utils/logger.js index 0a464a4c5..189b5e940 100644 --- a/apps/server/src/utils/logger.js +++ b/apps/server/src/utils/logger.js @@ -1,5 +1,3 @@ -import kebabCase from 'lodash.kebabcase' - export const loggerConf = { development: { transport: { @@ -16,14 +14,36 @@ export const loggerConf = { test: false, } -export const getLogInfos = (data) => { +export const addReqLogs = ({ req, error, description, extras }) => { const e = new Error() const frame = e.stack.split('\n')[2] - const fileName = frame.split(' ')[6].split('/').reverse()[0].split('.')[0] - const functionName = frame.split(' ')[5] - return { - section: fileName, - action: kebabCase(functionName), - data, + + let logInfos = { + file: frame.split(' ')[6].split(':')[0].split('src/')[1], + function: frame.split(' ')[5].split('.')[1], + requestorId: req.session?.user?.id, + requestorGroups: req.session?.user?.groups, + description, } + + if (extras) { + logInfos = { + ...logInfos, + ...extras, + } + } + + if (error) { + req.log.error({ + ...logInfos, + error: { + message: error?.message, + trace: error?.trace, + }, + }, + 'request processing') + return + } + + req.log.info(logInfos, 'request processing') } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b85546d60..e92e982b9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -173,9 +173,6 @@ importers: fastify-keycloak-adapter: specifier: ^2.0.1 version: 2.0.1 - lodash.kebabcase: - specifier: ^4.1.1 - version: 4.1.1 mustache: specifier: ^4.2.0 version: 4.2.0 @@ -2156,7 +2153,7 @@ packages: resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} dependencies: base64-js: 1.5.1 - ieee754: 1.1.13 + ieee754: 1.2.1 isarray: 1.0.0 dev: false @@ -5028,6 +5025,7 @@ packages: /lodash.kebabcase@4.1.1: resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + dev: true /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}