Skip to content

fix: bump dependencies flagged by Artifactory's curation policy - #1385

Merged
abueide merged 3 commits into
masterfrom
fix-vulnerable-deps
Jul 17, 2026
Merged

fix: bump dependencies flagged by Artifactory's curation policy#1385
abueide merged 3 commits into
masterfrom
fix-vulnerable-deps

Conversation

@abueide

@abueide abueide commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

release.yml's publish job resolves dependencies through curated Artifactory (see #1384). 42 package versions across the dependency tree were blocked by curation (known-CVE and/or cooldown-flagged versions - ws, minimatch, semver, tough-cookie, tar, @babel/traverse, axios, json5, path-to-regexp, and more), which would have kept every future release stuck the same way this one was. This clears all 42.

No breaking changes for package consumers

Everything bumped here is dev/build/test tooling or example-app dependencies (playwright, vite, wrangler, turbo, next, webpack, rollup, and their transitive chains) - nothing a consumer of @segment/analytics-next or the other published packages actually installs. The one exception, dset, only moves a stray transitive resolution (3.1.3) up to match the version this repo already declares (^3.1.4) - no range change, no consumer impact.

  • Direct pins: playwright/@playwright/test (1.28.1 → 1.61.1), vite (2.9.18 → 8.1.4, with-vite playground only), wrangler (3.11.0 → 4.111.0, node-integration-tests only), turbo (2.3.4 → 2.10.5), next (12.3.5 → 16.2.10, next-playground only).
  • Everything else forced via root resolutions, targeting the newest version within the same major where one exists (minimizing behavior change), only crossing a major where the flagged major line has no available fix (tar, ws, tough-cookie, minimatch, path-to-regexp, serialize-javascript, webpack-dev-middleware, http-proxy-middleware, is-email, js-yaml).

Code fixes required (test-only, no published-package impact)

  • devtools was removed from Playwright's LaunchOptions. Dropped it in ajs-tester.ts (launch already used headless: true there, so it was a no-op); replaced it in qa/lib/browser.ts with --auto-open-devtools-for-tabs in args, gated on debug mode, to preserve the actual local-debugging behavior.
  • browser-integration-tests/src/helpers/standalone-mock.ts derived its fixture-callback type via Parameters<typeof test['beforeEach']>[0], which silently resolved to the wrong overload once Playwright's beforeEach gained an optional-title overload. Replaced with the actual exported fixture-args type.
  • One test snapshot updated (packages/browser/src/core/user): jsdom's cookie-jar (test-environment only, not real browsers) is backed by tough-cookie, bumped 4.0.0 → 4.1.4 here - the newer version serializes an edge case differently (no leading empty segment). Verified this doesn't reflect our own runtime cookie code (js-cookie, unaffected) and re-recorded the snapshot.

CI-only regressions found and fixed after the first push

  • e2e-tests/performance/ajs-perf-browser.test.ts failed with "Class extends value undefined" - the newer playwright-core bundles @hono/node-server, which does class Request extends global.Request at import time, and jsdom's global (this file's inherited default test environment) doesn't provide that. Scoped a @jest-environment node docblock pragma to just this file rather than polyfilling globally - an earlier attempt at a global polyfill in jest.setup.js fixed this but broke 21 other suites by changing fetch's runtime behavior everywhere.
  • Same test then failed differently: ChunkLoadError fetching tsub-middleware.bundle.<hash>.js from the real production CDN. Root cause: the test's runtime CDN resolution (getCDN()) falls back to cdn.segment.com for any lazy-loaded chunk regardless of where the main script was served from, so the test was never actually hermetic - it only passed because production happened to match the local build's hash, which broke the moment the webpack bump changed that hash. Mocked the CDN bundle request in ajs-tester.ts to serve from the local dist/umd instead, mirroring the identical pattern already used in browser-integration-tests/src/helpers/standalone-mock.ts. Independent of production state now.
  • node-integration-tests' Cloudflare Workers suite failed on every test: wrangler 4.111.0's unstable_dev hard-fails if .dev.vars doesn't exist, where 3.11.0 tolerated its absence - confirmed as a real regression (the same CI job passed on master before this bump). Added an empty .dev.vars (no actual vars are needed) and gitignored the .wrangler/ local runtime cache it creates.

Verified locally

  • yarn build, yarn lint (turbo, all 22 workspaces including both playgrounds on the bumped Next.js/Vite), yarn scripts lint, yarn scripts test, yarn constraints - all pass.
  • Full make ci for browser (build, size-limit, lint, unit tests, e2e tests) - green end to end, including a real Chromium run: 70/70 unit suites, 841/845 tests, e2e-tests/performance 2/2.
  • Jest suites: core (14/14), node (18/18), consent-tools (6/6), generic-utils (2/2), page-tools (1/1), Cloudflare Workers (5/5) - all pass.

Test plan

  • Confirm release.yml's test job installs cleanly through curated Artifactory (no more 403 Forbidden on any of these 42)
  • CI green across all workspaces

release.yml's publish job resolves dependencies through curated
Artifactory (see #1384) - 42 package versions across the dependency
tree were blocked by curation (known-CVE and/or cooldown-flagged
versions: ws, minimatch, semver, tough-cookie, tar, @babel/traverse,
axios, json5, path-to-regexp, and more), which would have kept every
future release stuck the same way. This clears all 42.

None of this touches runtime dependencies published to consumers.
Everything bumped here is dev/build/test tooling or example-app
dependencies (playwright, vite, wrangler, turbo, next, webpack,
rollup, and their transitive chains) - nothing a consumer of
@segment/analytics-next or the other published packages installs.
The one exception, dset, only moves a stray transitive resolution
(3.1.3) up to match the version this repo already declares (^3.1.4)
- no range change, no consumer impact.

Direct pins bumped: playwright/@playwright/test (1.28.1 -> 1.61.1),
vite (2.9.18 -> 8.1.4, with-vite playground only), wrangler (3.11.0
-> 4.111.0, node-integration-tests only), turbo (2.3.4 -> 2.10.5),
next (12.3.5 -> 16.2.10, next-playground only). Everything else is
forced via root resolutions, targeting the newest version within the
same major where one exists (minimizing behavior change), and only
crossing a major where the flagged major line has no available fix
(tar, ws, tough-cookie, minimatch, path-to-regexp, serialize-javascript,
webpack-dev-middleware, http-proxy-middleware, is-email, js-yaml).

Two real code fixes needed for the Playwright major bump, both in
test-only code, no published-package impact:
- `devtools` was removed from Playwright's LaunchOptions. Dropped it
  in packages/browser/src/tester/ajs-tester.ts (launch already used
  headless: true there, so it was a no-op); replaced it in
  packages/browser/qa/lib/browser.ts with
  `--auto-open-devtools-for-tabs` in args, gated on debug mode, to
  preserve the actual local-debugging behavior.
- packages/browser-integration-tests/src/helpers/standalone-mock.ts
  derived its fixture-callback type via
  `Parameters<typeof test['beforeEach']>[0]`, which silently
  resolved to the wrong overload once Playwright's beforeEach gained
  an optional-title overload. Replaced with the actual exported
  fixture-args type.

One test snapshot updated: packages/browser/src/core/user's "Custom
cookie params" test asserted an exact `document.cookie` string.
jsdom's cookie-jar (used only in the Jest/jsdom test environment, not
real browsers) is backed by tough-cookie, which this bumps from 4.0.0
to 4.1.4 - the newer version serializes an edge case differently (no
leading empty segment). Verified this doesn't reflect our own runtime
cookie code (js-cookie, unaffected) and just re-recorded the snapshot.

Verified locally: build and lint/typecheck pass across all 22
workspaces (including both playgrounds, on the bumped Next.js/Vite).
Jest suites pass: browser (70/70), core (14/14), node (18/18),
consent-tools (6/6), generic-utils (2/2), page-tools (1/1).
node-integration-tests' Cloudflare Workers suite couldn't be verified
here - it requires a local .dev.vars file that has never existed in
this repo (confirmed via git history), unrelated to the wrangler
version.
@changeset-bot

changeset-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 64ebbe3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@tvs-twilio-segment

tvs-twilio-segment Bot commented Jul 17, 2026

Copy link
Copy Markdown

✅ TVS Validation Passed

View full report

Show details

All validation checks have successfully completed.

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.59%. Comparing base (db575f4) to head (7a2f47b).
⚠️ Report is 1 commits behind head on master.

⚠️ Current head 7a2f47b differs from pull request most recent head 64ebbe3

Please upload reports for the commit 64ebbe3 to get more accurate results.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1385   +/-   ##
=======================================
  Coverage   91.59%   91.59%           
=======================================
  Files         127      127           
  Lines        4142     4142           
  Branches     1033     1033           
=======================================
  Hits         3794     3794           
  Misses        348      348           
Flag Coverage Δ
browser 92.51% <ø> (ø)
core 90.07% <ø> (ø)
node 89.43% <ø> (ø)

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

didiergarcia
didiergarcia previously approved these changes Jul 17, 2026
Two real regressions surfaced in CI on #1385 that hadn't shown up
locally (yarn browser test excludes e2e-tests by default, and I hadn't
run the Cloudflare Workers suite there either):

- packages/browser/e2e-tests/performance/ajs-perf-browser.test.ts
  failed with "Class extends value undefined is not a constructor or
  null". The newer playwright-core (1.61.1) bundles @hono/node-server,
  which does `class Request extends global.Request` at import time.
  jsdom (this file's default test environment, inherited from
  jest.config.js) doesn't provide the Fetch API globals Node has
  natively, so global.Request is undefined there.

  First attempt polyfilled these globals in jest.setup.js, which fixed
  this file but broke 21 other suites - making global.fetch/Request
  real (via undici) instead of jsdom's own mocked versions changed
  runtime behavior for tests that depend on that mocking, surfacing
  undici internals (timeout.unref, clearImmediate) that don't work
  under jsdom's timer emulation. Reverted that entirely.

  Actual fix: this file drives a real browser via Playwright and never
  touches the DOM jsdom simulates, so it shouldn't run under jsdom at
  all. Added a `@jest-environment node` docblock pragma scoped to just
  this file - Node's own test environment has these globals natively,
  no polyfill needed, and nothing else is affected.

- packages/node-integration-tests' Cloudflare Workers suite
  (test:cloudflare-workers) failed on every test: wrangler 4.111.0's
  unstable_dev hard-fails if .dev.vars doesn't exist, where 3.11.0
  tolerated its absence. Confirmed as a real regression (not
  pre-existing) - the same job passed on master before this bump.
  No actual local vars are needed for these tests; added an empty
  .dev.vars so wrangler finds a file to load. Also gitignored
  .wrangler/, the local runtime cache directory unstable_dev creates
  when you actually run these tests.

Re-verified full `make ci` for browser (70/70 suites, 841/845 tests,
size-limit within budget) and the Cloudflare Workers suite (5/5)
locally after both fixes.
…ermetic

e2e-tests/performance/ajs-perf-browser.test.ts started failing with
"ChunkLoadError: Loading chunk 10 failed" against
https://cdn.segment.com/analytics-next/bundles/tsub-middleware.bundle.<hash>.js
once the webpack bump landed (5.73 -> 5.108) and produced a different
content hash for that chunk.

Root cause: this test's local page loads the freshly-built dist/umd
from a local server (src/tester/server.js on :3001), but the bundle's
runtime CDN resolution (getCDN(), used to set __webpack_public_path__)
falls back to the real production CDN for any lazy-loaded chunk,
regardless of where the main script was served from. The test was
never actually hermetic - it happened to pass only because whatever
was live on the real CDN matched the local build's hash, which breaks
the moment source or tooling changes that hash (this bump, but also
any future one).

Fixes it the same way browser-integration-tests/src/helpers/
standalone-mock.ts already mocks this exact CDN path for its own
tests: intercept requests to cdn.segment.com/analytics-next/bundles/*
and serve them from the local dist/umd instead. Now independent of
whatever's actually published to production.

Verified locally: e2e-tests/performance passes (2/2), and full
`make ci` for browser is green end to end (70/70 unit suites, e2e
tests, build, lint, size-limit).
@abueide
abueide enabled auto-merge (squash) July 17, 2026 20:00
@abueide
abueide merged commit 9ffe52b into master Jul 17, 2026
37 checks passed
@abueide
abueide deleted the fix-vulnerable-deps branch July 17, 2026 20:03
abueide added a commit that referenced this pull request Jul 17, 2026
…1386)

## Summary

The manual release trigger failed again after #1385 merged - confirmed
it *did* run against the fully-merged master (not a stale branch), so
this is a new, real finding: `axios@0.33.0` (the version #1385 picked as
"newest within the same major" for the stray transitive
`axios@0.25.0`/`0.27.2` resolutions) is *also* curation-blocked (`403
Forbidden`).

In hindsight this makes sense - axios's entire 0.x line has real,
unpatched SSRF/CSRF issues that were only actually fixed in the 1.x
rewrite, so "newest within the same major" wasn't a safe target for this
one specifically, unlike most of the other 41 packages in #1385.

## Fix

Bumps the resolution to `^1.6.2`, matching what `packages/node` already
declares directly as a real dependency. Both transitive consumers (the
legacy `analytics-node` npm package and `wait-on`, both dev/test-only,
confirmed via `yarn why axios`) now dedupe onto the exact same axios
version already in the tree - no new version introduced.

## Verified locally

- `packages/node`'s Jest suite: 18/18 suites, 146/147 tests (1 todo)
- `node-integration-tests` lint/typecheck: clean

## Test plan

- [ ] Re-run `release.yml`'s `test` job and confirm `yarn install
--immutable` completes with no more `403`s
abueide added a commit that referenced this pull request Jul 17, 2026
…1388)

## Summary

Same pattern as #1386's axios fix: `is-email@0.1.1` (the version #1385
picked as "newest within the same major") is also curation-blocked -
every 0.x release is.

## Unlike axios, this one is a real (narrow) behavior change

`is-email` is bundled into the shipped `@segment/analytics-next` bundle
via `@segment/facade` (a real runtime dependency, not dev tooling), used
for email-trait detection in `identify`/`track`/`page`/`group`
processing.

- `is-email@0.1.1`'s matcher: `/.+@.+\..+/` - very loose, matches almost
anything shaped like `x@y.z`
- `is-email@1.0.2` (the only available non-blocked version): a proper
RFC-5321-style pattern, plus a 320-character cap

So this makes that internal detection meaningfully stricter. Added as
its own changeset (`.changeset/bump-is-email-curation.md`) documenting
the behavior change, rather than folding it into the mechanical bump
commits like the other 40 packages.

## A second real break found via CI: wait-on incompatible with axios 1.x

`wait-on@6.0.1` (used by `jest-dev-server`, dev-only) does a hardcoded
`require('axios/lib/adapters/http')` - an internal axios 0.x file path
that doesn't exist in the 1.x rewrite (#1386). No curation-approved
axios version has that path anymore, so this broke unconditionally once
axios was forced to 1.x. Bumped `wait-on` itself to 9.0.10 - its public
API (`waitOn(opts, callback)`) is unchanged, and it's dev-only (no
published-package impact).

## Verified locally

- Full browser test suite: 70/70 suites, 841/845 tests
- `e2e-tests/performance` (the suite that caught the wait-on/axios
break): 2/2
- Full `make ci` for browser green end to end
- Confirmed the `is-email` fix against real curated Artifactory via a
manual `release.yml` trigger on this branch: the `test` job (Node 20)
installs cleanly

## Test plan

- [ ] Confirm the `publish` job's install (Node 24) also resolves
cleanly once merged - a scratch-branch dispatch can't reach that job
(the `production` environment correctly rejects non-`master`
deployments), so this can only be confirmed after merge
- [ ] CI green across all workspaces
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.

2 participants