@magield/collectors 0.12.2 → 0.13.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.
package/dist/registry.js CHANGED
@@ -13,6 +13,7 @@ import { featuresCollector } from './signals/features.js';
13
13
  import { integrityCollector } from './signals/integrity.js';
14
14
  import { mathCollector } from './signals/math.js';
15
15
  import { navigatorCollector } from './signals/navigator.js';
16
+ import { pageCollector } from './signals/page.js';
16
17
  import { pointerCollector } from './signals/pointer.js';
17
18
  import { canvasCollector, webglCollector } from './signals/render.js';
18
19
  import { screenCollector } from './signals/screen.js';
@@ -29,6 +30,8 @@ export const ALL_COLLECTORS = [
29
30
  // ran this sixth, behind a 5 ms budget its obfuscated build could not meet,
30
31
  // and shipped without bot detection for every integrator until 0.7.0.
31
32
  automationCollector,
33
+ // Second: two property reads, and the sequence check reads them.
34
+ pageCollector,
32
35
  navigatorCollector,
33
36
  screenCollector,
34
37
  featuresCollector,
@@ -0,0 +1,24 @@
1
+ import type { Collector } from '../types.js';
2
+ /**
3
+ * How long the page had been open when the token was made, and whether anyone
4
+ * had touched it.
5
+ *
6
+ * A script that drives a browser loads the page and submits in one motion: no
7
+ * click, no key, a second or two after navigation. A person cannot, because
8
+ * typing a password takes longer than that. The behaviour recorder sees the
9
+ * same thing in far more detail, but only where the integrator calls
10
+ * `observe()`; this needs nothing.
11
+ *
12
+ * Read at collect() time, which is when the form is submitted in every
13
+ * integration the SDK documents. `instant`, because it is two property reads.
14
+ *
15
+ * - `page.ageMs`: `performance.now()`, the time since navigation started. A
16
+ * single-page app reports the time since its first page loaded, which only
17
+ * ever makes it longer, so it can hide a fast bot and never accuse a person.
18
+ * - `page.activated`: `navigator.userActivation.hasBeenActive`, the browser's
19
+ * own record of a click, tap or key press on the page since it loaded. Kept
20
+ * by the browser from the start, so it does not depend on when the SDK was
21
+ * loaded; `null` where the browser lacks it (Firefox before 120, Safari
22
+ * before 16.4), and rules reading it then abstain.
23
+ */
24
+ export declare const pageCollector: Collector;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * How long the page had been open when the token was made, and whether anyone
3
+ * had touched it.
4
+ *
5
+ * A script that drives a browser loads the page and submits in one motion: no
6
+ * click, no key, a second or two after navigation. A person cannot, because
7
+ * typing a password takes longer than that. The behaviour recorder sees the
8
+ * same thing in far more detail, but only where the integrator calls
9
+ * `observe()`; this needs nothing.
10
+ *
11
+ * Read at collect() time, which is when the form is submitted in every
12
+ * integration the SDK documents. `instant`, because it is two property reads.
13
+ *
14
+ * - `page.ageMs`: `performance.now()`, the time since navigation started. A
15
+ * single-page app reports the time since its first page loaded, which only
16
+ * ever makes it longer, so it can hide a fast bot and never accuse a person.
17
+ * - `page.activated`: `navigator.userActivation.hasBeenActive`, the browser's
18
+ * own record of a click, tap or key press on the page since it loaded. Kept
19
+ * by the browser from the start, so it does not depend on when the SDK was
20
+ * loaded; `null` where the browser lacks it (Firefox before 120, Safari
21
+ * before 16.4), and rules reading it then abstain.
22
+ */
23
+ export const pageCollector = {
24
+ id: 'page',
25
+ wave: 'instant',
26
+ collect(env) {
27
+ const out = {};
28
+ out['page.ageMs'] = Math.round(env.performance.now());
29
+ const activation = env.navigator.userActivation;
30
+ out['page.activated'] = typeof activation?.hasBeenActive === 'boolean' ? activation.hasBeenActive : null;
31
+ return out;
32
+ },
33
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magield/collectors",
3
- "version": "0.12.2",
3
+ "version": "0.13.0",
4
4
  "description": "Browser signal collectors used by the Magic Shield web SDK",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "files": [