Cover three scenarios:
- browser.cdpUrl with query token and HTTP Basic auth credentials
- browser.profiles.*.cdpUrl with per-profile credentials
- bare cdpUrl addresses without credentials remain unchanged
Refs #67656, #53433
Browser CDP URLs (browser.cdpUrl, browser.profiles.*.cdpUrl) can embed
credentials via query tokens (?token=xxx) or HTTP Basic auth
(user:pass@host). Add .cdpUrl suffix to isSensitiveUrlConfigPath() so
these paths are correctly redacted in config.get responses.
Refs #67656, #53433
* test(gateway): add full unit coverage for http-common.ts
Adds tests exercising every export in src/gateway/http-common.ts so the module reaches 100% line, branch, function and statement coverage (33 tests). Captures current default security headers (including the existing Permissions-Policy microphone=() deny-list) and exhaustively covers sendJson/sendText/sendMethodNotAllowed/sendUnauthorized/sendRateLimited (with and without Retry-After), sendGatewayAuthFailure (both branches), sendInvalidRequest, readJsonBodyOrError (413/408/400/success), writeDone, setSseHeaders (with and without flushHeaders) and watchClientDisconnect (empty/single/dedup/distinct sockets, abort logic and listener cleanup).
* fix(gateway): allow microphone access for same-origin in Permissions-Policy header
The gateway's default security headers set Permissions-Policy to microphone=(), which denies microphone access for every origin including the page itself. As a result, the control-ui chat mic button (ui/src/ui/chat/speech.ts) cannot start SpeechRecognition: the browser refuses with 'Permissions policy violation: microphone is not allowed in this document' and the button silently resets.
Relax microphone to the same-origin allowlist (self) so the dashboard page can use the Web Speech API while still blocking third-party frames. Camera and geolocation remain fully denied.
Fixes#51085
* test(gateway): add seeded property/fuzz tests for http-common.ts
Adds src/gateway/http-common.fuzz.test.ts with 13 property-style tests (200 iterations each) driven by an in-file deterministic mulberry32 PRNG. Covers every export with invariants rather than fixed examples: baseline security headers across all opts shapes, Strict-Transport-Security iff non-empty string, sendJson/sendText status + body round-trips across random codes and payloads, sendMethodNotAllowed with random Allow values, sendRateLimited Retry-After iff retryAfterMs>0 with ceil-seconds value (including fractional ms), sendGatewayAuthFailure delegation, sendInvalidRequest message echo, readJsonBodyOrError status/body mapping across random error texts, writeDone sentinel, setSseHeaders with/without flushHeaders, and watchClientDisconnect invariants across arbitrary socket/controller/callback combinations (empty, same, distinct, pre-aborted). Deterministic seeds keep failures reproducible without introducing a new dev dependency.
Use shared SDK payload helpers directly in the outbound payload contract helper
and narrow ZaloUser target parsing to its session-route module. This preserves
the contract proof without loading broad extension runtime/test barrels.
Skip bundled channel discovery for plain message-action params and only resolve
plugin-owned media params when an extension field is actually present. This
keeps normal sends on the lightweight path while preserving plugin media-field
coverage.
Run setup auto-enable probes only for plugin ids made relevant by the
current config instead of loading every setup API. This keeps provider
plugin auto-enable checks from paying unrelated setup registration cost.
Lazy-load the SearXNG web-search client from provider execution and reuse
the shared contract helper for credential and selection wiring. Keep the
shared fast-path contract focused on the single bundled manifest it checks.