@corbado/autocapture 1.0.1 → 1.2.0

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.
@@ -0,0 +1,351 @@
1
+ import { p as NetworkBodyProjectionContext, l as HttpRequestStarted, H as HttpExchange, m as NavigationEvent, v as WebAuthnCeremonyEvent } from './types-lamU1Fd3.js';
2
+
3
+ /** Capture depth of a surface. `values` applies the redaction rules; anything no rule names becomes its class. */
4
+ type ProbeLevel = "off" | "inventory" | "shape" | "values";
5
+ /** Everything a probe config can observe. */
6
+ type ProbeSurface = "page" | "ui" | "act" | "nav" | "res" | "store" | "net" | "form" | "err" | "console" | "dl" | "msg" | "glob" | "cev";
7
+ /**
8
+ * Redaction method of a rule.
9
+ *
10
+ * - `drop`: the key / element is left out.
11
+ * - `presence`: `<set>` or `<empty>`.
12
+ * - `length`: `<len:n>`.
13
+ * - `class`: a coarse class such as `<email>`, `<digits:6>`, `<alpha:5>`, `<uuid>`, `<text:4w>` (the default).
14
+ * - `shape`: format mask — digits → `9`, letters → `a`, separators kept; optional `keepPrefix`.
15
+ * - `hash`: `<h:…>`, salted per page (the salt never leaves the page).
16
+ * - `mask`: `*` for every character except `keepStart` / `keepEnd`.
17
+ * - `enum`: the value when it is one of `values`, its class otherwise.
18
+ * - `clear`: the value itself (still subject to the always-on guards).
19
+ */
20
+ type ProbeMethod = "drop" | "presence" | "length" | "class" | "shape" | "hash" | "mask" | "enum" | "clear";
21
+ /** Options shared by every surface. */
22
+ type ProbeSurfaceConfig = {
23
+ level: ProbeLevel;
24
+ };
25
+ /** `net` surface options. */
26
+ type ProbeNetSurfaceConfig = ProbeSurfaceConfig & {
27
+ /** Host globs to observe (default: every host except Corbado's own). */
28
+ hosts?: string[];
29
+ /** Host globs never observed (Corbado's own hosts are always excluded). */
30
+ excludeHosts?: string[];
31
+ /** Path globs to observe (default: every path). */
32
+ paths?: string[];
33
+ /** Uppercase methods to observe (default: all). */
34
+ methods?: string[];
35
+ /** Read and redact bodies at `shape` / `values` (default true). */
36
+ bodies?: boolean;
37
+ };
38
+ /** `res` surface options. */
39
+ type ProbeResSurfaceConfig = ProbeSurfaceConfig & {
40
+ /** Host globs (default: all but Corbado's own). */
41
+ hosts?: string[];
42
+ /** Poll interval for new Resource Timing entries (default 5000 ms, min 1000). */
43
+ everyMs?: number;
44
+ };
45
+ /** `ui` surface options. */
46
+ type ProbeUiSurfaceConfig = ProbeSurfaceConfig & {
47
+ /** Max distinct views per document (default 30). */
48
+ maxViews?: number;
49
+ };
50
+ /** `console` surface options. */
51
+ type ProbeConsoleSurfaceConfig = ProbeSurfaceConfig & {
52
+ /** Console methods to observe (default `["error", "warn"]`). */
53
+ levels?: Array<"error" | "warn" | "info" | "log" | "debug">;
54
+ };
55
+ type ProbeSurfaces = {
56
+ page?: ProbeLevel | ProbeSurfaceConfig;
57
+ ui?: ProbeLevel | ProbeUiSurfaceConfig;
58
+ act?: ProbeLevel | ProbeSurfaceConfig;
59
+ nav?: ProbeLevel | ProbeSurfaceConfig;
60
+ res?: ProbeLevel | ProbeResSurfaceConfig;
61
+ store?: ProbeLevel | ProbeSurfaceConfig;
62
+ net?: ProbeLevel | ProbeNetSurfaceConfig;
63
+ form?: ProbeLevel | ProbeSurfaceConfig;
64
+ err?: ProbeLevel | ProbeSurfaceConfig;
65
+ console?: ProbeLevel | ProbeConsoleSurfaceConfig;
66
+ dl?: ProbeLevel | ProbeSurfaceConfig;
67
+ msg?: ProbeLevel | ProbeSurfaceConfig;
68
+ glob?: ProbeLevel | ProbeSurfaceConfig;
69
+ cev?: ProbeLevel | ProbeSurfaceConfig;
70
+ };
71
+ /** Method options (used by rules, snapshot fields and correlate values). */
72
+ type ProbeMethodOptions = {
73
+ method: ProbeMethod;
74
+ /** `enum`: the values that may be emitted as they are. */
75
+ values?: string[];
76
+ /** `shape`: leading characters kept as they are. */
77
+ keepPrefix?: number;
78
+ /** `mask`: characters kept at the start / end. */
79
+ keepStart?: number;
80
+ keepEnd?: number;
81
+ };
82
+ /**
83
+ * One redaction rule. A rule applies when every scope it names matches; the first matching rule wins.
84
+ * Keys are compared case-insensitively with `-`, `_` and spaces ignored; a key containing `.` is a dotted
85
+ * path glob matched against the end of the value's path (`data.json_data.bound`, `*.assertion_id`).
86
+ */
87
+ type ProbeRule = ProbeMethodOptions & {
88
+ surface?: ProbeSurface | ProbeSurface[];
89
+ /** Host globs of the URL the value belongs to (`net`, `res`, `page`, `nav`); the page host for DOM surfaces. */
90
+ host?: string | string[];
91
+ /** Path globs of that URL; the page path for DOM surfaces. */
92
+ path?: string | string[];
93
+ /** Key names or dotted path globs (body keys, query parameters, storage keys, form field names). */
94
+ key?: string | string[];
95
+ /** CSS selector (`ui`, `act`, `form`): applies to matching elements and their subtree. */
96
+ selector?: string;
97
+ /** `net` only: which part of the exchange. */
98
+ part?: "url" | "request" | "response";
99
+ };
100
+ /** Network matcher. */
101
+ type ProbeNetMatch = {
102
+ host?: string | string[];
103
+ path?: string | string[];
104
+ method?: string | string[];
105
+ /** Status codes, or `ok` (2xx/3xx) / `error` (0, ≥ 400 or not loaded). Ignored at request time. */
106
+ status?: number[] | "ok" | "error";
107
+ /** Request body conditions: dotted path → expected value(s), compared as strings. */
108
+ body?: Record<string, string | string[]>;
109
+ /** Response body conditions (same form). */
110
+ response?: Record<string, string | string[]>;
111
+ };
112
+ /** Something that happens on the page: used by `trigger.on`, `snapshot.on` and `count.on`. */
113
+ type ProbeMatch = {
114
+ net?: ProbeNetMatch;
115
+ /** A visible element matching this selector appears. */
116
+ selector?: string;
117
+ /** A click on (or inside) an element matching this selector. */
118
+ click?: string;
119
+ /** A form submit (`true` = any form, string = form selector). */
120
+ submit?: string | true;
121
+ /** `handle.signal(name)` from the host. */
122
+ signal?: string;
123
+ /** The host context (`deps.context().state`) enters this state. */
124
+ state?: string;
125
+ /** An uncaught error or unhandled rejection. */
126
+ error?: true;
127
+ };
128
+ /** A body value to read: dotted path (`[]` iterates arrays, `**` searches any depth; JSON strings are parsed). */
129
+ type ProbePathPick = Partial<ProbeMethodOptions> & {
130
+ path: string;
131
+ /** Output name (default: the path). */
132
+ as?: string;
133
+ };
134
+ type ProbeSnapshotAction = {
135
+ type: "snapshot";
136
+ name: string;
137
+ on: ProbeMatch;
138
+ /** Form fields: value via `method` (default `class`), validity flags, `aria-invalid`, nearby error text. */
139
+ fields?: Array<Partial<ProbeMethodOptions> & {
140
+ selector: string;
141
+ as?: string;
142
+ }>;
143
+ /** Visible texts of these selectors (free-text redaction). */
144
+ texts?: string[];
145
+ /** Request / response body values (only when `on.net` matched). */
146
+ request?: ProbePathPick[];
147
+ response?: ProbePathPick[];
148
+ /** Max snapshots per document (default 20). */
149
+ max?: number;
150
+ };
151
+ /**
152
+ * Remember `key → value` pairs seen in one exchange and resolve the key in a later one, emitting only the
153
+ * value (e.g. an OTP send: the channel id never leaves the page, its channel type does).
154
+ */
155
+ type ProbeCorrelateAction = {
156
+ type: "correlate";
157
+ name: string;
158
+ /** Item kind (default `corr`). */
159
+ kind?: string;
160
+ learn: {
161
+ net: ProbeNetMatch;
162
+ /** Body to learn from (default `response`). */
163
+ from?: "request" | "response";
164
+ /** Path of the objects to learn from (e.g. `**.channels[]`). */
165
+ items: string;
166
+ /** Path of the key inside an item (kept in memory only). */
167
+ key: string;
168
+ /** Path of the value inside an item. */
169
+ value: string;
170
+ /** How the value is emitted (default `enum` with `values`, else `class`). */
171
+ method?: ProbeMethod;
172
+ values?: string[];
173
+ /** Paths inside an item whose size is reported with the offered values (object keys / array length / 1). */
174
+ count?: string[];
175
+ };
176
+ resolve: {
177
+ net: ProbeNetMatch;
178
+ /** Body holding the key (default `request`). */
179
+ from?: "request" | "response";
180
+ /** Path(s) of the key; the first that resolves wins. */
181
+ key: string | string[];
182
+ /** Extra values emitted with the result. */
183
+ fields?: ProbePathPick[];
184
+ };
185
+ /** Max emissions per document (default 50). */
186
+ max?: number;
187
+ };
188
+ type ProbeCountAction = {
189
+ type: "count";
190
+ name: string;
191
+ on: ProbeMatch;
192
+ };
193
+ type ProbeAction = ProbeSnapshotAction | ProbeCorrelateAction | ProbeCountAction;
194
+ /** Conditions; all must hold. */
195
+ type ProbeWhen = {
196
+ /** Observe project ids (`deps.projectId`). */
197
+ projects?: string[];
198
+ /** ISO 8601 date or date-time; the probe is off after it. */
199
+ until?: string;
200
+ /** Fraction 0..1 of sessions, sticky per session id. */
201
+ sample?: number;
202
+ /** Browser names: `chrome`, `edge`, `safari`, `firefox`, `samsung`, `opera`, `other`. */
203
+ browser?: string[];
204
+ /** OS names: `windows`, `macos`, `ios`, `android`, `linux`, `chromeos`, `other`. */
205
+ os?: string[];
206
+ device?: Array<"desktop" | "mobile" | "tablet">;
207
+ /** Page path globs, evaluated per item. */
208
+ path?: string[];
209
+ /** Host context states (`deps.context().state`), evaluated per item. */
210
+ state?: string[];
211
+ /** Flow tags (`deps.tags()`): tag → allowed values (`*` = any). Items are buffered until the tag is known. */
212
+ tags?: Record<string, string[]>;
213
+ /** Integration version globs (`deps.integrationVersion`). */
214
+ integrationVersion?: string[];
215
+ };
216
+ /** Flight recorder: items are buffered and only sent when one of `on` happens. */
217
+ type ProbeTrigger = {
218
+ on: ProbeMatch[];
219
+ /** Ring buffer size in items (default 300) and bytes (default 300000). */
220
+ buffer?: number;
221
+ bufferBytes?: number;
222
+ /** After a trigger, items stream directly for this long (default 30000 ms) before buffering resumes. */
223
+ streamMs?: number;
224
+ };
225
+ type ProbeBudgets = {
226
+ /** Items per document (default 400). */
227
+ items?: number;
228
+ /** Serialized bytes per document (default 400000). */
229
+ bytes?: number;
230
+ /** Items per document and kind (defaults per kind, e.g. `ui` 40, `act` 150, `net` 150). */
231
+ perKind?: Record<string, number>;
232
+ };
233
+ /** Probe configuration, schema version 1. */
234
+ type ProbeConfig = {
235
+ v: 1;
236
+ /** Free label (not interpreted). */
237
+ name?: string;
238
+ when?: ProbeWhen;
239
+ trigger?: ProbeTrigger;
240
+ surfaces?: ProbeSurfaces;
241
+ rules?: ProbeRule[];
242
+ actions?: ProbeAction[];
243
+ budgets?: ProbeBudgets;
244
+ };
245
+ /** Host context stamped on items. */
246
+ type ProbeItemContext = {
247
+ state?: string;
248
+ flowType?: string;
249
+ step?: string;
250
+ };
251
+ /** What the engine hands to the sink (→ `tracker.probe`). */
252
+ type ProbeSinkItem = {
253
+ kind: string;
254
+ payload: Record<string, unknown> | unknown[];
255
+ pageId: string;
256
+ cfg: string;
257
+ ctx?: ProbeItemContext;
258
+ ts: number;
259
+ };
260
+ /**
261
+ * A network subscriber, shaped like autocapture-x's CaptureHub `NetworkSubscriber`: projectors run
262
+ * synchronously inside the network capture and are the only place raw bodies are seen.
263
+ */
264
+ type ProbeNetworkSubscriber = {
265
+ id: string;
266
+ match(url: URL, method: string): boolean;
267
+ projectRequest?(body: unknown, context: NetworkBodyProjectionContext<"request">): unknown;
268
+ projectResponse?(body: unknown, context: NetworkBodyProjectionContext<"response">): unknown;
269
+ onRequest?(request: HttpRequestStarted<unknown>): void;
270
+ onExchange?(exchange: HttpExchange<unknown, unknown>): void;
271
+ };
272
+ /** CaptureHub-compatible network source: `{ subscribe: (s) => hub.subscribeNetwork(s) }`. */
273
+ type ProbeNetworkSource = {
274
+ /** Called synchronously by `startProbes`; may return an unsubscribe function. */
275
+ subscribe(subscriber: ProbeNetworkSubscriber): (() => void) | void;
276
+ };
277
+ type ProbeNavigationSource = {
278
+ subscribe(listener: (event: NavigationEvent) => void): (() => void) | void;
279
+ };
280
+ type ProbeWebAuthnSource = {
281
+ subscribe(listener: (event: WebAuthnCeremonyEvent) => void): (() => void) | void;
282
+ };
283
+ type ProbeDeps = {
284
+ /** Receives every redacted item (→ `tracker.probe(item)`). */
285
+ sink(item: ProbeSinkItem): void;
286
+ projectId: string;
287
+ /** Network source; falls back to the package's own `captureNetwork` when absent. */
288
+ network?: ProbeNetworkSource;
289
+ /** Navigation source; falls back to `captureNavigation` when absent. */
290
+ navigation?: ProbeNavigationSource;
291
+ /** WebAuthn events, used only to taint ceremony values; none when absent. */
292
+ webauthn?: ProbeWebAuthnSource;
293
+ context?(): ProbeItemContext | undefined;
294
+ tags?(): Record<string, string> | undefined;
295
+ /** Session id for sticky sampling. */
296
+ sessionId?(): string | undefined;
297
+ /** For `when.integrationVersion`. */
298
+ integrationVersion?: string;
299
+ now?(): number;
300
+ };
301
+ type ProbeHandle = {
302
+ /** `active`: capturing; `off`: a condition does not hold or the config is invalid; `unavailable`: no page or another engine runs. */
303
+ readonly mode: "active" | "off" | "unavailable";
304
+ /** Config hash stamped on every item (`cfg`). */
305
+ readonly hash: string;
306
+ /** Why the probe is not active. */
307
+ readonly reason?: string;
308
+ /** Host-signalled event (e.g. a step error) for `trigger.on` / actions `{ signal }`. */
309
+ signal(name: string): void;
310
+ disconnect(): void;
311
+ };
312
+
313
+ /**
314
+ * Always-on guards. Not configurable: no config field reaches them.
315
+ *
316
+ * 1. Single DOM value read path: every field value read goes through {@link readFieldValue} /
317
+ * {@link fieldValueLength}; sensitive fields (passwords, one-time codes, card fields, inputs of
318
+ * WebAuthn-bound forms) yield at most their length.
319
+ * 2. Taint set: values that must never leave (typed passwords / OTPs, WebAuthn ceremony parts, cookie
320
+ * values, Authorization headers) are kept as salted rolling hashes; any occurrence anywhere in an
321
+ * item becomes `<tainted:len>`.
322
+ * 3. Pattern pass: JWT / JWE (any case), base64url WebAuthn client data, Luhn-valid card numbers,
323
+ * WebAuthn / password keys, high-entropy tokens ≥ 24 chars.
324
+ * 4. Fail closed: a guard that throws drops the item.
325
+ */
326
+
327
+ /** Salted rolling-hash fingerprints of values that must never leave. Values themselves are not kept. */
328
+ declare class ProbeTaint {
329
+ private readonly base1;
330
+ private readonly base2;
331
+ private readonly byLength;
332
+ private readonly order;
333
+ constructor();
334
+ /** Number of fingerprints held. */
335
+ get size(): number;
336
+ /** Adds a value (and its URL-encoded / JSON-escaped forms). Values under 6 chars are ignored. */
337
+ add(value: unknown): void;
338
+ private addOne;
339
+ private fingerprint;
340
+ /** Replaces every tainted occurrence with `<tainted:len>`. */
341
+ scrub(text: string): string;
342
+ }
343
+ /** A fresh taint set (for tests / the conformance runner), optionally pre-filled. */
344
+ declare function createProbeTaint(values?: string[]): ProbeTaint;
345
+ /**
346
+ * The final always-on pass over an item: taint, pattern and key guards. Returns a guarded copy, or
347
+ * `undefined` when the pass fails (the item must then be dropped — fail closed).
348
+ */
349
+ declare function applyGuards(item: unknown, taint?: ProbeTaint | null): unknown;
350
+
351
+ export { type ProbeTrigger as A, type ProbeUiSurfaceConfig as B, type ProbeWebAuthnSource as C, type ProbeWhen as D, applyGuards as E, createProbeTaint as F, type ProbeConfig as P, type ProbeDeps as a, type ProbeHandle as b, type ProbeAction as c, type ProbeBudgets as d, type ProbeConsoleSurfaceConfig as e, type ProbeCorrelateAction as f, type ProbeCountAction as g, type ProbeItemContext as h, type ProbeLevel as i, type ProbeMatch as j, type ProbeMethod as k, type ProbeMethodOptions as l, type ProbeNavigationSource as m, type ProbeNetMatch as n, type ProbeNetSurfaceConfig as o, type ProbeNetworkSource as p, type ProbeNetworkSubscriber as q, type ProbePathPick as r, type ProbeResSurfaceConfig as s, type ProbeRule as t, type ProbeSinkItem as u, type ProbeSnapshotAction as v, type ProbeSurface as w, type ProbeSurfaceConfig as x, type ProbeSurfaces as y, ProbeTaint as z };
package/dist/index.d.mts CHANGED
@@ -1,250 +1,7 @@
1
- import { WebAuthnIdentifierProjectors } from '@corbado/observe';
1
+ import { W as WebAuthnCaptureOptions, a as WebAuthnCaptureHandle, F as FederatedIdentityCaptureOptions, b as FederatedIdentityCaptureHandle, N as NetworkCaptureOptions, C as CaptureHandle, c as NavigationCaptureOptions } from './types-lamU1Fd3.mjs';
2
+ export { d as CredentialMediation, e as FederatedIdentityCompletedEvent, f as FederatedIdentityContext, g as FederatedIdentityEvent, h as FederatedIdentityFailedEvent, i as FederatedIdentityMode, j as FederatedIdentityProvider, k as FederatedIdentityStartedEvent, H as HttpExchange, l as HttpRequestStarted, L as Logger, m as NavigationEvent, n as NavigationSource, o as NetworkBodyDirection, p as NetworkBodyProjectionContext, q as NetworkBodyProjector, r as NetworkTransport, s as WebAuthnAttachSurface, t as WebAuthnCeremonyCompletedEvent, u as WebAuthnCeremonyContext, v as WebAuthnCeremonyEvent, w as WebAuthnCeremonyFailedEvent, x as WebAuthnCeremonyStartedEvent, y as WebAuthnMediation, z as WebAuthnUiMode } from './types-lamU1Fd3.mjs';
2
3
  export { WebAuthnIdentifierProjector, WebAuthnIdentifierProjectors, sanitizeAssertionResponse, sanitizeCreationOptions, sanitizeCreationResponse, sanitizeRequestOptions } from '@corbado/observe';
3
4
 
4
- /** Receives optional diagnostics. Capture functions remain silent when no logger is provided. */
5
- type Logger = {
6
- /** Records a non-fatal diagnostic message. */
7
- log: (...args: unknown[]) => void;
8
- };
9
- /** Controls a capture session. */
10
- type CaptureHandle = {
11
- /**
12
- * Result of starting the capture.
13
- *
14
- * - `"standard"`: capture started normally.
15
- * - `"unavailable"`: capture could not be started and will not emit events.
16
- */
17
- readonly mode: "standard" | "unavailable";
18
- /** Stops future event delivery. Safe to call more than once. */
19
- disconnect(): void;
20
- };
21
- /** Normalized Credential Management mediation. Missing mediation defaults to `optional`. */
22
- type WebAuthnMediation = "silent" | "optional" | "conditional" | "required" | "unknown";
23
- /** Normalized Credential Management UI mode for authentication ceremonies. */
24
- type WebAuthnUiMode = "default" | "immediate" | "unknown";
25
- /** Browser-native facts that remain stable for one ceremony. */
26
- type WebAuthnCeremonyContext = {
27
- kind: "authentication";
28
- mediation: WebAuthnMediation;
29
- uiMode: WebAuthnUiMode;
30
- /** Whether the RP supplied a non-empty allow list or requested discoverable credentials. */
31
- credentialSet: "allowlisted" | "discoverable";
32
- } | {
33
- kind: "registration";
34
- mediation: WebAuthnMediation;
35
- };
36
- type WebAuthnCeremonyBase = WebAuthnCeremonyContext & {
37
- /** Identifier shared by all events belonging to the same ceremony. */
38
- ceremonyId: string;
39
- };
40
- type WebAuthnCeremonyStartedEvent = WebAuthnCeremonyBase & {
41
- phase: "started";
42
- /** Whether transient user activation was active when the ceremony started, when exposed by the browser. */
43
- userActivation?: boolean;
44
- /**
45
- * JSON-encoded authentication publicKey options. All fields are retained.
46
- * Binary values are base64url-encoded. Treat this value as sensitive telemetry.
47
- */
48
- requestOptionsJson?: string;
49
- /** Creation publicKey options with user.name and user.displayName removed. */
50
- creationOptionsJson?: string;
51
- };
52
- type WebAuthnCeremonyCompletedEvent = WebAuthnCeremonyBase & {
53
- phase: "completed";
54
- /** JSON-encoded credential after the centralized blacklist; present only when applicable and serializable. Treat this value as sensitive telemetry. */
55
- credentialJson?: string;
56
- /** A credential manager may complete even after the ceremony signal was aborted. */
57
- aborted?: true;
58
- };
59
- type WebAuthnCeremonyFailedEvent = WebAuthnCeremonyBase & {
60
- phase: "failed";
61
- /** Rejection value from the failed ceremony. This may contain application-specific data. */
62
- error: unknown;
63
- /** DOM exception name, or `UnknownError` when no name is available. */
64
- errorName: string;
65
- /** Present when the request signal was aborted before settlement. */
66
- aborted?: true;
67
- };
68
- /** A protocol-native lifecycle event for WebAuthn authentication or registration. */
69
- type WebAuthnCeremonyEvent = WebAuthnCeremonyStartedEvent | WebAuthnCeremonyCompletedEvent | WebAuthnCeremonyFailedEvent;
70
- /**
71
- * Surface WebAuthn capture may attach to.
72
- *
73
- * - `"methods"`: `credentials.get` / `credentials.create` only.
74
- * - `"container"`: additionally the `navigator.credentials` container, used when the methods are
75
- * held by another integration in a form that cannot be shared.
76
- */
77
- type WebAuthnAttachSurface = "methods" | "container";
78
- /** Options for {@link captureWebAuthn}. */
79
- type WebAuthnCaptureOptions = {
80
- /** Receives WebAuthn lifecycle events. Return values are not awaited. */
81
- onEvent: (event: WebAuthnCeremonyEvent) => void;
82
- /** Optional diagnostic logger. */
83
- logger?: Logger;
84
- /**
85
- * Synchronous SDK user identifier projection for creation user.id and response userHandle.
86
- * Missing callbacks preserve user IDs; callback errors omit them. Credential IDs stay unchanged.
87
- * Use the same projector in network fallback serializers.
88
- * Projection affects telemetry only; authentication arguments, results and errors stay unchanged.
89
- */
90
- identifierProjectors?: WebAuthnIdentifierProjectors;
91
- /**
92
- * Highest surface capture may attach to. Defaults to `"methods"`.
93
- *
94
- * With `"container"`, a capture that cannot patch the methods attaches to the
95
- * `navigator.credentials` container instead: reads of `get`/`create` are observed while the
96
- * integration holding them keeps handling the ceremony. The methods surface is always tried
97
- * first, so this changes nothing when it is available.
98
- */
99
- attach?: WebAuthnAttachSurface;
100
- };
101
- /**
102
- * Handle returned by {@link captureWebAuthn}.
103
- *
104
- * `surface` reports where the capture actually attached, which is not implied by `mode`: an
105
- * `attach: "container"` capture reports `mode: "standard"` from either surface.
106
- */
107
- type WebAuthnCaptureHandle = CaptureHandle & {
108
- /** Surface this capture attached to; `"none"` when `mode` is `"unavailable"`. */
109
- readonly surface: WebAuthnAttachSurface | "none";
110
- };
111
- /** Network API used for an observed exchange. */
112
- type NetworkTransport = "xhr" | "fetch";
113
- /** Direction of a projected body within an observed network exchange. */
114
- type NetworkBodyDirection = "request" | "response";
115
- /** A matched network request immediately after the platform accepted it. */
116
- type HttpRequestStarted<RequestBody = unknown> = {
117
- /** Identifier shared with the eventual {@link HttpExchange}. */
118
- requestId: string;
119
- /** Network API used for the request. */
120
- transport: NetworkTransport;
121
- /** Uppercase HTTP method. */
122
- method: string;
123
- /** Resolved absolute request input URL. */
124
- url: string;
125
- /** Pathname component of the request URL. */
126
- path: string;
127
- /** Timestamp captured at the request boundary. */
128
- startedAt: number;
129
- /** Request-body value returned by the configured projector, when synchronously available. */
130
- requestBody?: RequestBody;
131
- };
132
- /** An observed network request and its outcome. */
133
- type HttpExchange<RequestBody = unknown, ResponseBody = unknown> = {
134
- /** Identifier shared with the corresponding {@link HttpRequestStarted}. */
135
- requestId: string;
136
- /** Network API used for the request. */
137
- transport: NetworkTransport;
138
- /** Uppercase HTTP method. */
139
- method: string;
140
- /**
141
- * Resolved absolute request input URL, including its query string and
142
- * fragment. Redact it before forwarding if either component may be sensitive.
143
- */
144
- url: string;
145
- /** Pathname component of the request URL. */
146
- path: string;
147
- /** HTTP status code, or `0` when a status is unavailable. */
148
- status: number;
149
- /** Whether the status code represents a successful response. */
150
- ok: boolean;
151
- /**
152
- * How the request completed. `load` includes successful and non-successful
153
- * HTTP responses; inspect `ok` or `status` for HTTP success.
154
- */
155
- outcome: "load" | "abort" | "timeout" | "error";
156
- /** Elapsed request time in milliseconds, when available. */
157
- durationMs?: number;
158
- /**
159
- * Final absolute response URL, when available. This may differ from `url`
160
- * after redirects and may contain sensitive query or fragment values.
161
- */
162
- responseUrl?: string;
163
- /** Request-body value returned by the configured projector, when available. */
164
- requestBody?: RequestBody;
165
- /** Response-body value returned by the configured projector, when available. */
166
- responseBody?: ResponseBody;
167
- };
168
- /** Metadata supplied to a body projector for one matched exchange. */
169
- type NetworkBodyProjectionContext<Direction extends NetworkBodyDirection = NetworkBodyDirection> = {
170
- /** Whether the observed body belongs to the request or response. */
171
- direction: Direction;
172
- /** Network API used by the application. */
173
- transport: NetworkTransport;
174
- /** Uppercase HTTP method. */
175
- method: string;
176
- /** Resolved absolute request URL. */
177
- url: string;
178
- /** Pathname component of the request URL. */
179
- path: string;
180
- };
181
- /**
182
- * Synchronously selects the only body data that may leave network capture.
183
- * Textual bodies are supplied as strings; an XHR with `responseType="json"`
184
- * supplies the browser-parsed value. Returning `undefined`, throwing, or
185
- * returning a Promise omits the body without affecting the application.
186
- * `ProjectedBody` describes the exact value delivered to callbacks.
187
- */
188
- type NetworkBodyProjector<ProjectedBody = unknown, Direction extends NetworkBodyDirection = NetworkBodyDirection> = (body: unknown, context: NetworkBodyProjectionContext<Direction>) => ProjectedBody | undefined;
189
- /**
190
- * Options for {@link captureNetwork}. Request and response body types are
191
- * inferred from their projectors and propagated to the corresponding callbacks.
192
- */
193
- type NetworkCaptureOptions<RequestBody = unknown, ResponseBody = unknown> = {
194
- /**
195
- * Selects requests to observe. The URL is resolved against the document base
196
- * URL and the method is uppercase. Return `true` to observe the request.
197
- * This callback must return synchronously; Promise results are not matched.
198
- */
199
- match: (url: URL, method: string) => boolean;
200
- /** Receives completed network exchanges. Return values are not awaited. */
201
- onExchange: (exchange: HttpExchange<NoInfer<RequestBody>, NoInfer<ResponseBody>>) => void;
202
- /**
203
- * Receives matched requests after the platform call succeeds. The request ID
204
- * matches the eventual exchange. Return values are not awaited.
205
- */
206
- onRequest?: (request: HttpRequestStarted<NoInfer<RequestBody>>) => void;
207
- /**
208
- * Network APIs to observe. Defaults to both `xhr` and `fetch`. Unavailable
209
- * transports are skipped if at least one requested transport can be observed.
210
- */
211
- transports?: readonly NetworkTransport[];
212
- /**
213
- * Best-effort body observation, enabled independently per direction by a
214
- * mandatory projector. Without a projector, that direction is never read.
215
- * Autocapture performs no generic parsing or redaction: the projector owns
216
- * data minimization and its return value is the only body data reported.
217
- */
218
- bodyCapture?: {
219
- /** Projects a request body. */
220
- request?: NetworkBodyProjector<RequestBody, "request">;
221
- /** Projects a response body. */
222
- response?: NetworkBodyProjector<ResponseBody, "response">;
223
- };
224
- /** Optional diagnostic logger. */
225
- logger?: Logger;
226
- };
227
- /** Mechanism that produced a navigation event. */
228
- type NavigationSource = "push" | "replace" | "pop" | "hash";
229
- /** A same-document navigation. */
230
- type NavigationEvent = {
231
- /** Current URL pathname. */
232
- path: string;
233
- /** Current URL query string, including the leading `?` when present. May contain sensitive data. */
234
- search: string;
235
- /** Current URL fragment, including the leading `#` when present. May contain sensitive data. */
236
- hash: string;
237
- /** Mechanism that produced the event. */
238
- source: NavigationSource;
239
- };
240
- /** Options for {@link captureNavigation}. */
241
- type NavigationCaptureOptions = {
242
- /** Receives same-document navigation events. Return values are not awaited. */
243
- onNavigate: (event: NavigationEvent) => void;
244
- /** Optional diagnostic logger. */
245
- logger?: Logger;
246
- };
247
-
248
5
  /**
249
6
  * Observes WebAuthn ceremonies initiated through
250
7
  * `navigator.credentials.get()` and `navigator.credentials.create()`.
@@ -259,7 +16,8 @@ type NavigationCaptureOptions = {
259
16
  * current environment — the API is missing, a capture is already active, or
260
17
  * another integration holds the credential methods in a form that cannot be
261
18
  * shared — nothing is modified and the returned handle reports
262
- * `mode: "unavailable"`.
19
+ * `mode: "unavailable"`. {@link captureFederatedIdentity} shares the same
20
+ * attachment; either capture can run and stop independently.
263
21
  *
264
22
  * Assumptions and limitations:
265
23
  *
@@ -281,6 +39,28 @@ type NavigationCaptureOptions = {
281
39
  */
282
40
  declare function captureWebAuthn(options: WebAuthnCaptureOptions): WebAuthnCaptureHandle;
283
41
 
42
+ /**
43
+ * Observes FedCM requests made through `navigator.credentials.get({ identity })`, such as Google
44
+ * One Tap on Chromium.
45
+ *
46
+ * Each request emits a `started` event followed by a correlated `completed` (an account was
47
+ * chosen) or `failed` event. Calls without `identity` options are not reported. Tokens, nonces,
48
+ * provider parameters and login hints are never read into events. Observation never changes a
49
+ * request's arguments, result, or error; the request is delegated synchronously before anything is
50
+ * observed, so user activation reaches the browser unchanged.
51
+ *
52
+ * Shares one attachment to `navigator.credentials` with {@link captureWebAuthn}; either capture can
53
+ * start first and stop independently, and a later one joins at whatever surface the first attached
54
+ * to. `attach` applies only when this capture attaches first, as in {@link captureWebAuthn}. The
55
+ * handle reports `mode: "unavailable"` when the credential methods cannot be observed or a federated
56
+ * identity capture is already active.
57
+ *
58
+ * @param options Event callback and optional diagnostic logger.
59
+ * @returns A handle used to inspect the capture mode or stop event delivery.
60
+ * @throws TypeError when `onEvent` is not a function.
61
+ */
62
+ declare function captureFederatedIdentity(options: FederatedIdentityCaptureOptions): FederatedIdentityCaptureHandle;
63
+
284
64
  /**
285
65
  * Observes selected requests made through `XMLHttpRequest` and `fetch`.
286
66
  *
@@ -377,4 +157,4 @@ declare function isValidationMessageVisible(element: Element | null): boolean;
377
157
  */
378
158
  declare function captureInputValidation(options: InputValidationCaptureOptions): InputValidationCaptureHandle;
379
159
 
380
- export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type InputValidationCaptureHandle, type InputValidationCaptureOptions, type InputValidationError, type InputValidationState, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, VERSION, type WebAuthnAttachSurface, type WebAuthnCaptureHandle, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureInputValidation, captureNavigation, captureNetwork, captureWebAuthn, composedPath, inputValidationCode, isValidationMessageVisible };
160
+ export { CaptureHandle, FederatedIdentityCaptureHandle, FederatedIdentityCaptureOptions, type InputValidationCaptureHandle, type InputValidationCaptureOptions, type InputValidationError, type InputValidationState, NavigationCaptureOptions, NetworkCaptureOptions, VERSION, WebAuthnCaptureHandle, WebAuthnCaptureOptions, captureFederatedIdentity, captureInputValidation, captureNavigation, captureNetwork, captureWebAuthn, composedPath, inputValidationCode, isValidationMessageVisible };