From 6a0c1ce81793a50b1b99181aee2365631e635f81 Mon Sep 17 00:00:00 2001 From: dev4 Date: Fri, 19 Sep 2025 08:01:16 +0000 Subject: [PATCH] ci: docker_tag=ext chore(back): v1.0.4 logs IdNot enrichis --- .env.exemple | 6 ++-- CHANGELOG.md | 11 ++++++ docs/analyse.md | 3 ++ package.json | 2 +- src/services/idnot/index.ts | 68 +++++++++++++++++++++++++++++-------- tests/analyse.md | 3 ++ 6 files changed, 75 insertions(+), 18 deletions(-) diff --git a/.env.exemple b/.env.exemple index d674744..bf2c0c4 100644 --- a/.env.exemple +++ b/.env.exemple @@ -7,7 +7,7 @@ IDNOT_ANNUARY_BASE_URL=https://qual-api.notaires.fr/annuaire # IDNOT_REDIRECT_URI=http://local.4nkweb.com:3004/authorized-client IDNOT_REDIRECT_URI=http://local.4nkweb.com:3000/authorized-client IDNOT_TOKEN_URL=https://qual-connexion.idnot.fr/user/IdPOAuth2/token/idnot_idp_v1 -IDNOT_API_BASE_URL=https://qual-api.notaires.fr/annuaire +IDNOT_API_BASE_URL=https://qual-api.notaires.fr # Configuration serveur APP_HOST=dev4.4nkweb.com @@ -44,10 +44,12 @@ NEXT_PUBLIC_DEFAULT_STORAGE_URLS=https://dev4.4nkweb.com/storage # WS # RELAY_URLS=wss://demo.4nkweb.com/ws RELAY_URLS=wss://dev4.4nkweb.com/ws + # SIGNER_WS_URL=ws://dev4.4nkweb.com/signer/ -SIGNER_WS_URL=ws://dev3.4nkweb.com/signer/ +SIGNER_WS_URL=ws://dev3.4nkweb.com SIGNER_BASE_URL=https://dev3.4nkweb.com + # IHM URLS # VITE_BOOTSTRAPURL=http://sdk_relay:8090/ VITE_BOOTSTRAPURL=https://dev4.4nkweb.com/ws/ diff --git a/CHANGELOG.md b/CHANGELOG.md index f4b7b15..9c589b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,3 +25,14 @@ ### v1.0.3+log - Ajout d’un log d’analyse non sensible dans `IdNotController.authenticate` pour tracer: `profile_idn`, `entity_idn`, `entite.typeEntite.name`, `entite.codeCrpcen`, `statutDuRattachement`, `typeLien.name`. + +### v1.0.4 + +- Logs IdNot enrichis dans `IdNotService`: + - Journalisation des URLs, statuts, statusText et extrait (<=500 chars) des réponses en échec pour: + - `exchangeCodeForTokens` + - `getUserRattachements` + - `getOfficeRattachements` + - `getUserData` + - `getOfficeLocationData` +- Objectif: faciliter le diagnostic des environnements et des bases URL. diff --git a/docs/analyse.md b/docs/analyse.md index 57ce57f..50ec419 100644 --- a/docs/analyse.md +++ b/docs/analyse.md @@ -38,6 +38,9 @@ Analyse synthétique de `lecoffre-back-mini` (Express + TypeScript). Note: dans `IdNotController.authenticate`, toute erreur possédant un `statusCode` 4xx (ou un `name` applicatif connu) est relancée telle quelle afin d’éviter un fallback en 502. +### Observabilité IdNot +- En cas d’échec côté IdNot, les logs indiquent désormais l’URL appelée, le `status`, le `statusText` et un extrait de réponse (<= 500 caractères) pour: token, userData, officeLocationData, rattachements. + ### Dépendances clés - **HTTP**: `express`, `cors` - **Infra**: `pg`, `dotenv` diff --git a/package.json b/package.json index 3117337..f3856ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lecoffre-back-mini", - "version": "1.0.3", + "version": "1.0.4", "description": "Mini serveur avec une route /api/ping", "main": "dist/server.js", "scripts": { diff --git a/src/services/idnot/index.ts b/src/services/idnot/index.ts index 9ca3f43..6daa445 100644 --- a/src/services/idnot/index.ts +++ b/src/services/idnot/index.ts @@ -1,6 +1,7 @@ import fetch from 'node-fetch'; import { IdNotUser, ECivility, EOfficeStatus, EIdnotRole } from '../../types'; import { ValidationError, UnauthorizedError, ExternalServiceError } from '../../types/errors'; +import { Logger } from '../../utils/logger'; export class IdNotService { static async exchangeCodeForTokens(code: string) { @@ -32,6 +33,13 @@ export class IdNotService { }); if (!response.ok) { + const text = await response.text().catch(() => ''); + Logger.error('IdNot token exchange failed', { + url: IDNOT_TOKEN_URL, + status: response.status, + statusText: response.statusText, + bodySnippet: text?.substring(0, 500) + }); if (response.status === 400) { throw new ValidationError('Invalid authorization code received from IdNot'); } @@ -61,6 +69,13 @@ export class IdNotService { const response = await fetch(url, { method: 'GET' }); if (!response.ok) { + const text = await response.text().catch(() => ''); + Logger.error('IdNot getUserRattachements failed', { + url, + status: response.status, + statusText: response.statusText, + bodySnippet: text?.substring(0, 500) + }); throw new Error(`Failed to fetch rattachements: ${response.status} ${response.statusText}`); } @@ -81,11 +96,18 @@ export class IdNotService { const url = `${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/entites/${idNot}/personnes?` + searchParams; - const json = await ( - await fetch(url, { - method: 'GET' - }) - ).json(); + const response = await fetch(url, { method: 'GET' }); + if (!response.ok) { + const text = await response.text().catch(() => ''); + Logger.error('IdNot getOfficeRattachements failed', { + url, + status: response.status, + statusText: response.statusText, + bodySnippet: text?.substring(0, 500) + }); + throw new Error(`Failed to fetch office rattachements: ${response.status} ${response.statusText}`); + } + const json = await response.json(); return json; } @@ -101,11 +123,19 @@ export class IdNotService { key: IDNOT_API_KEY }); - const userData = await ( - await fetch(`${IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${profileIdn}?` + searchParams, { - method: 'GET' - }) - ).json(); + const userUrl = `${IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${profileIdn}?` + searchParams; + const userResp = await fetch(userUrl, { method: 'GET' }); + if (!userResp.ok) { + const text = await userResp.text().catch(() => ''); + Logger.error('IdNot getUserData failed', { + url: userUrl, + status: userResp.status, + statusText: userResp.statusText, + bodySnippet: text?.substring(0, 500) + }); + throw new Error(`Failed to fetch user data: ${userResp.status} ${userResp.statusText}`); + } + const userData = await userResp.json(); return userData; } @@ -121,11 +151,19 @@ export class IdNotService { key: IDNOT_API_KEY }); - const officeLocationData = await ( - await fetch(`${IDNOT_API_BASE_URL}${locationsUrl}?` + searchParams, { - method: 'GET' - }) - ).json(); + const locUrl = `${IDNOT_API_BASE_URL}${locationsUrl}?` + searchParams; + const locResp = await fetch(locUrl, { method: 'GET' }); + if (!locResp.ok) { + const text = await locResp.text().catch(() => ''); + Logger.error('IdNot getOfficeLocationData failed', { + url: locUrl, + status: locResp.status, + statusText: locResp.statusText, + bodySnippet: text?.substring(0, 500) + }); + throw new Error(`Failed to fetch office location data: ${locResp.status} ${locResp.statusText}`); + } + const officeLocationData = await locResp.json(); return officeLocationData; } diff --git a/tests/analyse.md b/tests/analyse.md index e89c96d..ae26707 100644 --- a/tests/analyse.md +++ b/tests/analyse.md @@ -22,3 +22,6 @@ Axes de tests pour `lecoffre-back-mini` (sans exemples d’implémentation). Focus régression v1.0.3: - Cas « utilisateur non rattaché à une étude » doit renvoyer `403` (plus de 502). + +### Traces attendues (v1.0.4) +- En cas d’échec IdNot, vérifier la présence d’un log avec `url`, `status`, `statusText` et `bodySnippet`.