dbsc-toolkit 2.2.0 → 2.3.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/README.md CHANGED
@@ -100,17 +100,20 @@ You don't rewrite login, you don't migrate the session store. DBSC sits alongsid
100
100
 
101
101
  `sessionId` on line 5 is whatever id your existing session store already issues. DBSC binds to that same id; you don't manage a second id-space.
102
102
 
103
- **One guard per sensitive route required, not optional:**
103
+ ## Choose your protection level per route
104
104
 
105
- ```ts
106
- app.post("/payment", requireBoundProof({ storage: dbscStorage }), paymentHandler);
107
- app.post("/settings/password", requireBoundProof({ storage: dbscStorage }), passwordHandler);
108
- app.use("/admin", requireBoundProof({ storage: dbscStorage })); // gates everything under /admin
109
- ```
105
+ After the 6-line setup, every request through the middleware has a `tier` field on the request context. The library does not auto-protect anything — you pick the level per route. The library exposes three levers; this table tells you which one to reach for.
106
+
107
+ | Your route does… | Use this guard | What it stops | Detailed in |
108
+ |---|---|---|---|
109
+ | Public / read-only (feed, search, public profile) | Nothing | n/a — no auth gate at all | n/a |
110
+ | Authenticated action with no money / takeover risk (post, comment, upvote, edit own bio) | `if (req.dbsc.tier === "none") return 403` | Stolen cookie loses access after one refresh cycle (~60s–10min depending on `boundCookieTtl`) | [docs/integrating-existing-auth.md](./docs/integrating-existing-auth.md) (per-route policy table) |
111
+ | Account takeover risk (password change, email change, admin actions) | `requireBoundProof({ storage })` | Stolen cookie cannot ride along even while the victim is online — Firefox / Safari now have the same guarantee Chrome gets from native DBSC | [docs/per-request-signing.md](./docs/per-request-signing.md) |
112
+ | Moves money or numeric input that matters (payment, transfer, refund, withdraw) | `requireBoundProof({ storage, signBody: true })` on the server + `wrapFetch({ signBody: true })` on the client | All of the above PLUS an active MITM cannot substitute the request body (amount, recipient, etc.) within the timestamp window | [docs/per-request-signing.md#body-signing-setup-v230](./docs/per-request-signing.md) |
110
113
 
111
- The `tier` field on every request is informational. Without a guard, a stolen cookie still reaches your handler the library cannot infer which routes are sensitive, you mark them. `requireBoundProof` lets native DBSC traffic (`tier: "dbsc"`) through automatically (Chromium enforces session validity browser-side); Firefox / Safari traffic (`tier: "bound"`) must carry a fresh per-request signature, which the client-side [`wrapFetch()`](./docs/per-request-signing.md) adds for you.
114
+ **Each row is opt-in and additive.** A route can sit at row 2 today and graduate to row 3 next quarter when you ship payments no migration, no wire-format change, no version bump. The defaults (no guard) give DBSC's binding semantics without enforcement; pick the row your threat model needs.
112
115
 
113
- Fastify / Hono / Next.js variants of these six lines, plus the per-route policy table and a 30-day rollout timeline, are in [docs/integrating-existing-auth.md](./docs/integrating-existing-auth.md).
116
+ The full threat boundary for each level, the per-framework wiring (Fastify / Hono / Next.js), and the migration timeline for an existing app are in [docs/integrating-existing-auth.md](./docs/integrating-existing-auth.md) and [docs/per-request-signing.md](./docs/per-request-signing.md).
114
117
 
115
118
  ## Subpath imports
116
119
 
@@ -1,5 +1,11 @@
1
1
  export { wrapFetch } from "./wrapFetch.js";
2
2
  export type { WrapFetchOptions } from "./wrapFetch.js";
3
+ /**
4
+ * Clears the bound-key record from IndexedDB. Call this on logout so the next
5
+ * login starts from a clean slate instead of letting the SDK detect a session
6
+ * mismatch and clear it lazily on the next page load.
7
+ */
8
+ export declare function clearBoundKey(): Promise<void>;
3
9
  export interface InitBoundDbscOptions {
4
10
  statePath?: string;
5
11
  challengePath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,KAAK,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAC3E;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAgDtC,wBAAsB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgGjG;AAYD,wBAAgB,aAAa,IAAI,IAAI,CAKpC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD;;;;GAIG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAMnD;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,KAAK,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAC3E;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAgDtC,wBAAsB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgGjG;AAYD,wBAAgB,aAAa,IAAI,IAAI,CAKpC"}
@@ -1,6 +1,18 @@
1
1
  import { clearKeyRecord, getKeyRecord, setKeyRecord } from "./keystore.js";
2
2
  import { recordServerTime } from "./clockSync.js";
3
3
  export { wrapFetch } from "./wrapFetch.js";
4
+ /**
5
+ * Clears the bound-key record from IndexedDB. Call this on logout so the next
6
+ * login starts from a clean slate instead of letting the SDK detect a session
7
+ * mismatch and clear it lazily on the next page load.
8
+ */
9
+ export async function clearBoundKey() {
10
+ await clearKeyRecord().catch(() => { });
11
+ if (refreshTimer !== null) {
12
+ clearTimeout(refreshTimer);
13
+ refreshTimer = null;
14
+ }
15
+ }
4
16
  const DEFAULTS = {
5
17
  statePath: "/dbsc-bound/state",
6
18
  challengePath: "/dbsc-bound/challenge",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,16 @@
14
14
  export interface WrapFetchOptions {
15
15
  fetch?: typeof fetch;
16
16
  headerName?: string;
17
+ /**
18
+ * When true, the wrapper computes sha256(body) and signs it into the proof
19
+ * header. The server must be configured with `requireBoundProof({ signBody: true })`
20
+ * for the matching route. Defaults to false.
21
+ *
22
+ * Cost: one extra SHA-256 hash per request (~0.1 ms for typical JSON
23
+ * payloads). Cannot be used with streaming request bodies — the wrapper
24
+ * reads the body into memory to hash it.
25
+ */
26
+ signBody?: boolean;
17
27
  }
18
28
  export declare function wrapFetch(opts?: WrapFetchOptions): typeof fetch;
19
29
  //# sourceMappingURL=wrapFetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrapFetch.d.ts","sourceRoot":"","sources":["../../src/client/wrapFetch.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,KAAK,CA0BnE"}
1
+ {"version":3,"file":"wrapFetch.d.ts","sourceRoot":"","sources":["../../src/client/wrapFetch.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,KAAK,CAsDnE"}
@@ -2,6 +2,7 @@ import { getKeyRecord } from "./keystore.js";
2
2
  export function wrapFetch(opts = {}) {
3
3
  const base = opts.fetch ?? globalThis.fetch.bind(globalThis);
4
4
  const headerName = opts.headerName ?? "X-Dbsc-Bound-Proof";
5
+ const signBody = opts.signBody ?? false;
5
6
  return (async (input, init = {}) => {
6
7
  const rec = await getKeyRecord().catch(() => null);
7
8
  if (!rec)
@@ -10,14 +11,57 @@ export function wrapFetch(opts = {}) {
10
11
  const method = (init.method ?? "GET").toUpperCase();
11
12
  const offset = rec.clockOffsetMs ?? 0;
12
13
  const ts = Date.now() + offset;
13
- const message = `${rec.sessionId}.${method}.${url.pathname}.${ts}`;
14
+ let bodyHash = "";
15
+ let finalBody = init.body;
16
+ if (signBody && init.body !== undefined && init.body !== null) {
17
+ const bodyBytes = await readBodyBytes(init.body);
18
+ // Re-use the bytes as the actual request body so server hashes the same.
19
+ // Wrap in a Blob to satisfy BodyInit on every runtime (Node, browser).
20
+ finalBody = new Blob([bodyBytes]);
21
+ bodyHash = await sha256B64Url(bodyBytes);
22
+ }
23
+ const message = signBody && bodyHash
24
+ ? `${rec.sessionId}.${method}.${url.pathname}.${ts}.${bodyHash}`
25
+ : `${rec.sessionId}.${method}.${url.pathname}.${ts}`;
14
26
  const sigBytes = await crypto.subtle.sign({ name: "ECDSA", hash: "SHA-256" }, rec.keyPair.privateKey, new TextEncoder().encode(message));
15
27
  const sig = base64url(new Uint8Array(sigBytes));
16
28
  const headers = new Headers(init.headers);
17
- headers.set(headerName, `ts=${ts};sig=${sig}`);
18
- return base(input, { ...init, headers, credentials: init.credentials ?? "include" });
29
+ const headerValue = bodyHash
30
+ ? `ts=${ts};sig=${sig};bh=${bodyHash}`
31
+ : `ts=${ts};sig=${sig}`;
32
+ headers.set(headerName, headerValue);
33
+ const nextInit = {
34
+ ...init,
35
+ headers,
36
+ credentials: init.credentials ?? "include",
37
+ };
38
+ if (finalBody !== undefined && finalBody !== null) {
39
+ nextInit.body = finalBody;
40
+ }
41
+ return base(input, nextInit);
19
42
  });
20
43
  }
44
+ async function readBodyBytes(body) {
45
+ if (body instanceof Uint8Array)
46
+ return body;
47
+ if (body instanceof ArrayBuffer)
48
+ return new Uint8Array(body);
49
+ if (typeof body === "string")
50
+ return new TextEncoder().encode(body);
51
+ if (body instanceof Blob)
52
+ return new Uint8Array(await body.arrayBuffer());
53
+ if (body instanceof FormData || body instanceof URLSearchParams) {
54
+ return new TextEncoder().encode(body.toString());
55
+ }
56
+ if (body instanceof ReadableStream) {
57
+ throw new Error("wrapFetch with signBody: ReadableStream body is not supported");
58
+ }
59
+ return new TextEncoder().encode(String(body));
60
+ }
61
+ async function sha256B64Url(bytes) {
62
+ const digest = await crypto.subtle.digest("SHA-256", bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
63
+ return base64url(new Uint8Array(digest));
64
+ }
21
65
  function base64url(b) {
22
66
  let s = "";
23
67
  for (let i = 0; i < b.length; i++)
@@ -1 +1 @@
1
- {"version":3,"file":"wrapFetch.js","sourceRoot":"","sources":["../../src/client/wrapFetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAoB7C,MAAM,UAAU,SAAS,CAAC,OAAyB,EAAE;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,oBAAoB,CAAC;IAE3D,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAEnC,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAChF,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAC1E,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,IAAI,CAAC,CAAC;QACtC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;QAC/B,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,SAAS,IAAI,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CACvC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,GAAG,CAAC,OAAO,CAAC,UAAU,EACtB,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAClC,CAAC;QACF,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS,EAAE,CAAC,CAAC;IACvF,CAAC,CAAiB,CAAC;AACrB,CAAC;AAED,SAAS,SAAS,CAAC,CAAa;IAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC3E,CAAC"}
1
+ {"version":3,"file":"wrapFetch.js","sourceRoot":"","sources":["../../src/client/wrapFetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AA8B7C,MAAM,UAAU,SAAS,CAAC,OAAyB,EAAE;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,oBAAoB,CAAC;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;IAExC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAEnC,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAChF,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAC1E,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,IAAI,CAAC,CAAC;QACtC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;QAE/B,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,SAAS,GAAgC,IAAI,CAAC,IAAI,CAAC;QACvD,IAAI,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9D,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,yEAAyE;YACzE,uEAAuE;YACvE,SAAS,GAAG,IAAI,IAAI,CAAC,CAAC,SAAqB,CAAC,CAAC,CAAC;YAC9C,QAAQ,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,OAAO,GAAG,QAAQ,IAAI,QAAQ;YAClC,CAAC,CAAC,GAAG,GAAG,CAAC,SAAS,IAAI,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,IAAI,QAAQ,EAAE;YAChE,CAAC,CAAC,GAAG,GAAG,CAAC,SAAS,IAAI,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QAEvD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CACvC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,GAAG,CAAC,OAAO,CAAC,UAAU,EACtB,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAClC,CAAC;QACF,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEhD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,QAAQ;YAC1B,CAAC,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,QAAQ,EAAE;YACtC,CAAC,CAAC,MAAM,EAAE,QAAQ,GAAG,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAgB;YAC5B,GAAG,IAAI;YACP,OAAO;YACP,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS;SAC3C,CAAC;QACF,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YAClD,QAAQ,CAAC,IAAI,GAAG,SAAqB,CAAC;QACxC,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC,CAAiB,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAc;IACzC,IAAI,IAAI,YAAY,UAAU;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,IAAI,YAAY,WAAW;QAAE,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7D,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpE,IAAI,IAAI,YAAY,IAAI;QAAE,OAAO,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1E,IAAI,IAAI,YAAY,QAAQ,IAAI,IAAI,YAAY,eAAe,EAAE,CAAC;QAChE,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,IAAI,YAAY,cAAc,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,KAAiB;IAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CACvC,SAAS,EACT,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAgB,CACzF,CAAC;IACF,OAAO,SAAS,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,SAAS,CAAC,CAAa;IAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC3E,CAAC"}
@@ -6,10 +6,20 @@ export interface VerifyBoundProofRequest {
6
6
  method: string;
7
7
  path: string;
8
8
  timestampWindowMs?: number | undefined;
9
+ /**
10
+ * Raw request body bytes. When present, `signBody` is implied. The server
11
+ * computes sha256(bodyBytes) and demands the proof header carries a
12
+ * matching `bh=` field signed into the message. Pass undefined for GET/HEAD
13
+ * or when body signing is disabled.
14
+ */
15
+ bodyBytes?: Uint8Array | undefined;
16
+ /** Force body signing even on GET/HEAD requests (rare). */
17
+ signBody?: boolean | undefined;
9
18
  }
10
19
  export declare function verifyBoundProof(req: VerifyBoundProofRequest, storage: StorageAdapter): Promise<void>;
11
20
  export declare function parseProofHeader(s: string): {
12
21
  ts: number;
13
22
  sig: string;
23
+ bh?: string;
14
24
  } | null;
15
25
  //# sourceMappingURL=proof.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/bound/proof.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAGvD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,uBAAuB,EAC5B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAS9E"}
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/bound/proof.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAGvD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,uBAAuB,EAC5B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAW3F"}
@@ -18,7 +18,21 @@ export async function verifyBoundProof(req, storage) {
18
18
  if (!key) {
19
19
  throw new DbscVerificationError(ErrorCodes.KEY_NOT_FOUND, "no bound key for session");
20
20
  }
21
- const message = `${req.sessionId}.${req.method.toUpperCase()}.${req.path}.${parsed.ts}`;
21
+ const wantBodySig = req.signBody === true || (req.bodyBytes !== undefined && req.bodyBytes.byteLength > 0);
22
+ let expectedBodyHash = "";
23
+ if (wantBodySig) {
24
+ if (!parsed.bh) {
25
+ throw new DbscVerificationError(ErrorCodes.MALFORMED_PROOF, "proof header missing bh (body hash)");
26
+ }
27
+ const actualBodyHash = await sha256Base64Url(req.bodyBytes ?? new Uint8Array(0));
28
+ if (actualBodyHash !== parsed.bh) {
29
+ throw new DbscVerificationError(ErrorCodes.SIGNATURE_INVALID, "body hash mismatch");
30
+ }
31
+ expectedBodyHash = parsed.bh;
32
+ }
33
+ const message = wantBodySig
34
+ ? `${req.sessionId}.${req.method.toUpperCase()}.${req.path}.${parsed.ts}.${expectedBodyHash}`
35
+ : `${req.sessionId}.${req.method.toUpperCase()}.${req.path}.${parsed.ts}`;
22
36
  const ok = await verifyP256Signature(key.jwk, parsed.sig, message);
23
37
  if (!ok) {
24
38
  throw new DbscVerificationError(ErrorCodes.SIGNATURE_INVALID, "proof signature did not verify");
@@ -34,6 +48,19 @@ export function parseProofHeader(s) {
34
48
  const ts = Number(parts.ts);
35
49
  if (!Number.isFinite(ts) || !parts.sig)
36
50
  return null;
37
- return { ts, sig: parts.sig };
51
+ const out = { ts, sig: parts.sig };
52
+ if (parts.bh)
53
+ out.bh = parts.bh;
54
+ return out;
55
+ }
56
+ async function sha256Base64Url(bytes) {
57
+ const digest = await crypto.subtle.digest("SHA-256", bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
58
+ return base64UrlBytes(new Uint8Array(digest));
59
+ }
60
+ function base64UrlBytes(b) {
61
+ let s = "";
62
+ for (let i = 0; i < b.length; i++)
63
+ s += String.fromCharCode(b[i]);
64
+ return Buffer.from(s, "binary").toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
38
65
  }
39
66
  //# sourceMappingURL=proof.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../../src/core/bound/proof.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AACvD,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAUxC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAA4B,EAC5B,OAAuB;IAEvB,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC;IACxF,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,iBAAiB,IAAI,iBAAiB,CAAC;IAC5D,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,iBAAiB,EAAE,gCAAgC,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,aAAa,EAAE,0BAA0B,CAAC,CAAC;IACxF,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;IACxF,MAAM,EAAE,GAAG,MAAM,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACnE,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,iBAAiB,EAAE,gCAAgC,CAAC,CAAC;IAClG,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAAS;IACxC,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../../src/core/bound/proof.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,13 @@ export interface RequireBoundProofOptions {
6
6
  allowDbscWithoutProof?: boolean;
7
7
  /** Accepts proofs whose ts is within ±N ms of server time. Defaults to 5 minutes. */
8
8
  timestampWindowMs?: number;
9
+ /**
10
+ * When true, the proof must include a `bh=` body-hash field signed into the
11
+ * message. The middleware reads `req.body` as raw bytes — your route MUST
12
+ * use `express.raw({ type: '*\/*' })` for this to work, otherwise the parsed
13
+ * JSON body won't match the client's pre-hash bytes. Defaults to false.
14
+ */
15
+ signBody?: boolean;
9
16
  }
10
17
  /**
11
18
  * Gates a route on a fresh ECDSA P-256 proof signed by the bound key.
@@ -1 +1 @@
1
- {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/express/proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,8HAA8H;IAC9H,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,cAAc,CAgChF"}
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/express/proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,8HAA8H;IAC9H,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,cAAc,CAgDhF"}
@@ -9,6 +9,7 @@ import { verifyBoundProof, DbscVerificationError, } from "../core/index.js";
9
9
  */
10
10
  export function requireBoundProof(opts) {
11
11
  const allowDbsc = opts.allowDbscWithoutProof ?? true;
12
+ const signBody = opts.signBody ?? false;
12
13
  return async (req, res, next) => {
13
14
  const dbsc = res.locals.dbsc;
14
15
  if (!dbsc?.sessionId || dbsc.tier === "none") {
@@ -20,12 +21,30 @@ export function requireBoundProof(opts) {
20
21
  return;
21
22
  }
22
23
  try {
24
+ let bodyBytes;
25
+ if (signBody) {
26
+ const raw = req.body;
27
+ if (raw instanceof Buffer) {
28
+ bodyBytes = new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
29
+ }
30
+ else if (raw instanceof Uint8Array) {
31
+ bodyBytes = raw;
32
+ }
33
+ else if (typeof raw === "string") {
34
+ bodyBytes = new TextEncoder().encode(raw);
35
+ }
36
+ else {
37
+ bodyBytes = new Uint8Array(0);
38
+ }
39
+ }
23
40
  await verifyBoundProof({
24
41
  sessionId: dbsc.sessionId,
25
42
  proofHeader: req.headers["x-dbsc-bound-proof"],
26
43
  method: req.method,
27
44
  path: req.path,
28
45
  timestampWindowMs: opts.timestampWindowMs,
46
+ signBody,
47
+ bodyBytes,
29
48
  }, opts.storage);
30
49
  next();
31
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/express/proof.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAU1B;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA8B;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC;IACrD,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAiB,EAAE;QAC9E,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC;YACjF,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,EAAE,CAAC;YACtC,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,gBAAgB,CACpB;gBACE,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAuB;gBACpE,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;aAC1C,EACD,IAAI,CAAC,OAAO,CACb,CAAC;YACF,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;gBACzC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7D,OAAO;YACT,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/express/proof.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAiB1B;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA8B;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;IACxC,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAiB,EAAE;QAC9E,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC;YACjF,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,EAAE,CAAC;YACtC,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,IAAI,SAAiC,CAAC;YACtC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,GAAG,CAAC,IAAe,CAAC;gBAChC,IAAI,GAAG,YAAY,MAAM,EAAE,CAAC;oBAC1B,SAAS,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;gBACzE,CAAC;qBAAM,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;oBACrC,SAAS,GAAG,GAAG,CAAC;gBAClB,CAAC;qBAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACnC,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5C,CAAC;qBAAM,CAAC;oBACN,SAAS,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;YACD,MAAM,gBAAgB,CACpB;gBACE,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAuB;gBACpE,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,QAAQ;gBACR,SAAS;aACV,EACD,IAAI,CAAC,OAAO,CACb,CAAC;YACF,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;gBACzC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7D,OAAO;YACT,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -4,6 +4,13 @@ export interface RequireBoundProofOptions {
4
4
  storage: StorageAdapter;
5
5
  allowDbscWithoutProof?: boolean;
6
6
  timestampWindowMs?: number;
7
+ /**
8
+ * When true, the proof must include a `bh=` body-hash field. Your route
9
+ * MUST register a raw content-type parser via Fastify's
10
+ * `addContentTypeParser('*', { parseAs: 'buffer' }, ...)` for the route to
11
+ * deliver `req.body` as a Buffer matching the client's pre-hash bytes.
12
+ */
13
+ signBody?: boolean;
7
14
  }
8
15
  /**
9
16
  * Gates a route on a fresh ECDSA P-256 proof signed by the bound key.
@@ -1 +1 @@
1
- {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/fastify/proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgC,0BAA0B,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,0BAA0B,CA8B5F"}
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/fastify/proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgC,0BAA0B,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,0BAA0B,CA8C5F"}
@@ -5,6 +5,7 @@ import { verifyBoundProof, DbscVerificationError, } from "../core/index.js";
5
5
  */
6
6
  export function requireBoundProof(opts) {
7
7
  const allowDbsc = opts.allowDbscWithoutProof ?? true;
8
+ const signBody = opts.signBody ?? false;
8
9
  return async function preHandler(req, reply) {
9
10
  const dbsc = req.dbsc;
10
11
  if (!dbsc?.sessionId || dbsc.tier === "none") {
@@ -16,12 +17,30 @@ export function requireBoundProof(opts) {
16
17
  try {
17
18
  const proofHeaderRaw = req.headers["x-dbsc-bound-proof"];
18
19
  const proofHeader = Array.isArray(proofHeaderRaw) ? proofHeaderRaw[0] : proofHeaderRaw;
20
+ let bodyBytes;
21
+ if (signBody) {
22
+ const raw = req.body;
23
+ if (raw instanceof Buffer) {
24
+ bodyBytes = new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
25
+ }
26
+ else if (raw instanceof Uint8Array) {
27
+ bodyBytes = raw;
28
+ }
29
+ else if (typeof raw === "string") {
30
+ bodyBytes = new TextEncoder().encode(raw);
31
+ }
32
+ else {
33
+ bodyBytes = new Uint8Array(0);
34
+ }
35
+ }
19
36
  await verifyBoundProof({
20
37
  sessionId: dbsc.sessionId,
21
38
  proofHeader,
22
39
  method: req.method,
23
40
  path: req.url.split("?")[0] ?? req.url,
24
41
  timestampWindowMs: opts.timestampWindowMs,
42
+ signBody,
43
+ bodyBytes,
25
44
  }, opts.storage);
26
45
  }
27
46
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/fastify/proof.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAQ1B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA8B;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC;IACrD,OAAO,KAAK,UAAU,UAAU,CAAC,GAAmB,EAAE,KAAmB;QACvE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC;YACnF,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS;YAAE,OAAO;QAC9C,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;YACzD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;YACvF,MAAM,gBAAgB,CACpB;gBACE,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW;gBACX,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG;gBACtC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;aAC1C,EACD,IAAI,CAAC,OAAO,CACb,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;gBACzC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC/D,OAAO;YACT,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/fastify/proof.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAe1B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA8B;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;IACxC,OAAO,KAAK,UAAU,UAAU,CAAC,GAAmB,EAAE,KAAmB;QACvE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC;YACnF,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS;YAAE,OAAO;QAC9C,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;YACzD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;YACvF,IAAI,SAAiC,CAAC;YACtC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,GAAG,CAAC,IAAe,CAAC;gBAChC,IAAI,GAAG,YAAY,MAAM,EAAE,CAAC;oBAC1B,SAAS,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;gBACzE,CAAC;qBAAM,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;oBACrC,SAAS,GAAG,GAAG,CAAC;gBAClB,CAAC;qBAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACnC,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5C,CAAC;qBAAM,CAAC;oBACN,SAAS,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;YACD,MAAM,gBAAgB,CACpB;gBACE,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW;gBACX,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG;gBACtC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,QAAQ;gBACR,SAAS;aACV,EACD,IAAI,CAAC,OAAO,CACb,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;gBACzC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC/D,OAAO;YACT,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -4,6 +4,12 @@ export interface RequireBoundProofOptions {
4
4
  storage: StorageAdapter;
5
5
  allowDbscWithoutProof?: boolean;
6
6
  timestampWindowMs?: number;
7
+ /**
8
+ * When true, the middleware reads `c.req.raw.arrayBuffer()` and verifies a
9
+ * matching `bh=` body-hash field. Downstream handlers that need the body
10
+ * after this should use `c.req.arrayBuffer()` themselves (it is cached).
11
+ */
12
+ signBody?: boolean;
7
13
  }
8
14
  /**
9
15
  * Gates a route on a fresh ECDSA P-256 proof signed by the bound key.
@@ -1 +1 @@
1
- {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/hono/proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,iBAAiB,CAgCnF"}
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/hono/proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,iBAAiB,CAwCnF"}
@@ -5,6 +5,7 @@ import { verifyBoundProof, DbscVerificationError, } from "../core/index.js";
5
5
  */
6
6
  export function requireBoundProof(opts) {
7
7
  const allowDbsc = opts.allowDbscWithoutProof ?? true;
8
+ const signBody = opts.signBody ?? false;
8
9
  return async (c, next) => {
9
10
  const dbsc = c.get("dbsc");
10
11
  if (!dbsc?.sessionId || dbsc.tier === "none") {
@@ -17,12 +18,19 @@ export function requireBoundProof(opts) {
17
18
  try {
18
19
  const proofHeader = c.req.header("x-dbsc-bound-proof");
19
20
  const url = new URL(c.req.url);
21
+ let bodyBytes;
22
+ if (signBody) {
23
+ const ab = await c.req.arrayBuffer();
24
+ bodyBytes = new Uint8Array(ab);
25
+ }
20
26
  await verifyBoundProof({
21
27
  sessionId: dbsc.sessionId,
22
28
  proofHeader,
23
29
  method: c.req.method,
24
30
  path: url.pathname,
25
31
  timestampWindowMs: opts.timestampWindowMs,
32
+ signBody,
33
+ bodyBytes,
26
34
  }, opts.storage);
27
35
  await next();
28
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/hono/proof.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAQ1B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA8B;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC;IACrD,OAAO,KAAK,EAAE,CAAU,EAAE,IAAI,EAA4B,EAAE;QAC1D,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,EAAE,CAAC;YACtC,MAAM,IAAI,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;YACvD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,gBAAgB,CACpB;gBACE,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW;gBACX,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;gBACpB,IAAI,EAAE,GAAG,CAAC,QAAQ;gBAClB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;aAC1C,EACD,IAAI,CAAC,OAAO,CACb,CAAC;YACF,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;gBACzC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/hono/proof.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAc1B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA8B;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;IACxC,OAAO,KAAK,EAAE,CAAU,EAAE,IAAI,EAA4B,EAAE;QAC1D,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,EAAE,CAAC;YACtC,MAAM,IAAI,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;YACvD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,SAAiC,CAAC;YACtC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrC,SAAS,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;YACjC,CAAC;YACD,MAAM,gBAAgB,CACpB;gBACE,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW;gBACX,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;gBACpB,IAAI,EAAE,GAAG,CAAC,QAAQ;gBAClB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,QAAQ;gBACR,SAAS;aACV,EACD,IAAI,CAAC,OAAO,CACb,CAAC;YACF,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;gBACzC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -5,6 +5,13 @@ export interface RequireBoundProofOptions {
5
5
  storage: StorageAdapter;
6
6
  allowDbscWithoutProof?: boolean;
7
7
  timestampWindowMs?: number;
8
+ /**
9
+ * When true, the helper calls `req.arrayBuffer()` and verifies a matching
10
+ * `bh=` body-hash field. Note: NextRequest.arrayBuffer() consumes the body
11
+ * stream — the caller must either re-read the body via a clone or call
12
+ * `req.json()` on a clone afterwards.
13
+ */
14
+ signBody?: boolean;
8
15
  }
9
16
  export interface RequireBoundProofContext {
10
17
  sessionId: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/nextjs/proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,MAAM,uBAAuB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC;AAE3F;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,wBAAwB,EACjC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,uBAAuB,CAAC,CAkClC"}
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/nextjs/proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,MAAM,uBAAuB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC;AAE3F;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,wBAAwB,EACjC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,uBAAuB,CAAC,CA0ClC"}
@@ -21,12 +21,20 @@ export async function requireBoundProof(req, session, opts) {
21
21
  if (session.tier === "dbsc" && allowDbsc)
22
22
  return { ok: true };
23
23
  try {
24
+ const signBody = opts.signBody ?? false;
25
+ let bodyBytes;
26
+ if (signBody) {
27
+ const ab = await req.clone().arrayBuffer();
28
+ bodyBytes = new Uint8Array(ab);
29
+ }
24
30
  await verifyBoundProof({
25
31
  sessionId: session.sessionId,
26
32
  proofHeader: req.headers.get("x-dbsc-bound-proof") ?? undefined,
27
33
  method: req.method,
28
34
  path: req.nextUrl.pathname,
29
35
  timestampWindowMs: opts.timestampWindowMs,
36
+ signBody,
37
+ bodyBytes,
30
38
  }, opts.storage);
31
39
  return { ok: true };
32
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/nextjs/proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAGtB,MAAM,kBAAkB,CAAC;AAe1B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAgB,EAChB,OAAiC,EACjC,IAA8B;IAE9B,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC;IACrD,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAClD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,YAAY,CAAC,IAAI,CACzB,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAClD,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB;SACF,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,gBAAgB,CACpB;YACE,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,SAAS;YAC/D,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ;YAC1B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;SAC1C,EACD,IAAI,CAAC,OAAO,CACb,CAAC;QACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;YACzC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;aACrF,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/nextjs/proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAGtB,MAAM,kBAAkB,CAAC;AAsB1B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAgB,EAChB,OAAiC,EACjC,IAA8B;IAE9B,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC;IACrD,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAClD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,YAAY,CAAC,IAAI,CACzB,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAClD,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB;SACF,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;QACxC,IAAI,SAAiC,CAAC;QACtC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC;YAC3C,SAAS,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC;QACD,MAAM,gBAAgB,CACpB;YACE,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,SAAS;YAC/D,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ;YAC1B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,QAAQ;YACR,SAAS;SACV,EACD,IAAI,CAAC,OAAO,CACb,CAAC;QACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;YACzC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;aACrF,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbsc-toolkit",
3
- "version": "2.2.0",
3
+ "version": "2.3.1",
4
4
  "description": "Server-side Device Bound Session Credentials (DBSC) for Node.js plus a Web Crypto polyfill for Firefox, Safari, and older Chromium. Cookie-theft protection on every modern browser.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -98,9 +98,11 @@
98
98
  "@types/pg": "^8.0.0",
99
99
  "cookie-parser": "^1.4.7",
100
100
  "express": "^5.2.1",
101
+ "fake-indexeddb": "^6.2.5",
101
102
  "fastify": "^5.8.5",
102
103
  "hono": "^4.0.0",
103
104
  "ioredis": "^5.3.0",
105
+ "jsdom": "^29.1.1",
104
106
  "next": "^16.2.6",
105
107
  "pg": "^8.11.0",
106
108
  "rimraf": "^6.1.3",