diff --git a/package.json b/package.json index e159e0d..fd83e2c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lecoffre-back-mini", - "version": "1.0.8", + "version": "1.0.9", "description": "Mini serveur avec une route /api/ping", "main": "dist/server.js", "scripts": { diff --git a/src/controllers/idnot.controller.ts b/src/controllers/idnot.controller.ts index 07db594..11bae26 100644 --- a/src/controllers/idnot.controller.ts +++ b/src/controllers/idnot.controller.ts @@ -109,21 +109,16 @@ export class IdNotController { profile_idn: payload?.profile_idn }); - // Try standard flow with profile_idn; otherwise fallback via rattachements using sub - let userData: any; - if (payload?.profile_idn && typeof payload.profile_idn === 'string') { - userData = await IdNotService.getUserData(payload.profile_idn); - } else { - Logger.info('IdNot fallback via rattachements using sub'); - const rattachementsJson = await IdNotService.getUserRattachements(payload.sub); - const results: any[] = Array.isArray(rattachementsJson?.result) ? rattachementsJson.result : []; - // pick first office rattachement with a defined entite - const candidate = results.find((r: any) => r?.entite?.typeEntite?.name === 'office') || results[0]; - if (!candidate) { - throw new ForbiddenError('User not attached to an office'); - } - userData = candidate; + // Always use sub for rattachements API as it's more reliable than profile_idn + Logger.info('IdNot using rattachements API with sub', { sub: payload.sub }); + const rattachementsJson = await IdNotService.getUserRattachements(payload.sub); + const results: any[] = Array.isArray(rattachementsJson?.result) ? rattachementsJson.result : []; + // pick first office rattachement with a defined entite + const candidate = results.find((r: any) => r?.entite?.typeEntite?.name === 'office') || results[0]; + if (!candidate) { + throw new ForbiddenError('User not attached to an office'); } + const userData = candidate; // Log d'analyse (non sensible) pour diagnostiquer les cas de rattachement Logger.info('IdNot userData summary', { diff --git a/src/services/idnot/index.ts b/src/services/idnot/index.ts index 8c1ba54..2a12792 100644 --- a/src/services/idnot/index.ts +++ b/src/services/idnot/index.ts @@ -79,18 +79,18 @@ export class IdNotService { const baseUrl = endpoints[i]; const searchParams = searchParamsVariants[i]; const url = `${baseUrl}?${searchParams}`; - + try { Logger.info(`IdNot getUserRattachements attempt ${i + 1}`, { url, idNot }); - + const response = await fetch(url, { method: 'GET' }); - + if (response.ok) { const data = await response.json(); Logger.info(`IdNot getUserRattachements success`, { url, idNot }); return data; } - + // Log détaillé pour les erreurs const text = await response.text().catch(() => ''); Logger.error(`IdNot getUserRattachements attempt ${i + 1} failed`, { @@ -100,31 +100,31 @@ export class IdNotService { statusText: response.statusText, bodySnippet: text?.substring(0, 500) }); - + // Si c'est une erreur 4xx (sauf 404), ne pas réessayer if (response.status >= 400 && response.status < 500 && response.status !== 404) { throw new ExternalServiceError('IdNot', `Failed to fetch rattachements: ${response.status} ${response.statusText}`); } - + } catch (error) { Logger.error(`IdNot getUserRattachements attempt ${i + 1} error`, { url, idNot, error: error instanceof Error ? error.message : String(error) }); - + // Si c'est la dernière tentative, relancer l'erreur if (i === endpoints.length - 1) { throw error; } } - + // Attendre un peu avant la prochaine tentative if (i < endpoints.length - 1) { await new Promise(resolve => setTimeout(resolve, 300 * (i + 1))); } } - + throw new ExternalServiceError('IdNot', 'Failed to fetch rattachements after all attempts'); } @@ -159,20 +159,20 @@ export class IdNotService { } static async getUserData(profileIdn: string) { - const { IDNOT_API_KEY, IDNOT_API_BASE_URL } = process.env; + const { IDNOT_API_KEY, IDNOT_ANNUARY_BASE_URL } = process.env; - if (!IDNOT_API_KEY || !IDNOT_API_BASE_URL) { - throw new Error('Missing IDnot API key or base URL'); + if (!IDNOT_API_KEY || !IDNOT_ANNUARY_BASE_URL) { + throw new Error('Missing IDnot API key or annuary base URL'); } // Essayer plusieurs variantes d'endpoints selon la documentation API Annuaire V2 const endpoints = [ // Format correct selon doc: /api/pp/v2/personnes/{id}/rattachements - `${IDNOT_API_BASE_URL}/api/pp/v2/personnes/${profileIdn}/rattachements`, + `${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/personnes/${profileIdn}/rattachements`, // Variante sans /annuaire dans l'URL de base - `${IDNOT_API_BASE_URL.replace('/annuaire', '')}/api/pp/v2/personnes/${profileIdn}/rattachements`, + `${IDNOT_ANNUARY_BASE_URL.replace('/annuaire', '')}/api/pp/v2/personnes/${profileIdn}/rattachements`, // Ancien format (fallback) - `${IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${profileIdn}` + `${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/rattachements/${profileIdn}` ]; const searchParams = new URLSearchParams({ @@ -182,18 +182,18 @@ export class IdNotService { for (let i = 0; i < endpoints.length; i++) { const baseUrl = endpoints[i]; const userUrl = `${baseUrl}?${searchParams}`; - + try { Logger.info(`IdNot getUserData attempt ${i + 1}`, { url: userUrl, profileIdn }); - + const userResp = await fetch(userUrl, { method: 'GET' }); - + if (userResp.ok) { const userData = await userResp.json(); Logger.info(`IdNot getUserData success`, { url: userUrl, profileIdn }); return userData; } - + // Log détaillé pour les erreurs const text = await userResp.text().catch(() => ''); Logger.error(`IdNot getUserData attempt ${i + 1} failed`, { @@ -203,31 +203,31 @@ export class IdNotService { statusText: userResp.statusText, bodySnippet: text?.substring(0, 500) }); - + // Si c'est une erreur 4xx (sauf 404), ne pas réessayer if (userResp.status >= 400 && userResp.status < 500 && userResp.status !== 404) { throw new ExternalServiceError('IdNot', `Failed to fetch user data: ${userResp.status} ${userResp.statusText}`); } - + } catch (error) { Logger.error(`IdNot getUserData attempt ${i + 1} error`, { url: userUrl, profileIdn, error: error instanceof Error ? error.message : String(error) }); - + // Si c'est la dernière tentative, relancer l'erreur if (i === endpoints.length - 1) { throw error; } } - + // Attendre un peu avant la prochaine tentative if (i < endpoints.length - 1) { await new Promise(resolve => setTimeout(resolve, 200 * (i + 1))); } } - + throw new ExternalServiceError('IdNot', 'Failed to fetch user data after all attempts'); }