dbsc-toolkit 2.6.1 → 2.8.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/README.md +5 -3
- package/dist/client/index.d.ts +8 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +49 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/installFetchInterceptor.d.ts +41 -0
- package/dist/client/installFetchInterceptor.d.ts.map +1 -0
- package/dist/client/installFetchInterceptor.js +79 -0
- package/dist/client/installFetchInterceptor.js.map +1 -0
- package/dist/client/wrapFetch.d.ts +7 -1
- package/dist/client/wrapFetch.d.ts.map +1 -1
- package/dist/client/wrapFetch.js +1 -1
- package/dist/client/wrapFetch.js.map +1 -1
- package/dist/core/bound/proof.d.ts +8 -1
- package/dist/core/bound/proof.d.ts.map +1 -1
- package/dist/core/bound/proof.js +19 -2
- package/dist/core/bound/proof.js.map +1 -1
- package/dist/core/bound/refresh.d.ts.map +1 -1
- package/dist/core/bound/refresh.js +7 -3
- package/dist/core/bound/refresh.js.map +1 -1
- package/dist/core/bound/registration.d.ts.map +1 -1
- package/dist/core/bound/registration.js +14 -3
- package/dist/core/bound/registration.js.map +1 -1
- package/dist/core/errors.d.ts +3 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +7 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/protect-policy.d.ts +17 -10
- package/dist/core/protect-policy.d.ts.map +1 -1
- package/dist/core/protect-policy.js.map +1 -1
- package/dist/core/protocol/refresh.js +2 -2
- package/dist/core/protocol/refresh.js.map +1 -1
- package/dist/core/protocol/registration.d.ts.map +1 -1
- package/dist/core/protocol/registration.js +3 -2
- package/dist/core/protocol/registration.js.map +1 -1
- package/dist/core/replay/interface.d.ts +10 -0
- package/dist/core/replay/interface.d.ts.map +1 -0
- package/dist/core/replay/interface.js +11 -0
- package/dist/core/replay/interface.js.map +1 -0
- package/dist/core/telemetry/polyfill-missing.d.ts +21 -0
- package/dist/core/telemetry/polyfill-missing.d.ts.map +1 -0
- package/dist/core/telemetry/polyfill-missing.js +35 -0
- package/dist/core/telemetry/polyfill-missing.js.map +1 -0
- package/dist/core/testing/memory-storage-stub.d.ts +3 -3
- package/dist/core/testing/memory-storage-stub.d.ts.map +1 -1
- package/dist/core/testing/memory-storage-stub.js +20 -8
- package/dist/core/testing/memory-storage-stub.js.map +1 -1
- package/dist/core/types.d.ts +75 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/express/index.d.ts +3 -1
- package/dist/express/index.d.ts.map +1 -1
- package/dist/express/index.js +34 -4
- package/dist/express/index.js.map +1 -1
- package/dist/express/proof.d.ts +16 -2
- package/dist/express/proof.d.ts.map +1 -1
- package/dist/express/proof.js +2 -1
- package/dist/express/proof.js.map +1 -1
- package/dist/express/require-proof.d.ts.map +1 -1
- package/dist/express/require-proof.js +1 -0
- package/dist/express/require-proof.js.map +1 -1
- package/dist/fastify/index.d.ts +2 -1
- package/dist/fastify/index.d.ts.map +1 -1
- package/dist/fastify/index.js +27 -4
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/proof.d.ts +8 -2
- package/dist/fastify/proof.d.ts.map +1 -1
- package/dist/fastify/proof.js +2 -1
- package/dist/fastify/proof.js.map +1 -1
- package/dist/fastify/require-proof.d.ts.map +1 -1
- package/dist/fastify/require-proof.js +1 -0
- package/dist/fastify/require-proof.js.map +1 -1
- package/dist/hono/index.d.ts +2 -1
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +27 -4
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/proof.d.ts +8 -2
- package/dist/hono/proof.d.ts.map +1 -1
- package/dist/hono/proof.js +2 -1
- package/dist/hono/proof.js.map +1 -1
- package/dist/hono/require-proof.d.ts.map +1 -1
- package/dist/hono/require-proof.js +1 -0
- package/dist/hono/require-proof.js.map +1 -1
- package/dist/nextjs/create-dbsc.d.ts.map +1 -1
- package/dist/nextjs/create-dbsc.js +5 -1
- package/dist/nextjs/create-dbsc.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -0
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/index.js +32 -4
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/proof.d.ts +8 -2
- package/dist/nextjs/proof.d.ts.map +1 -1
- package/dist/nextjs/proof.js +2 -1
- package/dist/nextjs/proof.js.map +1 -1
- package/dist/nextjs/require-proof.d.ts.map +1 -1
- package/dist/nextjs/require-proof.js +1 -0
- package/dist/nextjs/require-proof.js.map +1 -1
- package/dist/storage/memory/index.d.ts +4 -3
- package/dist/storage/memory/index.d.ts.map +1 -1
- package/dist/storage/memory/index.js +23 -8
- package/dist/storage/memory/index.js.map +1 -1
- package/dist/storage/memory/replay-cache.d.ts +15 -0
- package/dist/storage/memory/replay-cache.d.ts.map +1 -0
- package/dist/storage/memory/replay-cache.js +28 -0
- package/dist/storage/memory/replay-cache.js.map +1 -0
- package/dist/storage/postgres/index.d.ts +3 -3
- package/dist/storage/postgres/index.d.ts.map +1 -1
- package/dist/storage/postgres/index.js +24 -7
- package/dist/storage/postgres/index.js.map +1 -1
- package/dist/storage/redis/index.d.ts +4 -3
- package/dist/storage/redis/index.d.ts.map +1 -1
- package/dist/storage/redis/index.js +49 -10
- package/dist/storage/redis/index.js.map +1 -1
- package/dist/storage/redis/replay-cache.d.ts +17 -0
- package/dist/storage/redis/replay-cache.d.ts.map +1 -0
- package/dist/storage/redis/replay-cache.js +22 -0
- package/dist/storage/redis/replay-cache.js.map +1 -0
- package/migrations/002_bound_key_kind.sql +26 -0
- package/package.json +1 -1
package/dist/core/errors.js
CHANGED
|
@@ -33,10 +33,17 @@ export const ErrorCodes = {
|
|
|
33
33
|
JTI_MISMATCH: "JTI_MISMATCH",
|
|
34
34
|
SIGNATURE_INVALID: "SIGNATURE_INVALID",
|
|
35
35
|
KEY_NOT_FOUND: "KEY_NOT_FOUND",
|
|
36
|
+
// v2.8+: kind-specific variants so the client can distinguish a storage
|
|
37
|
+
// wipe (the native key is gone — session must restart from /login) from a
|
|
38
|
+
// missing polyfill key (re-init the client SDK to re-register without a
|
|
39
|
+
// full logout).
|
|
40
|
+
KEY_NOT_FOUND_NATIVE: "KEY_NOT_FOUND_NATIVE",
|
|
41
|
+
KEY_NOT_FOUND_BOUND: "KEY_NOT_FOUND_BOUND",
|
|
36
42
|
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
37
43
|
SESSION_ALREADY_REGISTERED: "SESSION_ALREADY_REGISTERED",
|
|
38
44
|
RATE_LIMITED: "RATE_LIMITED",
|
|
39
45
|
MISSING_PROOF: "MISSING_PROOF",
|
|
40
46
|
MALFORMED_PROOF: "MALFORMED_PROOF",
|
|
47
|
+
PROOF_REPLAY: "PROOF_REPLAY",
|
|
41
48
|
};
|
|
42
49
|
//# sourceMappingURL=errors.js.map
|
package/dist/core/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IACrC,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,uBAAuB,EAAE,yBAAyB;IAClD,aAAa,EAAE,eAAe;IAC9B,WAAW,EAAE,aAAa;IAC1B,iBAAiB,EAAE,mBAAmB;IACtC,mBAAmB,EAAE,qBAAqB;IAC1C,iBAAiB,EAAE,mBAAmB;IACtC,kBAAkB,EAAE,oBAAoB;IACxC,YAAY,EAAE,cAAc;IAC5B,iBAAiB,EAAE,mBAAmB;IACtC,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;IACtC,0BAA0B,EAAE,4BAA4B;IACxD,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,eAAe;IAC9B,eAAe,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IACrC,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,uBAAuB,EAAE,yBAAyB;IAClD,aAAa,EAAE,eAAe;IAC9B,WAAW,EAAE,aAAa;IAC1B,iBAAiB,EAAE,mBAAmB;IACtC,mBAAmB,EAAE,qBAAqB;IAC1C,iBAAiB,EAAE,mBAAmB;IACtC,kBAAkB,EAAE,oBAAoB;IACxC,YAAY,EAAE,cAAc;IAC5B,iBAAiB,EAAE,mBAAmB;IACtC,aAAa,EAAE,eAAe;IAC9B,wEAAwE;IACxE,0EAA0E;IAC1E,wEAAwE;IACxE,gBAAgB;IAChB,oBAAoB,EAAE,sBAAsB;IAC5C,mBAAmB,EAAE,qBAAqB;IAC1C,iBAAiB,EAAE,mBAAmB;IACtC,0BAA0B,EAAE,4BAA4B;IACxD,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,eAAe;IAC9B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,cAAc;CACpB,CAAC"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { ProtectionTier, BoundKey, Session, Challenge, RegistrationProof, RefreshProof, StorageAdapter, RateLimiter, DbscOptions, DbscKitExtras, AutoBindResult, AnyTelemetryEvent, TelemetryEvent, RegistrationEvent, RefreshEvent, VerificationFailureEvent, SessionStolenEvent, TierChangeEvent, } from "./types.js";
|
|
1
|
+
export type { ProtectionTier, BoundKey, BoundKeyKind, Session, Challenge, RegistrationProof, RefreshProof, StorageAdapter, RateLimiter, ProofReplayCache, DbscOptions, DbscKitExtras, AutoBindResult, AnyTelemetryEvent, TelemetryEvent, RegistrationEvent, RefreshEvent, VerificationFailureEvent, SessionStolenEvent, TierChangeEvent, PolyfillMissingEvent, } from "./types.js";
|
|
2
2
|
export { DbscProtocolError, DbscVerificationError, DbscStorageError, ErrorCodes } from "./errors.js";
|
|
3
3
|
export { validateJwk, detectAlgorithm } from "./crypto/jwk.js";
|
|
4
4
|
export { verifyDbscJws, parseRegistrationJws } from "./crypto/jws.js";
|
|
@@ -13,7 +13,9 @@ export { verifyP256Signature } from "./bound/verify.js";
|
|
|
13
13
|
export { verifyBoundProof, parseProofHeader, BOUND_PROOF_HEADER } from "./bound/proof.js";
|
|
14
14
|
export type { VerifyBoundProofRequest } from "./bound/proof.js";
|
|
15
15
|
export { NoopRateLimiter } from "./ratelimit/interface.js";
|
|
16
|
+
export { NoopReplayCache } from "./replay/interface.js";
|
|
16
17
|
export { emit } from "./telemetry/hooks.js";
|
|
18
|
+
export { maybeEmitPolyfillMissing, POLYFILL_MISSING_GRACE_MS } from "./telemetry/polyfill-missing.js";
|
|
17
19
|
export { deriveSessionId } from "./derive-session-id.js";
|
|
18
20
|
export type { DeriveSessionIdInput } from "./derive-session-id.js";
|
|
19
21
|
export { noBindingReason } from "./protect-policy.js";
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,QAAQ,EACR,OAAO,EACP,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErG,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC1F,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAEtG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/core/index.js
CHANGED
|
@@ -10,7 +10,9 @@ export { handleBoundRefresh } from "./bound/refresh.js";
|
|
|
10
10
|
export { verifyP256Signature } from "./bound/verify.js";
|
|
11
11
|
export { verifyBoundProof, parseProofHeader, BOUND_PROOF_HEADER } from "./bound/proof.js";
|
|
12
12
|
export { NoopRateLimiter } from "./ratelimit/interface.js";
|
|
13
|
+
export { NoopReplayCache } from "./replay/interface.js";
|
|
13
14
|
export { emit } from "./telemetry/hooks.js";
|
|
15
|
+
export { maybeEmitPolyfillMissing, POLYFILL_MISSING_GRACE_MS } from "./telemetry/polyfill-missing.js";
|
|
14
16
|
export { deriveSessionId } from "./derive-session-id.js";
|
|
15
17
|
export { noBindingReason } from "./protect-policy.js";
|
|
16
18
|
export { parseCookieHeader } from "./protocol/cookies.js";
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErG,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG1F,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAEtG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,26 +1,33 @@
|
|
|
1
|
-
import type { StorageAdapter } from "./types.js";
|
|
1
|
+
import type { ProofReplayCache, StorageAdapter } from "./types.js";
|
|
2
2
|
import type { SkippedEntry } from "./protocol/headers.js";
|
|
3
3
|
/**
|
|
4
4
|
* Options for `requireProof()`. All optional — `requireProof()` with no
|
|
5
5
|
* arguments is the normal call. `requireProof()` always means: the request
|
|
6
|
-
* must come from a bound device and prove it per-request
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* body-hashed proof.
|
|
6
|
+
* must come from a bound device and prove it per-request, on every browser.
|
|
7
|
+
* As of v2.7 Chromium sessions register a polyfill key alongside the TPM
|
|
8
|
+
* key, so the per-request signature works the same way on every tier.
|
|
10
9
|
*/
|
|
11
10
|
export interface RequireProofOptions {
|
|
12
11
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
12
|
+
* Skip the per-request proof header on `tier: "dbsc"`. **Default `false`
|
|
13
|
+
* as of v2.7.** v2.6 and earlier defaulted to `true`, which left a
|
|
14
|
+
* refresh-cycle replay window open on Chromium (a stolen cookie could
|
|
15
|
+
* pass `requireProof()` until the next /dbsc/refresh failed signature
|
|
16
|
+
* verification — up to `boundCookieTtl + refreshGraceMs`). Setting this
|
|
17
|
+
* to `true` reinstates the legacy behavior; only safe if your Chromium
|
|
18
|
+
* client cannot ship the v2.7 polyfill co-registration.
|
|
18
19
|
*/
|
|
19
20
|
allowDbscWithoutProof?: boolean;
|
|
20
21
|
/** Accepted proof timestamp window, ms. */
|
|
21
22
|
timestampWindowMs?: number;
|
|
22
23
|
/** Storage override. Defaults to the storage the adapter middleware was given. */
|
|
23
24
|
storage?: StorageAdapter;
|
|
25
|
+
/**
|
|
26
|
+
* v2.8+: optional replay cache. Express / Fastify / Hono adapters read this
|
|
27
|
+
* from the middleware context (`DbscOptions.replayCache`); pass it here
|
|
28
|
+
* only when calling the Next.js `requireProof` directly or overriding.
|
|
29
|
+
*/
|
|
30
|
+
replayCache?: ProofReplayCache;
|
|
24
31
|
}
|
|
25
32
|
/** Human-readable reason for a `tier: "none"` rejection — quota-aware. */
|
|
26
33
|
export declare function noBindingReason(skipped?: SkippedEntry[]): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect-policy.d.ts","sourceRoot":"","sources":["../../src/core/protect-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"protect-policy.d.ts","sourceRoot":"","sources":["../../src/core/protect-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;OAQG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,OAAO,GAAE,YAAY,EAAO,GAAG,MAAM,CAKpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect-policy.js","sourceRoot":"","sources":["../../src/core/protect-policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protect-policy.js","sourceRoot":"","sources":["../../src/core/protect-policy.ts"],"names":[],"mappings":"AAiCA,0EAA0E;AAC1E,MAAM,UAAU,eAAe,CAAC,UAA0B,EAAE;IAC1D,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,gBAAgB,CAAC,EAAE,CAAC;QACvD,OAAO,yIAAyI,CAAC;IACnJ,CAAC;IACD,OAAO,oFAAoF,CAAC;AAC9F,CAAC"}
|
|
@@ -4,9 +4,9 @@ export async function handleRefresh(req, storage) {
|
|
|
4
4
|
if (!req.secSessionResponseHeader) {
|
|
5
5
|
throw new DbscProtocolError(ErrorCodes.MISSING_RESPONSE_HEADER, "Secure-Session-Response header is required for refresh");
|
|
6
6
|
}
|
|
7
|
-
const key = await storage.getBoundKey(req.sessionId);
|
|
7
|
+
const key = await storage.getBoundKey(req.sessionId, "native");
|
|
8
8
|
if (!key) {
|
|
9
|
-
throw new DbscVerificationError(ErrorCodes.
|
|
9
|
+
throw new DbscVerificationError(ErrorCodes.KEY_NOT_FOUND_NATIVE, "no native bound key for session");
|
|
10
10
|
}
|
|
11
11
|
const challenge = await storage.getChallenge(req.expectedJti);
|
|
12
12
|
if (!challenge) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../../src/core/protocol/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AASpF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAmB,EACnB,OAAuB;IAEvB,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QAClC,MAAM,IAAI,iBAAiB,CACzB,UAAU,CAAC,uBAAuB,EAClC,wDAAwD,CACzD,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../../src/core/protocol/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AASpF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAmB,EACnB,OAAuB;IAEvB,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QAClC,MAAM,IAAI,iBAAiB,CACzB,UAAU,CAAC,uBAAuB,EAClC,wDAAwD,CACzD,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC/D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,oBAAoB,EAC/B,iCAAiC,CAClC,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC;IACzF,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,qBAAqB,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,iBAAiB,EAAE,CAAC;YACtF,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACxD,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACjE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxD,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,GAAG,EAAE,GAAG,CAAC,WAAW;QACpB,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../../src/core/protocol/registration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,mBAAmB,EACxB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../../src/core/protocol/registration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,mBAAmB,EACxB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAuD7B"}
|
|
@@ -19,9 +19,9 @@ export async function handleRegistration(req, storage) {
|
|
|
19
19
|
if (claims.jti !== req.expectedJti) {
|
|
20
20
|
throw new DbscVerificationError(ErrorCodes.JTI_MISMATCH, "jti does not match challenge");
|
|
21
21
|
}
|
|
22
|
-
const existingKey = await storage.getBoundKey(req.sessionId);
|
|
22
|
+
const existingKey = await storage.getBoundKey(req.sessionId, "native");
|
|
23
23
|
if (existingKey) {
|
|
24
|
-
throw new DbscVerificationError(ErrorCodes.SESSION_ALREADY_REGISTERED, "session already has a bound key; cannot register again");
|
|
24
|
+
throw new DbscVerificationError(ErrorCodes.SESSION_ALREADY_REGISTERED, "session already has a native bound key; cannot register again");
|
|
25
25
|
}
|
|
26
26
|
const consumed = await storage.consumeChallenge(req.expectedJti);
|
|
27
27
|
if (!consumed) {
|
|
@@ -30,6 +30,7 @@ export async function handleRegistration(req, storage) {
|
|
|
30
30
|
const now = Date.now();
|
|
31
31
|
const boundKey = {
|
|
32
32
|
sessionId: req.sessionId,
|
|
33
|
+
kind: "native",
|
|
33
34
|
jwk,
|
|
34
35
|
createdAt: now,
|
|
35
36
|
algorithm,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.js","sourceRoot":"","sources":["../../../src/core/protocol/registration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAapF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAwB,EACxB,OAAuB;IAEvB,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QAClC,MAAM,IAAI,iBAAiB,CACzB,UAAU,CAAC,uBAAuB,EAClC,4CAA4C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAErE,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC;IACzF,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,YAAY,EAAE,8BAA8B,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"registration.js","sourceRoot":"","sources":["../../../src/core/protocol/registration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAapF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAwB,EACxB,OAAuB;IAEvB,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QAClC,MAAM,IAAI,iBAAiB,CACzB,UAAU,CAAC,uBAAuB,EAClC,4CAA4C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAErE,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC;IACzF,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,YAAY,EAAE,8BAA8B,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACvE,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,0BAA0B,EACrC,+DAA+D,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACjE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAa;QACzB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,IAAI,EAAE,QAAQ;QACd,GAAG;QACH,SAAS,EAAE,GAAG;QACd,SAAS;KACV,CAAC;IAEF,MAAM,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxD,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ProofReplayCache } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Default replay cache — accepts everything. v2.6 / v2.7 behavior. Apps that
|
|
4
|
+
* want the v2.8 same-second replay defense supply a real cache (Memory in
|
|
5
|
+
* dev, Redis in prod).
|
|
6
|
+
*/
|
|
7
|
+
export declare class NoopReplayCache implements ProofReplayCache {
|
|
8
|
+
checkAndRecord(_key: string, _ttlMs: number): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/core/replay/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;IAChD,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGrE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default replay cache — accepts everything. v2.6 / v2.7 behavior. Apps that
|
|
3
|
+
* want the v2.8 same-second replay defense supply a real cache (Memory in
|
|
4
|
+
* dev, Redis in prod).
|
|
5
|
+
*/
|
|
6
|
+
export class NoopReplayCache {
|
|
7
|
+
async checkAndRecord(_key, _ttlMs) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../src/core/replay/interface.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAC1B,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,MAAc;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AnyTelemetryEvent, Session, StorageAdapter } from "../types.js";
|
|
2
|
+
/** Default grace window before emitting polyfill_missing. */
|
|
3
|
+
export declare const POLYFILL_MISSING_GRACE_MS = 60000;
|
|
4
|
+
/**
|
|
5
|
+
* Per-adapter helper. Checks whether a Chromium-bound session has gone past
|
|
6
|
+
* the grace window without registering its polyfill key, and emits
|
|
7
|
+
* `polyfill_missing` once. The caller passes a Set used to dedupe within
|
|
8
|
+
* the process — restarts re-arm the set, which is fine.
|
|
9
|
+
*
|
|
10
|
+
* Caller has already loaded the session; pass it in to avoid a redundant
|
|
11
|
+
* storage read.
|
|
12
|
+
*/
|
|
13
|
+
export declare function maybeEmitPolyfillMissing(opts: {
|
|
14
|
+
storage: StorageAdapter;
|
|
15
|
+
session: Session;
|
|
16
|
+
ip: string;
|
|
17
|
+
emitted: Set<string>;
|
|
18
|
+
graceMs?: number;
|
|
19
|
+
onEvent?: (event: AnyTelemetryEvent) => void;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=polyfill-missing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polyfill-missing.d.ts","sourceRoot":"","sources":["../../../src/core/telemetry/polyfill-missing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG9E,6DAA6D;AAC7D,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE;IACnD,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC9C,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { emit } from "./hooks.js";
|
|
2
|
+
/** Default grace window before emitting polyfill_missing. */
|
|
3
|
+
export const POLYFILL_MISSING_GRACE_MS = 60_000;
|
|
4
|
+
/**
|
|
5
|
+
* Per-adapter helper. Checks whether a Chromium-bound session has gone past
|
|
6
|
+
* the grace window without registering its polyfill key, and emits
|
|
7
|
+
* `polyfill_missing` once. The caller passes a Set used to dedupe within
|
|
8
|
+
* the process — restarts re-arm the set, which is fine.
|
|
9
|
+
*
|
|
10
|
+
* Caller has already loaded the session; pass it in to avoid a redundant
|
|
11
|
+
* storage read.
|
|
12
|
+
*/
|
|
13
|
+
export async function maybeEmitPolyfillMissing(opts) {
|
|
14
|
+
if (!opts.onEvent)
|
|
15
|
+
return;
|
|
16
|
+
if (opts.session.tier !== "dbsc")
|
|
17
|
+
return;
|
|
18
|
+
if (opts.emitted.has(opts.session.id))
|
|
19
|
+
return;
|
|
20
|
+
const grace = opts.graceMs ?? POLYFILL_MISSING_GRACE_MS;
|
|
21
|
+
if (Date.now() - opts.session.createdAt < grace)
|
|
22
|
+
return;
|
|
23
|
+
const boundKey = await opts.storage.getBoundKey(opts.session.id, "bound");
|
|
24
|
+
if (boundKey)
|
|
25
|
+
return;
|
|
26
|
+
opts.emitted.add(opts.session.id);
|
|
27
|
+
emit(opts.onEvent, {
|
|
28
|
+
type: "polyfill_missing",
|
|
29
|
+
sessionId: opts.session.id,
|
|
30
|
+
tier: "dbsc",
|
|
31
|
+
timestamp: Date.now(),
|
|
32
|
+
ip: opts.ip,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=polyfill-missing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polyfill-missing.js","sourceRoot":"","sources":["../../../src/core/telemetry/polyfill-missing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,6DAA6D;AAC7D,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAO9C;IACC,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO;IAC1B,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO;IACzC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAAE,OAAO;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,IAAI,yBAAyB,CAAC;IACxD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,KAAK;QAAE,OAAO;IAExD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1E,IAAI,QAAQ;QAAE,OAAO;IAErB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QACjB,IAAI,EAAE,kBAAkB;QACxB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;QAC1B,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,EAAE,EAAE,IAAI,CAAC,EAAE;KACZ,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StorageAdapter, Session, BoundKey, Challenge } from "../types.js";
|
|
1
|
+
import type { StorageAdapter, Session, BoundKey, BoundKeyKind, Challenge } from "../types.js";
|
|
2
2
|
export declare class MemoryStorage implements StorageAdapter {
|
|
3
3
|
private sessions;
|
|
4
4
|
private keys;
|
|
@@ -6,9 +6,9 @@ export declare class MemoryStorage implements StorageAdapter {
|
|
|
6
6
|
getSession(id: string): Promise<Session | null>;
|
|
7
7
|
setSession(session: Session): Promise<void>;
|
|
8
8
|
deleteSession(id: string): Promise<void>;
|
|
9
|
-
getBoundKey(sessionId: string): Promise<BoundKey | null>;
|
|
9
|
+
getBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<BoundKey | null>;
|
|
10
10
|
setBoundKey(key: BoundKey): Promise<void>;
|
|
11
|
-
deleteBoundKey(sessionId: string): Promise<void>;
|
|
11
|
+
deleteBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<void>;
|
|
12
12
|
getChallenge(jti: string): Promise<Challenge | null>;
|
|
13
13
|
setChallenge(challenge: Challenge): Promise<void>;
|
|
14
14
|
consumeChallenge(jti: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-storage-stub.d.ts","sourceRoot":"","sources":["../../../src/core/testing/memory-storage-stub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-storage-stub.d.ts","sourceRoot":"","sources":["../../../src/core/testing/memory-storage-stub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE9F,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,UAAU,CAAgC;IAE5C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI/C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAS7E,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IASrE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAIpD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO/C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAStD"}
|
|
@@ -10,16 +10,26 @@ export class MemoryStorage {
|
|
|
10
10
|
}
|
|
11
11
|
async deleteSession(id) {
|
|
12
12
|
this.sessions.delete(id);
|
|
13
|
-
this.keys.delete(id);
|
|
13
|
+
this.keys.delete(`${id}:native`);
|
|
14
|
+
this.keys.delete(`${id}:bound`);
|
|
14
15
|
}
|
|
15
|
-
async getBoundKey(sessionId) {
|
|
16
|
-
|
|
16
|
+
async getBoundKey(sessionId, kind) {
|
|
17
|
+
if (kind)
|
|
18
|
+
return this.keys.get(`${sessionId}:${kind}`) ?? null;
|
|
19
|
+
return (this.keys.get(`${sessionId}:native`) ??
|
|
20
|
+
this.keys.get(`${sessionId}:bound`) ??
|
|
21
|
+
null);
|
|
17
22
|
}
|
|
18
23
|
async setBoundKey(key) {
|
|
19
|
-
this.keys.set(key.sessionId
|
|
24
|
+
this.keys.set(`${key.sessionId}:${key.kind}`, key);
|
|
20
25
|
}
|
|
21
|
-
async deleteBoundKey(sessionId) {
|
|
22
|
-
|
|
26
|
+
async deleteBoundKey(sessionId, kind) {
|
|
27
|
+
if (kind) {
|
|
28
|
+
this.keys.delete(`${sessionId}:${kind}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
this.keys.delete(`${sessionId}:native`);
|
|
32
|
+
this.keys.delete(`${sessionId}:bound`);
|
|
23
33
|
}
|
|
24
34
|
async getChallenge(jti) {
|
|
25
35
|
return this.challenges.get(jti) ?? null;
|
|
@@ -36,13 +46,15 @@ export class MemoryStorage {
|
|
|
36
46
|
}
|
|
37
47
|
async revokeSession(sessionId) {
|
|
38
48
|
this.sessions.delete(sessionId);
|
|
39
|
-
this.keys.delete(sessionId);
|
|
49
|
+
this.keys.delete(`${sessionId}:native`);
|
|
50
|
+
this.keys.delete(`${sessionId}:bound`);
|
|
40
51
|
}
|
|
41
52
|
async revokeAllForUser(userId) {
|
|
42
53
|
for (const [id, sess] of this.sessions.entries()) {
|
|
43
54
|
if (sess.userId === userId) {
|
|
44
55
|
this.sessions.delete(id);
|
|
45
|
-
this.keys.delete(id);
|
|
56
|
+
this.keys.delete(`${id}:native`);
|
|
57
|
+
this.keys.delete(`${id}:bound`);
|
|
46
58
|
}
|
|
47
59
|
}
|
|
48
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-storage-stub.js","sourceRoot":"","sources":["../../../src/core/testing/memory-storage-stub.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IAChB,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;IACtC,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAC;IACnC,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;IAElD,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAgB;QAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,EAAU;QAC5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-storage-stub.js","sourceRoot":"","sources":["../../../src/core/testing/memory-storage-stub.ts"],"names":[],"mappings":"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"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
export type ProtectionTier = "dbsc" | "bound" | "none";
|
|
2
|
+
/**
|
|
3
|
+
* Discriminator on `BoundKey`. v2.7+ a single session can hold two keys:
|
|
4
|
+
* the TPM/native key used by the W3C DBSC refresh flow, and the polyfill
|
|
5
|
+
* ECDSA key used by `requireProof()` to gate every request. Chromium
|
|
6
|
+
* sessions register both keys; non-Chromium sessions register the polyfill
|
|
7
|
+
* key only.
|
|
8
|
+
*/
|
|
9
|
+
export type BoundKeyKind = "native" | "bound";
|
|
2
10
|
export interface BoundKey {
|
|
3
11
|
sessionId: string;
|
|
12
|
+
/**
|
|
13
|
+
* `"native"` for the W3C DBSC TPM key (verified on /dbsc/refresh);
|
|
14
|
+
* `"bound"` for the polyfill ECDSA key (verified on every requireProof()
|
|
15
|
+
* request and on /dbsc-bound/refresh). Older `BoundKey` rows without a
|
|
16
|
+
* `kind` field are treated as `"native"` by the storage layer.
|
|
17
|
+
*/
|
|
18
|
+
kind: BoundKeyKind;
|
|
4
19
|
jwk: JsonWebKey;
|
|
5
20
|
createdAt: number;
|
|
6
21
|
algorithm: "ES256" | "RS256";
|
|
@@ -35,9 +50,20 @@ export interface StorageAdapter {
|
|
|
35
50
|
getSession(id: string): Promise<Session | null>;
|
|
36
51
|
setSession(session: Session): Promise<void>;
|
|
37
52
|
deleteSession(id: string): Promise<void>;
|
|
38
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Read a bound key. Pass `kind` to disambiguate when both `"native"` and
|
|
55
|
+
* `"bound"` rows exist for the session (Chromium sessions). Without
|
|
56
|
+
* `kind` the adapter returns `"native"` first, falling back to `"bound"`
|
|
57
|
+
* — matches v2.6 behavior on rows that have not yet been re-keyed by
|
|
58
|
+
* `kind`.
|
|
59
|
+
*/
|
|
60
|
+
getBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<BoundKey | null>;
|
|
39
61
|
setBoundKey(key: BoundKey): Promise<void>;
|
|
40
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Delete the bound key(s) for a session. Pass `kind` to remove just one
|
|
64
|
+
* slot; without `kind` both slots are removed.
|
|
65
|
+
*/
|
|
66
|
+
deleteBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<void>;
|
|
41
67
|
getChallenge(jti: string): Promise<Challenge | null>;
|
|
42
68
|
setChallenge(challenge: Challenge): Promise<void>;
|
|
43
69
|
consumeChallenge(jti: string): Promise<boolean>;
|
|
@@ -49,6 +75,26 @@ export interface RateLimiter {
|
|
|
49
75
|
checkRefresh(ip: string, sessionId: string): Promise<boolean>;
|
|
50
76
|
recordFailure(ip: string, sessionId?: string): Promise<void>;
|
|
51
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Replay cache for per-request proofs (v2.8+). Used by `verifyBoundProof`
|
|
80
|
+
* after the cryptographic checks pass: a `(sessionId, ts, sig-prefix)` tuple
|
|
81
|
+
* is recorded with a short TTL; a second request carrying the same tuple is
|
|
82
|
+
* rejected as `PROOF_REPLAY`. Closes the captured-proof replay gap that the
|
|
83
|
+
* ±5-minute timestamp window leaves open.
|
|
84
|
+
*
|
|
85
|
+
* Implementations:
|
|
86
|
+
* - `NoopReplayCache` (default) — accepts everything. Backward-compatible.
|
|
87
|
+
* - `MemoryReplayCache` — Map + setTimeout. Dev only; not multi-process safe.
|
|
88
|
+
* - `RedisReplayCache` — `SET NX EX`. Production. Multi-process safe.
|
|
89
|
+
*/
|
|
90
|
+
export interface ProofReplayCache {
|
|
91
|
+
/**
|
|
92
|
+
* Record `key` with the given TTL. Returns `true` if this is the first
|
|
93
|
+
* sighting (request is allowed), `false` if the key was already present
|
|
94
|
+
* (a replay — reject the request).
|
|
95
|
+
*/
|
|
96
|
+
checkAndRecord(key: string, ttlMs: number): Promise<boolean>;
|
|
97
|
+
}
|
|
52
98
|
export interface TelemetryEvent {
|
|
53
99
|
sessionId: string;
|
|
54
100
|
tier: ProtectionTier;
|
|
@@ -78,7 +124,23 @@ export interface TierChangeEvent extends TelemetryEvent {
|
|
|
78
124
|
to: ProtectionTier;
|
|
79
125
|
reason: string;
|
|
80
126
|
}
|
|
81
|
-
|
|
127
|
+
/**
|
|
128
|
+
* v2.8+: emitted when a Chromium session that holds a `kind: "native"` TPM
|
|
129
|
+
* key has gone past a grace window without ever co-registering its
|
|
130
|
+
* `kind: "bound"` polyfill key. The session reads `tier: "dbsc"` but
|
|
131
|
+
* `requireProof()` will 403 every guarded request — degraded state worth
|
|
132
|
+
* alerting on. Fires at most once per session per process (a small
|
|
133
|
+
* in-memory dedup set; restarts re-arm). The grace window starts at
|
|
134
|
+
* `session.createdAt` and defaults to 60s — long enough for native
|
|
135
|
+
* registration + polyfill co-registration to complete on a warm host, well
|
|
136
|
+
* shorter than the bound-cookie TTL so the signal arrives before the first
|
|
137
|
+
* background refresh.
|
|
138
|
+
*/
|
|
139
|
+
export interface PolyfillMissingEvent extends TelemetryEvent {
|
|
140
|
+
type: "polyfill_missing";
|
|
141
|
+
ip: string;
|
|
142
|
+
}
|
|
143
|
+
export type AnyTelemetryEvent = RegistrationEvent | RefreshEvent | VerificationFailureEvent | SessionStolenEvent | TierChangeEvent | PolyfillMissingEvent;
|
|
82
144
|
export interface DbscOptions {
|
|
83
145
|
storage: StorageAdapter;
|
|
84
146
|
registrationPath?: string;
|
|
@@ -103,6 +165,16 @@ export interface DbscOptions {
|
|
|
103
165
|
*/
|
|
104
166
|
cookieScope?: "host" | "site";
|
|
105
167
|
rateLimiter?: RateLimiter;
|
|
168
|
+
/**
|
|
169
|
+
* Replay cache for per-request proofs (v2.8+). Without it, an attacker who
|
|
170
|
+
* captures one valid proof off the wire can replay it for up to the
|
|
171
|
+
* timestamp window. With it, the second replay is rejected as
|
|
172
|
+
* `PROOF_REPLAY`. Defaults to a no-op cache (v2.6 / v2.7 behavior).
|
|
173
|
+
*
|
|
174
|
+
* Pass `new MemoryReplayCache()` for single-process apps; pass
|
|
175
|
+
* `new RedisReplayCache(redis)` for multi-process production.
|
|
176
|
+
*/
|
|
177
|
+
replayCache?: ProofReplayCache;
|
|
106
178
|
onEvent?: (event: AnyTelemetryEvent) => void;
|
|
107
179
|
/**
|
|
108
180
|
* Optional callback for transparent migration. On every request that does not
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;IAChB,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAChD,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/express/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Response, RequestHandler } from "express";
|
|
2
|
-
import { type DbscOptions, type StorageAdapter, type ProtectionTier, type SkippedEntry } from "../core/index.js";
|
|
2
|
+
import { type DbscOptions, type StorageAdapter, type ProofReplayCache, type ProtectionTier, type SkippedEntry } from "../core/index.js";
|
|
3
3
|
export { requireBoundProof } from "./proof.js";
|
|
4
4
|
export type { RequireBoundProofOptions } from "./proof.js";
|
|
5
5
|
export { requireProof } from "./require-proof.js";
|
|
@@ -9,6 +9,8 @@ export type { CreateDbscOptions, DbscKit, BindOptions } from "./create-dbsc.js";
|
|
|
9
9
|
export interface DbscInternal {
|
|
10
10
|
storage: StorageAdapter;
|
|
11
11
|
secure: boolean;
|
|
12
|
+
/** v2.8+: optional replay cache; undefined → no replay check (Noop). */
|
|
13
|
+
replayCache?: ProofReplayCache;
|
|
12
14
|
}
|
|
13
15
|
export declare const DBSC_INTERNAL: unique symbol;
|
|
14
16
|
export interface DbscExpressOptions extends DbscOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,QAAQ,EAAgB,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/E,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,QAAQ,EAAgB,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/E,OAAO,EAqBL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAErB,KAAK,cAAc,EACnB,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEhF,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AACD,eAAO,MAAM,aAAa,EAAE,OAAO,MAAgD,CAAC;AAYpF,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,MAAM;YACd,IAAI,EAAE,UAAU,CAAC;SAClB;KACF;CACF;AAuBD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,gHAAgH;IAChH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAugB7D"}
|