From fbf676a77f10c9fba2a3ef5b2f754a6809ae7d02 Mon Sep 17 00:00:00 2001 From: maziggy Date: Wed, 18 Feb 2026 18:08:07 +0100 Subject: [PATCH] Updated CI --- .github/workflows/security.yml | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index e5fc4a2de..0496148a4 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -230,7 +230,35 @@ jobs: id: npm-audit working-directory: frontend run: | - npm audit --omit=dev --json > npm-audit-results.json || echo "vulnerabilities_found=true" >> $GITHUB_OUTPUT + npm audit --omit=dev --json > npm-audit-raw.json 2>&1 || true + # Filter audit results to only include actual project dependencies + # (npm audit sometimes reports vulnerabilities in the npm CLI itself) + node -e " + const fs = require('fs'); + const results = JSON.parse(fs.readFileSync('npm-audit-raw.json', 'utf8')); + const depTree = JSON.parse(require('child_process').execSync( + 'npm ls --omit=dev --all --json 2>/dev/null', { encoding: 'utf8' } + )); + const prodDeps = new Set(); + (function walk(obj) { + for (const [name, info] of Object.entries(obj.dependencies || {})) { + prodDeps.add(name); + walk(info); + } + })(depTree); + const vulns = results.vulnerabilities || {}; + const filtered = {}; + for (const [name, info] of Object.entries(vulns)) { + if (prodDeps.has(name)) filtered[name] = info; + } + results.vulnerabilities = filtered; + fs.writeFileSync('npm-audit-results.json', JSON.stringify(results, null, 2)); + const count = Object.keys(filtered).length; + console.log(count > 0 + ? count + ' production vulnerabilities found' + : 'No production vulnerabilities (filtered ' + Object.keys(vulns).length + ' npm-internal entries)'); + if (count > 0) process.exit(1); + " || echo "vulnerabilities_found=true" >> $GITHUB_OUTPUT npm audit --omit=dev --audit-level=high || true - name: Upload audit results