From f86473ba7d0512c18f39c4de9ecb51ab4efbeb8d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 28 Aug 2026 00:53:54 +0000 Subject: [PATCH] Sync generated provider output --- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- .../detector/engines/browser/detect-url.mjs | 66 ++++++++++++++++++- .../impeccable/scripts/serve-question.mjs | 56 +++++++++++++--- 32 files changed, 1760 insertions(+), 192 deletions(-) diff --git a/.agents/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs b/.agents/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs index 5e3d5446b..f3ff43c84 100644 --- a/.agents/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +++ b/.agents/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs @@ -162,7 +162,68 @@ async function runVisualContrastFallback(page, serializedGroups, options, profil // Puppeteer detection (for URLs) // --------------------------------------------------------------------------- -async function detectUrl(url, options = {}) { +function decodeUrlComponent(value) { + try { + return decodeURIComponent(value); + } catch { + return value; + } +} + +function splitScanUrl(url) { + let parsed; + try { + parsed = new URL(url); + } catch { + return { href: url, credentials: null }; + } + if (!parsed.username && !parsed.password) { + return { href: url, credentials: null }; + } + const credentials = + parsed.protocol === 'http:' || parsed.protocol === 'https:' + ? { + username: decodeUrlComponent(parsed.username), + password: decodeUrlComponent(parsed.password), + } + : null; + parsed.username = ''; + parsed.password = ''; + return { href: parsed.href, credentials }; +} + +function basicAuthHeader(credentials) { + return `Basic ${Buffer.from(`${credentials.username}:${credentials.password}`).toString('base64')}`; +} + +// page.authenticate is page-wide: a cross-origin redirect that then 401s +// would receive these credentials. Attach Authorization only to the scan origin. +async function applyOriginScopedAuth(page, href, credentials) { + if (!credentials) return; + let origin = ''; + try { + origin = new URL(href).origin; + } catch { + return; + } + if (!origin) return; + const header = basicAuthHeader(credentials); + await page.setRequestInterception(true); + page.on('request', (request) => { + let headers; + try { + if (new URL(request.url()).origin === origin) { + headers = { ...request.headers(), authorization: header }; + } + } catch { + // invalid request URL: continue without auth + } + void request.continue(headers ? { headers } : undefined).catch(() => {}); + }); +} + +async function detectUrl(rawUrl, options = {}) { + const { href: url, credentials } = splitScanUrl(rawUrl); const profile = options?.profile; const waitUntil = options?.waitUntil || 'networkidle0'; const settleMs = Number.isFinite(options?.settleMs) ? options.settleMs : 0; @@ -238,6 +299,7 @@ async function detectUrl(url, options = {}) { ruleId: 'set-viewport', target: url, }, () => page.setViewport(viewport)); + await applyOriginScopedAuth(page, url, credentials); await profileStepAsync(profile, { engine: 'browser', phase: 'load', @@ -369,4 +431,4 @@ async function createBrowserDetector(options = {}) { }; } -export { runVisualContrastFallback, detectUrl, createBrowserDetector, launchBrowser }; +export { runVisualContrastFallback, detectUrl, createBrowserDetector, launchBrowser, splitScanUrl }; diff --git a/.agents/skills/impeccable/scripts/serve-question.mjs b/.agents/skills/impeccable/scripts/serve-question.mjs index 7c4ff0812..e08052c48 100644 --- a/.agents/skills/impeccable/scripts/serve-question.mjs +++ b/.agents/skills/impeccable/scripts/serve-question.mjs @@ -1019,7 +1019,9 @@ ${buildPath?.toggle ? `