@corbado/autocapture 0.1.0-next.2-dd9eb36 → 0.1.0-next.4-aa81c53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -14
- package/dist/index.d.mts +71 -66
- package/dist/index.d.ts +71 -66
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,15 +37,10 @@ Every observer follows the platform observer pattern (`MutationObserver`, `Resiz
|
|
|
37
37
|
it with a callback, receive events, and call `disconnect()` when finished.
|
|
38
38
|
|
|
39
39
|
```ts
|
|
40
|
-
import {
|
|
41
|
-
captureWebAuthn,
|
|
42
|
-
captureNetwork,
|
|
43
|
-
captureNavigation,
|
|
44
|
-
captureShadowRoots,
|
|
45
|
-
} from "@corbado/autocapture";
|
|
40
|
+
import { captureWebAuthn, captureNetwork, captureNavigation, captureShadowRoots } from "@corbado/autocapture";
|
|
46
41
|
|
|
47
42
|
const webauthn = captureWebAuthn({
|
|
48
|
-
onEvent: (event) => console.log(event.kind, event.phase, event.ceremonyId),
|
|
43
|
+
onEvent: (event) => console.log(event.kind, event.mediation, event.phase, event.ceremonyId),
|
|
49
44
|
});
|
|
50
45
|
|
|
51
46
|
const network = captureNetwork({
|
|
@@ -85,6 +80,13 @@ throwing; a misconfigured `captureNetwork` call (missing `match` or `onExchange`
|
|
|
85
80
|
`TypeError` instead, since that is a programming error, not a degraded environment. Full event and
|
|
86
81
|
option types ship with the package.
|
|
87
82
|
|
|
83
|
+
WebAuthn events use a protocol-native discriminated union. Authentication phases carry normalized
|
|
84
|
+
`mediation`, `uiMode`, and `credentialSet` (`"allowlisted"` or `"discoverable"`); registration
|
|
85
|
+
phases carry normalized `mediation`. The same profile is present on every phase of one ceremony.
|
|
86
|
+
Autocapture deliberately does not infer product concepts such as conditional-UI spec types,
|
|
87
|
+
known-identifier state, enrollment intent, or the user/system actor. Integrations map those facts in
|
|
88
|
+
their own state context.
|
|
89
|
+
|
|
88
90
|
## Safety invariants
|
|
89
91
|
|
|
90
92
|
The observers run inside application call paths, so their behaviour is defined by what they promise
|
|
@@ -130,13 +132,12 @@ Network observation is designed for minimal data exposure:
|
|
|
130
132
|
only on `onExchange`; string bodies passed through `RequestInit` are available synchronously.
|
|
131
133
|
- Autocapture performs no generic body parsing or redaction. The endpoint-specific projector is the
|
|
132
134
|
privacy boundary: it receives the matched raw body and must return only the fields the consumer is
|
|
133
|
-
allowed to observe.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
enabling it is a security and performance decision.
|
|
135
|
+
allowed to observe. The exact projected value is attached to the exchange without generic
|
|
136
|
+
serialization, cloning, or size limiting. Projector failures, promises, and `undefined` fail closed
|
|
137
|
+
by omitting the body.
|
|
138
|
+
- Readable bodies come from isolated clones read within a 500 ms window; the source body is never
|
|
139
|
+
directly consumed, and streaming and binary payloads are never read. Body cloning still has
|
|
140
|
+
inherent stream tee/backpressure costs, so enabling it is a security and performance decision.
|
|
140
141
|
|
|
141
142
|
Network metadata currently includes the resolved full URL and final response URL. Query strings can
|
|
142
143
|
contain secrets or PII; callers should restrict `match` accordingly until a URL-redaction policy is
|
package/dist/index.d.mts
CHANGED
|
@@ -15,55 +15,62 @@ type CaptureHandle = {
|
|
|
15
15
|
/** Stops future event delivery. Safe to call more than once. */
|
|
16
16
|
disconnect(): void;
|
|
17
17
|
};
|
|
18
|
-
/**
|
|
19
|
-
type
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
/** Normalized Credential Management mediation. Missing mediation defaults to `optional`. */
|
|
19
|
+
type WebAuthnMediation = "silent" | "optional" | "conditional" | "required" | "unknown";
|
|
20
|
+
/** Normalized Credential Management UI mode for authentication ceremonies. */
|
|
21
|
+
type WebAuthnUiMode = "default" | "immediate" | "unknown";
|
|
22
|
+
/** Browser-native facts that remain stable for one ceremony. */
|
|
23
|
+
type WebAuthnCeremonyContext = {
|
|
24
|
+
kind: "authentication";
|
|
25
|
+
mediation: WebAuthnMediation;
|
|
26
|
+
uiMode: WebAuthnUiMode;
|
|
27
|
+
/** Whether the RP supplied a non-empty allow list or requested discoverable credentials. */
|
|
28
|
+
credentialSet: "allowlisted" | "discoverable";
|
|
29
|
+
} | {
|
|
30
|
+
kind: "registration";
|
|
31
|
+
mediation: WebAuthnMediation;
|
|
32
|
+
};
|
|
33
|
+
type WebAuthnCeremonyBase = WebAuthnCeremonyContext & {
|
|
27
34
|
/** Identifier shared by all events belonging to the same ceremony. */
|
|
28
35
|
ceremonyId: string;
|
|
29
|
-
/**
|
|
30
|
-
phase: "started" | "completed" | "failed";
|
|
31
|
-
/** Requested mediation mode, when available. */
|
|
32
|
-
mediation?: string;
|
|
33
|
-
/** Whether transient user activation was active when the ceremony started. Present on `started` events when exposed by the browser. */
|
|
34
|
-
userActivation?: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* JSON-encoded request metadata for a `get` ceremony: `rpId`, `timeout`,
|
|
37
|
-
* `userVerification`, `hints`, `challenge`, and `allowCredentials`
|
|
38
|
-
* (`type`, `id`, and `transports`). Binary values are base64url-encoded.
|
|
39
|
-
* Unavailable fields are omitted. Present on `started` events when
|
|
40
|
-
* serialization succeeds. Treat this value as sensitive telemetry.
|
|
41
|
-
*/
|
|
36
|
+
/** Authentication request metadata; present only when applicable and serializable. */
|
|
42
37
|
requestOptionsJson?: string;
|
|
43
|
-
/**
|
|
44
|
-
hasAllowCredentials?: boolean;
|
|
45
|
-
/**
|
|
46
|
-
* JSON-encoded, allowlisted credential returned by a completed ceremony.
|
|
47
|
-
* Common fields are `id`, `rawId`, `type`, and `authenticatorAttachment`.
|
|
48
|
-
* Assertion responses include `clientDataJSON`, `authenticatorData`,
|
|
49
|
-
* `signature`, and `userHandle`; attestation responses include
|
|
50
|
-
* `clientDataJSON`, `attestationObject`, and `transports`. Binary values are
|
|
51
|
-
* base64url-encoded. Of the client-extension results, only `credProps.rk` may
|
|
52
|
-
* be included. Present when serialization succeeds. Treat this value as
|
|
53
|
-
* sensitive telemetry.
|
|
54
|
-
*/
|
|
38
|
+
/** Completed credential metadata; present only when applicable and serializable. */
|
|
55
39
|
credentialJson?: string;
|
|
56
|
-
/**
|
|
40
|
+
/** Failure details; present only for failed ceremonies. */
|
|
57
41
|
error?: unknown;
|
|
58
|
-
/** Error name for a failed ceremony, or `UnknownError` when no DOM exception name is available. */
|
|
59
42
|
errorName?: string;
|
|
43
|
+
/** Present when the request signal was aborted before settlement. */
|
|
44
|
+
aborted?: true;
|
|
45
|
+
};
|
|
46
|
+
type WebAuthnCeremonyStartedEvent = WebAuthnCeremonyBase & {
|
|
47
|
+
phase: "started";
|
|
48
|
+
/** Whether transient user activation was active when the ceremony started, when exposed by the browser. */
|
|
49
|
+
userActivation?: boolean;
|
|
60
50
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
51
|
+
* JSON-encoded request metadata for authentication: `rpId`, `timeout`,
|
|
52
|
+
* `userVerification`, `hints`, `challenge`, and `allowCredentials`.
|
|
53
|
+
* Binary values are base64url-encoded. Treat this value as sensitive telemetry.
|
|
64
54
|
*/
|
|
65
|
-
|
|
55
|
+
requestOptionsJson?: string;
|
|
56
|
+
};
|
|
57
|
+
type WebAuthnCeremonyCompletedEvent = WebAuthnCeremonyBase & {
|
|
58
|
+
phase: "completed";
|
|
59
|
+
/** JSON-encoded allowlisted credential. Treat this value as sensitive telemetry. */
|
|
60
|
+
credentialJson?: string;
|
|
61
|
+
/** A credential manager may complete even after the ceremony signal was aborted. */
|
|
62
|
+
aborted?: true;
|
|
63
|
+
};
|
|
64
|
+
type WebAuthnCeremonyFailedEvent = WebAuthnCeremonyBase & {
|
|
65
|
+
phase: "failed";
|
|
66
|
+
/** Rejection value from the failed ceremony. This may contain application-specific data. */
|
|
67
|
+
error: unknown;
|
|
68
|
+
/** DOM exception name, or `UnknownError` when no name is available. */
|
|
69
|
+
errorName: string;
|
|
70
|
+
aborted?: true;
|
|
66
71
|
};
|
|
72
|
+
/** A protocol-native lifecycle event for WebAuthn authentication or registration. */
|
|
73
|
+
type WebAuthnCeremonyEvent = WebAuthnCeremonyStartedEvent | WebAuthnCeremonyCompletedEvent | WebAuthnCeremonyFailedEvent;
|
|
67
74
|
/** Options for {@link captureWebAuthn}. */
|
|
68
75
|
type WebAuthnCaptureOptions = {
|
|
69
76
|
/** Receives WebAuthn lifecycle events. Return values are not awaited. */
|
|
@@ -73,8 +80,10 @@ type WebAuthnCaptureOptions = {
|
|
|
73
80
|
};
|
|
74
81
|
/** Network API used for an observed exchange. */
|
|
75
82
|
type NetworkTransport = "xhr" | "fetch";
|
|
83
|
+
/** Direction of a projected body within an observed network exchange. */
|
|
84
|
+
type NetworkBodyDirection = "request" | "response";
|
|
76
85
|
/** A matched network request immediately after the platform accepted it. */
|
|
77
|
-
type HttpRequestStarted = {
|
|
86
|
+
type HttpRequestStarted<RequestBody = unknown> = {
|
|
78
87
|
/** Identifier shared with the eventual {@link HttpExchange}. */
|
|
79
88
|
requestId: string;
|
|
80
89
|
/** Network API used for the request. */
|
|
@@ -88,10 +97,10 @@ type HttpRequestStarted = {
|
|
|
88
97
|
/** Timestamp captured at the request boundary. */
|
|
89
98
|
startedAt: number;
|
|
90
99
|
/** Request-body value returned by the configured projector, when synchronously available. */
|
|
91
|
-
requestBody?:
|
|
100
|
+
requestBody?: RequestBody;
|
|
92
101
|
};
|
|
93
102
|
/** An observed network request and its outcome. */
|
|
94
|
-
type HttpExchange = {
|
|
103
|
+
type HttpExchange<RequestBody = unknown, ResponseBody = unknown> = {
|
|
95
104
|
/** Identifier shared with the corresponding {@link HttpRequestStarted}. */
|
|
96
105
|
requestId: string;
|
|
97
106
|
/** Network API used for the request. */
|
|
@@ -122,14 +131,14 @@ type HttpExchange = {
|
|
|
122
131
|
*/
|
|
123
132
|
responseUrl?: string;
|
|
124
133
|
/** Request-body value returned by the configured projector, when available. */
|
|
125
|
-
requestBody?:
|
|
134
|
+
requestBody?: RequestBody;
|
|
126
135
|
/** Response-body value returned by the configured projector, when available. */
|
|
127
|
-
responseBody?:
|
|
136
|
+
responseBody?: ResponseBody;
|
|
128
137
|
};
|
|
129
138
|
/** Metadata supplied to a body projector for one matched exchange. */
|
|
130
|
-
type NetworkBodyProjectionContext = {
|
|
139
|
+
type NetworkBodyProjectionContext<Direction extends NetworkBodyDirection = NetworkBodyDirection> = {
|
|
131
140
|
/** Whether the observed body belongs to the request or response. */
|
|
132
|
-
direction:
|
|
141
|
+
direction: Direction;
|
|
133
142
|
/** Network API used by the application. */
|
|
134
143
|
transport: NetworkTransport;
|
|
135
144
|
/** Uppercase HTTP method. */
|
|
@@ -144,10 +153,14 @@ type NetworkBodyProjectionContext = {
|
|
|
144
153
|
* Textual bodies are supplied as strings; an XHR with `responseType="json"`
|
|
145
154
|
* supplies the browser-parsed value. Returning `undefined`, throwing, or
|
|
146
155
|
* returning a Promise omits the body without affecting the application.
|
|
156
|
+
* `ProjectedBody` describes the exact value delivered to callbacks.
|
|
147
157
|
*/
|
|
148
|
-
type NetworkBodyProjector = (body: unknown, context: NetworkBodyProjectionContext) =>
|
|
149
|
-
/**
|
|
150
|
-
|
|
158
|
+
type NetworkBodyProjector<ProjectedBody = unknown, Direction extends NetworkBodyDirection = NetworkBodyDirection> = (body: unknown, context: NetworkBodyProjectionContext<Direction>) => ProjectedBody | undefined;
|
|
159
|
+
/**
|
|
160
|
+
* Options for {@link captureNetwork}. Request and response body types are
|
|
161
|
+
* inferred from their projectors and propagated to the corresponding callbacks.
|
|
162
|
+
*/
|
|
163
|
+
type NetworkCaptureOptions<RequestBody = unknown, ResponseBody = unknown> = {
|
|
151
164
|
/**
|
|
152
165
|
* Selects requests to observe. The URL is resolved against the document base
|
|
153
166
|
* URL and the method is uppercase. Return `true` to observe the request. The
|
|
@@ -156,12 +169,12 @@ type NetworkCaptureOptions = {
|
|
|
156
169
|
*/
|
|
157
170
|
match: (url: URL, method: string) => boolean;
|
|
158
171
|
/** Receives completed network exchanges. Return values are not awaited. */
|
|
159
|
-
onExchange: (exchange: HttpExchange) => void;
|
|
172
|
+
onExchange: (exchange: HttpExchange<NoInfer<RequestBody>, NoInfer<ResponseBody>>) => void;
|
|
160
173
|
/**
|
|
161
174
|
* Receives matched requests after the platform call succeeds. The request ID
|
|
162
175
|
* matches the eventual exchange. Return values are not awaited.
|
|
163
176
|
*/
|
|
164
|
-
onRequest?: (request: HttpRequestStarted) => void;
|
|
177
|
+
onRequest?: (request: HttpRequestStarted<NoInfer<RequestBody>>) => void;
|
|
165
178
|
/**
|
|
166
179
|
* Network APIs to observe. Defaults to both `xhr` and `fetch`. Unavailable
|
|
167
180
|
* transports are skipped if at least one requested transport can be observed.
|
|
@@ -174,19 +187,11 @@ type NetworkCaptureOptions = {
|
|
|
174
187
|
* data minimization and its return value is the only body data reported.
|
|
175
188
|
*/
|
|
176
189
|
bodyCapture?: {
|
|
177
|
-
/** Projects a
|
|
178
|
-
request?: NetworkBodyProjector
|
|
179
|
-
/** Projects a
|
|
180
|
-
response?: NetworkBodyProjector
|
|
190
|
+
/** Projects a request body. */
|
|
191
|
+
request?: NetworkBodyProjector<RequestBody, "request">;
|
|
192
|
+
/** Projects a response body. */
|
|
193
|
+
response?: NetworkBodyProjector<ResponseBody, "response">;
|
|
181
194
|
};
|
|
182
|
-
/**
|
|
183
|
-
* Maximum size of a projected body attached to a request or exchange,
|
|
184
|
-
* measured on its JSON-serialized form; larger projections are omitted.
|
|
185
|
-
* Raw bodies are not size-checked before projection — matched traffic is
|
|
186
|
-
* first-party and assumed well-behaved. Must be a finite, non-negative
|
|
187
|
-
* number when provided. Defaults to 65,536.
|
|
188
|
-
*/
|
|
189
|
-
maxBodyChars?: number;
|
|
190
195
|
/** Optional diagnostic logger. */
|
|
191
196
|
logger?: Logger;
|
|
192
197
|
};
|
|
@@ -312,7 +317,7 @@ declare function captureWebAuthn(options: WebAuthnCaptureOptions): CaptureHandle
|
|
|
312
317
|
* @throws TypeError when `onExchange` or `match` is not a function — a
|
|
313
318
|
* misconfigured integration is a programming error, not a degraded mode.
|
|
314
319
|
*/
|
|
315
|
-
declare function captureNetwork(options: NetworkCaptureOptions): CaptureHandle;
|
|
320
|
+
declare function captureNetwork<RequestBody = unknown, ResponseBody = unknown>(options: NetworkCaptureOptions<RequestBody, ResponseBody>): CaptureHandle;
|
|
316
321
|
|
|
317
322
|
/**
|
|
318
323
|
* Observes same-document navigations produced by `history.pushState()`,
|
|
@@ -375,4 +380,4 @@ declare function createConsoleLogger(prefix?: string): Logger;
|
|
|
375
380
|
/** Version identifier embedded in the current build. */
|
|
376
381
|
declare const VERSION: string;
|
|
377
382
|
|
|
378
|
-
export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, type ShadowRootAttachedEvent, type ShadowRootCaptureOptions, type UiStateCaptureHandle, type UiStateCaptureOptions, type UiStateTrigger, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyEvent, type
|
|
383
|
+
export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, type ShadowRootAttachedEvent, type ShadowRootCaptureOptions, type UiStateCaptureHandle, type UiStateCaptureOptions, type UiStateTrigger, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureNavigation, captureNetwork, captureShadowRoots, captureUiState, captureWebAuthn, composedPath, composedTarget, createConsoleLogger };
|
package/dist/index.d.ts
CHANGED
|
@@ -15,55 +15,62 @@ type CaptureHandle = {
|
|
|
15
15
|
/** Stops future event delivery. Safe to call more than once. */
|
|
16
16
|
disconnect(): void;
|
|
17
17
|
};
|
|
18
|
-
/**
|
|
19
|
-
type
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
/** Normalized Credential Management mediation. Missing mediation defaults to `optional`. */
|
|
19
|
+
type WebAuthnMediation = "silent" | "optional" | "conditional" | "required" | "unknown";
|
|
20
|
+
/** Normalized Credential Management UI mode for authentication ceremonies. */
|
|
21
|
+
type WebAuthnUiMode = "default" | "immediate" | "unknown";
|
|
22
|
+
/** Browser-native facts that remain stable for one ceremony. */
|
|
23
|
+
type WebAuthnCeremonyContext = {
|
|
24
|
+
kind: "authentication";
|
|
25
|
+
mediation: WebAuthnMediation;
|
|
26
|
+
uiMode: WebAuthnUiMode;
|
|
27
|
+
/** Whether the RP supplied a non-empty allow list or requested discoverable credentials. */
|
|
28
|
+
credentialSet: "allowlisted" | "discoverable";
|
|
29
|
+
} | {
|
|
30
|
+
kind: "registration";
|
|
31
|
+
mediation: WebAuthnMediation;
|
|
32
|
+
};
|
|
33
|
+
type WebAuthnCeremonyBase = WebAuthnCeremonyContext & {
|
|
27
34
|
/** Identifier shared by all events belonging to the same ceremony. */
|
|
28
35
|
ceremonyId: string;
|
|
29
|
-
/**
|
|
30
|
-
phase: "started" | "completed" | "failed";
|
|
31
|
-
/** Requested mediation mode, when available. */
|
|
32
|
-
mediation?: string;
|
|
33
|
-
/** Whether transient user activation was active when the ceremony started. Present on `started` events when exposed by the browser. */
|
|
34
|
-
userActivation?: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* JSON-encoded request metadata for a `get` ceremony: `rpId`, `timeout`,
|
|
37
|
-
* `userVerification`, `hints`, `challenge`, and `allowCredentials`
|
|
38
|
-
* (`type`, `id`, and `transports`). Binary values are base64url-encoded.
|
|
39
|
-
* Unavailable fields are omitted. Present on `started` events when
|
|
40
|
-
* serialization succeeds. Treat this value as sensitive telemetry.
|
|
41
|
-
*/
|
|
36
|
+
/** Authentication request metadata; present only when applicable and serializable. */
|
|
42
37
|
requestOptionsJson?: string;
|
|
43
|
-
/**
|
|
44
|
-
hasAllowCredentials?: boolean;
|
|
45
|
-
/**
|
|
46
|
-
* JSON-encoded, allowlisted credential returned by a completed ceremony.
|
|
47
|
-
* Common fields are `id`, `rawId`, `type`, and `authenticatorAttachment`.
|
|
48
|
-
* Assertion responses include `clientDataJSON`, `authenticatorData`,
|
|
49
|
-
* `signature`, and `userHandle`; attestation responses include
|
|
50
|
-
* `clientDataJSON`, `attestationObject`, and `transports`. Binary values are
|
|
51
|
-
* base64url-encoded. Of the client-extension results, only `credProps.rk` may
|
|
52
|
-
* be included. Present when serialization succeeds. Treat this value as
|
|
53
|
-
* sensitive telemetry.
|
|
54
|
-
*/
|
|
38
|
+
/** Completed credential metadata; present only when applicable and serializable. */
|
|
55
39
|
credentialJson?: string;
|
|
56
|
-
/**
|
|
40
|
+
/** Failure details; present only for failed ceremonies. */
|
|
57
41
|
error?: unknown;
|
|
58
|
-
/** Error name for a failed ceremony, or `UnknownError` when no DOM exception name is available. */
|
|
59
42
|
errorName?: string;
|
|
43
|
+
/** Present when the request signal was aborted before settlement. */
|
|
44
|
+
aborted?: true;
|
|
45
|
+
};
|
|
46
|
+
type WebAuthnCeremonyStartedEvent = WebAuthnCeremonyBase & {
|
|
47
|
+
phase: "started";
|
|
48
|
+
/** Whether transient user activation was active when the ceremony started, when exposed by the browser. */
|
|
49
|
+
userActivation?: boolean;
|
|
60
50
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
51
|
+
* JSON-encoded request metadata for authentication: `rpId`, `timeout`,
|
|
52
|
+
* `userVerification`, `hints`, `challenge`, and `allowCredentials`.
|
|
53
|
+
* Binary values are base64url-encoded. Treat this value as sensitive telemetry.
|
|
64
54
|
*/
|
|
65
|
-
|
|
55
|
+
requestOptionsJson?: string;
|
|
56
|
+
};
|
|
57
|
+
type WebAuthnCeremonyCompletedEvent = WebAuthnCeremonyBase & {
|
|
58
|
+
phase: "completed";
|
|
59
|
+
/** JSON-encoded allowlisted credential. Treat this value as sensitive telemetry. */
|
|
60
|
+
credentialJson?: string;
|
|
61
|
+
/** A credential manager may complete even after the ceremony signal was aborted. */
|
|
62
|
+
aborted?: true;
|
|
63
|
+
};
|
|
64
|
+
type WebAuthnCeremonyFailedEvent = WebAuthnCeremonyBase & {
|
|
65
|
+
phase: "failed";
|
|
66
|
+
/** Rejection value from the failed ceremony. This may contain application-specific data. */
|
|
67
|
+
error: unknown;
|
|
68
|
+
/** DOM exception name, or `UnknownError` when no name is available. */
|
|
69
|
+
errorName: string;
|
|
70
|
+
aborted?: true;
|
|
66
71
|
};
|
|
72
|
+
/** A protocol-native lifecycle event for WebAuthn authentication or registration. */
|
|
73
|
+
type WebAuthnCeremonyEvent = WebAuthnCeremonyStartedEvent | WebAuthnCeremonyCompletedEvent | WebAuthnCeremonyFailedEvent;
|
|
67
74
|
/** Options for {@link captureWebAuthn}. */
|
|
68
75
|
type WebAuthnCaptureOptions = {
|
|
69
76
|
/** Receives WebAuthn lifecycle events. Return values are not awaited. */
|
|
@@ -73,8 +80,10 @@ type WebAuthnCaptureOptions = {
|
|
|
73
80
|
};
|
|
74
81
|
/** Network API used for an observed exchange. */
|
|
75
82
|
type NetworkTransport = "xhr" | "fetch";
|
|
83
|
+
/** Direction of a projected body within an observed network exchange. */
|
|
84
|
+
type NetworkBodyDirection = "request" | "response";
|
|
76
85
|
/** A matched network request immediately after the platform accepted it. */
|
|
77
|
-
type HttpRequestStarted = {
|
|
86
|
+
type HttpRequestStarted<RequestBody = unknown> = {
|
|
78
87
|
/** Identifier shared with the eventual {@link HttpExchange}. */
|
|
79
88
|
requestId: string;
|
|
80
89
|
/** Network API used for the request. */
|
|
@@ -88,10 +97,10 @@ type HttpRequestStarted = {
|
|
|
88
97
|
/** Timestamp captured at the request boundary. */
|
|
89
98
|
startedAt: number;
|
|
90
99
|
/** Request-body value returned by the configured projector, when synchronously available. */
|
|
91
|
-
requestBody?:
|
|
100
|
+
requestBody?: RequestBody;
|
|
92
101
|
};
|
|
93
102
|
/** An observed network request and its outcome. */
|
|
94
|
-
type HttpExchange = {
|
|
103
|
+
type HttpExchange<RequestBody = unknown, ResponseBody = unknown> = {
|
|
95
104
|
/** Identifier shared with the corresponding {@link HttpRequestStarted}. */
|
|
96
105
|
requestId: string;
|
|
97
106
|
/** Network API used for the request. */
|
|
@@ -122,14 +131,14 @@ type HttpExchange = {
|
|
|
122
131
|
*/
|
|
123
132
|
responseUrl?: string;
|
|
124
133
|
/** Request-body value returned by the configured projector, when available. */
|
|
125
|
-
requestBody?:
|
|
134
|
+
requestBody?: RequestBody;
|
|
126
135
|
/** Response-body value returned by the configured projector, when available. */
|
|
127
|
-
responseBody?:
|
|
136
|
+
responseBody?: ResponseBody;
|
|
128
137
|
};
|
|
129
138
|
/** Metadata supplied to a body projector for one matched exchange. */
|
|
130
|
-
type NetworkBodyProjectionContext = {
|
|
139
|
+
type NetworkBodyProjectionContext<Direction extends NetworkBodyDirection = NetworkBodyDirection> = {
|
|
131
140
|
/** Whether the observed body belongs to the request or response. */
|
|
132
|
-
direction:
|
|
141
|
+
direction: Direction;
|
|
133
142
|
/** Network API used by the application. */
|
|
134
143
|
transport: NetworkTransport;
|
|
135
144
|
/** Uppercase HTTP method. */
|
|
@@ -144,10 +153,14 @@ type NetworkBodyProjectionContext = {
|
|
|
144
153
|
* Textual bodies are supplied as strings; an XHR with `responseType="json"`
|
|
145
154
|
* supplies the browser-parsed value. Returning `undefined`, throwing, or
|
|
146
155
|
* returning a Promise omits the body without affecting the application.
|
|
156
|
+
* `ProjectedBody` describes the exact value delivered to callbacks.
|
|
147
157
|
*/
|
|
148
|
-
type NetworkBodyProjector = (body: unknown, context: NetworkBodyProjectionContext) =>
|
|
149
|
-
/**
|
|
150
|
-
|
|
158
|
+
type NetworkBodyProjector<ProjectedBody = unknown, Direction extends NetworkBodyDirection = NetworkBodyDirection> = (body: unknown, context: NetworkBodyProjectionContext<Direction>) => ProjectedBody | undefined;
|
|
159
|
+
/**
|
|
160
|
+
* Options for {@link captureNetwork}. Request and response body types are
|
|
161
|
+
* inferred from their projectors and propagated to the corresponding callbacks.
|
|
162
|
+
*/
|
|
163
|
+
type NetworkCaptureOptions<RequestBody = unknown, ResponseBody = unknown> = {
|
|
151
164
|
/**
|
|
152
165
|
* Selects requests to observe. The URL is resolved against the document base
|
|
153
166
|
* URL and the method is uppercase. Return `true` to observe the request. The
|
|
@@ -156,12 +169,12 @@ type NetworkCaptureOptions = {
|
|
|
156
169
|
*/
|
|
157
170
|
match: (url: URL, method: string) => boolean;
|
|
158
171
|
/** Receives completed network exchanges. Return values are not awaited. */
|
|
159
|
-
onExchange: (exchange: HttpExchange) => void;
|
|
172
|
+
onExchange: (exchange: HttpExchange<NoInfer<RequestBody>, NoInfer<ResponseBody>>) => void;
|
|
160
173
|
/**
|
|
161
174
|
* Receives matched requests after the platform call succeeds. The request ID
|
|
162
175
|
* matches the eventual exchange. Return values are not awaited.
|
|
163
176
|
*/
|
|
164
|
-
onRequest?: (request: HttpRequestStarted) => void;
|
|
177
|
+
onRequest?: (request: HttpRequestStarted<NoInfer<RequestBody>>) => void;
|
|
165
178
|
/**
|
|
166
179
|
* Network APIs to observe. Defaults to both `xhr` and `fetch`. Unavailable
|
|
167
180
|
* transports are skipped if at least one requested transport can be observed.
|
|
@@ -174,19 +187,11 @@ type NetworkCaptureOptions = {
|
|
|
174
187
|
* data minimization and its return value is the only body data reported.
|
|
175
188
|
*/
|
|
176
189
|
bodyCapture?: {
|
|
177
|
-
/** Projects a
|
|
178
|
-
request?: NetworkBodyProjector
|
|
179
|
-
/** Projects a
|
|
180
|
-
response?: NetworkBodyProjector
|
|
190
|
+
/** Projects a request body. */
|
|
191
|
+
request?: NetworkBodyProjector<RequestBody, "request">;
|
|
192
|
+
/** Projects a response body. */
|
|
193
|
+
response?: NetworkBodyProjector<ResponseBody, "response">;
|
|
181
194
|
};
|
|
182
|
-
/**
|
|
183
|
-
* Maximum size of a projected body attached to a request or exchange,
|
|
184
|
-
* measured on its JSON-serialized form; larger projections are omitted.
|
|
185
|
-
* Raw bodies are not size-checked before projection — matched traffic is
|
|
186
|
-
* first-party and assumed well-behaved. Must be a finite, non-negative
|
|
187
|
-
* number when provided. Defaults to 65,536.
|
|
188
|
-
*/
|
|
189
|
-
maxBodyChars?: number;
|
|
190
195
|
/** Optional diagnostic logger. */
|
|
191
196
|
logger?: Logger;
|
|
192
197
|
};
|
|
@@ -312,7 +317,7 @@ declare function captureWebAuthn(options: WebAuthnCaptureOptions): CaptureHandle
|
|
|
312
317
|
* @throws TypeError when `onExchange` or `match` is not a function — a
|
|
313
318
|
* misconfigured integration is a programming error, not a degraded mode.
|
|
314
319
|
*/
|
|
315
|
-
declare function captureNetwork(options: NetworkCaptureOptions): CaptureHandle;
|
|
320
|
+
declare function captureNetwork<RequestBody = unknown, ResponseBody = unknown>(options: NetworkCaptureOptions<RequestBody, ResponseBody>): CaptureHandle;
|
|
316
321
|
|
|
317
322
|
/**
|
|
318
323
|
* Observes same-document navigations produced by `history.pushState()`,
|
|
@@ -375,4 +380,4 @@ declare function createConsoleLogger(prefix?: string): Logger;
|
|
|
375
380
|
/** Version identifier embedded in the current build. */
|
|
376
381
|
declare const VERSION: string;
|
|
377
382
|
|
|
378
|
-
export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, type ShadowRootAttachedEvent, type ShadowRootCaptureOptions, type UiStateCaptureHandle, type UiStateCaptureOptions, type UiStateTrigger, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyEvent, type
|
|
383
|
+
export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, type ShadowRootAttachedEvent, type ShadowRootCaptureOptions, type UiStateCaptureHandle, type UiStateCaptureOptions, type UiStateTrigger, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureNavigation, captureNetwork, captureShadowRoots, captureUiState, captureWebAuthn, composedPath, composedTarget, createConsoleLogger };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var oe=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var Le=Object.getOwnPropertyNames;var Ne=Object.prototype.hasOwnProperty;var De=(e,t)=>{for(var n in t)oe(e,n,{get:t[n],enumerable:!0})},Te=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Le(t))!Ne.call(e,o)&&o!==n&&oe(e,o,{get:()=>t[o],enumerable:!(r=xe(t,o))||r.enumerable});return e};var He=e=>Te(oe({},"__esModule",{value:!0}),e);var Ke={};De(Ke,{VERSION:()=>Pe,captureNavigation:()=>Re,captureNetwork:()=>ve,captureShadowRoots:()=>Oe,captureUiState:()=>Ae,captureWebAuthn:()=>pe,composedPath:()=>ce,composedTarget:()=>Ce,createConsoleLogger:()=>ke});module.exports=He(Ke);var ae={log:()=>{}};function j(e){return e?{log:(...t)=>{try{let n=e.log(...t);if(n&&(typeof n=="object"||typeof n=="function"))try{Promise.resolve(n).catch(()=>{})}catch{}}catch{}}}:ae}var le=Symbol.for("corbado.autocapture.installed");function B(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,le)}catch{return!1}}function M(e,t){var r,o;let n=t;try{Object.defineProperty(e,le,{value:t,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(r=n.name)!=null?r:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=n.length)!=null?o:0,configurable:!0})}catch{}return e}function w(){return{mode:"unavailable",disconnect:()=>{}}}function _(e,t,n){let r=j(e);return o=>{try{let a=n(o);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(d=>r.log(`${t} listener failed`,d))}catch(d){r.log(`${t} listener failed`,d)}}catch(a){r.log(`${t} listener failed`,a)}}}function pe(e){let t=j(e.logger),n=e.onEvent;if(typeof n!="function")return w();let r=typeof navigator=="undefined"?void 0:navigator,o=r==null?void 0:r.credentials;if(!r||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),w();let a=o.get,d=o.create;if(typeof a!="function"||typeof d!="function")return t.log("webauthn capture unavailable: credentials methods missing"),w();if(B(a)||B(d))return t.log("webauthn capture unavailable: an equivalent capture is already active"),w();let p=!1,v=0,k=_(t,"webauthn",s=>{if(p)return n(s)}),D=(s,b)=>{let L={invoke(...q){let O=this,R=q[0];if(!p||!Q(R)||!Q(R.publicKey))return Reflect.apply(b,O,q);let Z=R.publicKey,V=`wa-${++v}`,ee=Reflect.apply(b,O,q),f=typeof R.mediation=="string"?R.mediation:void 0,m=Q(R.signal)?R.signal:void 0,C={kind:s,ceremonyId:V,phase:"started",mediation:f,userActivation:je(r)};if(s==="get"){let c=Z;C.requestOptionsJson=Ie(c,t),C.hasAllowCredentials=Array.isArray(c.allowCredentials)&&c.allowCredentials.length>0}return k(C),Promise.resolve(ee).then(c=>(p&&k({kind:s,ceremonyId:V,phase:"completed",mediation:f,credentialJson:Be(c,s,t),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),c),c=>{throw p&&k({kind:s,ceremonyId:V,phase:"failed",mediation:f,error:c,errorName:_e(c),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),c})}}.invoke;return M(L,{name:s,length:0})},h=(s,b)=>{let L=D(s,b),q=Object.getOwnPropertyDescriptor(o,s);if(q&&(!("value"in q)||q.writable!==!0))return null;try{o[s]=L}catch{return null}return()=>{o[s]===L&&(q?o[s]=q.value:delete o[s])}},S=h("get",a),u=S?h("create",d):null;return!S||!u?(S==null||S(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),w()):(p=!0,{mode:"standard",disconnect:()=>{p=!1,S(),u()}})}function je(e){let t=e.userActivation;return typeof(t==null?void 0:t.isActive)=="boolean"?t.isActive:void 0}function Be(e,t,n){var r;if(e)try{let o=e,a=o.response,d={id:z(o.id),rawId:$(o.rawId),type:z(o.type),authenticatorAttachment:z(o.authenticatorAttachment),response:t==="create"?{clientDataJSON:$(a==null?void 0:a.clientDataJSON),attestationObject:$(a==null?void 0:a.attestationObject),transports:ie((r=a==null?void 0:a.getTransports)==null?void 0:r.call(a))}:{clientDataJSON:$(a==null?void 0:a.clientDataJSON),authenticatorData:$(a==null?void 0:a.authenticatorData),signature:$(a==null?void 0:a.signature),userHandle:$(a==null?void 0:a.userHandle)},...t==="create"?Me(o):{}};return JSON.stringify(d)}catch(o){n.log("credential serialization failed",o);return}}function Ie(e,t){try{let n={},r=z(e.rpId),o=z(e.userVerification),a=ie(e.hints);return r!==void 0&&(n.rpId=r),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(n.timeout=e.timeout),o!==void 0&&(n.userVerification=o),a!==void 0&&(n.hints=a),n.challenge=$(e.challenge),Array.isArray(e.allowCredentials)&&(n.allowCredentials=Ue(e.allowCredentials)),JSON.stringify(n)}catch(n){t.log("request options serialization failed",n);return}}function Ue(e){let t=[];for(let n of e){if(!Q(n))continue;let r=n;t.push({type:z(r.type),id:$(r.id),transports:ie(r.transports)})}return t}function ie(e){if(Array.isArray(e))return e.filter(t=>typeof t=="string")}function z(e){return typeof e=="string"?e:void 0}function Me(e){var r;let t=(r=e.getClientExtensionResults)==null?void 0:r.call(e);if(!Q(t))return{};let n=t.credProps;return!n||typeof n.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:n.rk}}}}function $(e){let t;if(e instanceof ArrayBuffer)t=new Uint8Array(e);else if(ArrayBuffer.isView(e))t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let n="";for(let r of t)n+=String.fromCharCode(r);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Q(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function _e(e){return e instanceof DOMException?e.name:"UnknownError"}var fe=0;function he(){return fe+=1,`network-${fe}`}function Fe(e,t){let n=e.responseType;if(n===""||n==="text")return t(e.responseText);if(n==="json"){let r=e.response;return r==null?void 0:t(r)}}var Xe=500,We=65536,ge=Symbol("body-read-timeout");function ye(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function me(e,t){let n=e.body;if(!n)return;let r=n.getReader(),o;try{let a=new Promise(v=>{o=setTimeout(()=>v(ge),Xe)}),d=new TextDecoder,p=[];for(;;){let v=await Promise.race([r.read(),a]);if(v===ge){t.log("body omitted: read timed out"),r.cancel().catch(()=>{});return}if(v.done)break;p.push(d.decode(v.value,{stream:!0}))}return p.push(d.decode()),p.join("")}catch{r.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function se(e){var t;(t=e==null?void 0:e.body)==null||t.cancel().catch(()=>{})}function ue(e,t,n,r,o){try{let a=Object.getOwnPropertyDescriptor(e,t);Je(a,{...r,value:n})&&Object.defineProperty(e,t,r)}catch(a){o.log(`${String(t)} restoration skipped`,a)}}function Je(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function ve(e){var R,Z,V,ee;let{onExchange:t,onRequest:n,match:r}=e;if(typeof t!="function"||typeof r!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=j(e.logger),a=(R=e.transports)!=null?R:["xhr","fetch"],d=(Z=e.bodyCapture)==null?void 0:Z.request,p=(V=e.bodyCapture)==null?void 0:V.response,v=typeof d=="function",k=typeof p=="function",D=(ee=e.maxBodyChars)!=null?ee:We,h=!1,S=_(o,"network",f=>{if(h)return t(f)}),u=_(o,"network request",f=>{if(h)return n==null?void 0:n(f)}),s=(f,m)=>{let C=m.direction==="request"?d:p;if(typeof C=="function")try{let c=C(f,m);if(c===void 0||typeof(c==null?void 0:c.then)=="function")return;let F=JSON.stringify(c);return F===void 0||F.length>D?void 0:JSON.parse(F)}catch(c){o.log("body projection failed",c);return}},b=(f,m)=>{try{let C=typeof document!="undefined"?document.baseURI:void 0,c=new URL(String(f),C);return/\/observe\/events\/[^/]+\/?$/.test(c.pathname)?void 0:r(c,m)===!0?{url:c.href,path:c.pathname}:void 0}catch{return}},L=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let f=XMLHttpRequest.prototype,m=Object.getOwnPropertyDescriptor(f,"open"),C=Object.getOwnPropertyDescriptor(f,"send");if(!m||!("value"in m)||typeof m.value!="function"||!C||!("value"in C)||typeof C.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let c=m.value,F=C.value;if(B(c)||B(F))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let X=new WeakMap,A=new Set,x=!1,T={open(...E){var g;let i=Reflect.apply(c,this,E);if(!h||!x)return i;try{let N=X.get(this);N&&(N.reported=!0,(g=N.cleanupListeners)==null||g.call(N));let H=String(E[0]).toUpperCase(),P=b(E[1],H);P?X.set(this,{method:H,url:P.url,path:P.path,reported:!1}):X.delete(this)}catch(N){o.log("xhr open observation failed",N)}return i}}.open,J={send(...E){let i=h&&x?X.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(F,this,E);let g=()=>{},N=!1;try{i.requestId=he();let P={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=v&&typeof E[0]=="string"?s(E[0],P):void 0;let G=()=>{i.outcome===void 0&&(i.outcome="abort")},Y=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},y=()=>{var K;g();try{if(!h||!x||i.reported||!i.requestId)return;i.reported=!0;let U={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},re=this.status,de={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:re,ok:re>=200&&re<300,outcome:(K=i.outcome)!=null?K:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:k?Fe(this,qe=>s(qe,U)):void 0};i.requestEmitted?S(de):i.pendingExchange=de}catch(U){o.log("xhr exchange observation failed",U)}finally{X.get(this)===i&&X.delete(this)}},I=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&y()}catch(K){o.log("xhr ready-state observation failed",K)}},W=()=>y();g=()=>{for(let[K,U]of[["readystatechange",I],["abort",G],["timeout",Y],["error",l],["loadend",W]])this.removeEventListener(K,U);i.cleanupListeners===g&&(i.cleanupListeners=void 0),A.delete(g)},this.addEventListener("readystatechange",I),this.addEventListener("abort",G),this.addEventListener("timeout",Y),this.addEventListener("error",l),this.addEventListener("loadend",W),i.cleanupListeners=g,A.add(g),i.startedAt=Date.now(),N=!0}catch(P){o.log("xhr send observation failed",P),g()}let H;try{H=Reflect.apply(F,this,E)}catch(P){throw g(),P}if(N&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,u({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let P=i.pendingExchange;i.pendingExchange=void 0,P&&S(P)}return H}}.send;return M(T,c),M(J,F),m.writable!==!0||C.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(f,"open",{...m,value:T}),Object.defineProperty(f,"send",{...C,value:J}),x=!0,()=>{x=!1;for(let E of[...A])E();ue(f,"open",T,m,o),ue(f,"send",J,C,o)})},q=()=>{let f=globalThis,m=Object.getOwnPropertyDescriptor(f,"fetch");if(!m||!("value"in m))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let C=m.value;if(typeof C!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(B(C))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let c=!1,F=async(A,x,T,J)=>{try{if(!h||!c){se(T);return}let[E,i]=await Promise.all([J!=null?J:Promise.resolve(void 0),T?me(T,o):Promise.resolve(void 0)]);if(!h||!c)return;let g={direction:"request",transport:"fetch",method:A.method,url:A.url,path:A.path},N={...g,direction:"response"},H=A.requestBody;H===void 0&&E!==void 0&&(H=s(E,g));let P=i!==void 0?s(i,N):void 0;S({requestId:A.requestId,transport:"fetch",method:A.method,url:A.url,path:A.path,status:x.status,ok:x.ok,outcome:"load",durationMs:Date.now()-A.startedAt,responseUrl:x.url||void 0,requestBody:H,responseBody:P})}catch(E){o.log("fetch exchange observation failed",E)}},X={fetch(...A){var H,P,G,Y;let x;try{let l=A[0],y=A[1];if(h&&c&&v&&typeof Request!="undefined"&&l instanceof Request&&(y==null?void 0:y.body)===void 0&&l.body){let I=String((H=y==null?void 0:y.method)!=null?H:l.method).toUpperCase(),W=(P=l.headers.get("content-type"))!=null?P:"";b(l.url,I)&&ye(W)&&(x=l.clone())}}catch(l){o.log("fetch observation failed",l)}let T,J=Date.now();try{T=Reflect.apply(C,this,A)}catch(l){throw se(x),l}let E,i;try{if(h&&c){let l=A[0],y=A[1],I=typeof Request!="undefined"&&l instanceof Request,W=String((G=y==null?void 0:y.method)!=null?G:I?l.method:"GET").toUpperCase(),K=I?l.url:l,U=b(K,W);U&&(E={requestId:he(),method:W,url:U.url,path:U.path,startedAt:J},i=(Y=y==null?void 0:y.signal)!=null?Y:I?l.signal:void 0,v&&typeof(y==null?void 0:y.body)=="string"&&(E.requestBody=s(y.body,{direction:"request",transport:"fetch",method:W,url:U.url,path:U.path})))}}catch(l){o.log("fetch observation failed",l)}if(!E)return se(x),T;let g=E;u({requestId:g.requestId,transport:"fetch",method:g.method,url:g.url,path:g.path,startedAt:g.startedAt,requestBody:g.requestBody});let N=x?me(x,o):void 0;return T.then(l=>{var I;let y;try{if(h&&c&&k){let W=(I=l.headers.get("content-type"))!=null?I:"";ye(W)&&l.body&&(y=l.clone())}}catch{}F(g,l,y,N)},l=>{try{if(!h||!c)return;let y=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;S({requestId:g.requestId,transport:"fetch",method:g.method,url:g.url,path:g.path,status:0,ok:!1,outcome:y?"abort":"error",durationMs:Date.now()-g.startedAt})}catch(y){o.log("fetch failure observation failed",y)}}),T}}.fetch;return M(X,C),m.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(f,"fetch",{...m,value:X}),c=!0,()=>{c=!1,ue(f,"fetch",X,m,o)})},O=[];if(a.includes("xhr")){let f=L();f&&O.push(f)}if(a.includes("fetch")){let f=q();f&&O.push(f)}return O.length===0?w():(h=!0,{mode:"standard",disconnect:()=>{h=!1;for(let f of O.splice(0))f()}})}function Re(e){let t=j(),n;try{if(t=j(e.logger),n=e.onNavigate,typeof n!="function")return w()}catch{return w()}let r,o,a,d,p,v;try{if(r=window,o=r==null?void 0:r.history,!r||!o)return t.log("navigation capture unavailable: window/history missing"),w();if(p=we(o,"pushState"),v=we(o,"replaceState"),!p||!v)return t.log("navigation capture unavailable: history method descriptors missing"),w();if(a=p.descriptor.value,d=v.descriptor.value,typeof a!="function"||typeof d!="function")return t.log("navigation capture unavailable: history methods missing"),w();if(typeof r.addEventListener!="function"||typeof r.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),w()}catch(O){return t.log("navigation capture unavailable: history inspection failed",O),w()}if(B(a)||B(d))return t.log("navigation capture unavailable: an equivalent capture is already active"),w();let k=!1,D=()=>({path:r.location.pathname,search:r.location.search,hash:r.location.hash}),h;try{h=D()}catch(O){return t.log("navigation capture unavailable: location inspection failed",O),w()}let S=_(t,"navigation",O=>{if(k)return n(O)}),u=O=>{if(k)try{let R=D();if(R.path===h.path&&R.search===h.search&&R.hash===h.hash)return;h=R,S({...R,source:O})}catch(R){t.log("navigation observation failed",R)}},s={pushState(...O){let R=Reflect.apply(a,this,O);return u("push"),R}}.pushState,b={replaceState(...O){let R=Reflect.apply(d,this,O);return u("replace"),R}}.replaceState;M(s,a),M(b,d);let L=()=>u("pop"),q=()=>u("hash");try{if(be(p,s),be(v,b),o.pushState!==s||o.replaceState!==b)throw new Error("history method replacement did not take effect");r.addEventListener("popstate",L),r.addEventListener("hashchange",q),k=!0}catch(O){return k=!1,ne(r,"popstate",L,t),ne(r,"hashchange",q,t),te(v,b,t),te(p,s,t),t.log("navigation capture unavailable: history methods are not writable",O),n=()=>{},S=()=>{},t=j(),w()}return{mode:"standard",disconnect:()=>{k=!1,n=()=>{},ne(r,"popstate",L,t),ne(r,"hashchange",q,t),te(p,s,t),te(v,b,t),S=()=>{},t=j()}}}function we(e,t){let n=e;for(;n;){let r=Object.getOwnPropertyDescriptor(n,t);if(r)return!("value"in r)||typeof r.value!="function"?null:{owner:n,key:t,descriptor:r};n=Object.getPrototypeOf(n)}return null}function be(e,t){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let n=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!Se(n,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:t})}function Se(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function te(e,t,n){try{let r=Object.getOwnPropertyDescriptor(e.owner,e.key);Se(r,{...e.descriptor,value:t})&&Object.defineProperty(e.owner,e.key,e.descriptor)}catch(r){n.log(`navigation ${e.key} restoration skipped`,r)}}function ne(e,t,n,r){try{e.removeEventListener(t,n)}catch(o){r.log(`navigation ${t} listener removal skipped`,o)}}function Oe(e){var S;let t=(S=e.logger)!=null?S:ae,n=e.onAttached;if(typeof n!="function")return w();let r=Element.prototype,o=Object.getOwnPropertyDescriptor(r,"attachShadow");if(!o||typeof o.value!="function")return t.log("shadow-root capture unavailable: attachShadow not supported"),w();let a=o.value;if(B(a))return t.log("shadow-root capture unavailable: an equivalent capture is already active"),w();let d=!1,p=new WeakSet,v=_(t,"shadow-root",n),k=(u,s)=>{!d||p.has(s)||(p.add(s),v({host:u,shadowRoot:s,mode:s.mode==="closed"?"closed":"open"}))},D={attachShadow(...u){let s=Reflect.apply(a,this,u);return k(this,s),s}}.attachShadow;M(D,a);try{Object.defineProperty(r,"attachShadow",{...o,value:D})}catch(u){return t.log("shadow-root capture unavailable: attachShadow is locked",u),w()}d=!0;let h=u=>{let s=u.querySelectorAll("*");for(let b=0;b<s.length&&d;b++){let L=s[b].shadowRoot;L&&(k(s[b],L),h(L))}};return e.includeExisting&&h(document),{mode:"standard",disconnect:()=>{d=!1;let u=Object.getOwnPropertyDescriptor(r,"attachShadow");$e(u,{...o,value:D})&&Object.defineProperty(r,"attachShadow",o)}}}function Ce(e){var t;return(t=ce(e)[0])!=null?t:null}function ce(e){let t=e.composedPath();return t.length>0?t:e.target?[e.target]:[]}function $e(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Ae(e){var D,h,S;let t=j(e==null?void 0:e.logger),n=e==null?void 0:e.read,r=e==null?void 0:e.onState;if(typeof n!="function"||typeof r!="function")return Ee();let o=Number.isFinite(e.delayMs)&&((D=e.delayMs)!=null?D:0)>=0&&(h=e.delayMs)!=null?h:0,a=_(t,"ui-state",r),d=!0,p,v=[],k=()=>{d&&(p!==void 0&&clearTimeout(p),p=setTimeout(()=>{if(p=void 0,!!d)try{let u=n();u!==void 0&&a(u)}catch(u){t.log("ui-state read failed",u)}},o))};try{for(let u of(S=e.triggers)!=null?S:[]){if(!(u!=null&&u.target)||typeof u.target.addEventListener!="function")continue;let s=k;u.target.addEventListener(u.type,s,u.capture===!0),v.push({trigger:u,listener:s})}}catch(u){t.log("ui-state trigger installation failed",u);for(let{trigger:s,listener:b}of v)try{s.target.removeEventListener(s.type,b,s.capture===!0)}catch{}return d=!1,Ee()}return{mode:"standard",schedule:k,disconnect:()=>{if(d){d=!1,p!==void 0&&clearTimeout(p),p=void 0;for(let{trigger:u,listener:s}of v)try{u.target.removeEventListener(u.type,s,u.capture===!0)}catch(b){t.log("ui-state trigger removal failed",b)}v.length=0}}}}function Ee(){return{mode:"unavailable",schedule:()=>{},disconnect:()=>{}}}function ke(e="[autocapture]"){return{log:(...t)=>{try{let n=console.log(e,...t);if(n&&(typeof n=="object"||typeof n=="function"))try{Promise.resolve(n).catch(()=>{})}catch{}}catch{}}}}var Pe="0.1.0-next.2-dd9eb36";0&&(module.exports={VERSION,captureNavigation,captureNetwork,captureShadowRoots,captureUiState,captureWebAuthn,composedPath,composedTarget,createConsoleLogger});
|
|
1
|
+
"use strict";var ne=Object.defineProperty;var qe=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var xe=Object.prototype.hasOwnProperty;var De=(e,t)=>{for(var n in t)ne(e,n,{get:t[n],enumerable:!0})},Le=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Pe(t))!xe.call(e,o)&&o!==n&&ne(e,o,{get:()=>t[o],enumerable:!(r=qe(t,o))||r.enumerable});return e};var Ne=e=>Le(ne({},"__esModule",{value:!0}),e);var $e={};De($e,{VERSION:()=>ke,captureNavigation:()=>be,captureNetwork:()=>ge,captureShadowRoots:()=>Re,captureUiState:()=>Oe,captureWebAuthn:()=>de,composedPath:()=>se,composedTarget:()=>Ce,createConsoleLogger:()=>Ee});module.exports=Ne($e);var re={log:()=>{}};function H(e){return e?{log:(...t)=>{try{let n=e.log(...t);if(n&&(typeof n=="object"||typeof n=="function"))try{Promise.resolve(n).catch(()=>{})}catch{}}catch{}}}:re}var ce=Symbol.for("corbado.autocapture.installed");function M(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,ce)}catch{return!1}}function _(e,t){var r,o;let n=t;try{Object.defineProperty(e,ce,{value:t,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(r=n.name)!=null?r:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=n.length)!=null?o:0,configurable:!0})}catch{}return e}function v(){return{mode:"unavailable",disconnect:()=>{}}}function W(e,t,n){let r=H(e);return o=>{try{let a=n(o);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(c=>r.log(`${t} listener failed`,c))}catch(c){r.log(`${t} listener failed`,c)}}catch(a){r.log(`${t} listener failed`,a)}}}function de(e){let t=H(e.logger),n=e.onEvent;if(typeof n!="function")return v();let r=typeof navigator=="undefined"?void 0:navigator,o=r==null?void 0:r.credentials;if(!r||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),v();let a=o.get,c=o.create;if(typeof a!="function"||typeof c!="function")return t.log("webauthn capture unavailable: credentials methods missing"),v();if(M(a)||M(c))return t.log("webauthn capture unavailable: an equivalent capture is already active"),v();let d=!1,y=0,P=W(t,"webauthn",u=>{if(d)return n(u)}),g=(u,w)=>{let N={invoke(...x){let k=this,R=x[0];if(!d||!Q(R)||!Q(R.publicKey))return Reflect.apply(w,k,x);let z=R.publicKey,p=`wa-${++y}`,C=Reflect.apply(w,k,x),m=Q(R.signal)?R.signal:void 0,b=Be(u,R,z),X={...b,ceremonyId:p,phase:"started",userActivation:He(r)};if(b.kind==="authentication"){let A=z;X.requestOptionsJson=Ie(A,t)}return P(X),Promise.resolve(C).then(A=>(d&&P({...b,ceremonyId:p,phase:"completed",credentialJson:Me(A,u,t),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),A),A=>{throw d&&P({...b,ceremonyId:p,phase:"failed",error:A,errorName:We(A),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),A})}}.invoke;return _(N,{name:u,length:0})},O=(u,w)=>{let N=g(u,w),x=Object.getOwnPropertyDescriptor(o,u);if(x&&(!("value"in x)||x.writable!==!0))return null;try{o[u]=N}catch{return null}return()=>{o[u]===N&&(x?o[u]=x.value:delete o[u])}},E=O("get",a),s=E?O("create",c):null;return!E||!s?(E==null||E(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),v()):(d=!0,{mode:"standard",disconnect:()=>{d=!1,E(),s()}})}function Be(e,t,n){let r=Te(t.mediation);if(e==="create")return{kind:"registration",mediation:r};let o=n;return{kind:"authentication",mediation:r,uiMode:je(t.uiMode),credentialSet:Array.isArray(o.allowCredentials)&&o.allowCredentials.length>0?"allowlisted":"discoverable"}}function Te(e){return e===void 0?"optional":e==="silent"||e==="optional"||e==="conditional"||e==="required"?e:"unknown"}function je(e){return e===void 0?"default":e==="immediate"?"immediate":"unknown"}function He(e){let t=e.userActivation;return typeof(t==null?void 0:t.isActive)=="boolean"?t.isActive:void 0}function Me(e,t,n){var r;if(e)try{let o=e,a=o.response,c={id:J(o.id),rawId:V(o.rawId),type:J(o.type),authenticatorAttachment:J(o.authenticatorAttachment),response:t==="create"?{clientDataJSON:V(a==null?void 0:a.clientDataJSON),attestationObject:V(a==null?void 0:a.attestationObject),transports:oe((r=a==null?void 0:a.getTransports)==null?void 0:r.call(a))}:{clientDataJSON:V(a==null?void 0:a.clientDataJSON),authenticatorData:V(a==null?void 0:a.authenticatorData),signature:V(a==null?void 0:a.signature),userHandle:V(a==null?void 0:a.userHandle)},...t==="create"?_e(o):{}};return JSON.stringify(c)}catch(o){n.log("credential serialization failed",o);return}}function Ie(e,t){try{let n={},r=J(e.rpId),o=J(e.userVerification),a=oe(e.hints);return r!==void 0&&(n.rpId=r),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(n.timeout=e.timeout),o!==void 0&&(n.userVerification=o),a!==void 0&&(n.hints=a),n.challenge=V(e.challenge),Array.isArray(e.allowCredentials)&&(n.allowCredentials=Ue(e.allowCredentials)),JSON.stringify(n)}catch(n){t.log("request options serialization failed",n);return}}function Ue(e){let t=[];for(let n of e){if(!Q(n))continue;let r=n;t.push({type:J(r.type),id:V(r.id),transports:oe(r.transports)})}return t}function oe(e){if(Array.isArray(e))return e.filter(t=>typeof t=="string")}function J(e){return typeof e=="string"?e:void 0}function _e(e){var r;let t=(r=e.getClientExtensionResults)==null?void 0:r.call(e);if(!Q(t))return{};let n=t.credProps;return!n||typeof n.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:n.rk}}}}function V(e){let t;if(e instanceof ArrayBuffer)t=new Uint8Array(e);else if(ArrayBuffer.isView(e))t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let n="";for(let r of t)n+=String.fromCharCode(r);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Q(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function We(e){return e instanceof DOMException?e.name:"UnknownError"}var le=0;function pe(){return le+=1,`network-${le}`}function Fe(e,t){let n=e.responseType;if(n===""||n==="text")return t(e.responseText);if(n==="json"){let r=e.response;return r==null?void 0:t(r)}}var Xe=500,fe=Symbol("body-read-timeout");function he(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function ye(e,t){let n=e.body;if(!n)return;let r=n.getReader(),o;try{let a=new Promise(y=>{o=setTimeout(()=>y(fe),Xe)}),c=new TextDecoder,d=[];for(;;){let y=await Promise.race([r.read(),a]);if(y===fe){t.log("body omitted: read timed out"),r.cancel().catch(()=>{});return}if(y.done)break;d.push(c.decode(y.value,{stream:!0}))}return d.push(c.decode()),d.join("")}catch{r.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function ae(e){var t;(t=e==null?void 0:e.body)==null||t.cancel().catch(()=>{})}function ie(e,t,n,r,o){try{let a=Object.getOwnPropertyDescriptor(e,t);Ke(a,{...r,value:n})&&Object.defineProperty(e,t,r)}catch(a){o.log(`${String(t)} restoration skipped`,a)}}function Ke(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function ge(e){var k,R,z;let{onExchange:t,onRequest:n,match:r}=e;if(typeof t!="function"||typeof r!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=H(e.logger),a=(k=e.transports)!=null?k:["xhr","fetch"],c=(R=e.bodyCapture)==null?void 0:R.request,d=(z=e.bodyCapture)==null?void 0:z.response,y=typeof c=="function",P=typeof d=="function",g=!1,O=W(o,"network",p=>{if(g)return t(p)}),E=W(o,"network request",p=>{if(g)return n==null?void 0:n(p)}),s=(p,C,m)=>{if(typeof m=="function")try{return m(p,C)}catch(b){o.log("body projection failed",b);return}},u=(p,C)=>{try{let m=typeof document!="undefined"?document.baseURI:void 0,b=new URL(String(p),m);return r(b,C)===!0?{url:b.href,path:b.pathname}:void 0}catch{return}},w=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let p=XMLHttpRequest.prototype,C=Object.getOwnPropertyDescriptor(p,"open"),m=Object.getOwnPropertyDescriptor(p,"send");if(!C||!("value"in C)||typeof C.value!="function"||!m||!("value"in m)||typeof m.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let b=C.value,X=m.value;if(M(b)||M(X))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let A=new WeakMap,q=new Set,L=!1,T={open(...S){var f;let i=Reflect.apply(b,this,S);if(!g||!L)return i;try{let B=A.get(this);B&&(B.reported=!0,(f=B.cleanupListeners)==null||f.call(B));let j=String(S[0]).toUpperCase(),D=u(S[1],j);D?A.set(this,{method:j,url:D.url,path:D.path,reported:!1}):A.delete(this)}catch(B){o.log("xhr open observation failed",B)}return i}}.open,K={send(...S){let i=g&&L?A.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(X,this,S);let f=()=>{},B=!1;try{i.requestId=pe();let D={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=y&&typeof S[0]=="string"?s(S[0],D,c):void 0;let G=()=>{i.outcome===void 0&&(i.outcome="abort")},Y=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},h=()=>{var $;f();try{if(!g||!L||i.reported||!i.requestId)return;i.reported=!0;let U={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},te=this.status,ue={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:te,ok:te>=200&&te<300,outcome:($=i.outcome)!=null?$:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:P?Fe(this,Ae=>s(Ae,U,d)):void 0};i.requestEmitted?O(ue):i.pendingExchange=ue}catch(U){o.log("xhr exchange observation failed",U)}finally{A.get(this)===i&&A.delete(this)}},I=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&h()}catch($){o.log("xhr ready-state observation failed",$)}},F=()=>h();f=()=>{for(let[$,U]of[["readystatechange",I],["abort",G],["timeout",Y],["error",l],["loadend",F]])this.removeEventListener($,U);i.cleanupListeners===f&&(i.cleanupListeners=void 0),q.delete(f)},this.addEventListener("readystatechange",I),this.addEventListener("abort",G),this.addEventListener("timeout",Y),this.addEventListener("error",l),this.addEventListener("loadend",F),i.cleanupListeners=f,q.add(f),i.startedAt=Date.now(),B=!0}catch(D){o.log("xhr send observation failed",D),f()}let j;try{j=Reflect.apply(X,this,S)}catch(D){throw f(),D}if(B&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,E({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let D=i.pendingExchange;i.pendingExchange=void 0,D&&O(D)}return j}}.send;return _(T,b),_(K,X),C.writable!==!0||m.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(p,"open",{...C,value:T}),Object.defineProperty(p,"send",{...m,value:K}),L=!0,()=>{L=!1;for(let S of[...q])S();ie(p,"open",T,C,o),ie(p,"send",K,m,o)})},N=()=>{let p=globalThis,C=Object.getOwnPropertyDescriptor(p,"fetch");if(!C||!("value"in C))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let m=C.value;if(typeof m!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(M(m))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let b=!1,X=async(q,L,T,K)=>{try{if(!g||!b){ae(T);return}let[S,i]=await Promise.all([K!=null?K:Promise.resolve(void 0),T?ye(T,o):Promise.resolve(void 0)]);if(!g||!b)return;let f={direction:"request",transport:"fetch",method:q.method,url:q.url,path:q.path},B={...f,direction:"response"},j=q.requestBody;j===void 0&&S!==void 0&&(j=s(S,f,c));let D=i!==void 0?s(i,B,d):void 0;O({requestId:q.requestId,transport:"fetch",method:q.method,url:q.url,path:q.path,status:L.status,ok:L.ok,outcome:"load",durationMs:Date.now()-q.startedAt,responseUrl:L.url||void 0,requestBody:j,responseBody:D})}catch(S){o.log("fetch exchange observation failed",S)}},A={fetch(...q){var j,D,G,Y;let L;try{let l=q[0],h=q[1];if(g&&b&&y&&typeof Request!="undefined"&&l instanceof Request&&(h==null?void 0:h.body)===void 0&&l.body){let I=String((j=h==null?void 0:h.method)!=null?j:l.method).toUpperCase(),F=(D=l.headers.get("content-type"))!=null?D:"";u(l.url,I)&&he(F)&&(L=l.clone())}}catch(l){o.log("fetch observation failed",l)}let T,K=Date.now();try{T=Reflect.apply(m,this,q)}catch(l){throw ae(L),l}let S,i;try{if(g&&b){let l=q[0],h=q[1],I=typeof Request!="undefined"&&l instanceof Request,F=String((G=h==null?void 0:h.method)!=null?G:I?l.method:"GET").toUpperCase(),$=I?l.url:l,U=u($,F);U&&(S={requestId:pe(),method:F,url:U.url,path:U.path,startedAt:K},i=(Y=h==null?void 0:h.signal)!=null?Y:I?l.signal:void 0,y&&typeof(h==null?void 0:h.body)=="string"&&(S.requestBody=s(h.body,{direction:"request",transport:"fetch",method:F,url:U.url,path:U.path},c)))}}catch(l){o.log("fetch observation failed",l)}if(!S)return ae(L),T;let f=S;E({requestId:f.requestId,transport:"fetch",method:f.method,url:f.url,path:f.path,startedAt:f.startedAt,requestBody:f.requestBody});let B=L?ye(L,o):void 0;return T.then(l=>{var I;let h;try{if(g&&b&&P){let F=(I=l.headers.get("content-type"))!=null?I:"";he(F)&&l.body&&(h=l.clone())}}catch{}X(f,l,h,B)},l=>{try{if(!g||!b)return;let h=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;O({requestId:f.requestId,transport:"fetch",method:f.method,url:f.url,path:f.path,status:0,ok:!1,outcome:h?"abort":"error",durationMs:Date.now()-f.startedAt})}catch(h){o.log("fetch failure observation failed",h)}}),T}}.fetch;return _(A,m),C.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(p,"fetch",{...C,value:A}),b=!0,()=>{b=!1,ie(p,"fetch",A,C,o)})},x=[];if(a.includes("xhr")){let p=w();p&&x.push(p)}if(a.includes("fetch")){let p=N();p&&x.push(p)}return x.length===0?v():(g=!0,{mode:"standard",disconnect:()=>{g=!1;for(let p of x.splice(0))p()}})}function be(e){let t=H(),n;try{if(t=H(e.logger),n=e.onNavigate,typeof n!="function")return v()}catch{return v()}let r,o,a,c,d,y;try{if(r=window,o=r==null?void 0:r.history,!r||!o)return t.log("navigation capture unavailable: window/history missing"),v();if(d=me(o,"pushState"),y=me(o,"replaceState"),!d||!y)return t.log("navigation capture unavailable: history method descriptors missing"),v();if(a=d.descriptor.value,c=y.descriptor.value,typeof a!="function"||typeof c!="function")return t.log("navigation capture unavailable: history methods missing"),v();if(typeof r.addEventListener!="function"||typeof r.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),v()}catch(k){return t.log("navigation capture unavailable: history inspection failed",k),v()}if(M(a)||M(c))return t.log("navigation capture unavailable: an equivalent capture is already active"),v();let P=!1,g=()=>({path:r.location.pathname,search:r.location.search,hash:r.location.hash}),O;try{O=g()}catch(k){return t.log("navigation capture unavailable: location inspection failed",k),v()}let E=W(t,"navigation",k=>{if(P)return n(k)}),s=k=>{if(P)try{let R=g();if(R.path===O.path&&R.search===O.search&&R.hash===O.hash)return;O=R,E({...R,source:k})}catch(R){t.log("navigation observation failed",R)}},u={pushState(...k){let R=Reflect.apply(a,this,k);return s("push"),R}}.pushState,w={replaceState(...k){let R=Reflect.apply(c,this,k);return s("replace"),R}}.replaceState;_(u,a),_(w,c);let N=()=>s("pop"),x=()=>s("hash");try{if(ve(d,u),ve(y,w),o.pushState!==u||o.replaceState!==w)throw new Error("history method replacement did not take effect");r.addEventListener("popstate",N),r.addEventListener("hashchange",x),P=!0}catch(k){return P=!1,ee(r,"popstate",N,t),ee(r,"hashchange",x,t),Z(y,w,t),Z(d,u,t),t.log("navigation capture unavailable: history methods are not writable",k),n=()=>{},E=()=>{},t=H(),v()}return{mode:"standard",disconnect:()=>{P=!1,n=()=>{},ee(r,"popstate",N,t),ee(r,"hashchange",x,t),Z(d,u,t),Z(y,w,t),E=()=>{},t=H()}}}function me(e,t){let n=e;for(;n;){let r=Object.getOwnPropertyDescriptor(n,t);if(r)return!("value"in r)||typeof r.value!="function"?null:{owner:n,key:t,descriptor:r};n=Object.getPrototypeOf(n)}return null}function ve(e,t){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let n=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!we(n,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:t})}function we(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Z(e,t,n){try{let r=Object.getOwnPropertyDescriptor(e.owner,e.key);we(r,{...e.descriptor,value:t})&&Object.defineProperty(e.owner,e.key,e.descriptor)}catch(r){n.log(`navigation ${e.key} restoration skipped`,r)}}function ee(e,t,n,r){try{e.removeEventListener(t,n)}catch(o){r.log(`navigation ${t} listener removal skipped`,o)}}function Re(e){var E;let t=(E=e.logger)!=null?E:re,n=e.onAttached;if(typeof n!="function")return v();let r=Element.prototype,o=Object.getOwnPropertyDescriptor(r,"attachShadow");if(!o||typeof o.value!="function")return t.log("shadow-root capture unavailable: attachShadow not supported"),v();let a=o.value;if(M(a))return t.log("shadow-root capture unavailable: an equivalent capture is already active"),v();let c=!1,d=new WeakSet,y=W(t,"shadow-root",n),P=(s,u)=>{!c||d.has(u)||(d.add(u),y({host:s,shadowRoot:u,mode:u.mode==="closed"?"closed":"open"}))},g={attachShadow(...s){let u=Reflect.apply(a,this,s);return P(this,u),u}}.attachShadow;_(g,a);try{Object.defineProperty(r,"attachShadow",{...o,value:g})}catch(s){return t.log("shadow-root capture unavailable: attachShadow is locked",s),v()}c=!0;let O=s=>{let u=s.querySelectorAll("*");for(let w=0;w<u.length&&c;w++){let N=u[w].shadowRoot;N&&(P(u[w],N),O(N))}};return e.includeExisting&&O(document),{mode:"standard",disconnect:()=>{c=!1;let s=Object.getOwnPropertyDescriptor(r,"attachShadow");Ve(s,{...o,value:g})&&Object.defineProperty(r,"attachShadow",o)}}}function Ce(e){var t;return(t=se(e)[0])!=null?t:null}function se(e){let t=e.composedPath();return t.length>0?t:e.target?[e.target]:[]}function Ve(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Oe(e){var g,O,E;let t=H(e==null?void 0:e.logger),n=e==null?void 0:e.read,r=e==null?void 0:e.onState;if(typeof n!="function"||typeof r!="function")return Se();let o=Number.isFinite(e.delayMs)&&((g=e.delayMs)!=null?g:0)>=0&&(O=e.delayMs)!=null?O:0,a=W(t,"ui-state",r),c=!0,d,y=[],P=()=>{c&&(d!==void 0&&clearTimeout(d),d=setTimeout(()=>{if(d=void 0,!!c)try{let s=n();s!==void 0&&a(s)}catch(s){t.log("ui-state read failed",s)}},o))};try{for(let s of(E=e.triggers)!=null?E:[]){if(!(s!=null&&s.target)||typeof s.target.addEventListener!="function")continue;let u=P;s.target.addEventListener(s.type,u,s.capture===!0),y.push({trigger:s,listener:u})}}catch(s){t.log("ui-state trigger installation failed",s);for(let{trigger:u,listener:w}of y)try{u.target.removeEventListener(u.type,w,u.capture===!0)}catch{}return c=!1,Se()}return{mode:"standard",schedule:P,disconnect:()=>{if(c){c=!1,d!==void 0&&clearTimeout(d),d=void 0;for(let{trigger:s,listener:u}of y)try{s.target.removeEventListener(s.type,u,s.capture===!0)}catch(w){t.log("ui-state trigger removal failed",w)}y.length=0}}}}function Se(){return{mode:"unavailable",schedule:()=>{},disconnect:()=>{}}}function Ee(e="[autocapture]"){return{log:(...t)=>{try{let n=console.log(e,...t);if(n&&(typeof n=="object"||typeof n=="function"))try{Promise.resolve(n).catch(()=>{})}catch{}}catch{}}}}var ke="0.1.0-next.4-aa81c53";0&&(module.exports={VERSION,captureNavigation,captureNetwork,captureShadowRoots,captureUiState,captureWebAuthn,composedPath,composedTarget,createConsoleLogger});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var oe={log:()=>{}};function j(e){return e?{log:(...t)=>{try{let r=e.log(...t);if(r&&(typeof r=="object"||typeof r=="function"))try{Promise.resolve(r).catch(()=>{})}catch{}}catch{}}}:oe}var ce=Symbol.for("corbado.autocapture.installed");function B(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,ce)}catch{return!1}}function M(e,t){var n,o;let r=t;try{Object.defineProperty(e,ce,{value:t,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(n=r.name)!=null?n:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=r.length)!=null?o:0,configurable:!0})}catch{}return e}function w(){return{mode:"unavailable",disconnect:()=>{}}}function _(e,t,r){let n=j(e);return o=>{try{let a=r(o);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(d=>n.log(`${t} listener failed`,d))}catch(d){n.log(`${t} listener failed`,d)}}catch(a){n.log(`${t} listener failed`,a)}}}function Re(e){let t=j(e.logger),r=e.onEvent;if(typeof r!="function")return w();let n=typeof navigator=="undefined"?void 0:navigator,o=n==null?void 0:n.credentials;if(!n||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),w();let a=o.get,d=o.create;if(typeof a!="function"||typeof d!="function")return t.log("webauthn capture unavailable: credentials methods missing"),w();if(B(a)||B(d))return t.log("webauthn capture unavailable: an equivalent capture is already active"),w();let p=!1,v=0,k=_(t,"webauthn",s=>{if(p)return r(s)}),D=(s,b)=>{let L={invoke(...q){let O=this,R=q[0];if(!p||!Q(R)||!Q(R.publicKey))return Reflect.apply(b,O,q);let Z=R.publicKey,V=`wa-${++v}`,ee=Reflect.apply(b,O,q),f=typeof R.mediation=="string"?R.mediation:void 0,m=Q(R.signal)?R.signal:void 0,C={kind:s,ceremonyId:V,phase:"started",mediation:f,userActivation:Se(n)};if(s==="get"){let c=Z;C.requestOptionsJson=Ce(c,t),C.hasAllowCredentials=Array.isArray(c.allowCredentials)&&c.allowCredentials.length>0}return k(C),Promise.resolve(ee).then(c=>(p&&k({kind:s,ceremonyId:V,phase:"completed",mediation:f,credentialJson:Oe(c,s,t),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),c),c=>{throw p&&k({kind:s,ceremonyId:V,phase:"failed",mediation:f,error:c,errorName:ke(c),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),c})}}.invoke;return M(L,{name:s,length:0})},h=(s,b)=>{let L=D(s,b),q=Object.getOwnPropertyDescriptor(o,s);if(q&&(!("value"in q)||q.writable!==!0))return null;try{o[s]=L}catch{return null}return()=>{o[s]===L&&(q?o[s]=q.value:delete o[s])}},S=h("get",a),u=S?h("create",d):null;return!S||!u?(S==null||S(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),w()):(p=!0,{mode:"standard",disconnect:()=>{p=!1,S(),u()}})}function Se(e){let t=e.userActivation;return typeof(t==null?void 0:t.isActive)=="boolean"?t.isActive:void 0}function Oe(e,t,r){var n;if(e)try{let o=e,a=o.response,d={id:z(o.id),rawId:$(o.rawId),type:z(o.type),authenticatorAttachment:z(o.authenticatorAttachment),response:t==="create"?{clientDataJSON:$(a==null?void 0:a.clientDataJSON),attestationObject:$(a==null?void 0:a.attestationObject),transports:ae((n=a==null?void 0:a.getTransports)==null?void 0:n.call(a))}:{clientDataJSON:$(a==null?void 0:a.clientDataJSON),authenticatorData:$(a==null?void 0:a.authenticatorData),signature:$(a==null?void 0:a.signature),userHandle:$(a==null?void 0:a.userHandle)},...t==="create"?Ae(o):{}};return JSON.stringify(d)}catch(o){r.log("credential serialization failed",o);return}}function Ce(e,t){try{let r={},n=z(e.rpId),o=z(e.userVerification),a=ae(e.hints);return n!==void 0&&(r.rpId=n),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(r.timeout=e.timeout),o!==void 0&&(r.userVerification=o),a!==void 0&&(r.hints=a),r.challenge=$(e.challenge),Array.isArray(e.allowCredentials)&&(r.allowCredentials=Ee(e.allowCredentials)),JSON.stringify(r)}catch(r){t.log("request options serialization failed",r);return}}function Ee(e){let t=[];for(let r of e){if(!Q(r))continue;let n=r;t.push({type:z(n.type),id:$(n.id),transports:ae(n.transports)})}return t}function ae(e){if(Array.isArray(e))return e.filter(t=>typeof t=="string")}function z(e){return typeof e=="string"?e:void 0}function Ae(e){var n;let t=(n=e.getClientExtensionResults)==null?void 0:n.call(e);if(!Q(t))return{};let r=t.credProps;return!r||typeof r.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:r.rk}}}}function $(e){let t;if(e instanceof ArrayBuffer)t=new Uint8Array(e);else if(ArrayBuffer.isView(e))t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let r="";for(let n of t)r+=String.fromCharCode(n);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Q(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function ke(e){return e instanceof DOMException?e.name:"UnknownError"}var de=0;function le(){return de+=1,`network-${de}`}function Pe(e,t){let r=e.responseType;if(r===""||r==="text")return t(e.responseText);if(r==="json"){let n=e.response;return n==null?void 0:t(n)}}var qe=500,xe=65536,pe=Symbol("body-read-timeout");function fe(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function he(e,t){let r=e.body;if(!r)return;let n=r.getReader(),o;try{let a=new Promise(v=>{o=setTimeout(()=>v(pe),qe)}),d=new TextDecoder,p=[];for(;;){let v=await Promise.race([n.read(),a]);if(v===pe){t.log("body omitted: read timed out"),n.cancel().catch(()=>{});return}if(v.done)break;p.push(d.decode(v.value,{stream:!0}))}return p.push(d.decode()),p.join("")}catch{n.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function ie(e){var t;(t=e==null?void 0:e.body)==null||t.cancel().catch(()=>{})}function se(e,t,r,n,o){try{let a=Object.getOwnPropertyDescriptor(e,t);Le(a,{...n,value:r})&&Object.defineProperty(e,t,n)}catch(a){o.log(`${String(t)} restoration skipped`,a)}}function Le(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Ne(e){var R,Z,V,ee;let{onExchange:t,onRequest:r,match:n}=e;if(typeof t!="function"||typeof n!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=j(e.logger),a=(R=e.transports)!=null?R:["xhr","fetch"],d=(Z=e.bodyCapture)==null?void 0:Z.request,p=(V=e.bodyCapture)==null?void 0:V.response,v=typeof d=="function",k=typeof p=="function",D=(ee=e.maxBodyChars)!=null?ee:xe,h=!1,S=_(o,"network",f=>{if(h)return t(f)}),u=_(o,"network request",f=>{if(h)return r==null?void 0:r(f)}),s=(f,m)=>{let C=m.direction==="request"?d:p;if(typeof C=="function")try{let c=C(f,m);if(c===void 0||typeof(c==null?void 0:c.then)=="function")return;let F=JSON.stringify(c);return F===void 0||F.length>D?void 0:JSON.parse(F)}catch(c){o.log("body projection failed",c);return}},b=(f,m)=>{try{let C=typeof document!="undefined"?document.baseURI:void 0,c=new URL(String(f),C);return/\/observe\/events\/[^/]+\/?$/.test(c.pathname)?void 0:n(c,m)===!0?{url:c.href,path:c.pathname}:void 0}catch{return}},L=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let f=XMLHttpRequest.prototype,m=Object.getOwnPropertyDescriptor(f,"open"),C=Object.getOwnPropertyDescriptor(f,"send");if(!m||!("value"in m)||typeof m.value!="function"||!C||!("value"in C)||typeof C.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let c=m.value,F=C.value;if(B(c)||B(F))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let X=new WeakMap,A=new Set,x=!1,T={open(...E){var g;let i=Reflect.apply(c,this,E);if(!h||!x)return i;try{let N=X.get(this);N&&(N.reported=!0,(g=N.cleanupListeners)==null||g.call(N));let H=String(E[0]).toUpperCase(),P=b(E[1],H);P?X.set(this,{method:H,url:P.url,path:P.path,reported:!1}):X.delete(this)}catch(N){o.log("xhr open observation failed",N)}return i}}.open,J={send(...E){let i=h&&x?X.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(F,this,E);let g=()=>{},N=!1;try{i.requestId=le();let P={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=v&&typeof E[0]=="string"?s(E[0],P):void 0;let G=()=>{i.outcome===void 0&&(i.outcome="abort")},Y=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},y=()=>{var K;g();try{if(!h||!x||i.reported||!i.requestId)return;i.reported=!0;let U={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},re=this.status,ue={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:re,ok:re>=200&&re<300,outcome:(K=i.outcome)!=null?K:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:k?Pe(this,be=>s(be,U)):void 0};i.requestEmitted?S(ue):i.pendingExchange=ue}catch(U){o.log("xhr exchange observation failed",U)}finally{X.get(this)===i&&X.delete(this)}},I=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&y()}catch(K){o.log("xhr ready-state observation failed",K)}},W=()=>y();g=()=>{for(let[K,U]of[["readystatechange",I],["abort",G],["timeout",Y],["error",l],["loadend",W]])this.removeEventListener(K,U);i.cleanupListeners===g&&(i.cleanupListeners=void 0),A.delete(g)},this.addEventListener("readystatechange",I),this.addEventListener("abort",G),this.addEventListener("timeout",Y),this.addEventListener("error",l),this.addEventListener("loadend",W),i.cleanupListeners=g,A.add(g),i.startedAt=Date.now(),N=!0}catch(P){o.log("xhr send observation failed",P),g()}let H;try{H=Reflect.apply(F,this,E)}catch(P){throw g(),P}if(N&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,u({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let P=i.pendingExchange;i.pendingExchange=void 0,P&&S(P)}return H}}.send;return M(T,c),M(J,F),m.writable!==!0||C.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(f,"open",{...m,value:T}),Object.defineProperty(f,"send",{...C,value:J}),x=!0,()=>{x=!1;for(let E of[...A])E();se(f,"open",T,m,o),se(f,"send",J,C,o)})},q=()=>{let f=globalThis,m=Object.getOwnPropertyDescriptor(f,"fetch");if(!m||!("value"in m))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let C=m.value;if(typeof C!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(B(C))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let c=!1,F=async(A,x,T,J)=>{try{if(!h||!c){ie(T);return}let[E,i]=await Promise.all([J!=null?J:Promise.resolve(void 0),T?he(T,o):Promise.resolve(void 0)]);if(!h||!c)return;let g={direction:"request",transport:"fetch",method:A.method,url:A.url,path:A.path},N={...g,direction:"response"},H=A.requestBody;H===void 0&&E!==void 0&&(H=s(E,g));let P=i!==void 0?s(i,N):void 0;S({requestId:A.requestId,transport:"fetch",method:A.method,url:A.url,path:A.path,status:x.status,ok:x.ok,outcome:"load",durationMs:Date.now()-A.startedAt,responseUrl:x.url||void 0,requestBody:H,responseBody:P})}catch(E){o.log("fetch exchange observation failed",E)}},X={fetch(...A){var H,P,G,Y;let x;try{let l=A[0],y=A[1];if(h&&c&&v&&typeof Request!="undefined"&&l instanceof Request&&(y==null?void 0:y.body)===void 0&&l.body){let I=String((H=y==null?void 0:y.method)!=null?H:l.method).toUpperCase(),W=(P=l.headers.get("content-type"))!=null?P:"";b(l.url,I)&&fe(W)&&(x=l.clone())}}catch(l){o.log("fetch observation failed",l)}let T,J=Date.now();try{T=Reflect.apply(C,this,A)}catch(l){throw ie(x),l}let E,i;try{if(h&&c){let l=A[0],y=A[1],I=typeof Request!="undefined"&&l instanceof Request,W=String((G=y==null?void 0:y.method)!=null?G:I?l.method:"GET").toUpperCase(),K=I?l.url:l,U=b(K,W);U&&(E={requestId:le(),method:W,url:U.url,path:U.path,startedAt:J},i=(Y=y==null?void 0:y.signal)!=null?Y:I?l.signal:void 0,v&&typeof(y==null?void 0:y.body)=="string"&&(E.requestBody=s(y.body,{direction:"request",transport:"fetch",method:W,url:U.url,path:U.path})))}}catch(l){o.log("fetch observation failed",l)}if(!E)return ie(x),T;let g=E;u({requestId:g.requestId,transport:"fetch",method:g.method,url:g.url,path:g.path,startedAt:g.startedAt,requestBody:g.requestBody});let N=x?he(x,o):void 0;return T.then(l=>{var I;let y;try{if(h&&c&&k){let W=(I=l.headers.get("content-type"))!=null?I:"";fe(W)&&l.body&&(y=l.clone())}}catch{}F(g,l,y,N)},l=>{try{if(!h||!c)return;let y=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;S({requestId:g.requestId,transport:"fetch",method:g.method,url:g.url,path:g.path,status:0,ok:!1,outcome:y?"abort":"error",durationMs:Date.now()-g.startedAt})}catch(y){o.log("fetch failure observation failed",y)}}),T}}.fetch;return M(X,C),m.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(f,"fetch",{...m,value:X}),c=!0,()=>{c=!1,se(f,"fetch",X,m,o)})},O=[];if(a.includes("xhr")){let f=L();f&&O.push(f)}if(a.includes("fetch")){let f=q();f&&O.push(f)}return O.length===0?w():(h=!0,{mode:"standard",disconnect:()=>{h=!1;for(let f of O.splice(0))f()}})}function De(e){let t=j(),r;try{if(t=j(e.logger),r=e.onNavigate,typeof r!="function")return w()}catch{return w()}let n,o,a,d,p,v;try{if(n=window,o=n==null?void 0:n.history,!n||!o)return t.log("navigation capture unavailable: window/history missing"),w();if(p=ge(o,"pushState"),v=ge(o,"replaceState"),!p||!v)return t.log("navigation capture unavailable: history method descriptors missing"),w();if(a=p.descriptor.value,d=v.descriptor.value,typeof a!="function"||typeof d!="function")return t.log("navigation capture unavailable: history methods missing"),w();if(typeof n.addEventListener!="function"||typeof n.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),w()}catch(O){return t.log("navigation capture unavailable: history inspection failed",O),w()}if(B(a)||B(d))return t.log("navigation capture unavailable: an equivalent capture is already active"),w();let k=!1,D=()=>({path:n.location.pathname,search:n.location.search,hash:n.location.hash}),h;try{h=D()}catch(O){return t.log("navigation capture unavailable: location inspection failed",O),w()}let S=_(t,"navigation",O=>{if(k)return r(O)}),u=O=>{if(k)try{let R=D();if(R.path===h.path&&R.search===h.search&&R.hash===h.hash)return;h=R,S({...R,source:O})}catch(R){t.log("navigation observation failed",R)}},s={pushState(...O){let R=Reflect.apply(a,this,O);return u("push"),R}}.pushState,b={replaceState(...O){let R=Reflect.apply(d,this,O);return u("replace"),R}}.replaceState;M(s,a),M(b,d);let L=()=>u("pop"),q=()=>u("hash");try{if(ye(p,s),ye(v,b),o.pushState!==s||o.replaceState!==b)throw new Error("history method replacement did not take effect");n.addEventListener("popstate",L),n.addEventListener("hashchange",q),k=!0}catch(O){return k=!1,ne(n,"popstate",L,t),ne(n,"hashchange",q,t),te(v,b,t),te(p,s,t),t.log("navigation capture unavailable: history methods are not writable",O),r=()=>{},S=()=>{},t=j(),w()}return{mode:"standard",disconnect:()=>{k=!1,r=()=>{},ne(n,"popstate",L,t),ne(n,"hashchange",q,t),te(p,s,t),te(v,b,t),S=()=>{},t=j()}}}function ge(e,t){let r=e;for(;r;){let n=Object.getOwnPropertyDescriptor(r,t);if(n)return!("value"in n)||typeof n.value!="function"?null:{owner:r,key:t,descriptor:n};r=Object.getPrototypeOf(r)}return null}function ye(e,t){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let r=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!me(r,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:t})}function me(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function te(e,t,r){try{let n=Object.getOwnPropertyDescriptor(e.owner,e.key);me(n,{...e.descriptor,value:t})&&Object.defineProperty(e.owner,e.key,e.descriptor)}catch(n){r.log(`navigation ${e.key} restoration skipped`,n)}}function ne(e,t,r,n){try{e.removeEventListener(t,r)}catch(o){n.log(`navigation ${t} listener removal skipped`,o)}}function Te(e){var S;let t=(S=e.logger)!=null?S:oe,r=e.onAttached;if(typeof r!="function")return w();let n=Element.prototype,o=Object.getOwnPropertyDescriptor(n,"attachShadow");if(!o||typeof o.value!="function")return t.log("shadow-root capture unavailable: attachShadow not supported"),w();let a=o.value;if(B(a))return t.log("shadow-root capture unavailable: an equivalent capture is already active"),w();let d=!1,p=new WeakSet,v=_(t,"shadow-root",r),k=(u,s)=>{!d||p.has(s)||(p.add(s),v({host:u,shadowRoot:s,mode:s.mode==="closed"?"closed":"open"}))},D={attachShadow(...u){let s=Reflect.apply(a,this,u);return k(this,s),s}}.attachShadow;M(D,a);try{Object.defineProperty(n,"attachShadow",{...o,value:D})}catch(u){return t.log("shadow-root capture unavailable: attachShadow is locked",u),w()}d=!0;let h=u=>{let s=u.querySelectorAll("*");for(let b=0;b<s.length&&d;b++){let L=s[b].shadowRoot;L&&(k(s[b],L),h(L))}};return e.includeExisting&&h(document),{mode:"standard",disconnect:()=>{d=!1;let u=Object.getOwnPropertyDescriptor(n,"attachShadow");je(u,{...o,value:D})&&Object.defineProperty(n,"attachShadow",o)}}}function He(e){var t;return(t=ve(e)[0])!=null?t:null}function ve(e){let t=e.composedPath();return t.length>0?t:e.target?[e.target]:[]}function je(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Be(e){var D,h,S;let t=j(e==null?void 0:e.logger),r=e==null?void 0:e.read,n=e==null?void 0:e.onState;if(typeof r!="function"||typeof n!="function")return we();let o=Number.isFinite(e.delayMs)&&((D=e.delayMs)!=null?D:0)>=0&&(h=e.delayMs)!=null?h:0,a=_(t,"ui-state",n),d=!0,p,v=[],k=()=>{d&&(p!==void 0&&clearTimeout(p),p=setTimeout(()=>{if(p=void 0,!!d)try{let u=r();u!==void 0&&a(u)}catch(u){t.log("ui-state read failed",u)}},o))};try{for(let u of(S=e.triggers)!=null?S:[]){if(!(u!=null&&u.target)||typeof u.target.addEventListener!="function")continue;let s=k;u.target.addEventListener(u.type,s,u.capture===!0),v.push({trigger:u,listener:s})}}catch(u){t.log("ui-state trigger installation failed",u);for(let{trigger:s,listener:b}of v)try{s.target.removeEventListener(s.type,b,s.capture===!0)}catch{}return d=!1,we()}return{mode:"standard",schedule:k,disconnect:()=>{if(d){d=!1,p!==void 0&&clearTimeout(p),p=void 0;for(let{trigger:u,listener:s}of v)try{u.target.removeEventListener(u.type,s,u.capture===!0)}catch(b){t.log("ui-state trigger removal failed",b)}v.length=0}}}}function we(){return{mode:"unavailable",schedule:()=>{},disconnect:()=>{}}}function Ie(e="[autocapture]"){return{log:(...t)=>{try{let r=console.log(e,...t);if(r&&(typeof r=="object"||typeof r=="function"))try{Promise.resolve(r).catch(()=>{})}catch{}}catch{}}}}var Ue="0.1.0-next.2-dd9eb36";export{Ue as VERSION,De as captureNavigation,Ne as captureNetwork,Te as captureShadowRoots,Be as captureUiState,Re as captureWebAuthn,ve as composedPath,He as composedTarget,Ie as createConsoleLogger};
|
|
1
|
+
var ne={log:()=>{}};function H(e){return e?{log:(...t)=>{try{let r=e.log(...t);if(r&&(typeof r=="object"||typeof r=="function"))try{Promise.resolve(r).catch(()=>{})}catch{}}catch{}}}:ne}var se=Symbol.for("corbado.autocapture.installed");function M(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,se)}catch{return!1}}function _(e,t){var n,o;let r=t;try{Object.defineProperty(e,se,{value:t,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(n=r.name)!=null?n:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=r.length)!=null?o:0,configurable:!0})}catch{}return e}function v(){return{mode:"unavailable",disconnect:()=>{}}}function W(e,t,r){let n=H(e);return o=>{try{let a=r(o);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(c=>n.log(`${t} listener failed`,c))}catch(c){n.log(`${t} listener failed`,c)}}catch(a){n.log(`${t} listener failed`,a)}}}function be(e){let t=H(e.logger),r=e.onEvent;if(typeof r!="function")return v();let n=typeof navigator=="undefined"?void 0:navigator,o=n==null?void 0:n.credentials;if(!n||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),v();let a=o.get,c=o.create;if(typeof a!="function"||typeof c!="function")return t.log("webauthn capture unavailable: credentials methods missing"),v();if(M(a)||M(c))return t.log("webauthn capture unavailable: an equivalent capture is already active"),v();let d=!1,y=0,P=W(t,"webauthn",u=>{if(d)return r(u)}),g=(u,w)=>{let N={invoke(...x){let k=this,R=x[0];if(!d||!Q(R)||!Q(R.publicKey))return Reflect.apply(w,k,x);let z=R.publicKey,p=`wa-${++y}`,C=Reflect.apply(w,k,x),m=Q(R.signal)?R.signal:void 0,b=we(u,R,z),X={...b,ceremonyId:p,phase:"started",userActivation:Se(n)};if(b.kind==="authentication"){let A=z;X.requestOptionsJson=Ee(A,t)}return P(X),Promise.resolve(C).then(A=>(d&&P({...b,ceremonyId:p,phase:"completed",credentialJson:Oe(A,u,t),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),A),A=>{throw d&&P({...b,ceremonyId:p,phase:"failed",error:A,errorName:qe(A),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),A})}}.invoke;return _(N,{name:u,length:0})},O=(u,w)=>{let N=g(u,w),x=Object.getOwnPropertyDescriptor(o,u);if(x&&(!("value"in x)||x.writable!==!0))return null;try{o[u]=N}catch{return null}return()=>{o[u]===N&&(x?o[u]=x.value:delete o[u])}},E=O("get",a),s=E?O("create",c):null;return!E||!s?(E==null||E(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),v()):(d=!0,{mode:"standard",disconnect:()=>{d=!1,E(),s()}})}function we(e,t,r){let n=Re(t.mediation);if(e==="create")return{kind:"registration",mediation:n};let o=r;return{kind:"authentication",mediation:n,uiMode:Ce(t.uiMode),credentialSet:Array.isArray(o.allowCredentials)&&o.allowCredentials.length>0?"allowlisted":"discoverable"}}function Re(e){return e===void 0?"optional":e==="silent"||e==="optional"||e==="conditional"||e==="required"?e:"unknown"}function Ce(e){return e===void 0?"default":e==="immediate"?"immediate":"unknown"}function Se(e){let t=e.userActivation;return typeof(t==null?void 0:t.isActive)=="boolean"?t.isActive:void 0}function Oe(e,t,r){var n;if(e)try{let o=e,a=o.response,c={id:J(o.id),rawId:V(o.rawId),type:J(o.type),authenticatorAttachment:J(o.authenticatorAttachment),response:t==="create"?{clientDataJSON:V(a==null?void 0:a.clientDataJSON),attestationObject:V(a==null?void 0:a.attestationObject),transports:re((n=a==null?void 0:a.getTransports)==null?void 0:n.call(a))}:{clientDataJSON:V(a==null?void 0:a.clientDataJSON),authenticatorData:V(a==null?void 0:a.authenticatorData),signature:V(a==null?void 0:a.signature),userHandle:V(a==null?void 0:a.userHandle)},...t==="create"?Ae(o):{}};return JSON.stringify(c)}catch(o){r.log("credential serialization failed",o);return}}function Ee(e,t){try{let r={},n=J(e.rpId),o=J(e.userVerification),a=re(e.hints);return n!==void 0&&(r.rpId=n),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(r.timeout=e.timeout),o!==void 0&&(r.userVerification=o),a!==void 0&&(r.hints=a),r.challenge=V(e.challenge),Array.isArray(e.allowCredentials)&&(r.allowCredentials=ke(e.allowCredentials)),JSON.stringify(r)}catch(r){t.log("request options serialization failed",r);return}}function ke(e){let t=[];for(let r of e){if(!Q(r))continue;let n=r;t.push({type:J(n.type),id:V(n.id),transports:re(n.transports)})}return t}function re(e){if(Array.isArray(e))return e.filter(t=>typeof t=="string")}function J(e){return typeof e=="string"?e:void 0}function Ae(e){var n;let t=(n=e.getClientExtensionResults)==null?void 0:n.call(e);if(!Q(t))return{};let r=t.credProps;return!r||typeof r.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:r.rk}}}}function V(e){let t;if(e instanceof ArrayBuffer)t=new Uint8Array(e);else if(ArrayBuffer.isView(e))t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let r="";for(let n of t)r+=String.fromCharCode(n);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Q(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function qe(e){return e instanceof DOMException?e.name:"UnknownError"}var ue=0;function ce(){return ue+=1,`network-${ue}`}function Pe(e,t){let r=e.responseType;if(r===""||r==="text")return t(e.responseText);if(r==="json"){let n=e.response;return n==null?void 0:t(n)}}var xe=500,de=Symbol("body-read-timeout");function le(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function pe(e,t){let r=e.body;if(!r)return;let n=r.getReader(),o;try{let a=new Promise(y=>{o=setTimeout(()=>y(de),xe)}),c=new TextDecoder,d=[];for(;;){let y=await Promise.race([n.read(),a]);if(y===de){t.log("body omitted: read timed out"),n.cancel().catch(()=>{});return}if(y.done)break;d.push(c.decode(y.value,{stream:!0}))}return d.push(c.decode()),d.join("")}catch{n.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function oe(e){var t;(t=e==null?void 0:e.body)==null||t.cancel().catch(()=>{})}function ae(e,t,r,n,o){try{let a=Object.getOwnPropertyDescriptor(e,t);De(a,{...n,value:r})&&Object.defineProperty(e,t,n)}catch(a){o.log(`${String(t)} restoration skipped`,a)}}function De(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Le(e){var k,R,z;let{onExchange:t,onRequest:r,match:n}=e;if(typeof t!="function"||typeof n!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=H(e.logger),a=(k=e.transports)!=null?k:["xhr","fetch"],c=(R=e.bodyCapture)==null?void 0:R.request,d=(z=e.bodyCapture)==null?void 0:z.response,y=typeof c=="function",P=typeof d=="function",g=!1,O=W(o,"network",p=>{if(g)return t(p)}),E=W(o,"network request",p=>{if(g)return r==null?void 0:r(p)}),s=(p,C,m)=>{if(typeof m=="function")try{return m(p,C)}catch(b){o.log("body projection failed",b);return}},u=(p,C)=>{try{let m=typeof document!="undefined"?document.baseURI:void 0,b=new URL(String(p),m);return n(b,C)===!0?{url:b.href,path:b.pathname}:void 0}catch{return}},w=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let p=XMLHttpRequest.prototype,C=Object.getOwnPropertyDescriptor(p,"open"),m=Object.getOwnPropertyDescriptor(p,"send");if(!C||!("value"in C)||typeof C.value!="function"||!m||!("value"in m)||typeof m.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let b=C.value,X=m.value;if(M(b)||M(X))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let A=new WeakMap,q=new Set,L=!1,T={open(...S){var f;let i=Reflect.apply(b,this,S);if(!g||!L)return i;try{let B=A.get(this);B&&(B.reported=!0,(f=B.cleanupListeners)==null||f.call(B));let j=String(S[0]).toUpperCase(),D=u(S[1],j);D?A.set(this,{method:j,url:D.url,path:D.path,reported:!1}):A.delete(this)}catch(B){o.log("xhr open observation failed",B)}return i}}.open,K={send(...S){let i=g&&L?A.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(X,this,S);let f=()=>{},B=!1;try{i.requestId=ce();let D={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=y&&typeof S[0]=="string"?s(S[0],D,c):void 0;let G=()=>{i.outcome===void 0&&(i.outcome="abort")},Y=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},h=()=>{var $;f();try{if(!g||!L||i.reported||!i.requestId)return;i.reported=!0;let U={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},te=this.status,ie={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:te,ok:te>=200&&te<300,outcome:($=i.outcome)!=null?$:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:P?Pe(this,ve=>s(ve,U,d)):void 0};i.requestEmitted?O(ie):i.pendingExchange=ie}catch(U){o.log("xhr exchange observation failed",U)}finally{A.get(this)===i&&A.delete(this)}},I=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&h()}catch($){o.log("xhr ready-state observation failed",$)}},F=()=>h();f=()=>{for(let[$,U]of[["readystatechange",I],["abort",G],["timeout",Y],["error",l],["loadend",F]])this.removeEventListener($,U);i.cleanupListeners===f&&(i.cleanupListeners=void 0),q.delete(f)},this.addEventListener("readystatechange",I),this.addEventListener("abort",G),this.addEventListener("timeout",Y),this.addEventListener("error",l),this.addEventListener("loadend",F),i.cleanupListeners=f,q.add(f),i.startedAt=Date.now(),B=!0}catch(D){o.log("xhr send observation failed",D),f()}let j;try{j=Reflect.apply(X,this,S)}catch(D){throw f(),D}if(B&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,E({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let D=i.pendingExchange;i.pendingExchange=void 0,D&&O(D)}return j}}.send;return _(T,b),_(K,X),C.writable!==!0||m.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(p,"open",{...C,value:T}),Object.defineProperty(p,"send",{...m,value:K}),L=!0,()=>{L=!1;for(let S of[...q])S();ae(p,"open",T,C,o),ae(p,"send",K,m,o)})},N=()=>{let p=globalThis,C=Object.getOwnPropertyDescriptor(p,"fetch");if(!C||!("value"in C))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let m=C.value;if(typeof m!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(M(m))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let b=!1,X=async(q,L,T,K)=>{try{if(!g||!b){oe(T);return}let[S,i]=await Promise.all([K!=null?K:Promise.resolve(void 0),T?pe(T,o):Promise.resolve(void 0)]);if(!g||!b)return;let f={direction:"request",transport:"fetch",method:q.method,url:q.url,path:q.path},B={...f,direction:"response"},j=q.requestBody;j===void 0&&S!==void 0&&(j=s(S,f,c));let D=i!==void 0?s(i,B,d):void 0;O({requestId:q.requestId,transport:"fetch",method:q.method,url:q.url,path:q.path,status:L.status,ok:L.ok,outcome:"load",durationMs:Date.now()-q.startedAt,responseUrl:L.url||void 0,requestBody:j,responseBody:D})}catch(S){o.log("fetch exchange observation failed",S)}},A={fetch(...q){var j,D,G,Y;let L;try{let l=q[0],h=q[1];if(g&&b&&y&&typeof Request!="undefined"&&l instanceof Request&&(h==null?void 0:h.body)===void 0&&l.body){let I=String((j=h==null?void 0:h.method)!=null?j:l.method).toUpperCase(),F=(D=l.headers.get("content-type"))!=null?D:"";u(l.url,I)&&le(F)&&(L=l.clone())}}catch(l){o.log("fetch observation failed",l)}let T,K=Date.now();try{T=Reflect.apply(m,this,q)}catch(l){throw oe(L),l}let S,i;try{if(g&&b){let l=q[0],h=q[1],I=typeof Request!="undefined"&&l instanceof Request,F=String((G=h==null?void 0:h.method)!=null?G:I?l.method:"GET").toUpperCase(),$=I?l.url:l,U=u($,F);U&&(S={requestId:ce(),method:F,url:U.url,path:U.path,startedAt:K},i=(Y=h==null?void 0:h.signal)!=null?Y:I?l.signal:void 0,y&&typeof(h==null?void 0:h.body)=="string"&&(S.requestBody=s(h.body,{direction:"request",transport:"fetch",method:F,url:U.url,path:U.path},c)))}}catch(l){o.log("fetch observation failed",l)}if(!S)return oe(L),T;let f=S;E({requestId:f.requestId,transport:"fetch",method:f.method,url:f.url,path:f.path,startedAt:f.startedAt,requestBody:f.requestBody});let B=L?pe(L,o):void 0;return T.then(l=>{var I;let h;try{if(g&&b&&P){let F=(I=l.headers.get("content-type"))!=null?I:"";le(F)&&l.body&&(h=l.clone())}}catch{}X(f,l,h,B)},l=>{try{if(!g||!b)return;let h=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;O({requestId:f.requestId,transport:"fetch",method:f.method,url:f.url,path:f.path,status:0,ok:!1,outcome:h?"abort":"error",durationMs:Date.now()-f.startedAt})}catch(h){o.log("fetch failure observation failed",h)}}),T}}.fetch;return _(A,m),C.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(p,"fetch",{...C,value:A}),b=!0,()=>{b=!1,ae(p,"fetch",A,C,o)})},x=[];if(a.includes("xhr")){let p=w();p&&x.push(p)}if(a.includes("fetch")){let p=N();p&&x.push(p)}return x.length===0?v():(g=!0,{mode:"standard",disconnect:()=>{g=!1;for(let p of x.splice(0))p()}})}function Ne(e){let t=H(),r;try{if(t=H(e.logger),r=e.onNavigate,typeof r!="function")return v()}catch{return v()}let n,o,a,c,d,y;try{if(n=window,o=n==null?void 0:n.history,!n||!o)return t.log("navigation capture unavailable: window/history missing"),v();if(d=fe(o,"pushState"),y=fe(o,"replaceState"),!d||!y)return t.log("navigation capture unavailable: history method descriptors missing"),v();if(a=d.descriptor.value,c=y.descriptor.value,typeof a!="function"||typeof c!="function")return t.log("navigation capture unavailable: history methods missing"),v();if(typeof n.addEventListener!="function"||typeof n.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),v()}catch(k){return t.log("navigation capture unavailable: history inspection failed",k),v()}if(M(a)||M(c))return t.log("navigation capture unavailable: an equivalent capture is already active"),v();let P=!1,g=()=>({path:n.location.pathname,search:n.location.search,hash:n.location.hash}),O;try{O=g()}catch(k){return t.log("navigation capture unavailable: location inspection failed",k),v()}let E=W(t,"navigation",k=>{if(P)return r(k)}),s=k=>{if(P)try{let R=g();if(R.path===O.path&&R.search===O.search&&R.hash===O.hash)return;O=R,E({...R,source:k})}catch(R){t.log("navigation observation failed",R)}},u={pushState(...k){let R=Reflect.apply(a,this,k);return s("push"),R}}.pushState,w={replaceState(...k){let R=Reflect.apply(c,this,k);return s("replace"),R}}.replaceState;_(u,a),_(w,c);let N=()=>s("pop"),x=()=>s("hash");try{if(he(d,u),he(y,w),o.pushState!==u||o.replaceState!==w)throw new Error("history method replacement did not take effect");n.addEventListener("popstate",N),n.addEventListener("hashchange",x),P=!0}catch(k){return P=!1,ee(n,"popstate",N,t),ee(n,"hashchange",x,t),Z(y,w,t),Z(d,u,t),t.log("navigation capture unavailable: history methods are not writable",k),r=()=>{},E=()=>{},t=H(),v()}return{mode:"standard",disconnect:()=>{P=!1,r=()=>{},ee(n,"popstate",N,t),ee(n,"hashchange",x,t),Z(d,u,t),Z(y,w,t),E=()=>{},t=H()}}}function fe(e,t){let r=e;for(;r;){let n=Object.getOwnPropertyDescriptor(r,t);if(n)return!("value"in n)||typeof n.value!="function"?null:{owner:r,key:t,descriptor:n};r=Object.getPrototypeOf(r)}return null}function he(e,t){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let r=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!ye(r,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:t})}function ye(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Z(e,t,r){try{let n=Object.getOwnPropertyDescriptor(e.owner,e.key);ye(n,{...e.descriptor,value:t})&&Object.defineProperty(e.owner,e.key,e.descriptor)}catch(n){r.log(`navigation ${e.key} restoration skipped`,n)}}function ee(e,t,r,n){try{e.removeEventListener(t,r)}catch(o){n.log(`navigation ${t} listener removal skipped`,o)}}function Be(e){var E;let t=(E=e.logger)!=null?E:ne,r=e.onAttached;if(typeof r!="function")return v();let n=Element.prototype,o=Object.getOwnPropertyDescriptor(n,"attachShadow");if(!o||typeof o.value!="function")return t.log("shadow-root capture unavailable: attachShadow not supported"),v();let a=o.value;if(M(a))return t.log("shadow-root capture unavailable: an equivalent capture is already active"),v();let c=!1,d=new WeakSet,y=W(t,"shadow-root",r),P=(s,u)=>{!c||d.has(u)||(d.add(u),y({host:s,shadowRoot:u,mode:u.mode==="closed"?"closed":"open"}))},g={attachShadow(...s){let u=Reflect.apply(a,this,s);return P(this,u),u}}.attachShadow;_(g,a);try{Object.defineProperty(n,"attachShadow",{...o,value:g})}catch(s){return t.log("shadow-root capture unavailable: attachShadow is locked",s),v()}c=!0;let O=s=>{let u=s.querySelectorAll("*");for(let w=0;w<u.length&&c;w++){let N=u[w].shadowRoot;N&&(P(u[w],N),O(N))}};return e.includeExisting&&O(document),{mode:"standard",disconnect:()=>{c=!1;let s=Object.getOwnPropertyDescriptor(n,"attachShadow");je(s,{...o,value:g})&&Object.defineProperty(n,"attachShadow",o)}}}function Te(e){var t;return(t=ge(e)[0])!=null?t:null}function ge(e){let t=e.composedPath();return t.length>0?t:e.target?[e.target]:[]}function je(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function He(e){var g,O,E;let t=H(e==null?void 0:e.logger),r=e==null?void 0:e.read,n=e==null?void 0:e.onState;if(typeof r!="function"||typeof n!="function")return me();let o=Number.isFinite(e.delayMs)&&((g=e.delayMs)!=null?g:0)>=0&&(O=e.delayMs)!=null?O:0,a=W(t,"ui-state",n),c=!0,d,y=[],P=()=>{c&&(d!==void 0&&clearTimeout(d),d=setTimeout(()=>{if(d=void 0,!!c)try{let s=r();s!==void 0&&a(s)}catch(s){t.log("ui-state read failed",s)}},o))};try{for(let s of(E=e.triggers)!=null?E:[]){if(!(s!=null&&s.target)||typeof s.target.addEventListener!="function")continue;let u=P;s.target.addEventListener(s.type,u,s.capture===!0),y.push({trigger:s,listener:u})}}catch(s){t.log("ui-state trigger installation failed",s);for(let{trigger:u,listener:w}of y)try{u.target.removeEventListener(u.type,w,u.capture===!0)}catch{}return c=!1,me()}return{mode:"standard",schedule:P,disconnect:()=>{if(c){c=!1,d!==void 0&&clearTimeout(d),d=void 0;for(let{trigger:s,listener:u}of y)try{s.target.removeEventListener(s.type,u,s.capture===!0)}catch(w){t.log("ui-state trigger removal failed",w)}y.length=0}}}}function me(){return{mode:"unavailable",schedule:()=>{},disconnect:()=>{}}}function Me(e="[autocapture]"){return{log:(...t)=>{try{let r=console.log(e,...t);if(r&&(typeof r=="object"||typeof r=="function"))try{Promise.resolve(r).catch(()=>{})}catch{}}catch{}}}}var Ie="0.1.0-next.4-aa81c53";export{Ie as VERSION,Ne as captureNavigation,Le as captureNetwork,Be as captureShadowRoots,He as captureUiState,be as captureWebAuthn,ge as composedPath,Te as composedTarget,Me as createConsoleLogger};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corbado/autocapture",
|
|
3
|
-
"version": "0.1.0-next.
|
|
3
|
+
"version": "0.1.0-next.4-aa81c53",
|
|
4
4
|
"description": "Observer-style capture helpers for WebAuthn ceremonies, selected network exchanges, in-app navigation, shadow roots, and rendered UI state.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|