Skip to content

build(deps-dev): sweep dependencies for supply-chain safety - #518

Merged
chhoumann merged 8 commits into
masterfrom
chore/deps-upgrade-2026-10
Oct 24, 2026
Merged

chhoumann merged 8 commits into
masterfrom
chore/deps-upgrade-2026-10

Conversation

@chhoumann

@chhoumann chhoumann commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

A supply-chain sweep of every dependency, the lockfiles, GitHub Actions and pinned tooling. Nothing changes for users. The plugin bundle differs by 8 bytes of minifier output (details below).

It resolves every open alert except the leaked key, which needs revoking:

  • Dependabot (vite-plus, 5 advisories). vite-plus left the tree when build(deps-dev): bump obsidian-e2e to 0.14.0 #517 moved obsidian-e2e to 0.14.0. This branch is rebased on that.
  • Code scanning, js/bad-code-sanitization at docs/scripts/screenshots.mjs:208. The flagged line was one of 40 places where the docs, verify and helper scripts spliced JSON.stringify output into code that Obsidian evaluates. JSON is not a safe JavaScript literal there, because U+2028, U+2029, < and > need escaping. The e2e suite's jsLiteral moved to scripts/js-literal.mjs, and every one of those sites now goes through it.
  • Secret scanning Use Svelte for components #1, an OpenAI API key. It was added in 41fe0efc ("transcription WIP", 2023-03-10) as a hard-coded bearer token at src/main.ts:331, and removed in cb7f2068 ("feat: transcribe with OpenAI's Whisper", 2024-07-16). No branch or tag tip on origin contains it, and neither does this tree. It is still in history, so it must be revoked. History is not rewritten.
  • npm audit. Root and docs both report 0 vulnerabilities. Master had 6 in root (fast-uri, undici through wrangler) and 2 in docs (undici, zod).

Root lock entries go from 623 on master to 530. On master, four root entries ran install scripts: the root package's own postinstall, esbuild, workerd and fsevents. Only fsevents is left, and it is optional and installs only on macOS.

Version policy

"Latest safe" means the newest release that is at least 7 days old, the same cooldown Dependabot already uses here. Lock refreshes ran with npm --before=2026-10-17, so transitive packages follow the rule too. There are two exceptions:

  • fast-uri 3.1.9 (5 days old). It fixes four advisories we were exposed to. I checked it before taking it: npm provenance, no install scripts, and a diff limited to the scheme, host and relative-path fixes.
  • obsidian-e2e 0.14.0 (1 day old). It is your package, and you asked for its latest release. It landed in build(deps-dev): bump obsidian-e2e to 0.14.0 #517.

Newer releases inside the cooldown were held: oxlint 1.89.0, oxfmt 0.74.0, postcss 8.5.31, vite 8.3.5, astro 7.4.2, Starlight 0.42.7, and Obsidian 1.14.5 (the e2e app). None of their release notes mention a security fix, and Dependabot offers them once the cooldown passes.

Dependencies

Root package.json:

Package Old New Outcome
@sveltejs/vite-plugin-svelte 7.3.1 7.3.1 Kept, already latest
@testing-library/jest-dom 7.0.1 7.0.1 Kept, already latest. Many component tests use its matchers
@testing-library/svelte 5.4.2 5.4.2 Kept, already latest
@types/node 22.20.5 22.20.5 Kept, latest 22.x. 26.x would describe APIs Node 22 lacks
@typescript/native (typescript@7) 7.0.2 7.0.2 Kept, already latest
acorn 8.19.0 8.19.0 Kept. The syntax floor needs a strict ES2020 parser, and svelte depends on acorn anyway
eslint-plugin-obsidianmd 0.4.2 0.4.2 Kept, already latest. It runs Obsidian's review-bot rules
jsdom 30.1.3 30.1.3 Kept, already latest
obsidian 1.14.4 1.14.4 Kept, already latest
obsidian-e2e 0.13.0 0.14.0 Bumped in #517
oxfmt 0.73.0 0.73.0 Kept. 0.74.0 is inside the cooldown
oxlint 1.88.0 1.88.0 Kept. 1.89.0 is inside the cooldown
postcss 8.5.30 8.5.30 Kept. 8.5.31 is inside the cooldown. Vite depends on it anyway
svelte 5.57.2 5.57.2 Kept, already latest
svelte-check 4.7.6 (pinned) 4.7.7 Bumped. The local patch is deleted (see below)
svelte-policy 0.1.0 0.1.0 Kept, already latest
terser 5.51.2 5.51.2 Kept. Without it, main.js gzips 268 bytes over the 103,000-byte budget (measured)
typescript 6.0.3 6.0.3 Kept on 6. svelte-check declares ^5 || ^6, typescript-eslint <6.1.0
vite 8.3.4 8.3.4 Kept. 8.3.5 is inside the cooldown
vitest 5.0.5 5.0.5 Kept, already latest
wrangler 4.151.0 none Removed, with docs:deploy (see below)
yaml 2.9.1 2.9.1 Kept. The Obsidian mock's parseYaml uses the same library as Obsidian, and obsidian-e2e and vite depend on it anyway

Root overrides:

Override Outcome
@actions/http-client > undici ^6.27.0 Removed. Nothing depends on @actions/http-client any more
eslint-plugin-obsidianmd > moment 2.31.0 Kept. The lint plugin still pins obsidian@1.12.3, which declares moment 2.29.4 (GHSA-4p3w-j4w9-5jqw)
vite-plus > oxfmt Removed in #517

Docs docs/package.json:

Package Old New Outcome
astro 7.3.8 7.4.0 Bumped. 7.4.2 is inside the cooldown
@astrojs/starlight 0.42.6 0.42.6 Kept. 0.42.7 is inside the cooldown
sharp 0.35.5 0.35.5 Kept, already latest. The screenshot script crops with it
starlight-links-validator 0.27.0 0.27.0 Kept, already latest
postcss-nested override ^7.0.2 Kept. expressive-code 0.44.2 still asks for ^6 (GHSA-rj75-hqrm-r3gf). 0.44.3 moves to 7 and is inside the cooldown

Transitive packages that changed because of an advisory: fast-uri 3.1.8 to 3.1.9 (root), undici 8.11.2 to 8.12.2 and zod 4.6.5 to 4.6.7 (docs). The root refresh also moved 113 packages within their ranges and dropped 44 that nothing needs any more.

GitHub Actions and pinned tooling:

Item Version Outcome
actions/checkout v7.0.1 3d3c42e5 Kept, already latest and SHA-pinned
actions/setup-node v7.1.0 949feb24 Kept, already latest and SHA-pinned
actions/dependency-review-action v5.0.0 a1d282b3 Kept, already latest and SHA-pinned
chhoumann/obsidian-plugin-workflows v4 ebcf84b8 Kept, latest tag
Node (.nvmrc) 22.23.2 to 22.23.4 Bumped. Node 22 security release of 2026-10-20
obsidian-mobile-debug (scripts/omd.sh) deebf565 Kept. Already the head of main
Obsidian for e2e on Linux 1.14.4 Kept. 1.14.5 (2026-10-22) is inside the cooldown

Removals

  • wrangler. Cloudflare Pages already builds and publishes the docs through its GitHub integration (docs/README.md, "Deployment"). npm run docs:deploy was a second, manual path. Wrangler brought 85 lock entries, among them the workerd and esbuild binaries, esbuild's install script, sharp, and a miniflare pinning vulnerable undici 7.29.1. docs/wrangler.jsonc stays, because Pages reads pages_build_output_dir from it. To deploy by hand, run npx wrangler@<version> pages deploy docs/dist --project-name podnotes --branch master.
  • patches/svelte-check.mjs. svelte-check 4.7.7 includes fix: report a failed TypeScript compiler process instead of a clean run sveltejs/language-tools#3133, the fix the patch backported. The patch, its postinstall hook (the root package's only install script), its check:a11y call, its lint and format paths, its test and its Dependabot ignore are gone. The tooling tests that make the compiler fail still pass, against unpatched svelte-check. svelte-check 4.7.7 still passes a tsconfig that matches no files, which I checked, so lint:tsconfig stays.

Nothing was vendored. Each remaining dependency is either used widely, or a package we need anyway already depends on it.

Flaky test

The first full e2e run failed "a restored phone sidebar shows Library when selected through the workspace picker" once. On mobile, Obsidian drops a swipe when the first touchmove arrives more than 200 ms after its touchstart. touchDrag made one CLI call per touch event and paused 120 ms before the first move. On a busy host the first move arrived 137 to 195 ms after the touch. When it went over 200 ms, the right drawer never opened. With every CLI call slowed by 100 ms, the test failed 2 of 2 before the fix and passed 3 of 3 after. touchDrag now sends the whole gesture from the renderer, with no added timeout or retry.

Verification

Linux, Node 22.23.4, npm 10.9.9. Lockfiles were written with npm 11.21.0 (below).

  • npm run lint, npm run format:check, npm run typecheck, npm run build, npm run size, npm run test (126 files, 2,782 tests), npm run test:tooling (40 tests) and npm run docs:build (22 pages, links valid, 112 legacy fragments) all pass.
  • npm run size reports 314,260 raw bytes and 101,576 gzip bytes. Master's bundle was 314,268 and 101,575. The only difference is rolldown 1.2.14 turning one loop's trailing continue into an else if, which behaves the same.
  • npm run test:e2e passes 32 files and 243 tests on Obsidian 1.14.4, and again on the 1.13.7 floor (PODNOTES_OBSIDIAN_APP=/opt/Obsidian/obsidian). Both ran before the rebase. The rebase changed no package version and left main.js byte-identical. A final full run on the rebased branch, with the swipe fix, passes 32 files and 243 tests on 1.14.4.
  • In real Obsidian 1.14.4 on headless Linux, with a fresh isolated vault (podnotes-chore-deps-upgrade-2026-10), PodNotes 2.22.0 loaded with its API available. I added the fixture feed through the view's search field and clicked "Fixture Episode 1". It played: api.isPlaying stayed true and api.currentTime went from 8.4 s to 11.6 s. dev:errors captured none.
  • npm audit reports 0 vulnerabilities in root and in docs. npm ls --all exits 0.

Release impact

None. No settings, storage, API or URI changes, and every change is dev-only. The PR title's build(deps-dev) type does not cut a release.

Risks and follow-ups

  • npm 10 strips libc from the lockfile. Master's root lock is in npm 11's format, with libc on native-binding entries. Any lock write by Node 22's npm 10.9.x drops those fields, which can install glibc binaries on musl. These lockfiles were written with npx npm@11.21.0, which round-trips master byte for byte. Contributors and agents who run npm install on Node 22 will keep hitting this. Moving local tooling to npm 11 is a separate decision.
  • The npm cooldown setting does nothing here. npm 10.9.9 ignores min-release-age in ~/.npmrc: it installed a 5-day-old release with the setting at 7. Only --before enforces a cooldown on npm 10. Dependabot's cooldown is unaffected.
  • scripts/omd.sh is pinned by commit, but its dependencies are not. uvx --from git+...@deebf565 resolves obsidian-mobile-debug's Python dependencies fresh on each first run, with no lock or cutoff.
  • The jsLiteral change touches capture scripts I did not run end to end. These are docs/scripts/screenshots.mjs, videos.mjs and scene.mjs, plus .claude/skills/verify/screens. Every changed value evaluates to the same thing as before, and the e2e suite checks jsLiteral itself. The next node docs/scripts/screenshots.mjs run will exercise them.

The docs capture, verify and e2e helper scripts built Obsidian eval code
by interpolating JSON.stringify output. JSON is not a safe JavaScript
literal inside such code: U+2028/U+2029 and '<'/'>' need escaping. CodeQL
flagged one site (js/bad-code-sanitization, docs/scripts/screenshots.mjs).

Move the e2e suite's jsLiteral into scripts/js-literal.mjs and route all
40 code-building sites through it. JSON that only reaches a log, an error
message, a file or a CDP params object stays JSON.stringify.
Resolved with npm --before 2026-10-17, the repo's 7-day Dependabot
cooldown. undici 8.12.2 fixes GHSA-4qv8-2p9j-2685, GHSA-f72v-6w45-q472
and GHSA-xjj6-f33q-929c, and zod 4.6.7 fixes GHSA-mrhx-c7xc-m3w5.
npm audit reports no vulnerabilities in docs.
…atch

4.7.7 ships sveltejs/language-tools#3133, which patches/svelte-check.mjs
backported to 4.7.6: a check whose compiler process fails now exits
non-zero. Delete the patch, its postinstall and check:a11y calls, its
lint and format paths, the patch's own test and the Dependabot ignore.
The root package no longer runs an install script.

The tooling tests that fault the compiler now pass against unpatched
svelte-check. It still passes a tsconfig that matches no files, so
lint:tsconfig stays.
Cloudflare Pages deploys the docs through its GitHub integration, so the
manual Wrangler deploy path was unused. Wrangler brought 85 lock entries,
among them the workerd and esbuild binaries (esbuild's install script
goes with it), sharp, and a miniflare that pins undici 7.29.1
(GHSA-4qv8-2p9j-2685, GHSA-f72v-6w45-q472, GHSA-xjj6-f33q-929c).
docs/wrangler.jsonc stays: Pages reads pages_build_output_dir from it.
fast-uri 3.1.9 fixes GHSA-w74x-v6f9-j3xg, GHSA-xhq7-xmqj-769h,
GHSA-wjr9-j795-jxcr and GHSA-333x-w4r6-6crp under the Obsidian lint
plugin's ajv. It is inside the 7-day cooldown, so it was vetted: npm
provenance, no install scripts, and a diff limited to the scheme, host
and relative-path fixes.

No package depends on @actions/http-client any more, so its undici
override did nothing. Root npm audit now reports no vulnerabilities.
22.23.4 (2026-10-20) is a Node 22 security release. The Test, Platforms
and Documentation workflows read .nvmrc.
npm update --before 2026-10-17 moves 113 transitive packages to the
newest in-range release that is at least 7 days old and drops 44 that
nothing needs any more. obsidian-e2e 0.14.0 and fast-uri 3.1.9 stay as
vetted exceptions. Written with npm 11.21.0, which keeps the libc fields
that npm 10 drops from native binding entries.
Obsidian's mobile gesture handler drops a touch whose first touchmove
arrives more than 200 ms after its touchstart. touchDrag sent each touch
event through its own obsidian CLI call and waited 120 ms before the
first move. The renderer saw that move 137-195 ms after the touch. When
a CLI call ran slow, the swipe that opens the right drawer in "a restored
phone sidebar shows Library when selected through the workspace picker"
did nothing, and the test timed out waiting for the drawer's view picker.

touchDrag now sends the whole gesture in one eval through the window's
debugger, each event once the last is handled. It uses no timer, because
a renderer timer set after a touchstart fired about 100 ms late. The
first move now comes 18-66 ms after the touch under extra CPU load. With
every CLI call slowed by 100 ms, the test fails before this change and
passes after it.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying podnotes with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9962c5d
Status: ✅  Deploy successful!
Preview URL: https://3bdfec13.podnotes.pages.dev
Branch Preview URL: https://chore-deps-upgrade-2026-10.podnotes.pages.dev

View logs

@chhoumann
chhoumann marked this pull request as ready for review October 24, 2026 08:28
@chhoumann
chhoumann merged commit 105f580 into master Oct 24, 2026
22 checks passed
@chhoumann
chhoumann deleted the chore/deps-upgrade-2026-10 branch October 24, 2026 08:43
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