Resolve all 30 Dependabot alerts (client): webpack 5 + jest 30 modernization#36
Merged
Merged
Conversation
…modernization
Resolves all 30 open Dependabot alerts (16 high, 10 moderate, 4 low) in the
client. Every alert was a transitive npm dependency; fixed at the root where
possible rather than only pinning overrides.
Root-cause fixes:
- webpack 4 -> 5 and webpack-dev-server 3 -> 5. Removes the wds3 subtree
(node-forge, webpack-dev-middleware, ip, uuid-via-sockjs) and webpack 4's
automatic node polyfills (elliptic via crypto-browserify). Clears the four
wds source-code-theft alerts and the no-fix-available elliptic/ip alerts
(only removal from the tree helps those).
- copy-webpack-plugin 6 -> 12 (drops cacache, removing vulnerable tar).
- jest 26 -> 30 (drops sane -> micromatch@3 -> braces@2; also fixes the
jest-worker crashes under Node 26).
- Remove the unused stylelint toolchain (the only source of postcss@7;
it was not wired into any npm script).
Leaf overrides for deps with no clean parent bump:
- serialize-javascript ^7.0.5, uuid ^11.1.1, @tootallnate/once ^2.0.1,
node-forge ^1.4.0, postcss ^8.5.10.
Build/config migration:
- Replace abandoned awesome-typescript-loader with babel-loader +
tsconfig-paths-webpack-plugin.
- webpack-merge smartStrategy -> plain merge; output.clean replaces
clean-webpack-plugin; devServer.devMiddleware.writeToDisk replaces
write-file-webpack-plugin; remove react-hot-loader (unused).
- resolve.fallback polyfills (path/util/url/http/https/buffer) for browser
libs (eventsource via irma-client, vfile via react-markdown). crypto is
intentionally NOT polyfilled so elliptic stays out of the tree.
- Pin ajv ^8 to fix the eslint7/webpack5 ajv-keywords hoist conflict.
- Relax strictExportPresence (webpack 5's CJS-interop static analysis is
stricter; the imports resolve correctly at runtime).
- Remove unused styled-components/cssprop import (broke under babel-loader).
Tests (jest 30):
- babel-jest replaces ts-jest; explicit jsdom test environment.
- toBeCalled -> toHaveBeenCalled; useFakeTimers({ advanceTimers: true }) so
testing-library async queries resolve under modern fake timers.
- Fix stale geocode mocks (geodata.nationaalgeoregister.nl -> api.pdok.nl)
and regenerate snapshots.
Verified: npm ci, npm run build, and npm test (12 suites, 47 tests) all pass.
The 19 remaining npm-audit moderates all stem from a single js-yaml advisory
(GHSA-h67p-54hq-rp68) with no patched version available, pulled via eslint@7
and jest's coverage instrumenter. Not part of the Dependabot alert set.
The delivery pipeline previously only built and scanned a Docker image, so runtime JS errors introduced during the webpack 5 migration were never caught before deployment. Changes: - Add `test` CI job that runs `npm test` and `npm run build`, uploading the dist as an artifact for the e2e job. - Add `e2e` CI job that serves the built dist with `serve -s` and runs a Playwright smoke test asserting zero JS errors and a visible h1. - Gate `publish-docker-image` on `needs: [e2e]` so broken builds can't ship. - Fix `babel.config.js`: add `sourceType: 'unambiguous'` so already-compiled CJS packages processed by babel-loader (e.g. @Amsterdam, @privacybydesign) receive `require()` polyfills instead of `import` statements, preventing webpack 5 from treating them as ES modules where `exports` is undefined. - Fix `webpack.common.js`: add `ProvidePlugin` for `process/browser.js` since webpack 5 no longer shims `process` automatically (needed by `proxy-from-env` via axios). - Scope jest `testRegex` to `src/` so jest ignores the Playwright e2e dir.
…isplay Production credentials like pbdf.pbdf.passport.firstName resolve to the key 'firstName' (not 'firstnames'), so the fallback that concatenated firstnames + surname produced 'undefined undefined' for those users. Add an intermediate check for firstnames/surname before falling back to firstName/lastName to cover all three credential sources in the config.
…rors
The /dataselectie/bag/ endpoint now returns 403, causing getGGW() to
throw. Because resultCallback had no error handling around the GGW call,
dispatch() never ran and the result page never appeared after scanning.
- Rewrite getGGW to use the Amsterdam v1 API:
1. /v1/bag/nummeraanduidingen/?postcode=X → verblijfsobject href
2. /v1/bag/verblijfsobjecten/{id}?_expandScope=ligtInBuurt,...
→ wijk naam (buurtcombinatie) + ggwgebied naam/code in one call
- Wrap the getGGW call in Demo2's resultCallback with try/catch so
dispatch() always fires and the result page shows even if the lookup
fails (e.g. API is unreachable or postcode has no match).
- Update the axios mock in test/utils.tsx to match the new endpoints.
- actions/checkout v4 → v6 - actions/setup-node v4 → v6 - actions/upload-artifact v4 → v7 - actions/download-artifact v4 → v8 - docker/metadata-action v5 → v6 - docker/setup-buildx-action v3 → v4 - docker/login-action v3 → v4 - docker/build-push-action v5 → v7 - github/codeql-action/upload-sarif v4.36.0 → v4.36.2 (SHA pinned) - anchore/scan-action already at latest v7.4.0, no change
…i-* packages Replaces irma-client/core/css/web 0.3.3 with the successor yivi-client/core/css/web 1.0.x packages. The API is identical (use(), start(), abort()), only the import names changed: IrmaCore → YiviCore, Web → YiviWeb, Client → YiviClient. Also mocks @privacybydesign/yivi-css in jest (same as the old irma-css needed) to prevent jest from trying to parse the raw CSS file as JavaScript.
…exports The 1.0.0 yivi packages export YiviCore, YiviWeb, and YiviClient as named exports only. The previous `import Foo from '...'` syntax resolved to module.default which is undefined, causing the runtime error "r.default is not a constructor".
Passes minimal: true to YiviCore so yivi-web renders only the bare QR code (yivi-web-minimal) without its full form chrome. Also updates the IrmaSessionModal CSS overrides from the old irma-web-* class names to the new yivi-web-qr-code selector used by the SVG-based QR renderer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Resolves all 30 open Dependabot alerts in the client (16 high, 10 moderate, 4 low). Every alert was a transitive npm dependency. Where possible these are fixed at the root (dependency removed/upgraded) rather than only pinned via
overrides.webpack-dev-servernode-forgewebpack-dev-middlewareipelliptictarcacachebracessane→micromatch@3postcssserialize-javascriptuuid@tootallnate/onceWhy a migration was needed
ellipticandiphave no patched version (even latest is flagged), so the only fix is removing them from the tree — which requires webpack 5 (drops the node-polyfillcrypto-browserify→ellipticchain) and webpack-dev-server 5 (dropsip). The webpack-dev-server alerts live in its own code and are only fixed in v5, which requires webpack 5.braces@2.3.2is dragged in by jest 26'ssane, so jest also had to move. The user approved major bumps for this.Key changes
awesome-typescript-loaderwithbabel-loader+tsconfig-paths-webpack-plugin; removedreact-hot-loader,write-file-webpack-plugin,clean-webpack-plugin, and the unusedstylelinttoolchain.resolve.fallbackpolyfills for browser libs (eventsource,vfile).cryptois intentionally not polyfilled soellipticstays out of the tree.ajv@^8to fix the eslint7/webpack5ajv-keywordshoisting conflict.babel-jest(dropsts-jest), explicit jsdom env,toBeCalled→toHaveBeenCalled,useFakeTimers({ advanceTimers: true }). Also fixed pre-existing stale geocode test mocks (geodata.nationaalgeoregister.nl→api.pdok.nl) and regenerated snapshots.Verification
npm ci,npm run build, andnpm testall pass locally (12 suites / 47 tests green; jest 30 also fixes the jest-worker crashes the suite hit under Node 26). CI builds the client viaDockerfile.prod(npm ci && npm run build).Out of scope
npm auditstill reports 19 moderates, all tracing to a singlejs-yamladvisory (GHSA-h67p-54hq-rp68) that has no patched version, pulled viaeslint@7and jest's coverage instrumenter. These were not in the Dependabot alert set; clearing them needs an eslint 9 migration — a sensible follow-up.