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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
61ab464b45
commit
bcbc5ecdfb
+32
-14
@@ -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('<!doctype html><title>foreign</title>foreign 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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user