@osqd/bothandlerjs 0.5.0 → 0.7.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +227 -1
  2. package/README.md +18 -10
  3. package/dist/adapters/fastify.d.ts +10 -0
  4. package/dist/adapters/index.cjs +38 -10
  5. package/dist/adapters/index.cjs.map +1 -1
  6. package/dist/adapters/index.js +38 -10
  7. package/dist/adapters/index.js.map +1 -1
  8. package/dist/challenge/index.d.ts +40 -0
  9. package/dist/cli.cjs +2256 -103
  10. package/dist/cli.cjs.map +1 -1
  11. package/dist/cli.js +2256 -103
  12. package/dist/cli.js.map +1 -1
  13. package/dist/config.d.ts +55 -0
  14. package/dist/core.d.ts +48 -21
  15. package/dist/corpus/index.cjs +365 -7
  16. package/dist/corpus/index.cjs.map +1 -1
  17. package/dist/corpus/index.js +365 -7
  18. package/dist/corpus/index.js.map +1 -1
  19. package/dist/corpus/schema.d.ts +33 -0
  20. package/dist/crawler-ranges.d.ts +31 -0
  21. package/dist/dashboard/client/actions.d.ts +1 -1
  22. package/dist/dashboard/client/app.d.ts +9 -2
  23. package/dist/dashboard/client/boot.d.ts +32 -3
  24. package/dist/dashboard/client/query.d.ts +72 -12
  25. package/dist/dashboard/client/registry.d.ts +25 -0
  26. package/dist/dashboard/client/saved.d.ts +29 -0
  27. package/dist/dashboard/client/store.d.ts +16 -2
  28. package/dist/dashboard/client/types.d.ts +2 -0
  29. package/dist/dashboard/client.generated.d.ts +1 -1
  30. package/dist/dashboard/types.d.ts +15 -0
  31. package/dist/detectors/blended-identity.d.ts +34 -0
  32. package/dist/detectors/challenge-integrity.d.ts +26 -0
  33. package/dist/detectors/challenge-reaction.d.ts +39 -0
  34. package/dist/detectors/clearance.d.ts +1 -23
  35. package/dist/detectors/id-enumeration.d.ts +31 -0
  36. package/dist/detectors/index.d.ts +24 -1
  37. package/dist/detectors/known-bots.d.ts +11 -0
  38. package/dist/detectors/marker.d.ts +106 -0
  39. package/dist/detectors/parameter-sweep.d.ts +39 -0
  40. package/dist/detectors/probe-signature.d.ts +27 -0
  41. package/dist/detectors/probe-volume.d.ts +26 -0
  42. package/dist/detectors/site-baseline.d.ts +135 -0
  43. package/dist/detectors/target-integrity.d.ts +16 -0
  44. package/dist/detectors/transport-coherence.d.ts +31 -0
  45. package/dist/detectors/trap.d.ts +10 -3
  46. package/dist/detectors/types.d.ts +17 -0
  47. package/dist/element/index.cjs +730 -80
  48. package/dist/element/index.cjs.map +1 -1
  49. package/dist/element/index.js +730 -80
  50. package/dist/element/index.js.map +1 -1
  51. package/dist/index.cjs +2044 -123
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.ts +6 -2
  54. package/dist/index.js +2025 -123
  55. package/dist/index.js.map +1 -1
  56. package/dist/internal/async.d.ts +0 -3
  57. package/dist/internal/ip.d.ts +18 -0
  58. package/dist/internal/text.d.ts +28 -0
  59. package/dist/metrics.d.ts +18 -0
  60. package/dist/probe/index.d.ts +153 -0
  61. package/dist/probe/marker.d.ts +119 -0
  62. package/dist/site/index.d.ts +122 -0
  63. package/dist/state.d.ts +205 -0
  64. package/dist/stores/redis.d.ts +24 -1
  65. package/dist/types.d.ts +106 -0
  66. package/docs/course/05-detectors.md +9 -4
  67. package/docs/course/06-identity.md +1 -1
  68. package/docs/course/16-proving-it.md +15 -9
  69. package/docs/course/index.md +1 -1
  70. package/docs/design/decisions.md +1 -1
  71. package/docs/detection/correlation.md +284 -0
  72. package/docs/detection/detectors.md +259 -1
  73. package/docs/detection/index.md +2 -1
  74. package/docs/detection/shadow-mode.md +147 -0
  75. package/docs/detection/signatures.md +10 -2
  76. package/docs/index.md +3 -2
  77. package/docs/integration/client-ip.md +16 -0
  78. package/docs/operations/dashboard.md +40 -1
  79. package/docs/operations/filters.md +143 -0
  80. package/docs/operations/index.md +1 -0
  81. package/docs/operations/metrics.md +18 -0
  82. package/docs/policy/presets.md +1 -1
  83. package/docs/start/choosing-a-policy.md +1 -1
  84. package/docs/start/first-integration.md +1 -1
  85. package/docs/start/installation.md +2 -2
  86. package/docs/testing/cli.md +7 -1
  87. package/docs/testing/corpus.md +12 -8
  88. package/docs/testing/index.md +1 -1
  89. package/docs/testing/try-it.md +1 -1
  90. package/package.json +4 -1
@@ -0,0 +1,31 @@
1
+ import type { Detector } from "./types.js";
2
+ export interface TransportCoherenceOptions {
3
+ /**
4
+ * Report a claimed browser arriving over HTTP/1.0. Default true.
5
+ *
6
+ * Turn it off if something in front of this application speaks HTTP/1.0 to it. A few
7
+ * older load balancers and reverse proxies still do, and where that is true every
8
+ * request arrives that way — so the signal says something about your infrastructure
9
+ * rather than about your visitors, and a detector that fires on all of them is worse
10
+ * than one that fires on none.
11
+ */
12
+ legacyHttp?: boolean;
13
+ /** Requests an actor must have made before an all-HEAD visit means anything. Default 8. */
14
+ minHeadRequests?: number;
15
+ }
16
+ /**
17
+ * How a claimed browser *moves*, rather than what it says.
18
+ *
19
+ * The header checks read one request against the client it claims to be. This reads the
20
+ * transport underneath and the verbs across a visit, which are harder to copy because
21
+ * they are not in the part of the request most tools let you set.
22
+ *
23
+ * Two things, both measured as blind spots before this existed — a client claiming
24
+ * Chrome 120 over HTTP/1.0, and one whose entire visit is HEAD, each scored exactly what
25
+ * the honest control scored.
26
+ *
27
+ * Neither goes above `moderate`, and the reasons are different. HTTP/1.0 can be an
28
+ * intermediary's doing rather than the client's. An all-HEAD visit is a strong shape but a
29
+ * link checker is a real and mostly harmless thing to be.
30
+ */
31
+ export declare function transportCoherenceDetector(options?: TransportCoherenceOptions): Detector;
@@ -74,10 +74,17 @@ export interface TrapLinkOptions {
74
74
  * the group most at risk from clever traps — can never reach it. `rel="nofollow"`
75
75
  * asks search engines not to follow it, and belt-and-braces with `robots.txt`.
76
76
  *
77
- * The output is static and contains no interpolated user input, so it is safe to
78
- * inline. Emit it once, near the end of `<body>`.
77
+ * The path and the label are interpolated, and both are escaped on the way in the
78
+ * comment here used to claim the output contained no interpolated input at all, which
79
+ * was two lines above the code that interpolates it and is exactly the sentence that
80
+ * gets escaping deleted as redundant one day.
81
+ *
82
+ * Emit it once, near the end of `<body>`. With no path it uses the first of
83
+ * {@link DEFAULT_TRAP_PATHS}, which is what the documented example has always shown and
84
+ * what `trapRobotsEntries` already does — until this defaulted, copying that example gave
85
+ * you a route handler that threw.
79
86
  */
80
- export declare function renderTrapLink(path: string, options?: TrapLinkOptions): string;
87
+ export declare function renderTrapLink(path?: string, options?: TrapLinkOptions): string;
81
88
  /**
82
89
  * Renders a hidden honeypot form field. Give it a name a form-filler will want to
83
90
  * complete — `email_confirm`, `website` — and register that name in `formFields`.
@@ -6,6 +6,8 @@ import type { ActorState } from "../state.js";
6
6
  import type { Clock } from "../internal/clock.js";
7
7
  import type { IpRangeSet } from "../internal/ip.js";
8
8
  import type { DnsResolver } from "../internal/dns.js";
9
+ import type { MarkerObservation } from "../probe/index.js";
10
+ import type { SiteProfile } from "../site/index.js";
9
11
  /**
10
12
  * Everything a detector is allowed to see.
11
13
  *
@@ -32,6 +34,21 @@ export interface DetectionContext {
32
34
  readonly resolver: DnsResolver;
33
35
  /** Named IP range sets from config: `allowlist`, `denylist`, `datacenter`, and per-crawler ranges. */
34
36
  readonly ranges: ReadonlyMap<string, IpRangeSet>;
37
+ /**
38
+ * What the marker cookie on this request turned out to be, when the probe is on.
39
+ *
40
+ * `undefined` means the probe is not configured, which is the default — a detector
41
+ * reading this must treat absence as "no information" and never as "no marker".
42
+ */
43
+ readonly marker: MarkerObservation | undefined;
44
+ /**
45
+ * What the rest of the site's traffic looks like, when a profile is configured.
46
+ *
47
+ * `undefined` means no profile, which is the default. A profile that exists may still
48
+ * be cold — every reader must check `warm` before believing a count, because during
49
+ * warmup every path looks rare and every client looks unique.
50
+ */
51
+ readonly site: SiteProfile | undefined;
35
52
  /** Scratch space shared between detectors within one request. Cleared afterwards. */
36
53
  readonly shared: Map<string, unknown>;
37
54
  }