From 7b71f4392225e5bac4769d8241082a2708989adb Mon Sep 17 00:00:00 2001 From: Grace Date: Wed, 15 Jul 2026 14:43:45 +0100 Subject: [PATCH 1/5] install-time security hardening + toolchain pinning .npmrc: - min-release-age=7 (cooldown; @microbit/* and @microbit-foundation/* exempt) - allow-git/remote/file/directory=root (block transitive non-registry deps) - strict-allow-scripts=true + engine-strict=true package.json: - targetted allowScripts policy (esbuild, fsevents) - engines: node >=24.0.0, npm >=11.18.0 CI workflows: - bump GitHub-provided actions (checkout v7, setup-node v6, upload-pages-artifact v5, deploy-pages v5) - grab latest v11 npm directly after setup-node Regenerated package-lock.json under the new install policy (drops the stale apps/capacitor entry). --- .github/workflows/build-docs.yml | 9 +++--- .github/workflows/build.yml | 5 +-- .npmrc | 14 +++++++++ package-lock.json | 53 +++----------------------------- package.json | 8 +++++ 5 files changed, 34 insertions(+), 55 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 904aeb4a..5d0ae6c9 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -12,18 +12,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup Pages uses: actions/configure-pages@v5 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: "24.x" cache: npm + - run: npm install -g npm@11 --registry=https://registry.npmjs.org - run: npm ci - name: Build docs run: npm run docs -w @microbit/microbit-connection - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v5 with: path: ./packages/microbit-connection/docs/build @@ -40,4 +41,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fef95aa3..590b94cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,12 +12,13 @@ jobs: contents: read packages: write steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v7 + - uses: actions/setup-node@v6 with: node-version: "24.x" registry-url: "https://registry.npmjs.org" cache: npm + - run: npm install -g npm@11 --registry=https://registry.npmjs.org - run: npm ci env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.npmrc b/.npmrc index 94a06c21..ad165a7c 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,15 @@ access=public + +min-release-age=7 +min-release-age-exclude[]=@microbit/* +min-release-age-exclude[]=@microbit-foundation/* + +# root here means this project's package.json +allow-git=root +allow-remote=root +allow-file=root +allow-directory=root + +strict-allow-scripts=true + +engine-strict=true diff --git a/package-lock.json b/package-lock.json index c3e63dc8..073fc470 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,43 +11,10 @@ ], "devDependencies": { "prettier": "3.3.2" - } - }, - "apps/capacitor": { - "name": "@microbit/microbit-connection-capacitor", - "version": "0.0.0", - "extraneous": true, - "dependencies": { - "@capacitor-community/bluetooth-le": "^7.2.0", - "@capacitor/android": "^7.0.0", - "@capacitor/core": "^7.0.0", - "@capacitor/filesystem": "^7.1.4", - "@capacitor/ios": "^7.0.0", - "@capacitor/preferences": "^7.0.2", - "@capacitor/status-bar": "^7.0.3", - "@microbit/capacitor-community-nordic-dfu": "v7.0.0-microbit.4", - "@microbit/makecode-embed": "^0.4.0", - "@microbit/microbit-connection": "*", - "@microbit/microbit-universal-hex": "^0.2.2", - "nrf-intel-hex": "^1.4.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-router-dom": "^7.11.0" }, - "devDependencies": { - "@capacitor/cli": "^7.0.0", - "@eslint/js": "^9.17.0", - "@types/react": "^18.3.18", - "@types/react-dom": "^18.3.5", - "@types/react-router-dom": "^5.3.3", - "@vitejs/plugin-react": "^4.3.4", - "eslint": "^9.17.0", - "eslint-plugin-react-hooks": "^5.0.0", - "eslint-plugin-react-refresh": "^0.4.16", - "globals": "^15.14.0", - "typescript": "~5.6.2", - "typescript-eslint": "^8.18.2", - "vite": "^6.0.5" + "engines": { + "node": ">=24.0.0", + "npm": ">=11.18.0" } }, "apps/demo": { @@ -101,7 +68,6 @@ "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.6.5.tgz", "integrity": "sha512-JWyxD9LaK1oY588B/khJIG3Ec4NHI/Ki4v1b4XzqPNt2a27au0F2AhLTwYexV4Bp3Ruxf+8oYqxFAC8/7sGBWA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -220,7 +186,6 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -664,7 +629,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -688,7 +652,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -1896,7 +1859,6 @@ "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -2258,7 +2220,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3109,7 +3070,6 @@ "integrity": "sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssstyle": "^4.0.1", "data-urls": "^5.0.0", @@ -3667,7 +3627,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -3680,7 +3639,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -4175,8 +4133,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/typedoc": { "version": "0.27.9", @@ -4233,7 +4190,6 @@ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4331,7 +4287,6 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", diff --git a/package.json b/package.json index 4c1d65d9..7cb6b9b8 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,14 @@ "packages/*", "apps/*" ], + "allowScripts": { + "esbuild": true, + "fsevents": true + }, + "engines": { + "node": ">=24.0.0", + "npm": ">=11.18.0" + }, "scripts": { "build": "npm run build:lib && npm run build -w @microbit/microbit-connection-demo", "build:lib": "npm run build -w @microbit/microbit-connection", From d9dac39ef37e54c850804da89f316b1f61089f9c Mon Sep 17 00:00:00 2001 From: Grace Date: Wed, 15 Jul 2026 16:55:35 +0100 Subject: [PATCH 2/5] Configure CloudFlare pages to use node => v24 and npm >= v11.18 node version is defined by .node-version file. npm version is defined by packageManager in package.json. CloudFlare pages uses Corepack to manage package managers including npm. This allows CloudFlare deployments to use a later version of npm than the corresponding node version defined in .node-version. --- .node-version | 1 + package.json | 1 + 2 files changed, 2 insertions(+) create mode 100644 .node-version diff --git a/.node-version b/.node-version new file mode 100644 index 00000000..7329493e --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +24.18.0 \ No newline at end of file diff --git a/package.json b/package.json index 7cb6b9b8..b3e4e6f9 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "esbuild": true, "fsevents": true }, + "packageManager": "npm@11.18.0", "engines": { "node": ">=24.0.0", "npm": ">=11.18.0" From e7cf8bf06cd8413de657e3415b5dd4a34645aaa4 Mon Sep 17 00:00:00 2001 From: Grace Date: Fri, 17 Jul 2026 12:26:50 +0100 Subject: [PATCH 3/5] Add cludge around npm publish --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 590b94cd..77f2bfa8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: with: working-directory: packages/microbit-connection - run: npm run ci - - run: npm publish -w @microbit/microbit-connection + - run: npm publish -w @microbit/microbit-connection --allow-directory=all if: github.event_name == 'release' && github.event.action == 'created' env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From ba7985cd8a1c38bc4547fef8c3b074c9183cf5b1 Mon Sep 17 00:00:00 2001 From: Grace Date: Fri, 17 Jul 2026 12:46:30 +0100 Subject: [PATCH 4/5] Only apply strict engine req for library dev --- .npmrc | 2 -- package-lock.json | 4 ---- package.json | 14 +++++++++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.npmrc b/.npmrc index ad165a7c..538a0884 100644 --- a/.npmrc +++ b/.npmrc @@ -11,5 +11,3 @@ allow-file=root allow-directory=root strict-allow-scripts=true - -engine-strict=true diff --git a/package-lock.json b/package-lock.json index 073fc470..b2c4330b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,6 @@ ], "devDependencies": { "prettier": "3.3.2" - }, - "engines": { - "node": ">=24.0.0", - "npm": ">=11.18.0" } }, "apps/demo": { diff --git a/package.json b/package.json index b3e4e6f9..d188cc13 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,17 @@ "fsevents": true }, "packageManager": "npm@11.18.0", - "engines": { - "node": ">=24.0.0", - "npm": ">=11.18.0" + "devEngines": { + "runtime": { + "name": "node", + "version": ">=24.0.0", + "onFail": "error" + }, + "packageManager": { + "name": "npm", + "version": ">=11.18.0", + "onFail": "error" + } }, "scripts": { "build": "npm run build:lib && npm run build -w @microbit/microbit-connection-demo", From 8225c4016f0f04d1bb74ccba5faa63829aae2192 Mon Sep 17 00:00:00 2001 From: Grace Date: Fri, 17 Jul 2026 13:15:12 +0100 Subject: [PATCH 5/5] Revert "Only apply strict engine req for library dev" This reverts commit ba7985cd8a1c38bc4547fef8c3b074c9183cf5b1. --- .npmrc | 2 ++ package-lock.json | 4 ++++ package.json | 14 +++----------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.npmrc b/.npmrc index 538a0884..ad165a7c 100644 --- a/.npmrc +++ b/.npmrc @@ -11,3 +11,5 @@ allow-file=root allow-directory=root strict-allow-scripts=true + +engine-strict=true diff --git a/package-lock.json b/package-lock.json index b2c4330b..073fc470 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,10 @@ ], "devDependencies": { "prettier": "3.3.2" + }, + "engines": { + "node": ">=24.0.0", + "npm": ">=11.18.0" } }, "apps/demo": { diff --git a/package.json b/package.json index d188cc13..b3e4e6f9 100644 --- a/package.json +++ b/package.json @@ -10,17 +10,9 @@ "fsevents": true }, "packageManager": "npm@11.18.0", - "devEngines": { - "runtime": { - "name": "node", - "version": ">=24.0.0", - "onFail": "error" - }, - "packageManager": { - "name": "npm", - "version": ">=11.18.0", - "onFail": "error" - } + "engines": { + "node": ">=24.0.0", + "npm": ">=11.18.0" }, "scripts": { "build": "npm run build:lib && npm run build -w @microbit/microbit-connection-demo",