Files
reverse-engineering-anything/src/browser/CdpAuthorizedMainFrame.ts
T
morluto 09c2a2d241 fix(browser): preserve main-frame identity and scope refusal context
Read screenshot identity from the selected frame-tree root instead of a
filtered inventory that could substitute a child. Reuse the frame record
parser for initial and event identities, rejecting malformed roots before
capture while preserving known origin refusals.

Share explicit origin-scope diagnostics across CDP workflows without
changing policy or conflating startup uncertainty, document replacement,
worker protection, and Inspector restrictions. Document the recovery and
make screenshot navigation fixture ordering explicit.

Validation: 577 focused checks passed across 13 files; one platform-specific
invalid-byte-filename case skipped. Build, typecheck, lint, formatting,
generated documentation checks, README conformance, and discovery passed.
No full suite or live browser/provider execution.
2026-10-24 08:48:19 +08:00

47 lines
1.8 KiB
TypeScript

import type { BrowserObservationOperation } from "../domain/browserObservationErrors.js";
import { BrowserObservationError } from "../domain/browserObservationError.js";
import { cdpOriginScopeRefusal } from "./CdpOriginScopeError.js";
import type { CdpConnection } from "./CdpConnection.js";
import {
classifyCdpFrameUrl,
observeMainFrameUrl,
} from "./CdpCaptureDocuments.js";
import { delayWithCancellation } from "./CdpCaptureValues.js";
interface AuthorizedMainFrameOptions {
readonly connection: CdpConnection;
readonly sessionId: string | undefined;
readonly signal: AbortSignal | undefined;
readonly allowedOrigins: ReadonlySet<string>;
readonly operation: BrowserObservationOperation;
}
/** Wait for the attached target's main frame to enter its approved origin. */
export const authorizedMainFrame = async ({
connection,
sessionId,
signal,
allowedOrigins,
operation,
}: AuthorizedMainFrameOptions): Promise<unknown> => {
for (let attempt = 0; attempt < 80; attempt += 1) {
const result = await connection.send(
"Page.getFrameTree",
{},
sessionId,
signal,
);
const observed = observeMainFrameUrl(result);
const facts = classifyCdpFrameUrl(observed, allowedOrigins);
if (facts.scope === "outside_policy")
throw cdpOriginScopeRefusal(operation);
if (facts.scope === "approved" && observed.kind === "invalid_fragment")
throw new BrowserObservationError(operation, "protocol_error");
if (facts.url !== undefined) return result;
// Unsupported or missing base evidence cannot establish a policy exit.
// Keep the bounded startup retry even when the fragment is malformed.
await delayWithCancellation(25, operation, signal);
}
throw new BrowserObservationError(operation, "target_not_allowed");
};