github-advanced-security[bot] commented on code in PR #302:
URL: https://github.com/apache/cordova-paramedic/pull/302#discussion_r3258553302


##########
lib/ParamedicApp.js:
##########
@@ -106,10 +109,95 @@
         logger.normal('[paramedic] Setting the app start page to the test 
page');
         const filePath = path.join(this.tempFolder.name, 'config.xml');
         let config = fs.readFileSync(filePath, utilities.DEFAULT_ENCODING);
+
         config = config.replace('src="index.html"', 
'src="cdvtests/index.html"');
         fs.writeFileSync(filePath, config, utilities.DEFAULT_ENCODING);
     }
 
+    /**
+     * For browser platform, explicitly copies cordova-plugin-test-framework 
assets to
+     * www/cdvtests/ because the Cordova <asset> element may not execute 
reliably on
+     * the browser platform in CI environments.
+     */
+    ensureCdvTestsExists () {
+        if (!this.isBrowser) {
+            return;
+        }
+
+        const tfPluginAssetsDir = path.join(this.tempFolder.name, 'plugins', 
'cordova-plugin-test-framework', 'www', 'assets');
+        const cdvTestsDir = path.join(this.tempFolder.name, 'www', 'cdvtests');
+
+        if (!fs.existsSync(tfPluginAssetsDir)) {
+            logger.warn('[paramedic] cordova-plugin-test-framework assets not 
found at: ' + tfPluginAssetsDir);
+            return;
+        }
+
+        if (fs.existsSync(path.join(cdvTestsDir, 'index.html'))) {
+            logger.info('[paramedic] www/cdvtests/index.html already exists, 
skipping copy.');
+            return;
+        }
+
+        logger.info('[paramedic] Copying cordova-plugin-test-framework assets 
to www/cdvtests/');
+        fs.cpSync(tfPluginAssetsDir, cdvTestsDir, { recursive: true });
+        logger.info('[paramedic] Done copying to www/cdvtests/');
+    }
+
+    /**
+     * Ensures browser test page CSP allows localhost HTTP/WS endpoints used 
by Paramedic.
+     */
+    updateBrowserTestPageCSP () {
+        if (!this.isBrowser) {
+            return;
+        }
+
+        const testPagePath = path.join(this.tempFolder.name, 'www', 
'cdvtests', 'index.html');
+        if (!fs.existsSync(testPagePath)) {
+            return;
+        }
+
+        const addrs = [
+            'http://localhost:*',
+            'http://127.0.0.1:*',
+            'ws://localhost:*',
+            'ws://127.0.0.1:*'
+        ];
+
+        let html = fs.readFileSync(testPagePath, utilities.DEFAULT_ENCODING);
+        const cspMetaRegex = 
/<meta[^>]+http-equiv=["']Content-Security-Policy["'][^>]*>/i;
+        const cspContentRegex = /content=["']([^"']*)["']/i;
+
+        if (cspMetaRegex.test(html)) {
+            html = html.replace(cspMetaRegex, (metaTag) => {
+                const contentMatch = metaTag.match(cspContentRegex);
+                if (!contentMatch) {
+                    return metaTag;
+                }
+
+                let cspContent = contentMatch[1];
+                const connectSrcRegex = /connect-src\s+([^;]+)/i;
+
+                if (connectSrcRegex.test(cspContent)) {
+                    cspContent = cspContent.replace(connectSrcRegex, (full, 
sources) => {
+                        const sourceSet = new 
Set(sources.trim().split(/\s+/).filter(Boolean));
+                        addrs.forEach((addr) => sourceSet.add(addr));
+                        return `connect-src ${Array.from(sourceSet).join(' 
')}`;
+                    });
+                } else {
+                    cspContent = `${cspContent.trim().replace(/;?$/, ';')} 
connect-src 'self' ${addrs.join(' ')};`;
+                }
+
+                return metaTag.replace(cspContentRegex, 
`content="${cspContent}"`);
+            });
+        } else {
+            const cspTag = `<meta http-equiv="Content-Security-Policy" 
content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; 
style-src 'self' 'unsafe-inline'; media-src *; connect-src 'self' 
${addrs.join(' ')};">`;
+            if (/<head[^>]*>/i.test(html)) {
+                html = html.replace(/<head[^>]*>/i, (headTag) => `${headTag}\n 
   ${cspTag}`);
+            }
+        }
+
+        fs.writeFileSync(testPagePath, html, utilities.DEFAULT_ENCODING);

Review Comment:
   ## CodeQL / Potential file system race condition
   
   The file may have changed since it [was checked](1).
   
   [Show more 
details](https://github.com/apache/cordova-paramedic/security/code-scanning/2)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to