From edb4726d5f873e9f5ef3d9a2a2a38ca7df422823 Mon Sep 17 00:00:00 2001 From: Manus Date: Fri, 2 Oct 2026 15:01:42 +0000 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Correction=20recette=20:=20une=20?= =?UTF-8?q?variable=20REFERENTIEL=5FIA=5FTOKEN=20vide=20masquait=20le=20se?= =?UTF-8?q?cret=20Docker=20mont=C3=A9.=20Le=20serveur=20privil=C3=A9gie=20?= =?UTF-8?q?d=C3=A9sormais=20un=20jeton=20explicite=20non=20vide=20et=20bas?= =?UTF-8?q?cule=20vers=20le=20fichier=20secret=20sinon.=20Test=20de=20non-?= =?UTF-8?q?r=C3=A9gression=20ajout=C3=A9=20;=2089=20tests,=20TypeScript=20?= =?UTF-8?q?et=20build=20valid=C3=A9s.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/_core/env.ts | 11 ++++++++++- server/referentialIa.test.ts | 16 +++++++++++++++- todo.md | 5 +++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/server/_core/env.ts b/server/_core/env.ts index c2f52fc..f4dfcca 100644 --- a/server/_core/env.ts +++ b/server/_core/env.ts @@ -10,6 +10,12 @@ export function readSecretFile(path: string | undefined): string { } } +/** Préfère un secret explicite, puis le secret Docker si la variable est absente ou vide. */ +export function resolveServerSecret(value: string | undefined, secretPath: string | undefined): string { + const environmentValue = value?.trim(); + return environmentValue || readSecretFile(secretPath); +} + export const ENV = { appId: process.env.VITE_APP_ID ?? "", cookieSecret: process.env.JWT_SECRET ?? "", @@ -22,5 +28,8 @@ export const ENV = { mistralApiKey: process.env.MISTRAL_API_KEY ?? "", geminiApiKey: process.env.GEMINI_API_KEY ?? "", referentielIaUrl: process.env.REFERENTIEL_IA_URL ?? "", - referentielIaToken: process.env.REFERENTIEL_IA_TOKEN ?? readSecretFile(process.env.REFERENTIEL_IA_TOKEN_FILE), + referentielIaToken: resolveServerSecret( + process.env.REFERENTIEL_IA_TOKEN, + process.env.REFERENTIEL_IA_TOKEN_FILE, + ), }; diff --git a/server/referentialIa.test.ts b/server/referentialIa.test.ts index 27d0469..0e66a35 100644 --- a/server/referentialIa.test.ts +++ b/server/referentialIa.test.ts @@ -7,7 +7,7 @@ import { testReferentialIaConnection, type ReferentielIaConnection, } from "./referentialIa"; -import { readSecretFile } from "./_core/env"; +import { readSecretFile, resolveServerSecret } from "./_core/env"; const connection: ReferentielIaConnection = { baseUrl: "https://referentiel-ia.recette.santinova-soft.org", @@ -34,6 +34,20 @@ describe("Référentiel IA", () => { } }); + it("utilise le secret monté lorsque la variable d'environnement est vide", () => { + const directory = mkdtempSync(join(tmpdir(), "referentiel-ia-")); + const secretFile = join(directory, "token"); + try { + writeFileSync(secretFile, " mounted-secret\n", { mode: 0o600 }); + + expect(resolveServerSecret("", secretFile)).toBe("mounted-secret"); + expect(resolveServerSecret(" ", secretFile)).toBe("mounted-secret"); + expect(resolveServerSecret("environment-secret", secretFile)).toBe("environment-secret"); + } finally { + rmSync(directory, { recursive: true, force: true }); + } + }); + it("transmet une requête OpenAI-compatible à la passerelle sélectionnée", async () => { let receivedUrl = ""; let receivedInit: RequestInit | undefined; diff --git a/todo.md b/todo.md index 02f825e..cd3d87a 100644 --- a/todo.md +++ b/todo.md @@ -9,6 +9,11 @@ - [x] Vérifier une invocation contrôlée via la passerelle sans utiliser de document métier - [ ] Vérifier une extraction réelle via la passerelle et sa traçabilité dans le Référentiel IA +## Correction connexion Référentiel IA — recette — 02/10/2026 +- [x] Identifier le repli bloqué par une variable de jeton vide dans le conteneur +- [x] Corriger la lecture du secret Docker lorsqu’une variable vide est présente +- [ ] Valider et déployer le correctif en recette sans toucher à MySQL ni au volume PDF + ## Import manuel des connecteurs web — 30/09/2026 - [x] Analyser le flux serveur d’import web et définir le déclenchement manuel sécurisé - [x] Ajouter l’API de déclenchement, le suivi de résultat et le bouton avec confirmation