dbsc-toolkit 2.13.1 → 2.13.3
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 +4 -1
- package/dist/core/protocol/headers.d.ts +7 -0
- package/dist/core/protocol/headers.d.ts.map +1 -1
- package/dist/core/protocol/headers.js +3 -4
- package/dist/core/protocol/headers.js.map +1 -1
- package/dist/express/require-proof.d.ts.map +1 -1
- package/dist/express/require-proof.js +19 -20
- package/dist/express/require-proof.js.map +1 -1
- package/dist/fastify/require-proof.d.ts.map +1 -1
- package/dist/fastify/require-proof.js +17 -18
- package/dist/fastify/require-proof.js.map +1 -1
- package/dist/hono/require-proof.d.ts.map +1 -1
- package/dist/hono/require-proof.js +17 -18
- package/dist/hono/require-proof.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,9 @@ Native DBSC currently ships only on Chromium-based browsers. That leaves Firefox
|
|
|
62
62
|
|
|
63
63
|
DBSC Toolkit extends device-bound sessions to those browsers through a Web Crypto polyfill, so every user gets the same per-request guard. Today it's one of the few open-source implementations providing cross-browser DBSC-style protection for Node.js.
|
|
64
64
|
|
|
65
|
-
It's built in two layers. The protocol — every header, JWS shape, and the storage and cookie contracts — is written up as a **language-neutral spec** in [`spec/`](./spec/), with real test vectors. This Node.js package is the **reference implementation** of that spec. The spec is designed so a conforming server can be built in any ecosystem
|
|
65
|
+
It's built in two layers. The protocol — every header, JWS shape, and the storage and cookie contracts — is written up as a **language-neutral spec** in [`spec/`](./spec/), with real test vectors. This Node.js package is the **reference implementation** of that spec. The spec is designed so a conforming server can be built in any ecosystem, and the [test vectors](./spec/vectors) are what each one targets.
|
|
66
|
+
|
|
67
|
+
**PHP implementation:** [report-uri/dbsc-php](https://github.com/report-uri/dbsc-php) — an independent native-only DBSC server by Scott Helme (Report URI). It was built separately and cross-validates against these same vectors, so the two implementations verify each other's ES256 proofs.
|
|
66
68
|
|
|
67
69
|
## Install
|
|
68
70
|
|
|
@@ -264,6 +266,7 @@ The wire protocol is documented as a language-neutral spec in [`spec/`](./spec/)
|
|
|
264
266
|
## Docs
|
|
265
267
|
|
|
266
268
|
- **Protocol spec (language-neutral):** [spec/](./spec/) · [conformance](./spec/09-conformance.md) · [test vectors](./spec/vectors)
|
|
269
|
+
- **Other languages — PHP:** [report-uri/dbsc-php](https://github.com/report-uri/dbsc-php) (independent implementation, cross-validated against these vectors)
|
|
267
270
|
- **Concepts & protocol:** [HOW-IT-WORKS.md](./HOW-IT-WORKS.md)
|
|
268
271
|
- **Getting started:** [docs/quickstart.md](./docs/quickstart.md)
|
|
269
272
|
- **Add to an existing app:** [docs/guide.md](./docs/guide.md)
|
|
@@ -5,6 +5,13 @@ export interface RegistrationHeaderOptions {
|
|
|
5
5
|
/** @deprecated misnamed alias for registrationPath; kept for back-compat. */
|
|
6
6
|
refreshPath?: string;
|
|
7
7
|
challenge: string;
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated No longer emitted. The W3C draft defines no `id` parameter on
|
|
10
|
+
* `Secure-Session-Registration` — the bound cookie name is carried by the JSON
|
|
11
|
+
* registration response (`credentials[].name`), not the header. Chrome ignored
|
|
12
|
+
* this param; it was a no-op. Accepted for back-compat so existing callers keep
|
|
13
|
+
* compiling. See spec/vectors/registration-header.json.
|
|
14
|
+
*/
|
|
8
15
|
cookieName?: string;
|
|
9
16
|
}
|
|
10
17
|
export declare function buildRegistrationHeader(opts: RegistrationHeaderOptions): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../../src/core/protocol/headers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC9B,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,yBAAyB,GAAG,MAAM,CAO/E;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1C,MAAM,CAMR;AAED,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AACjE,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAC3D,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAEvD,eAAO,MAAM,0BAA0B,6BAA6B,CAAC;AACrE,eAAO,MAAM,sBAAsB,yBAAyB,CAAC;AAC7D,eAAO,MAAM,uBAAuB,0BAA0B,CAAC;AAC/D,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAE3D,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,MAAM,GAAG,SAAS,CAIpB;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,YAAY,EAAE,CAgChB"}
|
|
1
|
+
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../../src/core/protocol/headers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC9B,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,yBAAyB,GAAG,MAAM,CAO/E;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1C,MAAM,CAMR;AAED,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AACjE,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAC3D,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAEvD,eAAO,MAAM,0BAA0B,6BAA6B,CAAC;AACrE,eAAO,MAAM,sBAAsB,yBAAyB,CAAC;AAC7D,eAAO,MAAM,uBAAuB,0BAA0B,CAAC;AAC/D,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAE3D,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,MAAM,GAAG,SAAS,CAIpB;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,YAAY,EAAE,CAgChB"}
|
|
@@ -3,10 +3,9 @@ export function buildRegistrationHeader(opts) {
|
|
|
3
3
|
const path = opts.registrationPath ?? opts.refreshPath;
|
|
4
4
|
if (!path)
|
|
5
5
|
throw new Error("buildRegistrationHeader: registrationPath is required");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return parts.join(";");
|
|
6
|
+
// No `id` parameter: it is not defined for this header in the W3C draft. The
|
|
7
|
+
// cookie name is bound via the JSON registration response, not here.
|
|
8
|
+
return [`(${alg})`, `path="${path}"`, `challenge="${opts.challenge}"`].join(";");
|
|
10
9
|
}
|
|
11
10
|
export function buildChallengeHeader(jti, sessionId) {
|
|
12
11
|
const base = `"${jti}"`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../../src/core/protocol/headers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../../src/core/protocol/headers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-proof.d.ts","sourceRoot":"","sources":["../../src/express/require-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI7E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"require-proof.d.ts","sourceRoot":"","sources":["../../src/express/require-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI7E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,cAAc,CAyC3E"}
|
|
@@ -18,7 +18,6 @@ import { DBSC_INTERNAL } from "./index.js";
|
|
|
18
18
|
* middleware populates; pass `{ storage }` only to override.
|
|
19
19
|
*/
|
|
20
20
|
export function requireProof(opts = {}) {
|
|
21
|
-
let proofHandler;
|
|
22
21
|
return (req, res, next) => {
|
|
23
22
|
const dbsc = res.locals.dbsc;
|
|
24
23
|
const tier = dbsc?.tier ?? "none";
|
|
@@ -32,27 +31,27 @@ export function requireProof(opts = {}) {
|
|
|
32
31
|
});
|
|
33
32
|
return;
|
|
34
33
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
error: "requireProof: storage unavailable — mount dbsc() / createDbsc().install() before this route, or pass { storage }",
|
|
41
|
-
});
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
// When the bound polyfill is disabled, no bound key is ever registered,
|
|
45
|
-
// so a native dbsc-tier session has nothing to prove with. Auto-relax:
|
|
46
|
-
// pass dbsc through. An explicit option still wins.
|
|
47
|
-
const allowDbscWithoutProof = opts.allowDbscWithoutProof ?? (internal?.boundEnabled === false ? true : undefined);
|
|
48
|
-
proofHandler = requireBoundProof({
|
|
49
|
-
storage,
|
|
50
|
-
signBody: true,
|
|
51
|
-
...(allowDbscWithoutProof !== undefined && { allowDbscWithoutProof }),
|
|
52
|
-
...(opts.timestampWindowMs !== undefined && { timestampWindowMs: opts.timestampWindowMs }),
|
|
53
|
-
...(internal?.replayCache !== undefined && { replayCache: internal.replayCache }),
|
|
34
|
+
const internal = res.locals[DBSC_INTERNAL];
|
|
35
|
+
const storage = opts.storage ?? internal?.storage;
|
|
36
|
+
if (!storage) {
|
|
37
|
+
res.status(500).json({
|
|
38
|
+
error: "requireProof: storage unavailable — mount dbsc() / createDbsc().install() before this route, or pass { storage }",
|
|
54
39
|
});
|
|
40
|
+
return;
|
|
55
41
|
}
|
|
42
|
+
// When the bound polyfill is disabled, no bound key is ever registered, so a
|
|
43
|
+
// native dbsc-tier session has nothing to prove with. Auto-relax: pass dbsc
|
|
44
|
+
// through. An explicit option still wins. Resolved per request — boundEnabled
|
|
45
|
+
// can differ between requests (e.g. two kits dispatched by mode), so the
|
|
46
|
+
// handler must not be memoized across the first call's value.
|
|
47
|
+
const allowDbscWithoutProof = opts.allowDbscWithoutProof ?? (internal?.boundEnabled === false ? true : undefined);
|
|
48
|
+
const proofHandler = requireBoundProof({
|
|
49
|
+
storage,
|
|
50
|
+
signBody: true,
|
|
51
|
+
...(allowDbscWithoutProof !== undefined && { allowDbscWithoutProof }),
|
|
52
|
+
...(opts.timestampWindowMs !== undefined && { timestampWindowMs: opts.timestampWindowMs }),
|
|
53
|
+
...(internal?.replayCache !== undefined && { replayCache: internal.replayCache }),
|
|
54
|
+
});
|
|
56
55
|
proofHandler(req, res, next);
|
|
57
56
|
};
|
|
58
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-proof.js","sourceRoot":"","sources":["../../src/express/require-proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,
|
|
1
|
+
{"version":3,"file":"require-proof.js","sourceRoot":"","sources":["../../src/express/require-proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;QAC/D,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,MAAM,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;QACpC,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,+BAA+B;gBACtC,WAAW,EAAE,MAAM;gBACnB,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC;gBAChC,OAAO;aACR,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAI,GAAG,CAAC,MAAuC,CAAC,aAAa,CAE9D,CAAC;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,OAAO,CAAC;QAClD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EACH,kHAAkH;aACrH,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,6EAA6E;QAC7E,4EAA4E;QAC5E,8EAA8E;QAC9E,yEAAyE;QACzE,8DAA8D;QAC9D,MAAM,qBAAqB,GACzB,IAAI,CAAC,qBAAqB,IAAI,CAAC,QAAQ,EAAE,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtF,MAAM,YAAY,GAAG,iBAAiB,CAAC;YACrC,OAAO;YACP,QAAQ,EAAE,IAAI;YACd,GAAG,CAAC,qBAAqB,KAAK,SAAS,IAAI,EAAE,qBAAqB,EAAE,CAAC;YACrE,GAAG,CAAC,IAAI,CAAC,iBAAiB,KAAK,SAAS,IAAI,EAAE,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC1F,GAAG,CAAC,QAAQ,EAAE,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC;SAClF,CAAC,CAAC;QACH,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-proof.d.ts","sourceRoot":"","sources":["../../src/fastify/require-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgC,0BAA0B,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI7E;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,0BAA0B,
|
|
1
|
+
{"version":3,"file":"require-proof.d.ts","sourceRoot":"","sources":["../../src/fastify/require-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgC,0BAA0B,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI7E;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,0BAA0B,CAuCvF"}
|
|
@@ -12,7 +12,6 @@ import { DBSC_INTERNAL } from "./index.js";
|
|
|
12
12
|
* context the `dbsc` plugin populates; pass `{ storage }` only to override.
|
|
13
13
|
*/
|
|
14
14
|
export function requireProof(opts = {}) {
|
|
15
|
-
let proofHandler;
|
|
16
15
|
return async function preHandler(req, reply) {
|
|
17
16
|
const dbsc = req.dbsc;
|
|
18
17
|
const tier = dbsc?.tier ?? "none";
|
|
@@ -26,25 +25,25 @@ export function requireProof(opts = {}) {
|
|
|
26
25
|
});
|
|
27
26
|
return;
|
|
28
27
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
error: "requireProof: storage unavailable — register the dbsc plugin / createDbsc().install() first, or pass { storage }",
|
|
35
|
-
});
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
// bound polyfill off → no bound key exists → auto-relax the dbsc tier.
|
|
39
|
-
const allowDbscWithoutProof = opts.allowDbscWithoutProof ?? (internal?.boundEnabled === false ? true : undefined);
|
|
40
|
-
proofHandler = requireBoundProof({
|
|
41
|
-
storage,
|
|
42
|
-
signBody: true,
|
|
43
|
-
...(allowDbscWithoutProof !== undefined && { allowDbscWithoutProof }),
|
|
44
|
-
...(opts.timestampWindowMs !== undefined && { timestampWindowMs: opts.timestampWindowMs }),
|
|
45
|
-
...(internal?.replayCache !== undefined && { replayCache: internal.replayCache }),
|
|
28
|
+
const internal = req[DBSC_INTERNAL];
|
|
29
|
+
const storage = opts.storage ?? internal?.storage;
|
|
30
|
+
if (!storage) {
|
|
31
|
+
reply.status(500).send({
|
|
32
|
+
error: "requireProof: storage unavailable — register the dbsc plugin / createDbsc().install() first, or pass { storage }",
|
|
46
33
|
});
|
|
34
|
+
return;
|
|
47
35
|
}
|
|
36
|
+
// bound polyfill off → no bound key exists → auto-relax the dbsc tier.
|
|
37
|
+
// Resolved per request — boundEnabled can differ between requests (e.g. two
|
|
38
|
+
// plugins dispatched by mode), so the handler must not be memoized.
|
|
39
|
+
const allowDbscWithoutProof = opts.allowDbscWithoutProof ?? (internal?.boundEnabled === false ? true : undefined);
|
|
40
|
+
const proofHandler = requireBoundProof({
|
|
41
|
+
storage,
|
|
42
|
+
signBody: true,
|
|
43
|
+
...(allowDbscWithoutProof !== undefined && { allowDbscWithoutProof }),
|
|
44
|
+
...(opts.timestampWindowMs !== undefined && { timestampWindowMs: opts.timestampWindowMs }),
|
|
45
|
+
...(internal?.replayCache !== undefined && { replayCache: internal.replayCache }),
|
|
46
|
+
});
|
|
48
47
|
await proofHandler(req, reply);
|
|
49
48
|
};
|
|
50
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-proof.js","sourceRoot":"","sources":["../../src/fastify/require-proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,
|
|
1
|
+
{"version":3,"file":"require-proof.js","sourceRoot":"","sources":["../../src/fastify/require-proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,OAAO,KAAK,UAAU,UAAU,CAAC,GAAmB,EAAE,KAAmB;QACvE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,MAAM,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;QACpC,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACrB,KAAK,EAAE,+BAA+B;gBACtC,WAAW,EAAE,MAAM;gBACnB,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC;gBAChC,OAAO;aACR,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAI,GAA+C,CAAC,aAAa,CAElE,CAAC;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,OAAO,CAAC;QAClD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACrB,KAAK,EACH,kHAAkH;aACrH,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,uEAAuE;QACvE,4EAA4E;QAC5E,oEAAoE;QACpE,MAAM,qBAAqB,GACzB,IAAI,CAAC,qBAAqB,IAAI,CAAC,QAAQ,EAAE,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtF,MAAM,YAAY,GAAG,iBAAiB,CAAC;YACrC,OAAO;YACP,QAAQ,EAAE,IAAI;YACd,GAAG,CAAC,qBAAqB,KAAK,SAAS,IAAI,EAAE,qBAAqB,EAAE,CAAC;YACrE,GAAG,CAAC,IAAI,CAAC,iBAAiB,KAAK,SAAS,IAAI,EAAE,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC1F,GAAG,CAAC,QAAQ,EAAE,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC;SAClF,CAAC,CAAC;QACH,MAAO,YAA4E,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClG,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-proof.d.ts","sourceRoot":"","sources":["../../src/hono/require-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI7E;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"require-proof.d.ts","sourceRoot":"","sources":["../../src/hono/require-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI7E;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,iBAAiB,CA2C9E"}
|
|
@@ -11,7 +11,6 @@ import { DBSC_INTERNAL } from "./index.js";
|
|
|
11
11
|
* populates; pass `{ storage }` only to override.
|
|
12
12
|
*/
|
|
13
13
|
export function requireProof(opts = {}) {
|
|
14
|
-
let proofHandler;
|
|
15
14
|
return async (c, next) => {
|
|
16
15
|
const dbsc = c.get("dbsc");
|
|
17
16
|
const tier = dbsc?.tier ?? "none";
|
|
@@ -24,24 +23,24 @@ export function requireProof(opts = {}) {
|
|
|
24
23
|
skipped,
|
|
25
24
|
}, 403);
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}, 500);
|
|
34
|
-
}
|
|
35
|
-
// bound polyfill off → no bound key exists → auto-relax the dbsc tier.
|
|
36
|
-
const allowDbscWithoutProof = opts.allowDbscWithoutProof ?? (internal?.boundEnabled === false ? true : undefined);
|
|
37
|
-
proofHandler = requireBoundProof({
|
|
38
|
-
storage,
|
|
39
|
-
signBody: true,
|
|
40
|
-
...(allowDbscWithoutProof !== undefined && { allowDbscWithoutProof }),
|
|
41
|
-
...(opts.timestampWindowMs !== undefined && { timestampWindowMs: opts.timestampWindowMs }),
|
|
42
|
-
...(internal?.replayCache !== undefined && { replayCache: internal.replayCache }),
|
|
43
|
-
});
|
|
26
|
+
const internal = dbsc?.[DBSC_INTERNAL];
|
|
27
|
+
const storage = opts.storage ?? internal?.storage;
|
|
28
|
+
if (!storage) {
|
|
29
|
+
return c.json({
|
|
30
|
+
error: "requireProof: storage unavailable — mount dbsc() / createDbsc().install() before this route, or pass { storage }",
|
|
31
|
+
}, 500);
|
|
44
32
|
}
|
|
33
|
+
// bound polyfill off → no bound key exists → auto-relax the dbsc tier.
|
|
34
|
+
// Resolved per request — boundEnabled can differ between requests (e.g. two
|
|
35
|
+
// middlewares dispatched by mode), so the handler must not be memoized.
|
|
36
|
+
const allowDbscWithoutProof = opts.allowDbscWithoutProof ?? (internal?.boundEnabled === false ? true : undefined);
|
|
37
|
+
const proofHandler = requireBoundProof({
|
|
38
|
+
storage,
|
|
39
|
+
signBody: true,
|
|
40
|
+
...(allowDbscWithoutProof !== undefined && { allowDbscWithoutProof }),
|
|
41
|
+
...(opts.timestampWindowMs !== undefined && { timestampWindowMs: opts.timestampWindowMs }),
|
|
42
|
+
...(internal?.replayCache !== undefined && { replayCache: internal.replayCache }),
|
|
43
|
+
});
|
|
45
44
|
return proofHandler(c, next);
|
|
46
45
|
};
|
|
47
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-proof.js","sourceRoot":"","sources":["../../src/hono/require-proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,
|
|
1
|
+
{"version":3,"file":"require-proof.js","sourceRoot":"","sources":["../../src/hono/require-proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,MAAM,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;QACpC,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,OAAO,CAAC,CAAC,IAAI,CACX;gBACE,KAAK,EAAE,+BAA+B;gBACtC,WAAW,EAAE,MAAM;gBACnB,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC;gBAChC,OAAO;aACR,EACD,GAAG,CACJ,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAI,IAA4D,EAAE,CAC9E,aAAa,CACc,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,OAAO,CAAC;QAClD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,CAAC,IAAI,CACX;gBACE,KAAK,EACH,kHAAkH;aACrH,EACD,GAAG,CACJ,CAAC;QACJ,CAAC;QACD,uEAAuE;QACvE,4EAA4E;QAC5E,wEAAwE;QACxE,MAAM,qBAAqB,GACzB,IAAI,CAAC,qBAAqB,IAAI,CAAC,QAAQ,EAAE,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtF,MAAM,YAAY,GAAG,iBAAiB,CAAC;YACrC,OAAO;YACP,QAAQ,EAAE,IAAI;YACd,GAAG,CAAC,qBAAqB,KAAK,SAAS,IAAI,EAAE,qBAAqB,EAAE,CAAC;YACrE,GAAG,CAAC,IAAI,CAAC,iBAAiB,KAAK,SAAS,IAAI,EAAE,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC1F,GAAG,CAAC,QAAQ,EAAE,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC;SAClF,CAAC,CAAC;QACH,OAAO,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbsc-toolkit",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.3",
|
|
4
4
|
"description": "Server-side Device Bound Session Credentials (DBSC) for Node.js — Express, Fastify, Hono and Next.js adapters — 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",
|