# 02-Jul-2026 — clear npm audit backlog - 140 vulnerabilities down to 5 dev-only [ref #305](https://github.com/nbarrett/ngx-ramblers/issues/305)

## [build 732](https://github.com/nbarrett/ngx-ramblers/actions/runs/28599759318) — [commit 43d1c4c](https://github.com/nbarrett/ngx-ramblers/commit/43d1c4cad1163e60c4462376a37c349bb5f6dac6)

_____

### **client+server**: clear npm audit backlog ([#305](https://github.com/nbarrett/ngx-ramblers/issues/305))

## What's new

Dependency security sweep of both workspaces. Server npm audit drops from 66 vulnerabilities (6 critical, 30 high) to 3, all in a single dev-only chain (mocha's serialize-javascript, where no fixed release exists and npm's proposed remedy is a downgrade to 2020's mocha 8). The client workspace drops from 74 (5 critical, 28 high) to 2 low, both a build-time babel advisory inside Angular's own compiler toolchain with no sane fix. Every critical and every production-reachable high is cleared across both, and the combined dependency tree shrinks by roughly 700 packages.

## At a glance

- All 6 criticals cleared: lodash/glob chain (via unused matchdep), fast-xml-parser (AWS SDK), xmldom (via togpx, now overridden to the maintained @xmldom fork), form-data, minimist, mkdirp.
- All production highs cleared: express, mongoose, nodemailer, jsonwebtoken, axios, multer, ws, xlsx, body-parser, debug, passport chain and more.
- Seven more unused dependencies removed: matchdep, mkdirpsync, connect-livereload, serve-index, open, express-session, esbuild.
- The 3 remaining server findings are mocha-only (test runner, never loaded at runtime) with no genuine fix published; the 2 remaining client findings are low-severity build-time babel advisories inside @angular/compiler-cli
- all accepted and documented on the ticket.
- Client: three more dead dependencies removed (the npm "server" web framework, an unused js-yaml, and meetup-api which was never imported and carried a vulnerable ws 3.x)
- 241 packages gone in one step.
- Client: all @angular packages 21.2.4 -> 21.2.17 in lockstep (CLI/build 21.2.18), mermaid 11.16.0, mongoose 8.24.1, webpack-bundle-analyzer 5.3.0, plus the non-breaking audit-fix pass; frontend tsc clean and all 831 unit tests passing.

## Technical changes

- Removed unused: matchdep, mkdirpsync, connect-livereload, serve-index, open, express-session, esbuild (direct); googleapis and npm-fs went in the previous release.
- Non-breaking bumps: express 4.22.2, mongoose 8.24.1, ws 8.21.0, @xmldom/xmldom 0.8.13, body-parser 1.20.5, debug 4.4.3, compression 1.8.1, morgan 1.10.1, tsx 4.22.4, plus npm audit fix transitives.
- Major bumps, all compile-clean and unit-tested: jsonwebtoken 9.0.3 (HMAC sign/verify usage unaffected), axios 1.18.1 (three call sites, stable API), multer 2.2.0 (same middleware API), nodemailer 9.0.3, passport 0.7.0 + passport-jwt 4.0.1, js-yaml 5.2.1 (already using the load() API). The legacy app.use(passport.session()) line and dead serializeUser hook are removed, and authenticate() now passes session: false explicitly
- the app is JWT-only, and passport 0.6+ hard-errors on any session interaction without session middleware (both caught in local end-to-end testing).
- AWS SDK v3 3.180.0 -> 3.1078.0 (clears fast-xml-parser critical); client-sts declared directly; listBuckets moved from callback to promise form; CreateBucketCommandInput/BucketLocationConstraint typing in aws-setup.
- Serenity/JS 3.41.2 -> 3.44.0 with Playwright 1.58.2 -> 1.60.0 and the worker base image ghcr.io/serenity-js/playwright v1.58.1-noble -> v1.60.0-noble (bundled browsers must match the npm playwright version). Serenity 3.44's exports map no longer resolves file-level deep imports, so the two Task imports from @serenity-js/core/lib/screenplay/Task move to the public @serenity-js/core root (caught by a live worker upload run; full Playwright test discovery re-verified). A new test:serenity-discovery script (playwright test --list) runs in the CI test job so scenario load failures of this class fail the build instead of surfacing on the worker
- tsc cannot catch them because type resolution ignores the runtime exports map.
- xlsx 0.16.5 -> 0.20.3 from the official SheetJS registry tarball (SheetJS no longer publishes to npm; 0.20.x contains the DoS/prototype-pollution fixes). Member bulk load reads the workbook via xlsx.read() on a buffer instead of xlsx.readFile()
- the 0.20 ESM build has no filesystem wired so readFile fails under tsx
- and the upload promise chain gains a catch() so a workbook that fails to parse returns an audited error response instead of crashing the server on an unhandled rejection (both proven with live endpoint tests).
- togpx keeps working via an npm override mapping its xmldom dependency to @xmldom/xmldom 0.8.13; GPX generation smoke-tested.
- Verified: server tsc clean, 836 unit tests passing, lint:all clean, togpx/xlsx/js-yaml runtime smoke tests OK.