diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9b604e4..ad8a6ca9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,10 +74,10 @@ jobs: - run: go build ./... - run: go vet ./... - run: go test ./... - # The Filen helper ships in the backend image (Alpine's Node 20). + # The Filen helper ships in the backend image (Alpine's Node 22). - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: - node-version: "20" + node-version: "22.23.4" cache: npm cache-dependency-path: backend/filen-downloader/package-lock.json - name: Filen helper tests @@ -95,7 +95,7 @@ jobs: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: - node-version: "20" + node-version: "22.23.4" cache: npm cache-dependency-path: core/package-lock.json - run: npm ci @@ -112,7 +112,7 @@ jobs: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: - node-version: "20" + node-version: "22.23.4" cache: npm cache-dependency-path: | frontend/package-lock.json @@ -138,7 +138,7 @@ jobs: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: - node-version: "22" + node-version: "22.23.4" cache: npm cache-dependency-path: | frontend/package-lock.json @@ -158,7 +158,7 @@ jobs: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: - node-version: "22" # Wrangler and ESLint 10 need Node ^22.13 || >=24 + node-version: "22.23.4" # Wrangler and ESLint 10 need Node ^22.13 || >=24 cache: npm cache-dependency-path: landing/package-lock.json - run: npm ci @@ -178,7 +178,7 @@ jobs: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: - node-version: "20" + node-version: "22.23.4" cache: npm cache-dependency-path: mobile/package-lock.json # `npm ci`'s postinstall runs sync:core, which regenerates the vendored diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bc1b26c3..b9f943b9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -143,7 +143,7 @@ jobs: - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: - node-version: "20" + node-version: "22.23.4" cache: npm cache-dependency-path: | frontend/package-lock.json diff --git a/backend/Dockerfile b/backend/Dockerfile index da3ae115..4d4422bd 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -5,8 +5,11 @@ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /out/server ./cmd/server -FROM alpine:3.20@sha256:d9e853e87e55526f6b2917df91a2115c36dd7c696a35be12163d44e6e2a4b6bc -RUN apk add --no-cache ca-certificates ffmpeg font-dejavu nodejs npm tzdata \ +FROM alpine:3.22@sha256:2e0b81d60597f449baa56dc25d355367869d2dca4cd57e866f1e2b52af3eb55f +# Alpine's nodejs decodes Brotli through the shared brotli-libs, so the floor +# below is what keeps the Filen helper off decoders hit by CVE-2026-111497 +# (fixed upstream in 1.2.1, and in the 1.1.1 backport Alpine 3.22 ships). +RUN apk add --no-cache ca-certificates ffmpeg font-dejavu nodejs npm tzdata 'brotli-libs>=1.1.1' \ && addgroup -S app \ && adduser -S -G app -h /app app WORKDIR /app diff --git a/backend/README.md b/backend/README.md index 9c994fda..35e820dd 100644 --- a/backend/README.md +++ b/backend/README.md @@ -48,7 +48,7 @@ internal/ lastshare/ apitracker/ pinscan/ musicroots/ admin-managed scan roots fonts/ fonts bundled for preview image rendering -filen-downloader/ Node 20 helper the Docker image bundles for Filen links +filen-downloader/ Node 22 helper the Docker image bundles for Filen links ``` ## Run (local) diff --git a/backend/go.mod b/backend/go.mod index 0d8b34b9..08f122b4 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -21,7 +21,7 @@ require ( ) require ( - github.com/andybalholm/brotli v1.2.0 // indirect + github.com/andybalholm/brotli v1.2.7 // indirect github.com/bdandy/go-errors v1.2.2 // indirect github.com/bdandy/go-socks4 v1.2.3 // indirect github.com/bogdanfinn/quic-go-utls v1.0.9-utls // indirect diff --git a/backend/go.sum b/backend/go.sum index f1aeab7c..2b1742ac 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -2,8 +2,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= -github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= +github.com/andybalholm/brotli v1.2.7 h1:UgafRPGMam5ySHfRkhthMqOFA6IFoeF3D7mWIDLjG5A= +github.com/andybalholm/brotli v1.2.7/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/bdandy/go-errors v1.2.2 h1:WdFv/oukjTJCLa79UfkGmwX7ZxONAihKu4V0mLIs11Q= github.com/bdandy/go-errors v1.2.2/go.mod h1:NkYHl4Fey9oRRdbB1CoC6e84tuqQHiqrOcZpqFEkBxM= github.com/bdandy/go-socks4 v1.2.3 h1:Q6Y2heY1GRjCtHbmlKfnwrKVU/k81LS8mRGLRlmDlic= diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 54fe7b18..9aa7299f 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS build +FROM node:24.22.1-alpine@sha256:06d7adf3e0ef61a13f1d28682726366f97a15aa1888c934d3ecec86c33918b53 AS build WORKDIR /app # Core must land at /core: the app's package.json, tsconfig paths, and Vite # aliases all reference it as ../core relative to /app. diff --git a/mobile/tests/download-store.test.ts b/mobile/tests/download-store.test.ts index 5e0c9a30..1e63c8cd 100644 --- a/mobile/tests/download-store.test.ts +++ b/mobile/tests/download-store.test.ts @@ -231,8 +231,8 @@ async function finishTask( h.dirs.add(`${h.DOC}/offline-audio-v2/https_3A_2F_2Fapi.test/alice`); h.files.set(partUri(id), bytes); task.cbs.begin?.({ headers: { "content-type": contentType } }); - // Hand-rolled deferred rather than Promise.withResolvers, which needs - // Node 22 — CI and both Docker images run Node 20. + // Hand-rolled deferred rather than Promise.withResolvers, which Node 20 + // (still allowed for local runs) lacks. let resolve!: () => void; const promise = new Promise((res) => { resolve = res; diff --git a/scripts/build-desktop-docker.sh b/scripts/build-desktop-docker.sh index f3194812..d8ed0f7f 100755 --- a/scripts/build-desktop-docker.sh +++ b/scripts/build-desktop-docker.sh @@ -19,8 +19,9 @@ docker info >/dev/null repo_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) builder_home="${XDG_CACHE_HOME:-$HOME/.cache}/lumen-desktop-builder" mkdir -p "$builder_home" -# electronuserland/builder:wine, pinned so toolchain updates are intentional. -builder_image='electronuserland/builder@sha256:41ae540902461b6cbc988987db79547fcc10cda04d2a6c6367504f59d4b37c64' +# electronuserland/builder:wine (Node 24.22.1), pinned so toolchain updates +# are intentional. +builder_image='electronuserland/builder@sha256:f3a8d451994c881d0972e7b1846ee4d4fdc15eb41fc6b1f350b38cbf99ca90fe' publish_env=() if [[ $publish_mode == always ]]; then publish_env+=(--env GH_TOKEN)