@patchstack/connect 0.5.15 → 0.5.16

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/AGENT-INSTALL.md CHANGED
@@ -85,7 +85,7 @@ Only `map` analyses your source, and only `map --upload` sends anything derived
85
85
 
86
86
  ## Talk to the person while you work
87
87
 
88
- The person who asked for this usually did not write the project and has never installed a package. Installs and builds here can run for several minutes, and a silent wall of build output is the worst part of their first experience of Patchstack. Narrate it.
88
+ The person who asked for this usually did not write the project and has never installed a package. Installs and builds here can run for several minutes, and a silent wall of build output is the worst part of their first experience of Patchstack. Narrate it, one or two sentences at a time.
89
89
 
90
90
  - **Say what you are about to do, before the slow command.** One sentence, no command names: "I'm adding Patchstack to your site — this takes a few minutes because it has to reinstall everything the site is built from."
91
91
  - **Say what the wait is.** "It's downloading the pieces your site is built out of. Nothing is broken; this is just slow."
@@ -97,6 +97,17 @@ The person who asked for this usually did not write the project and has never in
97
97
 
98
98
  This is a request, not a mechanism: nothing in the install depends on it. Do it anyway — the wait is the only moment where the person is paying full attention.
99
99
 
100
+ ### The message you end on
101
+
102
+ When setup is finished, the person reads one short message, not a transcript of the install. Keep it to about ten lines, in this order:
103
+
104
+ 1. **One sentence on the result.** "Patchstack is now watching your site." If something did not finish, say what, in one line.
105
+ 2. **The four steps**, copied from the end of the `setup` output with their `✔` and `✘`.
106
+ 3. **The next step**, from the `Next:` line, in plain words, with its link or command.
107
+ 4. **Refresh and deploy.** Refresh the preview to see the Patchstack Connector, and deploy when ready.
108
+
109
+ Leave out the files you changed, the commands you ran, settings, and anything that worked as expected. If the person asks for the detail, give it then. `--verbose` prints it.
110
+
100
111
  ## Automated setup
101
112
 
102
113
  1. **Install** (skip if already present), matching the project's package manager:
@@ -135,7 +146,7 @@ This is a request, not a mechanism: nothing in the install depends on it. Do it
135
146
 
136
147
  **A `✘` line under `Missing` is yours to finish, not a result to report.** `setup` applies what it can apply safely and prints the exact edit (or the command that prints it) for anything it would have had to overwrite user code to do. They are: moving `@patchstack/connect` out of `devDependencies`, the widget tag in a root layout `setup` could not edit, the production marker on a server-rendered root, and wiring a generic guard into the server entry. The last three are steps 3 and 4 of "Manual setup" below; after the guard one, `npx @patchstack/connect protect --check` must exit 0.
137
148
 
138
- **Read the report.** `setup` and `scan` start with `Done` (what this run did) and `Missing` (what is still missing, each with the one thing to do); `guide` shows `Missing` only. All three end on the same four steps — `Install the Patchstack connector`, `Connect project to Patchstack account`, `Sync and monitor in local environment`, `Deploy project to protect live app` — each marked `✔` (done) or `✘` (not yet), followed by the one next step. A part the project cannot carry (no build script, no request path for runtime protection) is simply not listed. The CLI does not store whether the site has an owner, so `Connect` stays `✘` until a scan hears otherwise from Patchstack; do not report the site as connected from that line alone, and do not report it as unconnected once the person has signed in. Report what the project ended up with by name — dependency scans, the Patchstack Connector, the build hooks, runtime protection — and say which are not active and why.
149
+ **Read the report.** `setup` and `scan` start with `Done` (what this run did) and `Missing` (what is still missing, each with the one thing to do); `guide` shows `Missing` only. All three end on the same four steps — `Install the Patchstack connector`, `Connect project to Patchstack account`, `Sync and monitor in local environment`, `Deploy project to protect live app` — each marked `✔` (done) or `✘` (not yet), followed by the one next step. A part the project cannot carry (no build script, no request path for runtime protection) is simply not listed. The CLI does not store whether the site has an owner, so `Connect` stays `✘` until a scan hears otherwise from Patchstack; do not report the site as connected from that line alone, and do not report it as unconnected once the person has signed in. In the message you end on, name only the parts that are not active — dependency scans, the Patchstack Connector, the build hooks, runtime protection — and why, one line each; the four steps already say what is done.
139
150
 
140
151
  **The widget is part of the install.** It is on by default; add it without asking the person whether to. Honour `"widget": false` in `.patchstackrc.json` only when the person set it themselves. If it is there and they did not ask for it, remove it, run `setup` again, and tell them the widget is back on.
141
152
 
@@ -459,8 +470,9 @@ requests are aborted, it starts nothing further, and it discards what it was hol
459
470
  request to stop, not a guarantee — a transport that ignores it is detached rather than completed, so
460
471
  "resolved" means the reporter is finished with it, and a runtime that kills the process still wins
461
472
  regardless. Every detection event ends up delivered, refused or dropped and is reported in the health
462
- counts; block-log records have no counters, so one lost to a failed send or an expired shutdown is
463
- reported nowhere.
473
+ counts. The block log keeps the same kind of local counts: `protection.blockLogHealth()` returns how many
474
+ block records were accepted, delivered, failed or dropped, and how many are still queued. Those counts
475
+ carry no request data and stay in your process.
464
476
 
465
477
  The client address is reported with its **provenance**, because an address is only as trustworthy as
466
478
  whatever supplied it. `client_ip_source` is one of `runtime` (the address the transport observed),
@@ -468,7 +480,8 @@ whatever supplied it. `client_ip_source` is one of `runtime` (the address the tr
468
480
  `unavailable`. When it is `unavailable` the `client_ip` field is **omitted entirely** rather than sent
469
481
  empty, so a missing address cannot read as a failed lookup of a real one. A forwarded header is never
470
482
  trusted implicitly: with no `trustedProxy` policy the address is whatever the transport observed, and in a
471
- runtime that exposes no transport peer there is no address to report at all.
483
+ runtime that exposes no transport peer there is no address to report at all unless your code supplies one
484
+ with `peerAddress` (below).
472
485
 
473
486
  ### Behaviour change: how the client address is determined
474
487
 
@@ -483,11 +496,17 @@ Two consequences if you are upgrading:
483
496
  peer. **If your app runs behind a proxy or load balancer, addresses will now show as the proxy's**
484
497
  until you declare your proxies with `trustedProxy` (below) — which affects attribution in reports and
485
498
  any rule matching on `server.ip` or `REMOTE_ADDR`.
486
- - **Fetch runtimes report no address at all.** A WHATWG `Request` exposes no transport peer, so a Fetch
487
- guard (Workers, Deno, Bun, edge) has nothing to observe, and no forwarded header is accepted in its
488
- place under any `trustedProxy` policy: `client_ip_source` is `unavailable` and no address is sent.
499
+ - **Fetch runtimes report no address unless you supply the peer.** A WHATWG `Request` exposes no
500
+ transport peer, so a Fetch guard (Workers, Deno, Bun, edge) has nothing to observe on its own, and no
501
+ forwarded header is accepted in its place: `client_ip_source` is `unavailable` and no address is sent.
489
502
  Earlier versions reported the forwarded header here, so an address-scoped rule that appeared to work on
490
- such a runtime was matching a client-supplied value.
503
+ such a runtime was matching a client-supplied value. Where your runtime does know the peer, pass
504
+ `peerAddress: (request, ...handlerArgs) => string` — for example `(req, info) => info.remoteAddr.hostname`
505
+ on Deno, or `(req, server) => server.requestIP(req)?.address` on Bun. It receives the request and the
506
+ arguments your handler was called with (`fetchGuard()(request, ...args)` and
507
+ `screenResponse(response, request, ...args)` pass them on), and that address then counts as the
508
+ transport peer, including for `trustedProxy`. With `trustedProxy` set and no peer supplied, the guard
509
+ warns once, because the policy can never apply.
491
510
 
492
511
  `trustedProxy` is the only way to make a forwarded header count. It takes the proxies you actually run —
493
512
  `{ peers: ['10.0.0.0/8'] }`, or `{ hops: 1 }` to trust that many hops in from the peer, plus optional
@@ -576,8 +595,15 @@ carries no detections and would otherwise read as one. Those counts stay in your
576
595
  sent to report them.
577
596
 
578
597
  `protection.stop()` stops everything the guard has running in the background — the rule-refresh loop, the
579
- block-log reporter, the detection reporter — and flushes what is buffered. `protection.stopRefresh()` is
580
- the same method under its older name. Call it on shutdown; it is safe to call twice.
598
+ block-log reporter, the detection reporter — and flushes what is buffered. With `egress: true` it also
599
+ removes this guard's outbound-request screening; once no guard in the process is screening, `fetch` and
600
+ `node:http`/`node:https` are restored. Call it on shutdown; it is safe to call twice.
601
+ `protection.stopRefresh()` stops only the rule refresh: the reporters and outbound-request screening keep
602
+ running.
603
+
604
+ When more than one guard in a process has `egress: true`, an outbound call is checked by each of them and
605
+ refused if any one refuses it. A host listed in one guard's `allowHosts` is still refused when another guard
606
+ refuses it.
581
607
 
582
608
  Two more endpoints the package can call, for completeness:
583
609