ci: docker_tag=ext chore(back): v1.0.4 logs IdNot enrichis
All checks were successful
build-and-push-ext / build_push (push) Successful in 26s

This commit is contained in:
dev4 2025-09-19 08:01:16 +00:00
parent 8c8b9ce7d6
commit 6a0c1ce817
6 changed files with 75 additions and 18 deletions

View File

@ -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:3004/authorized-client
IDNOT_REDIRECT_URI=http://local.4nkweb.com:3000/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_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 # Configuration serveur
APP_HOST=dev4.4nkweb.com APP_HOST=dev4.4nkweb.com
@ -44,10 +44,12 @@ NEXT_PUBLIC_DEFAULT_STORAGE_URLS=https://dev4.4nkweb.com/storage
# WS # WS
# RELAY_URLS=wss://demo.4nkweb.com/ws # RELAY_URLS=wss://demo.4nkweb.com/ws
RELAY_URLS=wss://dev4.4nkweb.com/ws RELAY_URLS=wss://dev4.4nkweb.com/ws
# SIGNER_WS_URL=ws://dev4.4nkweb.com/signer/ # 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 SIGNER_BASE_URL=https://dev3.4nkweb.com
# IHM URLS # IHM URLS
# VITE_BOOTSTRAPURL=http://sdk_relay:8090/ # VITE_BOOTSTRAPURL=http://sdk_relay:8090/
VITE_BOOTSTRAPURL=https://dev4.4nkweb.com/ws/ VITE_BOOTSTRAPURL=https://dev4.4nkweb.com/ws/

View File

@ -25,3 +25,14 @@
### v1.0.3+log ### v1.0.3+log
- Ajout dun log danalyse non sensible dans `IdNotController.authenticate` pour tracer: `profile_idn`, `entity_idn`, `entite.typeEntite.name`, `entite.codeCrpcen`, `statutDuRattachement`, `typeLien.name`. - Ajout dun log danalyse 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.

View File

@ -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. 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 lURL appelée, le `status`, le `statusText` et un extrait de réponse (<= 500 caractères) pour: token, userData, officeLocationData, rattachements.
### Dépendances clés ### Dépendances clés
- **HTTP**: `express`, `cors` - **HTTP**: `express`, `cors`
- **Infra**: `pg`, `dotenv` - **Infra**: `pg`, `dotenv`

View File

@ -1,6 +1,6 @@
{ {
"name": "lecoffre-back-mini", "name": "lecoffre-back-mini",
"version": "1.0.3", "version": "1.0.4",
"description": "Mini serveur avec une route /api/ping", "description": "Mini serveur avec une route /api/ping",
"main": "dist/server.js", "main": "dist/server.js",
"scripts": { "scripts": {

View File

@ -1,6 +1,7 @@
import fetch from 'node-fetch'; import fetch from 'node-fetch';
import { IdNotUser, ECivility, EOfficeStatus, EIdnotRole } from '../../types'; import { IdNotUser, ECivility, EOfficeStatus, EIdnotRole } from '../../types';
import { ValidationError, UnauthorizedError, ExternalServiceError } from '../../types/errors'; import { ValidationError, UnauthorizedError, ExternalServiceError } from '../../types/errors';
import { Logger } from '../../utils/logger';
export class IdNotService { export class IdNotService {
static async exchangeCodeForTokens(code: string) { static async exchangeCodeForTokens(code: string) {
@ -32,6 +33,13 @@ export class IdNotService {
}); });
if (!response.ok) { 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) { if (response.status === 400) {
throw new ValidationError('Invalid authorization code received from IdNot'); throw new ValidationError('Invalid authorization code received from IdNot');
} }
@ -61,6 +69,13 @@ export class IdNotService {
const response = await fetch(url, { method: 'GET' }); const response = await fetch(url, { method: 'GET' });
if (!response.ok) { 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}`); 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 url = `${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/entites/${idNot}/personnes?` + searchParams;
const json = await ( const response = await fetch(url, { method: 'GET' });
await fetch(url, { if (!response.ok) {
method: 'GET' const text = await response.text().catch(() => '');
}) Logger.error('IdNot getOfficeRattachements failed', {
).json(); 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; return json;
} }
@ -101,11 +123,19 @@ export class IdNotService {
key: IDNOT_API_KEY key: IDNOT_API_KEY
}); });
const userData = await ( const userUrl = `${IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${profileIdn}?` + searchParams;
await fetch(`${IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${profileIdn}?` + searchParams, { const userResp = await fetch(userUrl, { method: 'GET' });
method: 'GET' if (!userResp.ok) {
}) const text = await userResp.text().catch(() => '');
).json(); 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; return userData;
} }
@ -121,11 +151,19 @@ export class IdNotService {
key: IDNOT_API_KEY key: IDNOT_API_KEY
}); });
const officeLocationData = await ( const locUrl = `${IDNOT_API_BASE_URL}${locationsUrl}?` + searchParams;
await fetch(`${IDNOT_API_BASE_URL}${locationsUrl}?` + searchParams, { const locResp = await fetch(locUrl, { method: 'GET' });
method: 'GET' if (!locResp.ok) {
}) const text = await locResp.text().catch(() => '');
).json(); 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; return officeLocationData;
} }

View File

@ -22,3 +22,6 @@ Axes de tests pour `lecoffre-back-mini` (sans exemples dimplémentation).
Focus régression v1.0.3: Focus régression v1.0.3:
- Cas « utilisateur non rattaché à une étude » doit renvoyer `403` (plus de 502). - 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 dun log avec `url`, `status`, `statusText` et `bodySnippet`.