@corbado/observe 1.14.1 → 1.15.1
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/CHANGELOG.md +37 -0
- package/dist/analysis/config.mjs +20 -1
- package/dist/analysis/device.mjs +4 -2
- package/dist/analysis/index.mjs +11 -0
- package/dist/analysis/plugins/device-handle-max-age.mjs +8 -0
- package/dist/analysis/queue.mjs +3 -28
- package/dist/analysis/readers/page.mjs +4 -1
- package/dist/analysis/store/event-store.mjs +24 -1
- package/dist/analysis/tracker-core.mjs +30 -19
- package/dist/analysis/utils/email-link-continuity.mjs +6 -1
- package/dist/analysis/utils/source-path.mjs +23 -1
- package/dist/analysis/utils/webauthn-ceremony.mjs +279 -0
- package/dist/analysis/utils/webauthn-payloads.mjs +11 -5
- package/dist/analysis/version.mjs +1 -1
- package/dist/cdn/script.global.js +2 -2
- package/dist/index.d.mts +85 -23
- package/dist/index.d.ts +85 -23
- package/dist/index.js +4 -4
- package/dist/index.mjs +4 -4
- package/dist/manifest/index.d.mts +309 -0
- package/dist/manifest/index.d.ts +309 -0
- package/dist/manifest/index.js +787 -0
- package/dist/manifest/index.mjs +740 -0
- package/manifest/package.json +8 -0
- package/package.json +4 -2
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection manifest v2 (`corbado.collection/v2`): the descriptor contract shared by the SDK, the autocapture
|
|
3
|
+
* library and the autocapture tools, plus the shared vocabulary (collection levels, categories, kinds).
|
|
4
|
+
*
|
|
5
|
+
* Descriptors are DATA for the tools (`ac manifest`, the gate) and are never part of a shipped bundle: runtime
|
|
6
|
+
* code never imports `src/manifest/**` (checked by `manifest.test.ts` and `scripts/check-data-guards.mjs`).
|
|
7
|
+
* Import them from the `@corbado/observe/manifest` subpath (Node ESM: `@corbado/observe/dist/manifest/index.mjs`).
|
|
8
|
+
*
|
|
9
|
+
* Model: feature-docs/autocapture-releases/manifest-model-v1.html (v1.3), sections 0, 0b, 2, 3, 6.
|
|
10
|
+
*
|
|
11
|
+
* Changes to the shapes below are additive only (the tools of older and newer packages read them).
|
|
12
|
+
*/
|
|
13
|
+
/** Non-value collection levels: they reveal nothing about the content. */
|
|
14
|
+
type NonValueLevel = "presence" | "empty" | "interaction" | "shown" | "request-metadata" | "ceremony" | "equality";
|
|
15
|
+
/** Value collection levels: derived from the value, they reveal something about it. */
|
|
16
|
+
type ValueLevel = "size" | "class" | "enum" | "pseudonym" | "partial" | "pattern" | "raw";
|
|
17
|
+
/** One collection level per field (JSON key `level`). `generated` is not a level: generated ids are an output. */
|
|
18
|
+
type CollectionLevel = NonValueLevel | ValueLevel;
|
|
19
|
+
/** Non-value levels (order within a kind's ladder: see {@link KIND_LADDERS}). */
|
|
20
|
+
declare const NON_VALUE_LEVELS: readonly NonValueLevel[];
|
|
21
|
+
/** Value levels ordered by what a reader learns about the content (section 2, "The order of value levels"). */
|
|
22
|
+
declare const VALUE_LEVELS: readonly ValueLevel[];
|
|
23
|
+
/** What a field is about (the subject), never derived from its level. */
|
|
24
|
+
type Category = "secret" | "personal-identifier" | "opaque-identifier" | "personal-data" | "device" | "technical";
|
|
25
|
+
declare const CATEGORIES: readonly Category[];
|
|
26
|
+
/**
|
|
27
|
+
* Allowed VALUE levels per category (section 3). Non-value levels (and `equality`) are allowed for every category.
|
|
28
|
+
* `personal-identifier` pseudonyms must be keyed or project-salted; `personal-data` patterns closed or structural.
|
|
29
|
+
*/
|
|
30
|
+
declare const CATEGORY_VALUE_LEVELS: {
|
|
31
|
+
readonly [C in Category]: readonly ValueLevel[];
|
|
32
|
+
};
|
|
33
|
+
/** Source kinds (section 1). */
|
|
34
|
+
type SourceKind = "dom-input" | "dom-element" | "url" | "request" | "storage" | "host-config" | "host-event" | "browser-api" | "page/window" | "generated"
|
|
35
|
+
/** Additive (WP3 follow-up): fields the SDK itself adds to every record it sends (ordering counters). */
|
|
36
|
+
| "record";
|
|
37
|
+
/**
|
|
38
|
+
* One ladder per kind (section 2): non-value levels below value levels, each in its order. `equality` is allowed on
|
|
39
|
+
* every kind with values and is not listed per ladder.
|
|
40
|
+
*/
|
|
41
|
+
declare const KIND_LADDERS: {
|
|
42
|
+
readonly [K in Exclude<SourceKind, "generated">]: {
|
|
43
|
+
readonly nonValue: readonly NonValueLevel[];
|
|
44
|
+
readonly value: readonly ValueLevel[];
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
/** A field id `<source key>#<field path>`, a `generated:` / `storage:` / `telemetry:` / `transport:` id. */
|
|
48
|
+
type ManifestId = string;
|
|
49
|
+
/** A reviewed collector with an algorithm between browser object and output (section 0b, one card each). */
|
|
50
|
+
interface CapabilityDescriptor {
|
|
51
|
+
/** `sdk:input`, `ac:ceremony`, `sdk:window`, ... (rendered as `<key>@<version>`, referenced by fields' `via`). */
|
|
52
|
+
key: string;
|
|
53
|
+
version: number;
|
|
54
|
+
/** Plain customer language (section 0b). */
|
|
55
|
+
title: string;
|
|
56
|
+
why: string;
|
|
57
|
+
collects: string[];
|
|
58
|
+
/** `proof` = the id of a test in this repo (`<key>@<version>#never.<slug>`, part of the test's title). */
|
|
59
|
+
never: {
|
|
60
|
+
text: string;
|
|
61
|
+
proof: string;
|
|
62
|
+
}[];
|
|
63
|
+
modes?: Record<string, string>;
|
|
64
|
+
/** Named options a project declaration can set, e.g. `passkeyReference`. */
|
|
65
|
+
options?: {
|
|
66
|
+
name: string;
|
|
67
|
+
adds: string;
|
|
68
|
+
}[];
|
|
69
|
+
/** What the capability does on the page beyond reading; `when` = the build switch that enables it. */
|
|
70
|
+
sideEffects?: SideEffect[];
|
|
71
|
+
review?: string;
|
|
72
|
+
/** Additive (WP2): short plain-language line shown under the card, e.g. "used on: input fields". */
|
|
73
|
+
usedOn?: string;
|
|
74
|
+
/** Additive (WP2): the build switch that removes the whole capability from builds that turn it off. */
|
|
75
|
+
when?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Conditions shared by descriptor entries (all additive, all optional):
|
|
79
|
+
* - `when`: the build switch or config flag (static config / `build.config`) the entry depends on; `"!<name>"` = only
|
|
80
|
+
* when it is off (e.g. `"!static"`: only with a downloaded config).
|
|
81
|
+
* - `requires`: the never-ship item (id of the tools' never-ship list, e.g. `"cross-origin-session"`,
|
|
82
|
+
* `"sdk-operations"`) whose optional code produces the entry; omit the entry when that code is not in the bundle.
|
|
83
|
+
*/
|
|
84
|
+
interface Conditional {
|
|
85
|
+
when?: string;
|
|
86
|
+
requires?: string;
|
|
87
|
+
}
|
|
88
|
+
/** Something a capability does on the page beyond reading (shown in the overview's behavior list). */
|
|
89
|
+
interface SideEffect extends Conditional {
|
|
90
|
+
/** `<area>.<slug>`, stable across versions. Entries of several capabilities with the same id describe one effect. */
|
|
91
|
+
id: string;
|
|
92
|
+
text: string;
|
|
93
|
+
/** Build switch / config flag that enables it, e.g. `"aap"`, `"privateMode"`, `"pmd"`. */
|
|
94
|
+
when?: string;
|
|
95
|
+
}
|
|
96
|
+
/** Gateways without an algorithm and the output gateways (sections 4 and 6). */
|
|
97
|
+
interface GatewayDescriptor {
|
|
98
|
+
key: string;
|
|
99
|
+
version: number;
|
|
100
|
+
/** Always-collected fields. */
|
|
101
|
+
fields?: GatewayField[];
|
|
102
|
+
generated?: GeneratedEntry[];
|
|
103
|
+
stored?: StoredEntry[];
|
|
104
|
+
telemetry?: TelemetryEntry[];
|
|
105
|
+
/** Additive (WP1/WP2): the source the `fields` belong to; field ids are `<source.key>#<path>`. */
|
|
106
|
+
source?: {
|
|
107
|
+
key: string;
|
|
108
|
+
kind: SourceKind | string;
|
|
109
|
+
title?: string;
|
|
110
|
+
};
|
|
111
|
+
/** Additive (WP2): plain-language title of the gateway. */
|
|
112
|
+
title?: string;
|
|
113
|
+
/** Additive (WP2): transport facts (`transport:<fact>`), only on the transport gateway. */
|
|
114
|
+
transport?: TransportFact[];
|
|
115
|
+
}
|
|
116
|
+
interface GatewayField extends Conditional {
|
|
117
|
+
path: string;
|
|
118
|
+
/** A category, or `"role"`: inherit the category of the input role the field is read from. */
|
|
119
|
+
category: Category | "role" | string;
|
|
120
|
+
level: CollectionLevel | string;
|
|
121
|
+
label: string;
|
|
122
|
+
/** Additive (WP2): capability that produces the field, `<key>@<version>`. */
|
|
123
|
+
via?: string;
|
|
124
|
+
/** Additive (WP2): parameters of the level (enum values, pattern, template, buckets, ...). */
|
|
125
|
+
transform?: Record<string, unknown>;
|
|
126
|
+
/** Additive (WP2): synthetic examples fitting the level. */
|
|
127
|
+
examples?: (string | number | boolean)[];
|
|
128
|
+
/** Additive (WP2): build switch the field depends on (absent in builds that turn it off). */
|
|
129
|
+
when?: string;
|
|
130
|
+
/** Additive (WP1): what an opaque-identifier field points to (credential, browser, session, tab, flow). */
|
|
131
|
+
pointsTo?: string;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* A generated identifier (an output type, not a collection level).
|
|
135
|
+
* - `lifetime`: `"event"`, `"page-load"`, `"tab"`, `"persistent"` or an ISO 8601 duration (e.g. `"PT30M"` of
|
|
136
|
+
* inactivity).
|
|
137
|
+
* - `exposedTo`: who besides Corbado can see it, e.g. `"corbado"`, `"page scripts (getSessionId)"`,
|
|
138
|
+
* `"page scripts (local storage)"`.
|
|
139
|
+
*/
|
|
140
|
+
interface GeneratedEntry extends Conditional {
|
|
141
|
+
id: string;
|
|
142
|
+
category: Category | string;
|
|
143
|
+
pointsTo: string;
|
|
144
|
+
lifetime: string;
|
|
145
|
+
scope?: string;
|
|
146
|
+
exposedTo: string[];
|
|
147
|
+
/** Additive (WP2): plain-language label. */
|
|
148
|
+
label?: string;
|
|
149
|
+
/** Additive (WP2): build switch / config flag the entry depends on. */
|
|
150
|
+
when?: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Something the bundle writes to the browser.
|
|
154
|
+
* - `area`: `"local"`, `"session"`, `"cookie"`, `"indexeddb"`, `"opfs"`, `"web-locks"`, ...
|
|
155
|
+
* - `scope`: `"tab"`, `"origin"`, `"cookie domain + path"`.
|
|
156
|
+
* - `retention`: an ISO 8601 duration (enforced by code), `"tab"` (sessionStorage), `"PT0S"` (removed at once) or
|
|
157
|
+
* `"persistent"`.
|
|
158
|
+
* - `owner`: `"sdk"`, `"project"`, `"third-party (<package>)"`.
|
|
159
|
+
* - `contents`: field and generated ids (typed references); `"sent:events"` = the whole queued event as sent.
|
|
160
|
+
* - `when` (see {@link Conditional}): without `otherwise` the entry is absent when `when` does not hold; with
|
|
161
|
+
* `otherwise` the entry stays, merged with `otherwise` (e.g. a cache a build does not write but still removes).
|
|
162
|
+
*/
|
|
163
|
+
interface StoredEntry extends Conditional {
|
|
164
|
+
id: string;
|
|
165
|
+
area: string;
|
|
166
|
+
scope: string;
|
|
167
|
+
retention: string;
|
|
168
|
+
owner: string;
|
|
169
|
+
contents: string[];
|
|
170
|
+
/** Additive (WP2): the keys as written (`cbo_<name>_<projectId>`; `*` = the project id or a family). */
|
|
171
|
+
keys?: string[];
|
|
172
|
+
/** Additive (WP2): plain-language label. */
|
|
173
|
+
label?: string;
|
|
174
|
+
/** Additive (WP2): whether `retention` is enforced by code (purged), not only described. */
|
|
175
|
+
enforced?: boolean;
|
|
176
|
+
/** Additive (WP2): build switch / config flag the entry depends on. */
|
|
177
|
+
when?: string;
|
|
178
|
+
/**
|
|
179
|
+
* Additive (v2 descriptors): the bundle never writes the entry, it only removes it when found (keys of older
|
|
180
|
+
* versions). Such an entry keeps nothing (`contents` empty); its `retention` is `"PT0S"` for older tools.
|
|
181
|
+
*/
|
|
182
|
+
deleteOnly?: boolean;
|
|
183
|
+
/** Additive (v2 descriptors): a plain-language remark shown with the entry. */
|
|
184
|
+
note?: string;
|
|
185
|
+
/** Additive (v2 descriptors): what the entry becomes when its `when` does not hold (merged over the entry). */
|
|
186
|
+
otherwise?: StoredVariant;
|
|
187
|
+
}
|
|
188
|
+
/** Additive (v2 descriptors): the fields of a {@link StoredEntry} that its `otherwise` variant may replace. */
|
|
189
|
+
type StoredVariant = Partial<Pick<StoredEntry, "retention" | "enforced" | "contents" | "label" | "deleteOnly" | "note" | "keys">>;
|
|
190
|
+
interface TelemetryEntry {
|
|
191
|
+
kind: string;
|
|
192
|
+
fields: string[];
|
|
193
|
+
/** Additive (WP2): plain-language label. */
|
|
194
|
+
label?: string;
|
|
195
|
+
}
|
|
196
|
+
/** Additive (WP2): what the transport sends besides the events (`transport:<fact>`). */
|
|
197
|
+
interface TransportFact {
|
|
198
|
+
id: string;
|
|
199
|
+
label: string;
|
|
200
|
+
/** `"browser"` = added by the browser, not by the SDK. */
|
|
201
|
+
addedBy: "sdk" | "browser";
|
|
202
|
+
when?: string;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* `ac:ceremony@1` (SDK part): the WebAuthn allowlist (`src/utils/webauthn-ceremony.ts`), used by the sanitizers in
|
|
207
|
+
* builds that define `__CBO_DATA_CEREMONY__ = true` (build switch `ceremony`). The library's credentials wrapper and
|
|
208
|
+
* its endpoint reductions are the callers (second entry point: WebAuthn payloads in request and response bodies).
|
|
209
|
+
* The side effects are the library's (`@corbado/autocapture` `src/readers/credentials.ts`): it wraps the two methods;
|
|
210
|
+
* the container proxy is used only where the runtime's server config allows it (`aap` = `"c1"`) and the methods
|
|
211
|
+
* themselves cannot be wrapped.
|
|
212
|
+
*/
|
|
213
|
+
declare const AC_CEREMONY: CapabilityDescriptor;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Values the integration hands to the SDK's API that the SDK keeps in its own storage (referenced by
|
|
217
|
+
* `sdk:own-storage`). The full host contract (init options, page config) is gap G15 and follows with the library's
|
|
218
|
+
* host-config gateway.
|
|
219
|
+
*/
|
|
220
|
+
declare const SDK_API: GatewayDescriptor;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Device gateway (`src/readers/device.ts`, collected by `src/device.ts`): fixed readers, no capability. Sent once
|
|
224
|
+
* per page with the first events (device info), together with the generated device handle and tab id (see
|
|
225
|
+
* the generated-ids gateway).
|
|
226
|
+
*/
|
|
227
|
+
declare const SDK_DEVICE: GatewayDescriptor;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Generated-ids output gateway (`outputs.sent.generated`, gap G3). Rule (model 11e): technical if an id lives at most
|
|
231
|
+
* one tab or flow and never leaves the tab, otherwise opaque-identifier. Every id below is sent to Corbado, so all
|
|
232
|
+
* random ids are opaque-identifier. The sequence counters are not ids: they are technical fields of each record
|
|
233
|
+
* ({@link SDK_RECORD}).
|
|
234
|
+
*/
|
|
235
|
+
declare const SDK_GENERATED: GatewayDescriptor;
|
|
236
|
+
/**
|
|
237
|
+
* Fields the SDK adds to every record it sends (decided 2026-11-08: the sequence counters are a technical field of
|
|
238
|
+
* the event, not a generated id). Source kind `record`: nothing is read from the page.
|
|
239
|
+
*/
|
|
240
|
+
declare const SDK_RECORD: GatewayDescriptor;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Own-storage output gateway (`outputs.stored`, gap G2): every key the SDK writes. Keys are written as
|
|
244
|
+
* `cbo_<name>_<projectId>` (`*` below). `retention` is enforced by code where `enforced` is true: the outboxes and
|
|
245
|
+
* the email-link notes only in builds with `__CBO_DATA_RETENTION__` (build switch `retention`); without it the
|
|
246
|
+
* outboxes keep entries up to their caps (500 events, 1000 low events) and expired email-link notes stay until the
|
|
247
|
+
* next write. Contents reference field and generated ids; `sent:events` = whole queued records as they are sent.
|
|
248
|
+
*
|
|
249
|
+
* Not listed: the private-mode library's temporary test databases, test directory and `test` entry (removed at once,
|
|
250
|
+
* nothing kept on the device): a side effect of `sdk:private-mode@1`. Entries with `otherwise` stay in the manifest
|
|
251
|
+
* when their `when` does not hold, merged with the variant (contract `StoredEntry.otherwise`).
|
|
252
|
+
*/
|
|
253
|
+
declare const SDK_OWN_STORAGE: GatewayDescriptor;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Page gateway (`src/readers/page.ts`), declared as it behaves today: the page path is sent raw (no templates yet,
|
|
257
|
+
* gap G8) with every batch's first event; query keys stay, their values are masked unless the config allowlists the
|
|
258
|
+
* key (`sourcePathQuery` / `sourcePathQueryAllow`). Templates, declared query reductions and the navigation entry
|
|
259
|
+
* follow with the G8 change.
|
|
260
|
+
*/
|
|
261
|
+
declare const SDK_PAGE: GatewayDescriptor;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* `sdk:input@1`: the input gateway (`src/readers/input.ts`, `src/readers/input-paste.ts`, collectors in
|
|
265
|
+
* `src/low-events/`), declared as it behaves today (v1). Inside the gateway it reads the field's LENGTH (and a
|
|
266
|
+
* checkbox's checked state) to tell typing, pasting, clearing and several-characters-at-once changes apart; neither
|
|
267
|
+
* the value nor the length leaves it. A value-free v2 comes later (model section 13, "Later").
|
|
268
|
+
* Side effect: the library's input reader (`@corbado/autocapture` `onInput`, `src/readers/inputs.ts`) watches the
|
|
269
|
+
* document for added fields; `ac:element@1` lists the same effect (same id) for element roles.
|
|
270
|
+
*/
|
|
271
|
+
declare const SDK_INPUT: CapabilityDescriptor;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* `sdk:password-managers@1`: password-manager detection (`src/readers/password-manager-extensions.ts`, sampled by
|
|
275
|
+
* `src/utils/password-manager-sampler.ts`). Compiled out with `__CBO_DATA_PMD__ = false` (build switch `pmd`).
|
|
276
|
+
*/
|
|
277
|
+
declare const SDK_PASSWORD_MANAGERS: CapabilityDescriptor;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* `sdk:private-mode@1`: private-mode detection (`src/readers/private-mode.ts`, the third-party library
|
|
281
|
+
* detectincognitojs). Compiled out with `__CBO_DATA_PRIVATE_MODE__ = false` (build switch `privateMode`).
|
|
282
|
+
* The library's temporary test databases, test directory and `test` storage entry are only this side effect: they
|
|
283
|
+
* are removed at once, so `sdk:own-storage` does not list them (nothing is kept on the device).
|
|
284
|
+
*/
|
|
285
|
+
declare const SDK_PRIVATE_MODE: CapabilityDescriptor;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Transport output gateway (`src/transports/fetch.ts`, `src/readers/network.ts`): ingestion requests with fetch
|
|
289
|
+
* (keepalive, no credentials) and `sendBeacon` on page hide. Lists what leaves besides the events themselves.
|
|
290
|
+
*/
|
|
291
|
+
declare const SDK_TRANSPORT: GatewayDescriptor;
|
|
292
|
+
|
|
293
|
+
/** `sdk:window@1`: the window gateway (`src/readers/window-events.ts`, `src/low-events/shared-window-observer.ts`). */
|
|
294
|
+
declare const SDK_WINDOW: CapabilityDescriptor;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* `@corbado/observe/manifest`: collection manifest v2 descriptors of the SDK's gateways and capabilities, read by
|
|
298
|
+
* the autocapture tools from the package. Never imported by runtime code, so never part of a bundle.
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
/** Every capability descriptor of this package. */
|
|
302
|
+
declare const SDK_CAPABILITIES: readonly CapabilityDescriptor[];
|
|
303
|
+
/** Every gateway descriptor of this package. */
|
|
304
|
+
declare const SDK_GATEWAYS: readonly GatewayDescriptor[];
|
|
305
|
+
/** WP1 names: the same lists. */
|
|
306
|
+
declare const capabilities: CapabilityDescriptor[];
|
|
307
|
+
declare const gateways: GatewayDescriptor[];
|
|
308
|
+
|
|
309
|
+
export { AC_CEREMONY, CATEGORIES, CATEGORY_VALUE_LEVELS, type CapabilityDescriptor, type Category, type CollectionLevel, type Conditional, type GatewayDescriptor, type GatewayField, type GeneratedEntry, KIND_LADDERS, type ManifestId, NON_VALUE_LEVELS, type NonValueLevel, SDK_API, SDK_CAPABILITIES, SDK_DEVICE, SDK_GATEWAYS, SDK_GENERATED, SDK_INPUT, SDK_OWN_STORAGE, SDK_PAGE, SDK_PASSWORD_MANAGERS, SDK_PRIVATE_MODE, SDK_RECORD, SDK_TRANSPORT, SDK_WINDOW, type SideEffect, type SourceKind, type StoredEntry, type StoredVariant, type TelemetryEntry, type TransportFact, VALUE_LEVELS, type ValueLevel, capabilities, gateways };
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection manifest v2 (`corbado.collection/v2`): the descriptor contract shared by the SDK, the autocapture
|
|
3
|
+
* library and the autocapture tools, plus the shared vocabulary (collection levels, categories, kinds).
|
|
4
|
+
*
|
|
5
|
+
* Descriptors are DATA for the tools (`ac manifest`, the gate) and are never part of a shipped bundle: runtime
|
|
6
|
+
* code never imports `src/manifest/**` (checked by `manifest.test.ts` and `scripts/check-data-guards.mjs`).
|
|
7
|
+
* Import them from the `@corbado/observe/manifest` subpath (Node ESM: `@corbado/observe/dist/manifest/index.mjs`).
|
|
8
|
+
*
|
|
9
|
+
* Model: feature-docs/autocapture-releases/manifest-model-v1.html (v1.3), sections 0, 0b, 2, 3, 6.
|
|
10
|
+
*
|
|
11
|
+
* Changes to the shapes below are additive only (the tools of older and newer packages read them).
|
|
12
|
+
*/
|
|
13
|
+
/** Non-value collection levels: they reveal nothing about the content. */
|
|
14
|
+
type NonValueLevel = "presence" | "empty" | "interaction" | "shown" | "request-metadata" | "ceremony" | "equality";
|
|
15
|
+
/** Value collection levels: derived from the value, they reveal something about it. */
|
|
16
|
+
type ValueLevel = "size" | "class" | "enum" | "pseudonym" | "partial" | "pattern" | "raw";
|
|
17
|
+
/** One collection level per field (JSON key `level`). `generated` is not a level: generated ids are an output. */
|
|
18
|
+
type CollectionLevel = NonValueLevel | ValueLevel;
|
|
19
|
+
/** Non-value levels (order within a kind's ladder: see {@link KIND_LADDERS}). */
|
|
20
|
+
declare const NON_VALUE_LEVELS: readonly NonValueLevel[];
|
|
21
|
+
/** Value levels ordered by what a reader learns about the content (section 2, "The order of value levels"). */
|
|
22
|
+
declare const VALUE_LEVELS: readonly ValueLevel[];
|
|
23
|
+
/** What a field is about (the subject), never derived from its level. */
|
|
24
|
+
type Category = "secret" | "personal-identifier" | "opaque-identifier" | "personal-data" | "device" | "technical";
|
|
25
|
+
declare const CATEGORIES: readonly Category[];
|
|
26
|
+
/**
|
|
27
|
+
* Allowed VALUE levels per category (section 3). Non-value levels (and `equality`) are allowed for every category.
|
|
28
|
+
* `personal-identifier` pseudonyms must be keyed or project-salted; `personal-data` patterns closed or structural.
|
|
29
|
+
*/
|
|
30
|
+
declare const CATEGORY_VALUE_LEVELS: {
|
|
31
|
+
readonly [C in Category]: readonly ValueLevel[];
|
|
32
|
+
};
|
|
33
|
+
/** Source kinds (section 1). */
|
|
34
|
+
type SourceKind = "dom-input" | "dom-element" | "url" | "request" | "storage" | "host-config" | "host-event" | "browser-api" | "page/window" | "generated"
|
|
35
|
+
/** Additive (WP3 follow-up): fields the SDK itself adds to every record it sends (ordering counters). */
|
|
36
|
+
| "record";
|
|
37
|
+
/**
|
|
38
|
+
* One ladder per kind (section 2): non-value levels below value levels, each in its order. `equality` is allowed on
|
|
39
|
+
* every kind with values and is not listed per ladder.
|
|
40
|
+
*/
|
|
41
|
+
declare const KIND_LADDERS: {
|
|
42
|
+
readonly [K in Exclude<SourceKind, "generated">]: {
|
|
43
|
+
readonly nonValue: readonly NonValueLevel[];
|
|
44
|
+
readonly value: readonly ValueLevel[];
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
/** A field id `<source key>#<field path>`, a `generated:` / `storage:` / `telemetry:` / `transport:` id. */
|
|
48
|
+
type ManifestId = string;
|
|
49
|
+
/** A reviewed collector with an algorithm between browser object and output (section 0b, one card each). */
|
|
50
|
+
interface CapabilityDescriptor {
|
|
51
|
+
/** `sdk:input`, `ac:ceremony`, `sdk:window`, ... (rendered as `<key>@<version>`, referenced by fields' `via`). */
|
|
52
|
+
key: string;
|
|
53
|
+
version: number;
|
|
54
|
+
/** Plain customer language (section 0b). */
|
|
55
|
+
title: string;
|
|
56
|
+
why: string;
|
|
57
|
+
collects: string[];
|
|
58
|
+
/** `proof` = the id of a test in this repo (`<key>@<version>#never.<slug>`, part of the test's title). */
|
|
59
|
+
never: {
|
|
60
|
+
text: string;
|
|
61
|
+
proof: string;
|
|
62
|
+
}[];
|
|
63
|
+
modes?: Record<string, string>;
|
|
64
|
+
/** Named options a project declaration can set, e.g. `passkeyReference`. */
|
|
65
|
+
options?: {
|
|
66
|
+
name: string;
|
|
67
|
+
adds: string;
|
|
68
|
+
}[];
|
|
69
|
+
/** What the capability does on the page beyond reading; `when` = the build switch that enables it. */
|
|
70
|
+
sideEffects?: SideEffect[];
|
|
71
|
+
review?: string;
|
|
72
|
+
/** Additive (WP2): short plain-language line shown under the card, e.g. "used on: input fields". */
|
|
73
|
+
usedOn?: string;
|
|
74
|
+
/** Additive (WP2): the build switch that removes the whole capability from builds that turn it off. */
|
|
75
|
+
when?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Conditions shared by descriptor entries (all additive, all optional):
|
|
79
|
+
* - `when`: the build switch or config flag (static config / `build.config`) the entry depends on; `"!<name>"` = only
|
|
80
|
+
* when it is off (e.g. `"!static"`: only with a downloaded config).
|
|
81
|
+
* - `requires`: the never-ship item (id of the tools' never-ship list, e.g. `"cross-origin-session"`,
|
|
82
|
+
* `"sdk-operations"`) whose optional code produces the entry; omit the entry when that code is not in the bundle.
|
|
83
|
+
*/
|
|
84
|
+
interface Conditional {
|
|
85
|
+
when?: string;
|
|
86
|
+
requires?: string;
|
|
87
|
+
}
|
|
88
|
+
/** Something a capability does on the page beyond reading (shown in the overview's behavior list). */
|
|
89
|
+
interface SideEffect extends Conditional {
|
|
90
|
+
/** `<area>.<slug>`, stable across versions. Entries of several capabilities with the same id describe one effect. */
|
|
91
|
+
id: string;
|
|
92
|
+
text: string;
|
|
93
|
+
/** Build switch / config flag that enables it, e.g. `"aap"`, `"privateMode"`, `"pmd"`. */
|
|
94
|
+
when?: string;
|
|
95
|
+
}
|
|
96
|
+
/** Gateways without an algorithm and the output gateways (sections 4 and 6). */
|
|
97
|
+
interface GatewayDescriptor {
|
|
98
|
+
key: string;
|
|
99
|
+
version: number;
|
|
100
|
+
/** Always-collected fields. */
|
|
101
|
+
fields?: GatewayField[];
|
|
102
|
+
generated?: GeneratedEntry[];
|
|
103
|
+
stored?: StoredEntry[];
|
|
104
|
+
telemetry?: TelemetryEntry[];
|
|
105
|
+
/** Additive (WP1/WP2): the source the `fields` belong to; field ids are `<source.key>#<path>`. */
|
|
106
|
+
source?: {
|
|
107
|
+
key: string;
|
|
108
|
+
kind: SourceKind | string;
|
|
109
|
+
title?: string;
|
|
110
|
+
};
|
|
111
|
+
/** Additive (WP2): plain-language title of the gateway. */
|
|
112
|
+
title?: string;
|
|
113
|
+
/** Additive (WP2): transport facts (`transport:<fact>`), only on the transport gateway. */
|
|
114
|
+
transport?: TransportFact[];
|
|
115
|
+
}
|
|
116
|
+
interface GatewayField extends Conditional {
|
|
117
|
+
path: string;
|
|
118
|
+
/** A category, or `"role"`: inherit the category of the input role the field is read from. */
|
|
119
|
+
category: Category | "role" | string;
|
|
120
|
+
level: CollectionLevel | string;
|
|
121
|
+
label: string;
|
|
122
|
+
/** Additive (WP2): capability that produces the field, `<key>@<version>`. */
|
|
123
|
+
via?: string;
|
|
124
|
+
/** Additive (WP2): parameters of the level (enum values, pattern, template, buckets, ...). */
|
|
125
|
+
transform?: Record<string, unknown>;
|
|
126
|
+
/** Additive (WP2): synthetic examples fitting the level. */
|
|
127
|
+
examples?: (string | number | boolean)[];
|
|
128
|
+
/** Additive (WP2): build switch the field depends on (absent in builds that turn it off). */
|
|
129
|
+
when?: string;
|
|
130
|
+
/** Additive (WP1): what an opaque-identifier field points to (credential, browser, session, tab, flow). */
|
|
131
|
+
pointsTo?: string;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* A generated identifier (an output type, not a collection level).
|
|
135
|
+
* - `lifetime`: `"event"`, `"page-load"`, `"tab"`, `"persistent"` or an ISO 8601 duration (e.g. `"PT30M"` of
|
|
136
|
+
* inactivity).
|
|
137
|
+
* - `exposedTo`: who besides Corbado can see it, e.g. `"corbado"`, `"page scripts (getSessionId)"`,
|
|
138
|
+
* `"page scripts (local storage)"`.
|
|
139
|
+
*/
|
|
140
|
+
interface GeneratedEntry extends Conditional {
|
|
141
|
+
id: string;
|
|
142
|
+
category: Category | string;
|
|
143
|
+
pointsTo: string;
|
|
144
|
+
lifetime: string;
|
|
145
|
+
scope?: string;
|
|
146
|
+
exposedTo: string[];
|
|
147
|
+
/** Additive (WP2): plain-language label. */
|
|
148
|
+
label?: string;
|
|
149
|
+
/** Additive (WP2): build switch / config flag the entry depends on. */
|
|
150
|
+
when?: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Something the bundle writes to the browser.
|
|
154
|
+
* - `area`: `"local"`, `"session"`, `"cookie"`, `"indexeddb"`, `"opfs"`, `"web-locks"`, ...
|
|
155
|
+
* - `scope`: `"tab"`, `"origin"`, `"cookie domain + path"`.
|
|
156
|
+
* - `retention`: an ISO 8601 duration (enforced by code), `"tab"` (sessionStorage), `"PT0S"` (removed at once) or
|
|
157
|
+
* `"persistent"`.
|
|
158
|
+
* - `owner`: `"sdk"`, `"project"`, `"third-party (<package>)"`.
|
|
159
|
+
* - `contents`: field and generated ids (typed references); `"sent:events"` = the whole queued event as sent.
|
|
160
|
+
* - `when` (see {@link Conditional}): without `otherwise` the entry is absent when `when` does not hold; with
|
|
161
|
+
* `otherwise` the entry stays, merged with `otherwise` (e.g. a cache a build does not write but still removes).
|
|
162
|
+
*/
|
|
163
|
+
interface StoredEntry extends Conditional {
|
|
164
|
+
id: string;
|
|
165
|
+
area: string;
|
|
166
|
+
scope: string;
|
|
167
|
+
retention: string;
|
|
168
|
+
owner: string;
|
|
169
|
+
contents: string[];
|
|
170
|
+
/** Additive (WP2): the keys as written (`cbo_<name>_<projectId>`; `*` = the project id or a family). */
|
|
171
|
+
keys?: string[];
|
|
172
|
+
/** Additive (WP2): plain-language label. */
|
|
173
|
+
label?: string;
|
|
174
|
+
/** Additive (WP2): whether `retention` is enforced by code (purged), not only described. */
|
|
175
|
+
enforced?: boolean;
|
|
176
|
+
/** Additive (WP2): build switch / config flag the entry depends on. */
|
|
177
|
+
when?: string;
|
|
178
|
+
/**
|
|
179
|
+
* Additive (v2 descriptors): the bundle never writes the entry, it only removes it when found (keys of older
|
|
180
|
+
* versions). Such an entry keeps nothing (`contents` empty); its `retention` is `"PT0S"` for older tools.
|
|
181
|
+
*/
|
|
182
|
+
deleteOnly?: boolean;
|
|
183
|
+
/** Additive (v2 descriptors): a plain-language remark shown with the entry. */
|
|
184
|
+
note?: string;
|
|
185
|
+
/** Additive (v2 descriptors): what the entry becomes when its `when` does not hold (merged over the entry). */
|
|
186
|
+
otherwise?: StoredVariant;
|
|
187
|
+
}
|
|
188
|
+
/** Additive (v2 descriptors): the fields of a {@link StoredEntry} that its `otherwise` variant may replace. */
|
|
189
|
+
type StoredVariant = Partial<Pick<StoredEntry, "retention" | "enforced" | "contents" | "label" | "deleteOnly" | "note" | "keys">>;
|
|
190
|
+
interface TelemetryEntry {
|
|
191
|
+
kind: string;
|
|
192
|
+
fields: string[];
|
|
193
|
+
/** Additive (WP2): plain-language label. */
|
|
194
|
+
label?: string;
|
|
195
|
+
}
|
|
196
|
+
/** Additive (WP2): what the transport sends besides the events (`transport:<fact>`). */
|
|
197
|
+
interface TransportFact {
|
|
198
|
+
id: string;
|
|
199
|
+
label: string;
|
|
200
|
+
/** `"browser"` = added by the browser, not by the SDK. */
|
|
201
|
+
addedBy: "sdk" | "browser";
|
|
202
|
+
when?: string;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* `ac:ceremony@1` (SDK part): the WebAuthn allowlist (`src/utils/webauthn-ceremony.ts`), used by the sanitizers in
|
|
207
|
+
* builds that define `__CBO_DATA_CEREMONY__ = true` (build switch `ceremony`). The library's credentials wrapper and
|
|
208
|
+
* its endpoint reductions are the callers (second entry point: WebAuthn payloads in request and response bodies).
|
|
209
|
+
* The side effects are the library's (`@corbado/autocapture` `src/readers/credentials.ts`): it wraps the two methods;
|
|
210
|
+
* the container proxy is used only where the runtime's server config allows it (`aap` = `"c1"`) and the methods
|
|
211
|
+
* themselves cannot be wrapped.
|
|
212
|
+
*/
|
|
213
|
+
declare const AC_CEREMONY: CapabilityDescriptor;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Values the integration hands to the SDK's API that the SDK keeps in its own storage (referenced by
|
|
217
|
+
* `sdk:own-storage`). The full host contract (init options, page config) is gap G15 and follows with the library's
|
|
218
|
+
* host-config gateway.
|
|
219
|
+
*/
|
|
220
|
+
declare const SDK_API: GatewayDescriptor;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Device gateway (`src/readers/device.ts`, collected by `src/device.ts`): fixed readers, no capability. Sent once
|
|
224
|
+
* per page with the first events (device info), together with the generated device handle and tab id (see
|
|
225
|
+
* the generated-ids gateway).
|
|
226
|
+
*/
|
|
227
|
+
declare const SDK_DEVICE: GatewayDescriptor;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Generated-ids output gateway (`outputs.sent.generated`, gap G3). Rule (model 11e): technical if an id lives at most
|
|
231
|
+
* one tab or flow and never leaves the tab, otherwise opaque-identifier. Every id below is sent to Corbado, so all
|
|
232
|
+
* random ids are opaque-identifier. The sequence counters are not ids: they are technical fields of each record
|
|
233
|
+
* ({@link SDK_RECORD}).
|
|
234
|
+
*/
|
|
235
|
+
declare const SDK_GENERATED: GatewayDescriptor;
|
|
236
|
+
/**
|
|
237
|
+
* Fields the SDK adds to every record it sends (decided 2026-11-08: the sequence counters are a technical field of
|
|
238
|
+
* the event, not a generated id). Source kind `record`: nothing is read from the page.
|
|
239
|
+
*/
|
|
240
|
+
declare const SDK_RECORD: GatewayDescriptor;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Own-storage output gateway (`outputs.stored`, gap G2): every key the SDK writes. Keys are written as
|
|
244
|
+
* `cbo_<name>_<projectId>` (`*` below). `retention` is enforced by code where `enforced` is true: the outboxes and
|
|
245
|
+
* the email-link notes only in builds with `__CBO_DATA_RETENTION__` (build switch `retention`); without it the
|
|
246
|
+
* outboxes keep entries up to their caps (500 events, 1000 low events) and expired email-link notes stay until the
|
|
247
|
+
* next write. Contents reference field and generated ids; `sent:events` = whole queued records as they are sent.
|
|
248
|
+
*
|
|
249
|
+
* Not listed: the private-mode library's temporary test databases, test directory and `test` entry (removed at once,
|
|
250
|
+
* nothing kept on the device): a side effect of `sdk:private-mode@1`. Entries with `otherwise` stay in the manifest
|
|
251
|
+
* when their `when` does not hold, merged with the variant (contract `StoredEntry.otherwise`).
|
|
252
|
+
*/
|
|
253
|
+
declare const SDK_OWN_STORAGE: GatewayDescriptor;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Page gateway (`src/readers/page.ts`), declared as it behaves today: the page path is sent raw (no templates yet,
|
|
257
|
+
* gap G8) with every batch's first event; query keys stay, their values are masked unless the config allowlists the
|
|
258
|
+
* key (`sourcePathQuery` / `sourcePathQueryAllow`). Templates, declared query reductions and the navigation entry
|
|
259
|
+
* follow with the G8 change.
|
|
260
|
+
*/
|
|
261
|
+
declare const SDK_PAGE: GatewayDescriptor;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* `sdk:input@1`: the input gateway (`src/readers/input.ts`, `src/readers/input-paste.ts`, collectors in
|
|
265
|
+
* `src/low-events/`), declared as it behaves today (v1). Inside the gateway it reads the field's LENGTH (and a
|
|
266
|
+
* checkbox's checked state) to tell typing, pasting, clearing and several-characters-at-once changes apart; neither
|
|
267
|
+
* the value nor the length leaves it. A value-free v2 comes later (model section 13, "Later").
|
|
268
|
+
* Side effect: the library's input reader (`@corbado/autocapture` `onInput`, `src/readers/inputs.ts`) watches the
|
|
269
|
+
* document for added fields; `ac:element@1` lists the same effect (same id) for element roles.
|
|
270
|
+
*/
|
|
271
|
+
declare const SDK_INPUT: CapabilityDescriptor;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* `sdk:password-managers@1`: password-manager detection (`src/readers/password-manager-extensions.ts`, sampled by
|
|
275
|
+
* `src/utils/password-manager-sampler.ts`). Compiled out with `__CBO_DATA_PMD__ = false` (build switch `pmd`).
|
|
276
|
+
*/
|
|
277
|
+
declare const SDK_PASSWORD_MANAGERS: CapabilityDescriptor;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* `sdk:private-mode@1`: private-mode detection (`src/readers/private-mode.ts`, the third-party library
|
|
281
|
+
* detectincognitojs). Compiled out with `__CBO_DATA_PRIVATE_MODE__ = false` (build switch `privateMode`).
|
|
282
|
+
* The library's temporary test databases, test directory and `test` storage entry are only this side effect: they
|
|
283
|
+
* are removed at once, so `sdk:own-storage` does not list them (nothing is kept on the device).
|
|
284
|
+
*/
|
|
285
|
+
declare const SDK_PRIVATE_MODE: CapabilityDescriptor;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Transport output gateway (`src/transports/fetch.ts`, `src/readers/network.ts`): ingestion requests with fetch
|
|
289
|
+
* (keepalive, no credentials) and `sendBeacon` on page hide. Lists what leaves besides the events themselves.
|
|
290
|
+
*/
|
|
291
|
+
declare const SDK_TRANSPORT: GatewayDescriptor;
|
|
292
|
+
|
|
293
|
+
/** `sdk:window@1`: the window gateway (`src/readers/window-events.ts`, `src/low-events/shared-window-observer.ts`). */
|
|
294
|
+
declare const SDK_WINDOW: CapabilityDescriptor;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* `@corbado/observe/manifest`: collection manifest v2 descriptors of the SDK's gateways and capabilities, read by
|
|
298
|
+
* the autocapture tools from the package. Never imported by runtime code, so never part of a bundle.
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
/** Every capability descriptor of this package. */
|
|
302
|
+
declare const SDK_CAPABILITIES: readonly CapabilityDescriptor[];
|
|
303
|
+
/** Every gateway descriptor of this package. */
|
|
304
|
+
declare const SDK_GATEWAYS: readonly GatewayDescriptor[];
|
|
305
|
+
/** WP1 names: the same lists. */
|
|
306
|
+
declare const capabilities: CapabilityDescriptor[];
|
|
307
|
+
declare const gateways: GatewayDescriptor[];
|
|
308
|
+
|
|
309
|
+
export { AC_CEREMONY, CATEGORIES, CATEGORY_VALUE_LEVELS, type CapabilityDescriptor, type Category, type CollectionLevel, type Conditional, type GatewayDescriptor, type GatewayField, type GeneratedEntry, KIND_LADDERS, type ManifestId, NON_VALUE_LEVELS, type NonValueLevel, SDK_API, SDK_CAPABILITIES, SDK_DEVICE, SDK_GATEWAYS, SDK_GENERATED, SDK_INPUT, SDK_OWN_STORAGE, SDK_PAGE, SDK_PASSWORD_MANAGERS, SDK_PRIVATE_MODE, SDK_RECORD, SDK_TRANSPORT, SDK_WINDOW, type SideEffect, type SourceKind, type StoredEntry, type StoredVariant, type TelemetryEntry, type TransportFact, VALUE_LEVELS, type ValueLevel, capabilities, gateways };
|