Skip to content

fix(build): #ENABLING-1200 axios sain, build compatible, dépendances propres (v2.0.0) - #22

Open
pascalsaussier-edifice wants to merge 8 commits into
develop-enablingfrom
fix-ENABLING-1200-bump-axios
Open

fix(build): #ENABLING-1200 axios sain, build compatible, dépendances propres (v2.0.0)#22
pascalsaussier-edifice wants to merge 8 commits into
develop-enablingfrom
fix-ENABLING-1200-bump-axios

Conversation

@pascalsaussier-edifice

Copy link
Copy Markdown

Résumé

Reconstruction majeure d'entcore-toolkit pour éliminer l'exposition CVE d'axios (CVE-2020-28168, CVE-2021-3749, CVE-2023-45857) sur les 34 apps consommatrices, sans qu'aucune d'elles n'ait à modifier sa configuration de build.

  • Bump axios ^0.15.2^1.20.0.
  • Remplacement de l'émission JS de gulp-typescript par esbuild --bundle --platform=browser --target=es2015, qui inline et transpile axios (gulp-typescript/tsc reste utilisé uniquement pour les .d.ts).
  • Plugin esbuild qui stub l'import de l'adaptateur fetch d'axios — code mort (XHR gagne toujours en navigateur réel), mais seul porteur d'un générateur async natif que le pipeline Babel/IE11 d'Angular CLI (entcore/admin) ne sait pas transpiler (Cannot find module '@babel/runtime/helpers/regeneratorValues').
  • axios basculé de dependencies/peerDependencies vers devDependencies uniquement (inliné dans le bundle, plus de dépendance runtime).
  • Suppression de lodash, core-js, merge2, @types/node : jamais utilisés dans le code source, vérifié sans dépendance fantôme sur 35 apps connues + entcore/admin.
  • Suppression des configs orphelines config/rollup.bundle.config.js et config/tsconfig.compile.json (pipeline rollup jamais invoqué depuis le passage à gulp-typescript).
  • Version passée en majeure (2.0.0) : le changement de format de dist/ (fichier bundlé unique au lieu d'un fichier par module) et le changement de comportement de build le justifient. Une version majeure n'est pas captée automatiquement par les ranges ^1.x des apps consommatrices — pas de casse silencieuse pour celles pas encore migrées (US3 / ENABLING-1202).
  • CHANGELOG.md créé (aucune convention préexistante), documentant breaking changes / sécurité / suppressions.

Pourquoi une PR aussi large

Le fix de sécurité lui-même est trivial (bump de version). Ce qui a élargi le scope, documenté au fil de l'eau dans axios-cve-audit.md et PLAN-remediation-axios.md :

  • Le webpack réellement utilisé par les apps consommatrices n'est pas celui déclaré (webpack-stream embarque son propre webpack 1.15.0) et ne parse pas la syntaxe moderne d'axios — d'où le bundling esbuild.
  • Une fois qu'on touche déjà au bundling, autant assainir dependencies/peerDependencies/devDependencies dans la même version majeure plutôt que d'en faire une seconde vague.
  • entcore/admin (Angular CLI), trouvée après coup via un recoupement d'exhaustivité de l'audit, a révélé un second problème de compatibilité (Babel/regenerator) — corrigé par le même changement (stub de l'adaptateur fetch), sans toucher à entcore/admin.

Vérifications réelles effectuées

  • Build réel (npm run build, esbuild + gulp-typescript) : bundle produit, API exportée inchangée (AbstractCollection, AbstractCrud, AbstractModel, Autosave, Collection, Crud, Eventer, Mix, Model, Provider, Selection, TypedArray).
  • pages et edt (famille gulp/webpack-stream) : npm link + gulp build réel, exit 0, sans régression.
  • entcore/admin (Angular CLI) : npm link + ng build réel, exit 0 — corrige l'échec regeneratorValues initial.
  • calendar : une erreur TypeScript (TS2610 sur Selection.all) a été détectée pendant ces tests, mais confirmée pré-existante (antérieure à cette branche, via git merge-base contre develop-enabling) — sans rapport avec ce changement, à traiter dans le code propre de calendar lors de sa propre migration (US3).
  • Phantom-dependency check (lodash/core-js/merge2/@types/node) sur 35 apps connues + entcore/admin : aucun usage implicite détecté.
  • Aucun import profond (entcore-toolkit/dist/...) trouvé sur les 34 apps consommatrices connues — le passage à un dist/index.js unique ne casse rien côté consommateurs.

Documentation associée

Test plan

  • npm run build sans erreur
  • Build réel sur pages, edt (gulp/webpack-stream)
  • Build réel sur entcore/admin (Angular CLI)
  • Phantom-dependency check sur le parc connu
  • Revue de code
  • Publication npm de la version majeure après merge

🤖 Generated with Claude Code

axios ^0.15.2 était vulnérable aux CVE-2020-28168, CVE-2021-3749 et
CVE-2023-45857, ainsi qu'à un ensemble d'advisories additionnelles
plus récentes. Bump vers ^1.20.0 (dernière version stable) dans
dependencies et peerDependencies.

package-lock.json régénéré (l'ancien lockfile était un stub vide).
Build gulp vérifié OK, npm audit ne remonte plus axios.
L'ancien "1.4.0-dev.3" référençait la branche dev (dist-tag "dev"),
plus pertinente ici. build.sh publish taggue le paquet npm avec le
nom de la branche courante (--tag $GIT_BRANCH) : sur develop-enabling,
la version doit donc porter ce suffixe pour rester cohérente avec le
dist-tag qui sera réellement publié.

Bump en patch (1.4.0 -> 1.4.1) puisqu'aucune API publique ne change,
suffixe de prerelease develop-enabling.0 pour ne pas être résolu par
un range semver classique tant que ce n'est pas mergé sur master.
lodash, core-js, merge2, @types/node : jamais importés dans src/,
retirés de dependencies (et peerDependencies pour lodash/core-js).
typescript : utilisé uniquement par gulpfile.js, déplacé de
dependencies vers devDependencies explicite (déjà présent en
peerDependencies pour la compatibilité de types côté consommateurs).

rollup, rollup-plugin-typescript, rollup-plugin-uglify, uglify-js :
config/rollup.bundle.config.js n'est invoquée par aucun script réel
(package.json, build.sh, Jenkinsfile) depuis le passage au pipeline
gulp-typescript. Fichier de config retiré avec ses dépendances.
config/tsconfig.compile.json (compagnon de cette config, module
es2015) également orpheline, retirée.

@types/core-js conservé : nécessaire à la compilation via l'option
"types" du compilateur TS dans gulpfile.js, indépendamment du
retrait du paquet runtime core-js.

Vérifié sans dépendance fantôme sur les 35 apps consommatrices
connues (19 Edifice + 16 CGI) : aucune ne relève de lodash/core-js/
merge2/@types/node/typescript via le hoisting d'entcore-toolkit.
L'émission JS passe désormais par esbuild (--bundle --platform=browser
--target=es2015 --format=cjs) au lieu de gulp-typescript, qui ne sert
plus qu'à générer les .d.ts (fonction compileDts). axios est ainsi
inliné et transpilé dans dist/index.js, consommable tel quel par le
webpack de 2016 embarqué dans webpack-stream côté apps clientes — sans
qu'elles aient à modifier leur configuration de build.

Cible ES2015 : la plus basse qu'esbuild sait émettre sans erreur sur
let/class (ES5 non supporté), et suffisamment basse pour que
async/await et les générateurs async d'axios soient redescendus via
des helpers plutôt que laissés en syntaxe native (voir
axios-cve-audit.md section 14 pour le détail des cibles testées).

Vérifié réellement (npm link + gulp build, sans contournement) sur
pages et calendar : build réussi, aucune régression.

merge2 n'est plus utilisé dans gulpfile.js (compileDts ne retourne
plus qu'un seul stream) : retiré des devDependencies.

dist/ régénéré : les fichiers .js par module (autosaver.js,
provider.js, etc.) disparaissent au profit d'un seul dist/index.js
bundlé et de son sourcemap ; les .d.ts restent inchangés (un par
module, nécessaires à la résolution de types des imports barrel).
Oubliée lors du bump initial : la version doit être majeure, pas
patch. Pas pour la raison d'origine (le fix esbuild fonctionne, un
range ^1.x qui le récupérerait automatiquement ne casserait plus
rien) mais pour deux ruptures réelles introduites par ailleurs :
- la structure de dist/ change (un seul index.js bundlé au lieu
  d'un fichier par module) — casse tout import profond
  (entcore-toolkit/dist/...) chez un consommateur inconnu ;
- le nettoyage de dependencies/peerDependencies (lodash, core-js,
  merge2, @types/node, typescript) — casse tout consommateur
  inconnu qui en dépendrait implicitement via le hoisting.

Aucune des deux n'a été détectée sur les 35 apps connues, mais un
range ^1.x ne doit pas capter cette version automatiquement pour
un consommateur qu'on n'a pas pu auditer.
Complète le nettoyage entamé plus tôt : axios était encore déclaré en
dependencies et peerDependencies, alors que le bundling esbuild (déjà
en place) l'inline entièrement dans dist/index.js — vérifié qu'aucun
require("axios") ne subsiste dans le bundle. Plus aucun consommateur
n'a donc besoin d'axios comme dépendance runtime ; il ne reste requis
qu'en devDependency, pour qu'esbuild puisse le bundler pendant le
build de la lib elle-même.

Rebuild + smoke test sur pages et edt (déjà validés précédemment) :
aucune régression.
Aucun CHANGELOG n'existait dans ce repo. Documente les breaking
changes de la 2.0.0 (structure de dist/, dépendances retirées, axios
devenu bundlé) pour que les consommateurs sachent quoi faire en cas
d'erreur au moment de leur montée de version (US3).
…le bundle

L'adaptateur fetch d'axios n'est jamais sélectionné en pratique (priorité
['xhr', 'http', 'fetch'], XHR gagne toujours en navigateur réel) mais c'est
le seul endroit du module qui contient un générateur async natif
(trackStream.js), que le pipeline Babel/regenerator d'un consommateur
ciblant IE11 (build Angular CLI de entcore/admin) échoue à transpiler
(Cannot find module '@babel/runtime/helpers/regeneratorValues'). Le stub
esbuild retire ce code mort du bundle, sans changement d'API.

Vérifié via un vrai `npm run build` puis un vrai `ng build` sur
entcore/admin (succès), et une régression-check sur pages et edt
(gulp build inchangé).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant