From bcbc5ecdfb58e388cb31dffc95167ef9518792de Mon Sep 17 00:00:00 2001 From: Lotus CI Date: Wed, 30 Sep 2026 12:46:30 -0400 Subject: [PATCH] windows smoke: foreign-page mic check on a local origin, navigation verified The example.com check could pass vacuously if the runner can't reach the internet (goto failed silently, the mic request then came from the app's own page). Serve a page on http://localhost:9333 instead, confirm the navigation happened, and fail on builds that should refuse it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA --- scripts/windows-smoke.mjs | 46 +++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/scripts/windows-smoke.mjs b/scripts/windows-smoke.mjs index a757340..1808d1b 100644 --- a/scripts/windows-smoke.mjs +++ b/scripts/windows-smoke.mjs @@ -11,6 +11,7 @@ // instead of failing, so the same script runs on main and on PR branches. import { writeFileSync, mkdirSync } from 'node:fs'; import { execSync } from 'node:child_process'; +import { createServer } from 'node:http'; import { chromium } from 'playwright-core'; const OUT = process.argv[2] || 'smoke-out'; @@ -150,21 +151,38 @@ else if (!kc.supported) record('keychain round trip', 'fail', 'secure_session_su else record('keychain round trip', kc.roundTrip && kc.restored ? 'pass' : 'fail', JSON.stringify(kc)); // 7. A foreign page loaded in the window must not get the microphone (#22). -await page.goto('https://example.com/').catch(() => undefined); -const foreignMic = await page.evaluate(async () => { - try { - const s = await navigator.mediaDevices.getUserMedia({ audio: true }); - s.getTracks().forEach((t) => t.stop()); - return 'ok'; - } catch (e) { - return e.name; - } +// Served locally on another port (a different origin, still a secure context), +// so the check doesn't depend on the runner reaching the internet. +const foreign = createServer((_, res) => { + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end('foreignforeign page'); }); -record( - 'microphone refused to a foreign page', - foreignMic === 'NotAllowedError' ? 'pass' : 'info', - `${foreignMic}${foreignMic === 'ok' ? ' (build without the #22 origin check)' : ''}`, -); +await new Promise((r) => foreign.listen(9333, '127.0.0.1', r)); +const FOREIGN = 'http://localhost:9333/'; +await page.goto(FOREIGN).catch(() => undefined); +if (!page.url().startsWith(FOREIGN)) { + record('microphone refused to a foreign page', 'fail', `navigation did not happen (at ${page.url()})`); +} else { + const foreignMic = await page.evaluate(async () => { + try { + const s = await navigator.mediaDevices.getUserMedia({ audio: true }); + s.getTracks().forEach((t) => t.stop()); + return 'ok'; + } catch (e) { + return e.name; + } + }); + const guarded = cfg.desktopCallOrigin !== undefined; // builds with #22 also carry #43 + let status = 'info'; + if (foreignMic === 'NotAllowedError') status = 'pass'; + else if (guarded) status = 'fail'; + record( + 'microphone refused to a foreign page', + status, + `${foreignMic} at ${page.url()}${status === 'info' ? ' (build without the #22 origin check)' : ''}`, + ); +} +foreign.close(); await page.goto(APP).catch(() => undefined); await page.screenshot({ path: `${OUT}/02-end.png` }).catch(() => undefined);