@corbado/observe 1.15.0 → 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.
@@ -67,17 +67,32 @@ interface CapabilityDescriptor {
67
67
  adds: string;
68
68
  }[];
69
69
  /** What the capability does on the page beyond reading; `when` = the build switch that enables it. */
70
- sideEffects?: {
71
- id: string;
72
- text: string;
73
- when?: string;
74
- }[];
70
+ sideEffects?: SideEffect[];
75
71
  review?: string;
76
72
  /** Additive (WP2): short plain-language line shown under the card, e.g. "used on: input fields". */
77
73
  usedOn?: string;
78
74
  /** Additive (WP2): the build switch that removes the whole capability from builds that turn it off. */
79
75
  when?: string;
80
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
+ }
81
96
  /** Gateways without an algorithm and the output gateways (sections 4 and 6). */
82
97
  interface GatewayDescriptor {
83
98
  key: string;
@@ -98,7 +113,7 @@ interface GatewayDescriptor {
98
113
  /** Additive (WP2): transport facts (`transport:<fact>`), only on the transport gateway. */
99
114
  transport?: TransportFact[];
100
115
  }
101
- interface GatewayField {
116
+ interface GatewayField extends Conditional {
102
117
  path: string;
103
118
  /** A category, or `"role"`: inherit the category of the input role the field is read from. */
104
119
  category: Category | "role" | string;
@@ -122,7 +137,7 @@ interface GatewayField {
122
137
  * - `exposedTo`: who besides Corbado can see it, e.g. `"corbado"`, `"page scripts (getSessionId)"`,
123
138
  * `"page scripts (local storage)"`.
124
139
  */
125
- interface GeneratedEntry {
140
+ interface GeneratedEntry extends Conditional {
126
141
  id: string;
127
142
  category: Category | string;
128
143
  pointsTo: string;
@@ -142,8 +157,10 @@ interface GeneratedEntry {
142
157
  * `"persistent"`.
143
158
  * - `owner`: `"sdk"`, `"project"`, `"third-party (<package>)"`.
144
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).
145
162
  */
146
- interface StoredEntry {
163
+ interface StoredEntry extends Conditional {
147
164
  id: string;
148
165
  area: string;
149
166
  scope: string;
@@ -158,7 +175,18 @@ interface StoredEntry {
158
175
  enforced?: boolean;
159
176
  /** Additive (WP2): build switch / config flag the entry depends on. */
160
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;
161
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">>;
162
190
  interface TelemetryEntry {
163
191
  kind: string;
164
192
  fields: string[];
@@ -178,6 +206,9 @@ interface TransportFact {
178
206
  * `ac:ceremony@1` (SDK part): the WebAuthn allowlist (`src/utils/webauthn-ceremony.ts`), used by the sanitizers in
179
207
  * builds that define `__CBO_DATA_CEREMONY__ = true` (build switch `ceremony`). The library's credentials wrapper and
180
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.
181
212
  */
182
213
  declare const AC_CEREMONY: CapabilityDescriptor;
183
214
 
@@ -214,6 +245,10 @@ declare const SDK_RECORD: GatewayDescriptor;
214
245
  * the email-link notes only in builds with `__CBO_DATA_RETENTION__` (build switch `retention`); without it the
215
246
  * outboxes keep entries up to their caps (500 events, 1000 low events) and expired email-link notes stay until the
216
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`).
217
252
  */
218
253
  declare const SDK_OWN_STORAGE: GatewayDescriptor;
219
254
 
@@ -230,6 +265,8 @@ declare const SDK_PAGE: GatewayDescriptor;
230
265
  * `src/low-events/`), declared as it behaves today (v1). Inside the gateway it reads the field's LENGTH (and a
231
266
  * checkbox's checked state) to tell typing, pasting, clearing and several-characters-at-once changes apart; neither
232
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.
233
270
  */
234
271
  declare const SDK_INPUT: CapabilityDescriptor;
235
272
 
@@ -242,6 +279,8 @@ declare const SDK_PASSWORD_MANAGERS: CapabilityDescriptor;
242
279
  /**
243
280
  * `sdk:private-mode@1`: private-mode detection (`src/readers/private-mode.ts`, the third-party library
244
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).
245
284
  */
246
285
  declare const SDK_PRIVATE_MODE: CapabilityDescriptor;
247
286
 
@@ -267,4 +306,4 @@ declare const SDK_GATEWAYS: readonly GatewayDescriptor[];
267
306
  declare const capabilities: CapabilityDescriptor[];
268
307
  declare const gateways: GatewayDescriptor[];
269
308
 
270
- export { AC_CEREMONY, CATEGORIES, CATEGORY_VALUE_LEVELS, type CapabilityDescriptor, type Category, type CollectionLevel, 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 SourceKind, type StoredEntry, type TelemetryEntry, type TransportFact, VALUE_LEVELS, type ValueLevel, capabilities, gateways };
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 };
@@ -67,17 +67,32 @@ interface CapabilityDescriptor {
67
67
  adds: string;
68
68
  }[];
69
69
  /** What the capability does on the page beyond reading; `when` = the build switch that enables it. */
70
- sideEffects?: {
71
- id: string;
72
- text: string;
73
- when?: string;
74
- }[];
70
+ sideEffects?: SideEffect[];
75
71
  review?: string;
76
72
  /** Additive (WP2): short plain-language line shown under the card, e.g. "used on: input fields". */
77
73
  usedOn?: string;
78
74
  /** Additive (WP2): the build switch that removes the whole capability from builds that turn it off. */
79
75
  when?: string;
80
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
+ }
81
96
  /** Gateways without an algorithm and the output gateways (sections 4 and 6). */
82
97
  interface GatewayDescriptor {
83
98
  key: string;
@@ -98,7 +113,7 @@ interface GatewayDescriptor {
98
113
  /** Additive (WP2): transport facts (`transport:<fact>`), only on the transport gateway. */
99
114
  transport?: TransportFact[];
100
115
  }
101
- interface GatewayField {
116
+ interface GatewayField extends Conditional {
102
117
  path: string;
103
118
  /** A category, or `"role"`: inherit the category of the input role the field is read from. */
104
119
  category: Category | "role" | string;
@@ -122,7 +137,7 @@ interface GatewayField {
122
137
  * - `exposedTo`: who besides Corbado can see it, e.g. `"corbado"`, `"page scripts (getSessionId)"`,
123
138
  * `"page scripts (local storage)"`.
124
139
  */
125
- interface GeneratedEntry {
140
+ interface GeneratedEntry extends Conditional {
126
141
  id: string;
127
142
  category: Category | string;
128
143
  pointsTo: string;
@@ -142,8 +157,10 @@ interface GeneratedEntry {
142
157
  * `"persistent"`.
143
158
  * - `owner`: `"sdk"`, `"project"`, `"third-party (<package>)"`.
144
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).
145
162
  */
146
- interface StoredEntry {
163
+ interface StoredEntry extends Conditional {
147
164
  id: string;
148
165
  area: string;
149
166
  scope: string;
@@ -158,7 +175,18 @@ interface StoredEntry {
158
175
  enforced?: boolean;
159
176
  /** Additive (WP2): build switch / config flag the entry depends on. */
160
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;
161
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">>;
162
190
  interface TelemetryEntry {
163
191
  kind: string;
164
192
  fields: string[];
@@ -178,6 +206,9 @@ interface TransportFact {
178
206
  * `ac:ceremony@1` (SDK part): the WebAuthn allowlist (`src/utils/webauthn-ceremony.ts`), used by the sanitizers in
179
207
  * builds that define `__CBO_DATA_CEREMONY__ = true` (build switch `ceremony`). The library's credentials wrapper and
180
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.
181
212
  */
182
213
  declare const AC_CEREMONY: CapabilityDescriptor;
183
214
 
@@ -214,6 +245,10 @@ declare const SDK_RECORD: GatewayDescriptor;
214
245
  * the email-link notes only in builds with `__CBO_DATA_RETENTION__` (build switch `retention`); without it the
215
246
  * outboxes keep entries up to their caps (500 events, 1000 low events) and expired email-link notes stay until the
216
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`).
217
252
  */
218
253
  declare const SDK_OWN_STORAGE: GatewayDescriptor;
219
254
 
@@ -230,6 +265,8 @@ declare const SDK_PAGE: GatewayDescriptor;
230
265
  * `src/low-events/`), declared as it behaves today (v1). Inside the gateway it reads the field's LENGTH (and a
231
266
  * checkbox's checked state) to tell typing, pasting, clearing and several-characters-at-once changes apart; neither
232
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.
233
270
  */
234
271
  declare const SDK_INPUT: CapabilityDescriptor;
235
272
 
@@ -242,6 +279,8 @@ declare const SDK_PASSWORD_MANAGERS: CapabilityDescriptor;
242
279
  /**
243
280
  * `sdk:private-mode@1`: private-mode detection (`src/readers/private-mode.ts`, the third-party library
244
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).
245
284
  */
246
285
  declare const SDK_PRIVATE_MODE: CapabilityDescriptor;
247
286
 
@@ -267,4 +306,4 @@ declare const SDK_GATEWAYS: readonly GatewayDescriptor[];
267
306
  declare const capabilities: CapabilityDescriptor[];
268
307
  declare const gateways: GatewayDescriptor[];
269
308
 
270
- export { AC_CEREMONY, CATEGORIES, CATEGORY_VALUE_LEVELS, type CapabilityDescriptor, type Category, type CollectionLevel, 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 SourceKind, type StoredEntry, type TelemetryEntry, type TransportFact, VALUE_LEVELS, type ValueLevel, capabilities, gateways };
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 };
@@ -83,6 +83,17 @@ var AC_CEREMONY = {
83
83
  adds: "the passkey's random id, to recognize the same passkey across sign-ins. Its own field, category opaque-identifier, level raw. Without it the ids are replaced by random stand-ins that only match within one page load, so projects that track credentials (passkey KPIs, passkey provider at sign-in) declare passkeyReference: true (adx, vg, vr, adb). A runtime option (not a build switch): the autocapture runtime passes it from the static config, the manifest records its value from build.config."
84
84
  }
85
85
  ],
86
+ sideEffects: [
87
+ {
88
+ id: "ceremony.wrap-credentials",
89
+ text: "wraps navigator.credentials.get and navigator.credentials.create, so every passkey prompt of the page passes through it"
90
+ },
91
+ {
92
+ id: "ceremony.credentials-proxy",
93
+ text: "navigator.credentials is replaced by a proxy that forwards to the original",
94
+ when: "aap"
95
+ }
96
+ ],
86
97
  usedOn: "passkey prompts, passkey data in request bodies and page attributes (fields declared via ac:ceremony@1); default set: technical and device facts only",
87
98
  when: "ceremony"
88
99
  };
@@ -105,7 +116,9 @@ var SDK_API = {
105
116
  path: "emailLink.transactionId",
106
117
  level: "pseudonym",
107
118
  category: "personal-identifier",
108
- label: "Transaction reference of an email link, as the integration passes it (a projects' declaration narrows it)"
119
+ label: "Transaction reference of an email link, as the integration passes it (a projects' declaration narrows it)",
120
+ // email-link typed operation (`utils/email-link-operation-full.ts`), optional code
121
+ requires: "sdk-operations"
109
122
  }
110
123
  ]
111
124
  };
@@ -342,7 +355,13 @@ var SDK_OWN_STORAGE = {
342
355
  enforced: true,
343
356
  owner: "sdk",
344
357
  contents: ["sent:events"],
345
- label: "Field and window interaction records not yet delivered; never kept longer than 7 days"
358
+ label: "Field and window interaction records not yet delivered; never kept longer than 7 days",
359
+ // queue.ts enqueueLow writes only with durableLowOutbox; the queue always opens the low outbox to recover and
360
+ // resend (or drop after 7 days / on rejection) what an earlier load left
361
+ when: "durableLowOutbox",
362
+ otherwise: {
363
+ note: "Not written by this build (durableLowOutbox is off): low events are sent from memory; entries left by an older build are sent or removed."
364
+ }
346
365
  },
347
366
  {
348
367
  id: "storage:sdk.session",
@@ -406,8 +425,10 @@ var SDK_OWN_STORAGE = {
406
425
  enforced: false,
407
426
  owner: "sdk",
408
427
  contents: [],
409
- label: "Corbado's settings for the script (no personal data); refreshed at most daily. Absent with a static config",
410
- when: "serverConfig"
428
+ label: "Corbado's settings for the script (no personal data); refreshed at most daily",
429
+ // only ConfigManager (absent from static-config builds) reads, writes or removes it; nothing removes an older
430
+ // cache in a static build (storage/migration.ts may still copy a pre-multi-project `cbo_sdk_config` once)
431
+ when: "!static"
411
432
  },
412
433
  {
413
434
  id: "storage:sdk.private-mode",
@@ -450,7 +471,9 @@ var SDK_OWN_STORAGE = {
450
471
  enforced: true,
451
472
  owner: "sdk",
452
473
  contents: [`${API}#emailLink.transactionId`, "generated:sdk.event", "generated:sdk.session"],
453
- label: "Started email links (at most 10), to continue them on the link's page; deleted after 24 hours"
474
+ label: "Started email links (at most 10), to continue them on the link's page; deleted after 24 hours",
475
+ // written only by the email-link typed operation (`utils/email-link-operation-full.ts`)
476
+ requires: "sdk-operations"
454
477
  },
455
478
  {
456
479
  id: "storage:sdk.storage-schema",
@@ -474,14 +497,18 @@ var SDK_OWN_STORAGE = {
474
497
  },
475
498
  {
476
499
  id: "storage:sdk.legacy-debug",
477
- keys: ["cbo_visibility_change_debug", "cbo_pagehide_debug"],
500
+ // queue.ts removes the project-scoped keys at start (a one-time storage/migration.ts copy of a pre-multi-project
501
+ // unscoped key included, removed in the same start); the unscoped originals are left untouched
502
+ keys: ["cbo_visibility_change_debug_*", "cbo_pagehide_debug_*"],
478
503
  area: "local",
479
504
  scope: "origin",
480
505
  retention: "PT0S",
481
506
  enforced: true,
507
+ deleteOnly: true,
482
508
  owner: "sdk",
483
509
  contents: [],
484
- label: "Debug output older script versions wrote in debug mode (it held the full page address): no longer written, deleted when the script starts"
510
+ label: "Debug keys of older versions",
511
+ note: "Debug keys of older versions (they held the unmasked page address); removed when found, never written."
485
512
  },
486
513
  {
487
514
  id: "storage:sdk.cross-origin-session",
@@ -492,43 +519,8 @@ var SDK_OWN_STORAGE = {
492
519
  owner: "sdk",
493
520
  contents: ["generated:sdk.session", "record:sdk.event#seq"],
494
521
  label: "Visit shared across the site's subdomains (first-party cookie); only with the cross-origin session plugin",
495
- when: "crossOriginSession"
496
- },
497
- {
498
- id: "storage:sdk.private-mode-probe-local",
499
- keys: ["test"],
500
- area: "local",
501
- scope: "origin",
502
- retention: "PT0S",
503
- enforced: true,
504
- owner: "third-party (detectincognitojs)",
505
- contents: [],
506
- label: "Test entry of the private-mode check (value 1), removed at once",
507
- when: "privateMode"
508
- },
509
- {
510
- id: "storage:sdk.private-mode-probe-indexeddb",
511
- keys: ["<random>", "__di_<random>", "inPrivate"],
512
- area: "indexeddb",
513
- scope: "origin",
514
- retention: "PT0S",
515
- enforced: true,
516
- owner: "third-party (detectincognitojs)",
517
- contents: [],
518
- label: "Test databases of the private-mode check (no data), deleted at once",
519
- when: "privateMode"
520
- },
521
- {
522
- id: "storage:sdk.private-mode-probe-opfs",
523
- keys: ["origin private file system root (opened, nothing written)"],
524
- area: "opfs",
525
- scope: "origin",
526
- retention: "PT0S",
527
- enforced: true,
528
- owner: "third-party (detectincognitojs)",
529
- contents: [],
530
- label: "Private-mode check opens the origin's private file system, writes nothing",
531
- when: "privateMode"
522
+ when: "crossOriginSession",
523
+ requires: "cross-origin-session"
532
524
  }
533
525
  ]
534
526
  };
@@ -582,6 +574,12 @@ var SDK_INPUT = {
582
574
  single: "per field",
583
575
  group: "Group (one-time codes): only whether all fields are empty; no moves between the fields"
584
576
  },
577
+ sideEffects: [
578
+ {
579
+ id: "dom.mutation-observers",
580
+ text: "watches the whole document for added elements (MutationObserver, child list and subtree) to find declared elements and fields when the page changes"
581
+ }
582
+ ],
585
583
  usedOn: "input fields",
586
584
  review: "SEC-input-v1"
587
585
  };
@@ -591,10 +589,10 @@ var SDK_PASSWORD_MANAGERS = {
591
589
  key: "sdk:password-managers",
592
590
  version: 1,
593
591
  title: "Installed password managers",
594
- why: "Helps explain autofill behaviour and failures.",
592
+ why: "Helps explain autofill behavior and failures.",
595
593
  collects: ["names of detected password managers from a fixed list"],
596
594
  never: [
597
- { text: "whether you are signed in to them", proof: "sdk:password-managers@1#never.signed-in" },
595
+ { text: "whether the person is signed in to them", proof: "sdk:password-managers@1#never.signed-in" },
598
596
  { text: "anything stored in them", proof: "sdk:password-managers@1#never.contents" }
599
597
  ],
600
598
  sideEffects: [
@@ -652,8 +650,16 @@ var SDK_TRANSPORT = {
652
650
  addedBy: "browser"
653
651
  },
654
652
  { id: "transport:origin", label: "The page's origin (Origin header)", addedBy: "browser" },
655
- { id: "transport:client-hints", label: "Browser client hints, where the browser sends them", addedBy: "browser" },
656
- { id: "transport:ip-address", label: "IP address (seen by Corbado's servers)", addedBy: "browser" },
653
+ {
654
+ id: "transport:client-hints",
655
+ label: "The browser's default client hints (brand and version, mobile or not, operating system), if the browser sends them; the detailed device facts (for example the model) are read separately and listed under device information.",
656
+ addedBy: "browser"
657
+ },
658
+ {
659
+ id: "transport:ip-address",
660
+ label: "The visitor's IP address reaches Corbado's backend with every request, as with any web request. It is discarded there and not stored with the data; it is only kept for a limited time (90 days) in firewall logs when the request was flagged as suspicious.",
661
+ addedBy: "browser"
662
+ },
657
663
  {
658
664
  id: "transport:beacon-cookies",
659
665
  label: "Cookies of the ingestion host, on requests sent while the page is closing",
@@ -37,6 +37,17 @@ var AC_CEREMONY = {
37
37
  adds: "the passkey's random id, to recognize the same passkey across sign-ins. Its own field, category opaque-identifier, level raw. Without it the ids are replaced by random stand-ins that only match within one page load, so projects that track credentials (passkey KPIs, passkey provider at sign-in) declare passkeyReference: true (adx, vg, vr, adb). A runtime option (not a build switch): the autocapture runtime passes it from the static config, the manifest records its value from build.config."
38
38
  }
39
39
  ],
40
+ sideEffects: [
41
+ {
42
+ id: "ceremony.wrap-credentials",
43
+ text: "wraps navigator.credentials.get and navigator.credentials.create, so every passkey prompt of the page passes through it"
44
+ },
45
+ {
46
+ id: "ceremony.credentials-proxy",
47
+ text: "navigator.credentials is replaced by a proxy that forwards to the original",
48
+ when: "aap"
49
+ }
50
+ ],
40
51
  usedOn: "passkey prompts, passkey data in request bodies and page attributes (fields declared via ac:ceremony@1); default set: technical and device facts only",
41
52
  when: "ceremony"
42
53
  };
@@ -59,7 +70,9 @@ var SDK_API = {
59
70
  path: "emailLink.transactionId",
60
71
  level: "pseudonym",
61
72
  category: "personal-identifier",
62
- label: "Transaction reference of an email link, as the integration passes it (a projects' declaration narrows it)"
73
+ label: "Transaction reference of an email link, as the integration passes it (a projects' declaration narrows it)",
74
+ // email-link typed operation (`utils/email-link-operation-full.ts`), optional code
75
+ requires: "sdk-operations"
63
76
  }
64
77
  ]
65
78
  };
@@ -296,7 +309,13 @@ var SDK_OWN_STORAGE = {
296
309
  enforced: true,
297
310
  owner: "sdk",
298
311
  contents: ["sent:events"],
299
- label: "Field and window interaction records not yet delivered; never kept longer than 7 days"
312
+ label: "Field and window interaction records not yet delivered; never kept longer than 7 days",
313
+ // queue.ts enqueueLow writes only with durableLowOutbox; the queue always opens the low outbox to recover and
314
+ // resend (or drop after 7 days / on rejection) what an earlier load left
315
+ when: "durableLowOutbox",
316
+ otherwise: {
317
+ note: "Not written by this build (durableLowOutbox is off): low events are sent from memory; entries left by an older build are sent or removed."
318
+ }
300
319
  },
301
320
  {
302
321
  id: "storage:sdk.session",
@@ -360,8 +379,10 @@ var SDK_OWN_STORAGE = {
360
379
  enforced: false,
361
380
  owner: "sdk",
362
381
  contents: [],
363
- label: "Corbado's settings for the script (no personal data); refreshed at most daily. Absent with a static config",
364
- when: "serverConfig"
382
+ label: "Corbado's settings for the script (no personal data); refreshed at most daily",
383
+ // only ConfigManager (absent from static-config builds) reads, writes or removes it; nothing removes an older
384
+ // cache in a static build (storage/migration.ts may still copy a pre-multi-project `cbo_sdk_config` once)
385
+ when: "!static"
365
386
  },
366
387
  {
367
388
  id: "storage:sdk.private-mode",
@@ -404,7 +425,9 @@ var SDK_OWN_STORAGE = {
404
425
  enforced: true,
405
426
  owner: "sdk",
406
427
  contents: [`${API}#emailLink.transactionId`, "generated:sdk.event", "generated:sdk.session"],
407
- label: "Started email links (at most 10), to continue them on the link's page; deleted after 24 hours"
428
+ label: "Started email links (at most 10), to continue them on the link's page; deleted after 24 hours",
429
+ // written only by the email-link typed operation (`utils/email-link-operation-full.ts`)
430
+ requires: "sdk-operations"
408
431
  },
409
432
  {
410
433
  id: "storage:sdk.storage-schema",
@@ -428,14 +451,18 @@ var SDK_OWN_STORAGE = {
428
451
  },
429
452
  {
430
453
  id: "storage:sdk.legacy-debug",
431
- keys: ["cbo_visibility_change_debug", "cbo_pagehide_debug"],
454
+ // queue.ts removes the project-scoped keys at start (a one-time storage/migration.ts copy of a pre-multi-project
455
+ // unscoped key included, removed in the same start); the unscoped originals are left untouched
456
+ keys: ["cbo_visibility_change_debug_*", "cbo_pagehide_debug_*"],
432
457
  area: "local",
433
458
  scope: "origin",
434
459
  retention: "PT0S",
435
460
  enforced: true,
461
+ deleteOnly: true,
436
462
  owner: "sdk",
437
463
  contents: [],
438
- label: "Debug output older script versions wrote in debug mode (it held the full page address): no longer written, deleted when the script starts"
464
+ label: "Debug keys of older versions",
465
+ note: "Debug keys of older versions (they held the unmasked page address); removed when found, never written."
439
466
  },
440
467
  {
441
468
  id: "storage:sdk.cross-origin-session",
@@ -446,43 +473,8 @@ var SDK_OWN_STORAGE = {
446
473
  owner: "sdk",
447
474
  contents: ["generated:sdk.session", "record:sdk.event#seq"],
448
475
  label: "Visit shared across the site's subdomains (first-party cookie); only with the cross-origin session plugin",
449
- when: "crossOriginSession"
450
- },
451
- {
452
- id: "storage:sdk.private-mode-probe-local",
453
- keys: ["test"],
454
- area: "local",
455
- scope: "origin",
456
- retention: "PT0S",
457
- enforced: true,
458
- owner: "third-party (detectincognitojs)",
459
- contents: [],
460
- label: "Test entry of the private-mode check (value 1), removed at once",
461
- when: "privateMode"
462
- },
463
- {
464
- id: "storage:sdk.private-mode-probe-indexeddb",
465
- keys: ["<random>", "__di_<random>", "inPrivate"],
466
- area: "indexeddb",
467
- scope: "origin",
468
- retention: "PT0S",
469
- enforced: true,
470
- owner: "third-party (detectincognitojs)",
471
- contents: [],
472
- label: "Test databases of the private-mode check (no data), deleted at once",
473
- when: "privateMode"
474
- },
475
- {
476
- id: "storage:sdk.private-mode-probe-opfs",
477
- keys: ["origin private file system root (opened, nothing written)"],
478
- area: "opfs",
479
- scope: "origin",
480
- retention: "PT0S",
481
- enforced: true,
482
- owner: "third-party (detectincognitojs)",
483
- contents: [],
484
- label: "Private-mode check opens the origin's private file system, writes nothing",
485
- when: "privateMode"
476
+ when: "crossOriginSession",
477
+ requires: "cross-origin-session"
486
478
  }
487
479
  ]
488
480
  };
@@ -536,6 +528,12 @@ var SDK_INPUT = {
536
528
  single: "per field",
537
529
  group: "Group (one-time codes): only whether all fields are empty; no moves between the fields"
538
530
  },
531
+ sideEffects: [
532
+ {
533
+ id: "dom.mutation-observers",
534
+ text: "watches the whole document for added elements (MutationObserver, child list and subtree) to find declared elements and fields when the page changes"
535
+ }
536
+ ],
539
537
  usedOn: "input fields",
540
538
  review: "SEC-input-v1"
541
539
  };
@@ -545,10 +543,10 @@ var SDK_PASSWORD_MANAGERS = {
545
543
  key: "sdk:password-managers",
546
544
  version: 1,
547
545
  title: "Installed password managers",
548
- why: "Helps explain autofill behaviour and failures.",
546
+ why: "Helps explain autofill behavior and failures.",
549
547
  collects: ["names of detected password managers from a fixed list"],
550
548
  never: [
551
- { text: "whether you are signed in to them", proof: "sdk:password-managers@1#never.signed-in" },
549
+ { text: "whether the person is signed in to them", proof: "sdk:password-managers@1#never.signed-in" },
552
550
  { text: "anything stored in them", proof: "sdk:password-managers@1#never.contents" }
553
551
  ],
554
552
  sideEffects: [
@@ -606,8 +604,16 @@ var SDK_TRANSPORT = {
606
604
  addedBy: "browser"
607
605
  },
608
606
  { id: "transport:origin", label: "The page's origin (Origin header)", addedBy: "browser" },
609
- { id: "transport:client-hints", label: "Browser client hints, where the browser sends them", addedBy: "browser" },
610
- { id: "transport:ip-address", label: "IP address (seen by Corbado's servers)", addedBy: "browser" },
607
+ {
608
+ id: "transport:client-hints",
609
+ label: "The browser's default client hints (brand and version, mobile or not, operating system), if the browser sends them; the detailed device facts (for example the model) are read separately and listed under device information.",
610
+ addedBy: "browser"
611
+ },
612
+ {
613
+ id: "transport:ip-address",
614
+ label: "The visitor's IP address reaches Corbado's backend with every request, as with any web request. It is discarded there and not stored with the data; it is only kept for a limited time (90 days) in firewall logs when the request was flagged as suspicious.",
615
+ addedBy: "browser"
616
+ },
611
617
  {
612
618
  id: "transport:beacon-cookies",
613
619
  label: "Cookies of the ingestion host, on requests sent while the page is closing",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corbado/observe",
3
- "version": "1.15.0",
3
+ "version": "1.15.1",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",