Skip to content

build: repair the lockfile, clear every npm advisory, and let CI see Node - #212

Merged
ogorzalka merged 1 commit into
mainfrom
support/npm-security-update
Sep 22, 2026
Merged

ogorzalka merged 1 commit into
mainfrom
support/npm-security-update

Conversation

@ogorzalka

Copy link
Copy Markdown
Member

Follows #211, which removed the yarn.lock that produced 35 of the 56 alerts.
This clears the remaining 21 — and explains why they were able to accumulate.

npm ci did not work on main

$ npm ci
npm error Invalid: lock file's emoji-regex@8.0.0 does not satisfy emoji-regex@10.6.0

The committed package-lock.json disagreed with itself, so a fresh clone could
not install with the one command that installs exactly what the lock says.

It went unnoticed because nothing exercised it. composer setup runs
npm install, which repairs such a lock in silence and reports success, and
no workflow ran Node at all. Both paths anyone actually walks were blind to
it.

With the lock repaired, every advisory clears

npm update, within the declared ranges:

Package Before After Patched at
axios 1.15.2 1.20.0 1.18.0
vite 7.3.2 7.3.6 7.3.5
postcss ≤ 8.5.22 8.5.28 8.5.23
nanoid < 3.3.12 3.3.19 3.3.12
esbuild 0.27.x 0.28.2 0.28.1
shell-quote ≤ 1.8.3 1.9.0 1.8.4
form-data < 4.0.6 4.0.6 4.0.6

npm audit: 7 vulnerabilities (1 critical, 5 high, 1 low) → 0.

The declared floor for axios moves from ^1.8.2 to ^1.20.0. The old range
still admitted the vulnerable version it named, which is what Dependabot #166
was asking for — that PR is superseded by this one.

Why CI never caught any of it

No workflow ran Node. The new Assets job runs npm ci then npm run build
on both Node floors Vite 7 accepts.

npm ci rather than npm install is the whole point: npm install would have
repaired the broken lock and reported success, which is precisely how the
broken lock reached main.

Testing both floors rather than only the newest keeps the documented minimum
honest — which it was not: the README asked for "Node.js 20+" while Vite 7
requires ^20.19.0 || >=22.12.0, so Node 20.0 through 20.18 would fail the
build the README implied they could run. Corrected.

Verified locally, Node 22.22

npm ci from a removed node_modules, then npm run build: 60 modules, built
in 1.18s, manifest and assets emitted. The client bundle grows from 38.57 kB to
51.53 kB — that is axios 1.8.2 → 1.20.0, and it is the honest cost of the
update.

Dependabot pull requests this settles

With #211, all nine open ones are now dead or superseded:

PR Touches Status
#168, #165, #164, #161 yarn.lock only file removed in #211
#167, #158, #154 themes/default/package-lock.json themes/ holds only .gitkeep on main; themes are separate repositories now
#74 app/Themes/Apiary/… path has not existed for a long time
#166 root package.json axios floor superseded here, and to a higher floor

They should be closed with a comment rather than merged.

…Node

Three findings, one cause: no workflow ran Node, so nothing about the asset
tree was ever checked.

`npm ci` failed on main. The committed package-lock.json disagreed with
itself — "Invalid: lock file's emoji-regex@8.0.0 does not satisfy
emoji-regex@10.6.0" — so a fresh clone could not install with the one command
that installs exactly what the lock says. `composer setup` runs `npm install`,
which repairs such a lock silently and reports success, so the breakage was
invisible from every path anyone actually walks.

With the lock repaired, `npm update` moves axios, vite, postcss, nanoid,
esbuild, shell-quote and form-data to patched versions: `npm audit` goes from 7
vulnerabilities (1 critical, 5 high, 1 low) to 0. The declared floor for axios
moves to ^1.20.0 — `^1.8.2` still admitted the vulnerable version it named.

The README asked for "Node.js 20+", while Vite 7 requires ^20.19.0 || >=22.12.0.

The Assets job runs `npm ci` then `npm run build` on both floors. `npm ci` is
the point: `npm install` would have papered over the very state this job exists
to catch.

Verified locally on Node 22.22: `npm ci` from a removed node_modules, then
`npm run build` — 60 modules, built in 1.18s. The client bundle grows from
38.57 kB to 51.53 kB, which is axios 1.8.2 to 1.20.0.
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