From 6c82d3e4ca02a98adc63aae97ce2bde2fa9c194e Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 15:50:11 +0400 Subject: [PATCH 01/11] fix: use express-rate-limit in CSP demo server to resolve CodeQL alert --- apps/demos/package.json | 1 + apps/demos/utils/server/csp-server.js | 24 +++++------------------- pnpm-lock.yaml | 13 +++++++++++++ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/apps/demos/package.json b/apps/demos/package.json index 3803c321062b..c20ab88bd052 100644 --- a/apps/demos/package.json +++ b/apps/demos/package.json @@ -116,6 +116,7 @@ "babel-jest": "29.7.0", "consola": "3.2.3", "cookie-parser": "1.4.7", + "express-rate-limit": "7.5.0", "cross-env": "7.0.3", "devextreme-screenshot-comparer": "2.0.17", "eslint": "catalog:", diff --git a/apps/demos/utils/server/csp-server.js b/apps/demos/utils/server/csp-server.js index 38d40a9ba8df..ab25f614ee54 100644 --- a/apps/demos/utils/server/csp-server.js +++ b/apps/demos/utils/server/csp-server.js @@ -2,6 +2,7 @@ const crypto = require('crypto'); const express = require('express'); +const rateLimit = require('express-rate-limit'); const serveStatic = require('serve-static'); const cookieParser = require('cookie-parser'); const { join, resolve } = require('path'); @@ -376,25 +377,10 @@ const demoIndexHandler = (request, response) => { response.send(fileContent); }; -const createRateLimiter = (windowMs = 60000, maxRequests = 200) => { - const hits = new Map(); - - setInterval(() => hits.clear(), windowMs); - - return (req, res, next) => { - const key = req.ip; - const count = (hits.get(key) || 0) + 1; - hits.set(key, count); - - if (count > maxRequests) { - res.status(429).send('Too Many Requests'); - return; - } - next(); - }; -}; - -const rateLimiter = createRateLimiter(); +const rateLimiter = rateLimit({ + windowMs: 60 * 1000, + max: 200, +}); const app = express(); app.use(cookieParser()); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 52971a0e7d7b..b82a84e6e649 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -699,6 +699,9 @@ importers: express: specifier: 4.22.1 version: 4.22.1 + express-rate-limit: + specifier: 7.5.0 + version: 7.5.0(express@4.22.1) glob: specifier: 11.1.0 version: 11.1.0 @@ -10695,6 +10698,12 @@ packages: exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + express-rate-limit@7.5.0: + resolution: {integrity: sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==} + engines: {node: '>= 16'} + peerDependencies: + express: ^4.11 || 5 || ^5.0.0-beta.1 + express-rate-limit@8.3.1: resolution: {integrity: sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==} engines: {node: '>= 16'} @@ -31584,6 +31593,10 @@ snapshots: exponential-backoff@3.1.1: {} + express-rate-limit@7.5.0(express@4.22.1): + dependencies: + express: 4.22.1 + express-rate-limit@8.3.1(express@5.2.1): dependencies: express: 5.2.1 From 0e7c18659b3a6ecdeb28affcda3ffb53e9745f32 Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 15:59:41 +0400 Subject: [PATCH 02/11] update version --- apps/demos/package.json | 2 +- pnpm-lock.yaml | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/demos/package.json b/apps/demos/package.json index c20ab88bd052..0da49877a56f 100644 --- a/apps/demos/package.json +++ b/apps/demos/package.json @@ -116,7 +116,7 @@ "babel-jest": "29.7.0", "consola": "3.2.3", "cookie-parser": "1.4.7", - "express-rate-limit": "7.5.0", + "express-rate-limit": "8.3.1", "cross-env": "7.0.3", "devextreme-screenshot-comparer": "2.0.17", "eslint": "catalog:", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b82a84e6e649..b1a0d71f8c56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -700,8 +700,8 @@ importers: specifier: 4.22.1 version: 4.22.1 express-rate-limit: - specifier: 7.5.0 - version: 7.5.0(express@4.22.1) + specifier: 8.3.1 + version: 8.3.1(express@4.22.1) glob: specifier: 11.1.0 version: 11.1.0 @@ -10698,12 +10698,6 @@ packages: exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} - express-rate-limit@7.5.0: - resolution: {integrity: sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==} - engines: {node: '>= 16'} - peerDependencies: - express: ^4.11 || 5 || ^5.0.0-beta.1 - express-rate-limit@8.3.1: resolution: {integrity: sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==} engines: {node: '>= 16'} @@ -31593,9 +31587,10 @@ snapshots: exponential-backoff@3.1.1: {} - express-rate-limit@7.5.0(express@4.22.1): + express-rate-limit@8.3.1(express@4.22.1): dependencies: express: 4.22.1 + ip-address: 10.1.0 express-rate-limit@8.3.1(express@5.2.1): dependencies: From 7a175cc9ad90e8e496112bbb5a41c4f568081227 Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 16:49:02 +0400 Subject: [PATCH 03/11] Update csp-server.js --- apps/demos/utils/server/csp-server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/demos/utils/server/csp-server.js b/apps/demos/utils/server/csp-server.js index ab25f614ee54..b39ab0ad36bc 100644 --- a/apps/demos/utils/server/csp-server.js +++ b/apps/demos/utils/server/csp-server.js @@ -379,7 +379,7 @@ const demoIndexHandler = (request, response) => { const rateLimiter = rateLimit({ windowMs: 60 * 1000, - max: 200, + max: 2000, }); const app = express(); From e0b37905cbcc07a9ac8caa64103ffb8a2853ed30 Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 18:13:18 +0400 Subject: [PATCH 04/11] update configuration --- apps/demos/utils/server/csp-check.js | 4 ++-- apps/demos/utils/server/csp-server.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/demos/utils/server/csp-check.js b/apps/demos/utils/server/csp-check.js index d0928a8fb506..085b61a1f636 100644 --- a/apps/demos/utils/server/csp-check.js +++ b/apps/demos/utils/server/csp-check.js @@ -9,7 +9,7 @@ const DEMO_ROOT = join(__dirname, '..', '..'); const REPORT_DIR = join(DEMO_ROOT, 'csp-reports'); const SERVER_URL = process.env.CSP_SERVER_URL || 'http://localhost:8080'; const FRAMEWORK = (process.env.CSP_FRAMEWORKS || 'jQuery').trim(); -const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 8; +const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 5; function findChrome() { const candidates = [ @@ -87,7 +87,7 @@ function visitPage(url) { '--virtual-time-budget=5000', '--window-size=100,100', url, - ], { timeout: 30000 }, () => resolve()); + ], { timeout: 10000 }, () => resolve()); child.on('error', (err) => { reject(new Error(`Failed to launch Chrome at "${CHROME_PATH}": ${err.message}`)); }); diff --git a/apps/demos/utils/server/csp-server.js b/apps/demos/utils/server/csp-server.js index b39ab0ad36bc..d81c2c15d232 100644 --- a/apps/demos/utils/server/csp-server.js +++ b/apps/demos/utils/server/csp-server.js @@ -379,7 +379,7 @@ const demoIndexHandler = (request, response) => { const rateLimiter = rateLimit({ windowMs: 60 * 1000, - max: 2000, + max: 5000, }); const app = express(); From 9d058e8502095774b1583f6c297aa1972deb22bc Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 18:33:37 +0400 Subject: [PATCH 05/11] remove excess parts --- apps/demos/package.json | 1 - apps/demos/utils/server/csp-check.js | 2 +- apps/demos/utils/server/csp-server.js | 12 +----------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/apps/demos/package.json b/apps/demos/package.json index 0da49877a56f..3803c321062b 100644 --- a/apps/demos/package.json +++ b/apps/demos/package.json @@ -116,7 +116,6 @@ "babel-jest": "29.7.0", "consola": "3.2.3", "cookie-parser": "1.4.7", - "express-rate-limit": "8.3.1", "cross-env": "7.0.3", "devextreme-screenshot-comparer": "2.0.17", "eslint": "catalog:", diff --git a/apps/demos/utils/server/csp-check.js b/apps/demos/utils/server/csp-check.js index 085b61a1f636..0a58f5f1d74c 100644 --- a/apps/demos/utils/server/csp-check.js +++ b/apps/demos/utils/server/csp-check.js @@ -9,7 +9,7 @@ const DEMO_ROOT = join(__dirname, '..', '..'); const REPORT_DIR = join(DEMO_ROOT, 'csp-reports'); const SERVER_URL = process.env.CSP_SERVER_URL || 'http://localhost:8080'; const FRAMEWORK = (process.env.CSP_FRAMEWORKS || 'jQuery').trim(); -const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 5; +const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 4; function findChrome() { const candidates = [ diff --git a/apps/demos/utils/server/csp-server.js b/apps/demos/utils/server/csp-server.js index d81c2c15d232..014cf7f49a68 100644 --- a/apps/demos/utils/server/csp-server.js +++ b/apps/demos/utils/server/csp-server.js @@ -2,8 +2,6 @@ const crypto = require('crypto'); const express = require('express'); -const rateLimit = require('express-rate-limit'); -const serveStatic = require('serve-static'); const cookieParser = require('cookie-parser'); const { join, resolve } = require('path'); const { readFileSync, readdirSync } = require('fs'); @@ -377,15 +375,9 @@ const demoIndexHandler = (request, response) => { response.send(fileContent); }; -const rateLimiter = rateLimit({ - windowMs: 60 * 1000, - max: 5000, -}); - const app = express(); app.use(cookieParser()); app.use(cspMiddleware); -app.use(rateLimiter); app.post('/csp-report', cspReportHandler); app.get('/csp-violations', cspViolationsHandler); @@ -394,9 +386,7 @@ app.delete('/csp-violations', cspViolationsClearHandler); app.get('/apps/demos/Demos/:widget/:name/:approach', demoIndexHandler); app.get(`/apps/demos/Demos/:widget/:name/:approach/${indexFileName}`, demoIndexHandler); -app.use( - serveStatic(root, { index: [indexFileName] }), -); +app.use(express.static(root, { index: [indexFileName] })); const server = app.listen(port, host, () => { console.log(`CSP Demo server listening on http://${host}:${port}`); From 5011a9c6be09ed288cdb8c967309e0819320f463 Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 18:35:41 +0400 Subject: [PATCH 06/11] Update pnpm-lock.yaml --- pnpm-lock.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1a0d71f8c56..52971a0e7d7b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -699,9 +699,6 @@ importers: express: specifier: 4.22.1 version: 4.22.1 - express-rate-limit: - specifier: 8.3.1 - version: 8.3.1(express@4.22.1) glob: specifier: 11.1.0 version: 11.1.0 @@ -31587,11 +31584,6 @@ snapshots: exponential-backoff@3.1.1: {} - express-rate-limit@8.3.1(express@4.22.1): - dependencies: - express: 4.22.1 - ip-address: 10.1.0 - express-rate-limit@8.3.1(express@5.2.1): dependencies: express: 5.2.1 From 38d2527213768442ce079cda6c881109dd9cfded Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 19:12:28 +0400 Subject: [PATCH 07/11] speedup tests --- apps/demos/utils/server/csp-check.js | 78 ++++++++++++++-------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/apps/demos/utils/server/csp-check.js b/apps/demos/utils/server/csp-check.js index 0a58f5f1d74c..83e303ae3dbd 100644 --- a/apps/demos/utils/server/csp-check.js +++ b/apps/demos/utils/server/csp-check.js @@ -9,7 +9,7 @@ const DEMO_ROOT = join(__dirname, '..', '..'); const REPORT_DIR = join(DEMO_ROOT, 'csp-reports'); const SERVER_URL = process.env.CSP_SERVER_URL || 'http://localhost:8080'; const FRAMEWORK = (process.env.CSP_FRAMEWORKS || 'jQuery').trim(); -const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 4; +const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 10; function findChrome() { const candidates = [ @@ -87,7 +87,7 @@ function visitPage(url) { '--virtual-time-budget=5000', '--window-size=100,100', url, - ], { timeout: 10000 }, () => resolve()); + ], { timeout: 10000, killSignal: 'SIGKILL' }, () => resolve()); child.on('error', (err) => { reject(new Error(`Failed to launch Chrome at "${CHROME_PATH}": ${err.message}`)); }); @@ -112,6 +112,21 @@ function httpRequest(url, method) { }); } +async function runPool(items, concurrency, fn) { + let nextIndex = 0; + async function worker() { + while (nextIndex < items.length) { + const i = nextIndex++; + await fn(items[i], i); + } + } + const workers = []; + for (let w = 0; w < Math.min(concurrency, items.length); w += 1) { + workers.push(worker()); + } + await Promise.all(workers); +} + async function main() { console.log(`Chrome: ${CHROME_PATH}`); console.log(`Server: ${SERVER_URL}`); @@ -130,48 +145,33 @@ async function main() { let demosWithViolations = 0; const allViolations = []; - for (let batchStart = 0; batchStart < demos.length; batchStart += CONCURRENCY) { - const batch = demos.slice(batchStart, batchStart + CONCURRENCY); - - await httpRequest(`${SERVER_URL}/csp-violations`, 'DELETE'); - - await Promise.all(batch.map((demo) => visitPage(demo.url))); + await httpRequest(`${SERVER_URL}/csp-violations`, 'DELETE'); - await new Promise((resolve) => { setTimeout(resolve, 500); }); + let visited = 0; + await runPool(demos, CONCURRENCY, async (demo) => { + await visitPage(demo.url); + visited += 1; const result = await httpRequest(`${SERVER_URL}/csp-violations`); - const violations = result.violations || []; - - const violationsByUrl = {}; - for (const v of violations) { - const uri = v.documentUri || ''; - if (!violationsByUrl[uri]) violationsByUrl[uri] = []; - violationsByUrl[uri].push(v); - } - - for (let j = 0; j < batch.length; j += 1) { - const demo = batch[j]; - const idx = batchStart + j + 1; - const demoViolations = violationsByUrl[demo.url] - || violationsByUrl[`${demo.url}index.html`] - || []; - - if (demoViolations.length > 0) { - demosWithViolations += 1; - totalViolations += demoViolations.length; - - console.log(` ❌ [${idx}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework} — ${demoViolations.length} violation(s)`); - for (const v of demoViolations) { - const blocked = v.blockedUri || 'N/A'; - const directive = v.effectiveDirective || v.violatedDirective || '?'; - console.log(` ${directive}: ${blocked}`); - allViolations.push({ ...v, framework: FRAMEWORK }); - } - } else { - console.log(` ✅ [${idx}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework}`); + const violations = (result.violations || []).filter( + (v) => v.documentUri === demo.url || v.documentUri === `${demo.url}index.html`, + ); + + if (violations.length > 0) { + demosWithViolations += 1; + totalViolations += violations.length; + + console.log(` ❌ [${visited}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework} — ${violations.length} violation(s)`); + for (const v of violations) { + const blocked = v.blockedUri || 'N/A'; + const directive = v.effectiveDirective || v.violatedDirective || '?'; + console.log(` ${directive}: ${blocked}`); + allViolations.push({ ...v, framework: FRAMEWORK }); } + } else { + console.log(` ✅ [${visited}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework}`); } - } + }); const reportFile = join(REPORT_DIR, `csp-violations-${FRAMEWORK.toLowerCase()}.jsonl`); From 83559dd9e1282441187ec286ff26e46a35d95bef Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 19:13:43 +0400 Subject: [PATCH 08/11] Update csp-check.js --- apps/demos/utils/server/csp-check.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/demos/utils/server/csp-check.js b/apps/demos/utils/server/csp-check.js index 83e303ae3dbd..bb3d7f2a7c35 100644 --- a/apps/demos/utils/server/csp-check.js +++ b/apps/demos/utils/server/csp-check.js @@ -116,7 +116,8 @@ async function runPool(items, concurrency, fn) { let nextIndex = 0; async function worker() { while (nextIndex < items.length) { - const i = nextIndex++; + const i = nextIndex; + nextIndex += 1; await fn(items[i], i); } } From 48e264c252f975217ca26d7dc0153f0ea67e1d5d Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 19:45:41 +0400 Subject: [PATCH 09/11] Update csp-check.js --- apps/demos/utils/server/csp-check.js | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/apps/demos/utils/server/csp-check.js b/apps/demos/utils/server/csp-check.js index bb3d7f2a7c35..0b075c453df2 100644 --- a/apps/demos/utils/server/csp-check.js +++ b/apps/demos/utils/server/csp-check.js @@ -9,7 +9,7 @@ const DEMO_ROOT = join(__dirname, '..', '..'); const REPORT_DIR = join(DEMO_ROOT, 'csp-reports'); const SERVER_URL = process.env.CSP_SERVER_URL || 'http://localhost:8080'; const FRAMEWORK = (process.env.CSP_FRAMEWORKS || 'jQuery').trim(); -const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 10; +const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 6; function findChrome() { const candidates = [ @@ -87,7 +87,13 @@ function visitPage(url) { '--virtual-time-budget=5000', '--window-size=100,100', url, - ], { timeout: 10000, killSignal: 'SIGKILL' }, () => resolve()); + ], { timeout: 50000, killSignal: 'SIGKILL' }, (error) => { + if (error && error.killed) { + reject(new Error(`Chrome timed out for ${url}`)); + } else { + resolve(); + } + }); child.on('error', (err) => { reject(new Error(`Failed to launch Chrome at "${CHROME_PATH}": ${err.message}`)); }); @@ -148,10 +154,14 @@ async function main() { await httpRequest(`${SERVER_URL}/csp-violations`, 'DELETE'); - let visited = 0; - await runPool(demos, CONCURRENCY, async (demo) => { - await visitPage(demo.url); - visited += 1; + await runPool(demos, CONCURRENCY, async (demo, i) => { + const idx = i + 1; + try { + await visitPage(demo.url); + } catch (err) { + console.log(` ⚠️ [${idx}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework} — ${err.message}`); + return; + } const result = await httpRequest(`${SERVER_URL}/csp-violations`); const violations = (result.violations || []).filter( @@ -162,7 +172,7 @@ async function main() { demosWithViolations += 1; totalViolations += violations.length; - console.log(` ❌ [${visited}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework} — ${violations.length} violation(s)`); + console.log(` ❌ [${idx}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework} — ${violations.length} violation(s)`); for (const v of violations) { const blocked = v.blockedUri || 'N/A'; const directive = v.effectiveDirective || v.violatedDirective || '?'; @@ -170,7 +180,7 @@ async function main() { allViolations.push({ ...v, framework: FRAMEWORK }); } } else { - console.log(` ✅ [${visited}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework}`); + console.log(` ✅ [${idx}/${demos.length}] ${demo.widget}/${demo.demo}/${demo.framework}`); } }); From 2ffdcf297f4337141df70061235f454f496f4b74 Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 20:12:11 +0400 Subject: [PATCH 10/11] increase concurrency --- apps/demos/utils/server/csp-check.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/demos/utils/server/csp-check.js b/apps/demos/utils/server/csp-check.js index 0b075c453df2..9208275949f0 100644 --- a/apps/demos/utils/server/csp-check.js +++ b/apps/demos/utils/server/csp-check.js @@ -9,7 +9,7 @@ const DEMO_ROOT = join(__dirname, '..', '..'); const REPORT_DIR = join(DEMO_ROOT, 'csp-reports'); const SERVER_URL = process.env.CSP_SERVER_URL || 'http://localhost:8080'; const FRAMEWORK = (process.env.CSP_FRAMEWORKS || 'jQuery').trim(); -const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 6; +const CONCURRENCY = parseInt(process.env.CSP_CONCURRENCY, 10) || 10; function findChrome() { const candidates = [ @@ -84,7 +84,7 @@ function visitPage(url) { '--disable-software-rasterizer', '--disable-dev-shm-usage', '--dump-dom', - '--virtual-time-budget=5000', + '--virtual-time-budget=2000', '--window-size=100,100', url, ], { timeout: 50000, killSignal: 'SIGKILL' }, (error) => { From b94598cae0b138c3d78d327c29476eed8d2bb37d Mon Sep 17 00:00:00 2001 From: EugeniyKiyashko Date: Mon, 16 Mar 2026 20:25:59 +0400 Subject: [PATCH 11/11] Update csp-check.js --- apps/demos/utils/server/csp-check.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/demos/utils/server/csp-check.js b/apps/demos/utils/server/csp-check.js index 9208275949f0..480b96a8c91b 100644 --- a/apps/demos/utils/server/csp-check.js +++ b/apps/demos/utils/server/csp-check.js @@ -156,6 +156,9 @@ async function main() { await runPool(demos, CONCURRENCY, async (demo, i) => { const idx = i + 1; + const snapshot = await httpRequest(`${SERVER_URL}/csp-violations`); + const since = snapshot.lastId || 0; + try { await visitPage(demo.url); } catch (err) { @@ -163,7 +166,7 @@ async function main() { return; } - const result = await httpRequest(`${SERVER_URL}/csp-violations`); + const result = await httpRequest(`${SERVER_URL}/csp-violations?since=${since}`); const violations = (result.violations || []).filter( (v) => v.documentUri === demo.url || v.documentUri === `${demo.url}index.html`, );