mirror of
https://github.com/morluto/rea.git
synced 2026-11-03 21:36:13 +00:00
* fix(browser): preserve capture evidence fidelity * fix(browser): align frame identity comparisons * fix(browser): retain historical frame evidence * fix(electron): retain same-document script owners * fix(electron): bind frame proof to tree reads * fix(browser): retain malformed frame scope * fix(browser): retain WebMCP event scope * fix(browser): retain malformed timeline identity * fix(browser): unify frame identity and scope * fix(electron): prove enclosing frame ancestry * fix(electron): separate ancestry from file policy * fix(browser): preserve transient fragment semantics * fix(browser): retry uncertain initial frame scope * fix(browser): preserve runtime frame identity * refactor(browser): separate independent capture fixes * fix(electron): detect tree-first document replacement * fix(electron): retain same-document tree authority --------- Co-authored-by: eco-null <eco-null@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
46 lines
1.7 KiB
TypeScript
46 lines
1.7 KiB
TypeScript
import type { BrowserObservationOperation } from "../domain/browserObservationErrors.js";
|
|
import { BrowserObservationError } from "../domain/browserObservationError.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 new BrowserObservationError(operation, "target_not_allowed");
|
|
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");
|
|
};
|