dbsc-toolkit 2.8.1 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +2 -0
  2. package/dist/core/cookies/options.d.ts +56 -0
  3. package/dist/core/cookies/options.d.ts.map +1 -0
  4. package/dist/core/cookies/options.js +84 -0
  5. package/dist/core/cookies/options.js.map +1 -0
  6. package/dist/core/index.d.ts +2 -0
  7. package/dist/core/index.d.ts.map +1 -1
  8. package/dist/core/index.js +1 -0
  9. package/dist/core/index.js.map +1 -1
  10. package/dist/core/types.d.ts +15 -5
  11. package/dist/core/types.d.ts.map +1 -1
  12. package/dist/express/create-dbsc.d.ts.map +1 -1
  13. package/dist/express/create-dbsc.js +19 -7
  14. package/dist/express/create-dbsc.js.map +1 -1
  15. package/dist/express/index.d.ts +5 -1
  16. package/dist/express/index.d.ts.map +1 -1
  17. package/dist/express/index.js +40 -25
  18. package/dist/express/index.js.map +1 -1
  19. package/dist/fastify/create-dbsc.d.ts.map +1 -1
  20. package/dist/fastify/create-dbsc.js +17 -6
  21. package/dist/fastify/create-dbsc.js.map +1 -1
  22. package/dist/fastify/index.d.ts +5 -1
  23. package/dist/fastify/index.d.ts.map +1 -1
  24. package/dist/fastify/index.js +24 -11
  25. package/dist/fastify/index.js.map +1 -1
  26. package/dist/hono/create-dbsc.d.ts.map +1 -1
  27. package/dist/hono/create-dbsc.js +17 -6
  28. package/dist/hono/create-dbsc.js.map +1 -1
  29. package/dist/hono/index.d.ts +5 -1
  30. package/dist/hono/index.d.ts.map +1 -1
  31. package/dist/hono/index.js +30 -12
  32. package/dist/hono/index.js.map +1 -1
  33. package/dist/nextjs/create-dbsc.d.ts.map +1 -1
  34. package/dist/nextjs/create-dbsc.js +15 -2
  35. package/dist/nextjs/create-dbsc.js.map +1 -1
  36. package/dist/nextjs/index.d.ts +7 -1
  37. package/dist/nextjs/index.d.ts.map +1 -1
  38. package/dist/nextjs/index.js +41 -23
  39. package/dist/nextjs/index.js.map +1 -1
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -129,6 +129,8 @@ app.post("/logout", async (req, res) => {
129
129
 
130
130
  **No server-side session id** (NextAuth JWT mode, iron-session, Lucia stateless)? Call `dbsc.bind(res, { userId })` with no id — the kit derives a stable one and manages a per-device cookie so each browser of the same user binds independently. Per-system recipes: [docs/integration-recipes.md](./docs/integration-recipes.md).
131
131
 
132
+ **App split across subdomains** (`app.example.com` + `api.example.com`)? Default `__Host-` cookies are origin-locked — keep DBSC on one origin (proxy `/dbsc/*` and `/dbsc-bound/*` through the UI host) for the strongest setting. If a same-origin layout is genuinely not workable, v2.9.0+ exposes `cookieScope: "site"` + `cookieDomain: "example.com"` on `createDbsc({...})`, switching the binding cookies to `__Secure-` with a `Domain` attribute. The validator throws at construction if either is wrong, so misconfiguration is loud, not silent. Trade-off and concrete recipe: [docs/integration-recipes.md#multi-subdomain-apps-cookiescope-site](./docs/integration-recipes.md#multi-subdomain-apps-cookiescope-site).
133
+
132
134
  **The full step-by-step** — every option and its default, the `autoBind` transparent-rollout variant, the per-route policy table, the migration timeline — is in [docs/integrating-existing-auth.md](./docs/integrating-existing-auth.md).
133
135
 
134
136
  ## Protect your routes
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Cookie-scope helpers shared by every adapter (v2.9+).
3
+ *
4
+ * Single source of truth for the cookie prefix (`__Host-` vs `__Secure-`),
5
+ * the `Domain` attribute, and the `attributes` string echoed back in the
6
+ * registration response's `credentials[].attributes` field.
7
+ *
8
+ * The four adapters wrap framework-specific cookie APIs around the values
9
+ * returned here. The validator throws on construction so a missing
10
+ * `cookieDomain` cannot silently degrade into a broken state at request
11
+ * time.
12
+ */
13
+ export type CookieScope = "host" | "site";
14
+ export interface CookieScopeOptions {
15
+ secure: boolean;
16
+ cookieScope?: CookieScope;
17
+ cookieDomain?: string;
18
+ }
19
+ export interface CookieScopeResolved {
20
+ /** Whether the cookies use the `__Host-` prefix (host scope, secure). */
21
+ hostPrefix: boolean;
22
+ /** `"__Host-"`, `"__Secure-"`, or `""` (insecure dev). */
23
+ prefix: "__Host-" | "__Secure-" | "";
24
+ /** The `Domain` attribute value, or undefined when no domain is emitted. */
25
+ domain: string | undefined;
26
+ }
27
+ /**
28
+ * Validates a cookie-scope configuration and returns the resolved values
29
+ * the adapters consume. Throws when `"site"` scope is requested without a
30
+ * `cookieDomain`, or when an insecure config tries to use site scope (a
31
+ * `__Secure-` cookie requires the `Secure` flag, which requires HTTPS).
32
+ */
33
+ export declare function resolveCookieScope(opts: CookieScopeOptions): CookieScopeResolved;
34
+ /**
35
+ * Returns the three cookie names (`bound`, `reg`, `challenge`) the adapters
36
+ * read and write. Encapsulates the prefix swap so callers never concatenate
37
+ * a prefix by hand.
38
+ */
39
+ export declare function cookieNames(opts: CookieScopeOptions): {
40
+ bound: string;
41
+ reg: string;
42
+ challenge: string;
43
+ };
44
+ /**
45
+ * The name of the per-device cookie used by the JWT-mode `bind()` path.
46
+ * Same prefix rules as the binding cookies above.
47
+ */
48
+ export declare function deviceCookieName(opts: CookieScopeOptions): string;
49
+ /**
50
+ * Returns the `attributes` string echoed back in the registration response's
51
+ * `credentials[].attributes` field, which Chromium re-reads to know how to
52
+ * re-issue the bound cookie on refresh. Must match what the server actually
53
+ * sets in `Set-Cookie`, byte for byte, or Chromium drops the binding.
54
+ */
55
+ export declare function cookieAttributesString(opts: CookieScopeOptions): string;
56
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/core/cookies/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,UAAU,EAAE,OAAO,CAAC;IACpB,0DAA0D;IAC1D,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,EAAE,CAAC;IACrC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,mBAAmB,CAwChF;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB,CAOA;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAGjE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAKvE"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Cookie-scope helpers shared by every adapter (v2.9+).
3
+ *
4
+ * Single source of truth for the cookie prefix (`__Host-` vs `__Secure-`),
5
+ * the `Domain` attribute, and the `attributes` string echoed back in the
6
+ * registration response's `credentials[].attributes` field.
7
+ *
8
+ * The four adapters wrap framework-specific cookie APIs around the values
9
+ * returned here. The validator throws on construction so a missing
10
+ * `cookieDomain` cannot silently degrade into a broken state at request
11
+ * time.
12
+ */
13
+ /**
14
+ * Validates a cookie-scope configuration and returns the resolved values
15
+ * the adapters consume. Throws when `"site"` scope is requested without a
16
+ * `cookieDomain`, or when an insecure config tries to use site scope (a
17
+ * `__Secure-` cookie requires the `Secure` flag, which requires HTTPS).
18
+ */
19
+ export function resolveCookieScope(opts) {
20
+ const scope = opts.cookieScope ?? "host";
21
+ const secure = opts.secure;
22
+ if (scope === "site") {
23
+ if (!opts.cookieDomain) {
24
+ throw new Error('dbsc: cookieScope: "site" requires cookieDomain. ' +
25
+ "Set cookieDomain to the registrable apex (e.g. \"example.com\") " +
26
+ "so the binding cookie can be shared across subdomains. " +
27
+ 'Drop cookieScope to keep the default "host" mode.');
28
+ }
29
+ if (!secure) {
30
+ throw new Error('dbsc: cookieScope: "site" requires secure: true. ' +
31
+ "The __Secure- prefix is rejected by browsers without the Secure flag.");
32
+ }
33
+ if (opts.cookieDomain.startsWith(".")) {
34
+ throw new Error('dbsc: cookieDomain must not start with a leading dot. ' +
35
+ 'Use "example.com", not ".example.com".');
36
+ }
37
+ return { hostPrefix: false, prefix: "__Secure-", domain: opts.cookieDomain };
38
+ }
39
+ // host scope
40
+ if (opts.cookieDomain) {
41
+ throw new Error('dbsc: cookieDomain is only valid when cookieScope: "site". ' +
42
+ 'Remove cookieDomain or set cookieScope: "site".');
43
+ }
44
+ return {
45
+ hostPrefix: secure,
46
+ prefix: secure ? "__Host-" : "",
47
+ domain: undefined,
48
+ };
49
+ }
50
+ /**
51
+ * Returns the three cookie names (`bound`, `reg`, `challenge`) the adapters
52
+ * read and write. Encapsulates the prefix swap so callers never concatenate
53
+ * a prefix by hand.
54
+ */
55
+ export function cookieNames(opts) {
56
+ const { prefix } = resolveCookieScope(opts);
57
+ return {
58
+ bound: `${prefix}dbsc-session`,
59
+ reg: `${prefix}dbsc-reg`,
60
+ challenge: `${prefix}dbsc-challenge`,
61
+ };
62
+ }
63
+ /**
64
+ * The name of the per-device cookie used by the JWT-mode `bind()` path.
65
+ * Same prefix rules as the binding cookies above.
66
+ */
67
+ export function deviceCookieName(opts) {
68
+ const { prefix } = resolveCookieScope(opts);
69
+ return `${prefix}dbsc-device`;
70
+ }
71
+ /**
72
+ * Returns the `attributes` string echoed back in the registration response's
73
+ * `credentials[].attributes` field, which Chromium re-reads to know how to
74
+ * re-issue the bound cookie on refresh. Must match what the server actually
75
+ * sets in `Set-Cookie`, byte for byte, or Chromium drops the binding.
76
+ */
77
+ export function cookieAttributesString(opts) {
78
+ const { domain } = resolveCookieScope(opts);
79
+ const parts = ["Path=/", "Secure", "HttpOnly", "SameSite=Lax"];
80
+ if (domain)
81
+ parts.push(`Domain=${domain}`);
82
+ return parts.join("; ");
83
+ }
84
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/core/cookies/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAmBH;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAwB;IACzD,MAAM,KAAK,GAAgB,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAE3B,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,mDAAmD;gBACjD,kEAAkE;gBAClE,yDAAyD;gBACzD,mDAAmD,CACtD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,mDAAmD;gBACjD,uEAAuE,CAC1E,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CACb,wDAAwD;gBACtD,wCAAwC,CAC3C,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;IAC/E,CAAC;IAED,aAAa;IACb,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,6DAA6D;YAC3D,iDAAiD,CACpD,CAAC;IACJ,CAAC;IACD,OAAO;QACL,UAAU,EAAE,MAAM;QAClB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;QAC/B,MAAM,EAAE,SAAS;KAClB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAwB;IAKlD,MAAM,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC5C,OAAO;QACL,KAAK,EAAE,GAAG,MAAM,cAAc;QAC9B,GAAG,EAAE,GAAG,MAAM,UAAU;QACxB,SAAS,EAAE,GAAG,MAAM,gBAAgB;KACrC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAwB;IACvD,MAAM,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC5C,OAAO,GAAG,MAAM,aAAa,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAwB;IAC7D,MAAM,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;IAC/D,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;IAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -21,4 +21,6 @@ export type { DeriveSessionIdInput } from "./derive-session-id.js";
21
21
  export { noBindingReason } from "./protect-policy.js";
22
22
  export type { RequireProofOptions } from "./protect-policy.js";
23
23
  export { parseCookieHeader } from "./protocol/cookies.js";
24
+ export { resolveCookieScope, cookieNames as resolveCookieNames, deviceCookieName, cookieAttributesString, } from "./cookies/options.js";
25
+ export type { CookieScope, CookieScopeOptions, CookieScopeResolved } from "./cookies/options.js";
24
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
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"}
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;AAE1D,OAAO,EACL,kBAAkB,EAClB,WAAW,IAAI,kBAAkB,EACjC,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -16,4 +16,5 @@ export { maybeEmitPolyfillMissing, POLYFILL_MISSING_GRACE_MS } from "./telemetry
16
16
  export { deriveSessionId } from "./derive-session-id.js";
17
17
  export { noBindingReason } from "./protect-policy.js";
18
18
  export { parseCookieHeader } from "./protocol/cookies.js";
19
+ export { resolveCookieScope, cookieNames as resolveCookieNames, deviceCookieName, cookieAttributesString, } from "./cookies/options.js";
19
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
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
+ {"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;AAE1D,OAAO,EACL,kBAAkB,EAClB,WAAW,IAAI,kBAAkB,EACjC,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC"}
@@ -157,13 +157,23 @@ export interface DbscOptions {
157
157
  */
158
158
  refreshGraceMs?: number;
159
159
  /**
160
- * Cookie prefix scope. "host" (default) uses `__Host-` cookies — origin
161
- * locked, no Domain attribute, strongest. "site" uses `__Secure-` cookies
162
- * with a Domain attribute so the binding works across subdomains
163
- * (app.example.com + api.example.com); this drops `__Host-`'s
164
- * subdomain-takeover protection. See docs/integration-recipes.md.
160
+ * Cookie prefix scope. `"host"` (default) uses `__Host-` cookies —
161
+ * origin-locked, no `Domain` attribute, strongest. `"site"` uses
162
+ * `__Secure-` cookies carrying `Domain=<cookieDomain>` so the binding works
163
+ * across subdomains (e.g. `app.example.com` + `api.example.com`). The
164
+ * `"site"` mode drops `__Host-`'s protection against a sibling subdomain
165
+ * setting or overwriting the cookie; only enable it when a same-origin
166
+ * deployment is genuinely not workable. See docs/integration-recipes.md.
165
167
  */
166
168
  cookieScope?: "host" | "site";
169
+ /**
170
+ * Required when `cookieScope: "site"`. The `Domain` attribute attached to
171
+ * every DBSC cookie — typically the registrable apex (`example.com`) so the
172
+ * cookie is visible on every subdomain. Omit the leading dot. Throws at
173
+ * `dbsc()` / `createDbsc()` construction when `"site"` is set without it.
174
+ * Ignored in `"host"` mode.
175
+ */
176
+ cookieDomain?: string;
167
177
  rateLimiter?: RateLimiter;
168
178
  /**
169
179
  * Replay cache for per-request proofs (v2.8+). Without it, an attacker who
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
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;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9C,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,IAAI,EAAE,YAAY,CAAC;IACnB,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;;;;;;OAMG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC9E,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,WAAW;IAC1B,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,wBAAyB,SAAQ,cAAc;IAC9D,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,IAAI,EAAE,gBAAgB,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,cAAc,CAAC;IACrB,EAAE,EAAE,cAAc,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,IAAI,EAAE,kBAAkB,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,iBAAiB,GACzB,iBAAiB,GACjB,YAAY,GACZ,wBAAwB,GACxB,kBAAkB,GAClB,eAAe,GACf,oBAAoB,CAAC;AAEzB,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,cAAc,GAAG,IAAI,CAAC;CACjF;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-dbsc.d.ts","sourceRoot":"","sources":["../../src/express/create-dbsc.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,KAAK,OAAO,EAAgB,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAGlG,OAAO,EAAsC,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA4BxE,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,yFAAyF;IACzF,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,wDAAwD;IACxD,UAAU,IAAI,cAAc,CAAC;IAC7B,4FAA4F;IAC5F,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3E,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,uEAAuE;IACvE,YAAY,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,cAAc,CAAC;CAC1D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAoD3D"}
1
+ {"version":3,"file":"create-dbsc.d.ts","sourceRoot":"","sources":["../../src/express/create-dbsc.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,KAAK,OAAO,EAAgB,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAGlG,OAAO,EAKL,KAAK,mBAAmB,EAEzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAqCxE,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,yFAAyF;IACzF,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,wDAAwD;IACxD,UAAU,IAAI,cAAc,CAAC;IAC7B,4FAA4F;IAC5F,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3E,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,uEAAuE;IACvE,YAAY,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,cAAc,CAAC;CAC1D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CA6D3D"}
@@ -1,17 +1,19 @@
1
1
  import express from "express";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { randomBytes } from "node:crypto";
4
- import { deriveSessionId, parseCookieHeader } from "../core/index.js";
4
+ import { deriveSessionId, parseCookieHeader, deviceCookieName, resolveCookieScope, } from "../core/index.js";
5
5
  import { dbsc, bindSession } from "./index.js";
6
6
  import { requireProof } from "./require-proof.js";
7
7
  const DEVICE_COOKIE_TTL_MS = 365 * 24 * 60 * 60 * 1000;
8
8
  /**
9
9
  * Returns a stable per-device value for the JWT `bind()` path: reads the
10
- * `__Host-dbsc-device` cookie, or mints + sets one if absent. Two browsers of
11
- * the same user thus derive distinct sessionIds and bind independently.
10
+ * device cookie (named per cookie scope), or mints + sets one if absent. Two
11
+ * browsers of the same user thus derive distinct sessionIds and bind
12
+ * independently.
12
13
  */
13
- function resolveDeviceHint(res, secure) {
14
- const name = secure ? "__Host-dbsc-device" : "dbsc-device";
14
+ function resolveDeviceHint(res, scope) {
15
+ const name = deviceCookieName(scope);
16
+ const { domain } = resolveCookieScope(scope);
15
17
  const req = res.req;
16
18
  const existing = req?.cookies?.[name] ??
17
19
  parseCookieHeader(req?.headers?.cookie)[name];
@@ -20,10 +22,11 @@ function resolveDeviceHint(res, secure) {
20
22
  const value = randomBytes(16).toString("hex");
21
23
  res.cookie(name, value, {
22
24
  httpOnly: true,
23
- secure,
25
+ secure: scope.secure,
24
26
  sameSite: "lax",
25
27
  path: "/",
26
28
  maxAge: DEVICE_COOKIE_TTL_MS,
29
+ ...(domain !== undefined && { domain }),
27
30
  });
28
31
  return value;
29
32
  }
@@ -34,6 +37,13 @@ function resolveDeviceHint(res, secure) {
34
37
  */
35
38
  export function createDbsc(opts) {
36
39
  const secure = opts.secure ?? true;
40
+ const cookieScope = opts.cookieScope;
41
+ const cookieDomain = opts.cookieDomain;
42
+ const scope = {
43
+ secure,
44
+ ...(cookieScope !== undefined && { cookieScope }),
45
+ ...(cookieDomain !== undefined && { cookieDomain }),
46
+ };
37
47
  const clientPath = opts.clientPath ?? "/dbsc-client";
38
48
  const registrationPath = opts.registrationPath ?? "/dbsc/registration";
39
49
  const boundRegistrationPath = opts.boundRegistrationPath ?? "/dbsc-bound/registration";
@@ -48,7 +58,7 @@ export function createDbsc(opts) {
48
58
  else {
49
59
  // JWT path: no sessionId. An explicit deviceHint wins; otherwise the kit
50
60
  // manages a per-device cookie so each browser binds independently.
51
- const deviceHint = bindOpts.deviceHint ?? resolveDeviceHint(res, secure);
61
+ const deviceHint = bindOpts.deviceHint ?? resolveDeviceHint(res, scope);
52
62
  sessionId = await deriveSessionId({
53
63
  userId: bindOpts.userId,
54
64
  deviceHint,
@@ -58,6 +68,8 @@ export function createDbsc(opts) {
58
68
  await bindSession(res, sessionId, opts.storage, {
59
69
  userId: bindOpts.userId,
60
70
  secure,
71
+ ...(cookieScope !== undefined && { cookieScope }),
72
+ ...(cookieDomain !== undefined && { cookieDomain }),
61
73
  registrationPath,
62
74
  ...(opts.registrationCookieTtl !== undefined && {
63
75
  registrationCookieTtl: opts.registrationCookieTtl,
@@ -1 +1 @@
1
- {"version":3,"file":"create-dbsc.js","sourceRoot":"","sources":["../../src/express/create-dbsc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-dbsc.js","sourceRoot":"","sources":["../../src/express/create-dbsc.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { Response, RequestHandler } from "express";
2
- import { type DbscOptions, type StorageAdapter, type ProofReplayCache, type ProtectionTier, type SkippedEntry } from "../core/index.js";
2
+ import { type DbscOptions, type StorageAdapter, type ProofReplayCache, type ProtectionTier, type SkippedEntry, type CookieScope } 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";
@@ -37,6 +37,10 @@ export interface BindSessionOptions {
37
37
  userId: string;
38
38
  /** Match the value passed to dbsc({ secure }). Defaults true. Mismatch = cookies the middleware cannot read. */
39
39
  secure?: boolean;
40
+ /** Match the value passed to dbsc({ cookieScope }). Defaults "host". */
41
+ cookieScope?: CookieScope;
42
+ /** Match the value passed to dbsc({ cookieDomain }). Required for cookieScope: "site". */
43
+ cookieDomain?: string;
40
44
  registrationPath?: string;
41
45
  registrationCookieTtl?: number;
42
46
  sessionTtl?: number;
@@ -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,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"}
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;AAC/E,OAAO,EAwBL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,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;AAcpF,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;AA0BD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,gHAAgH;IAChH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,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,CA8Cf;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAmhB7D"}
@@ -1,23 +1,21 @@
1
- import { handleRegistration, handleRefresh, handleBoundRegistration, handleBoundRefresh, issueChallenge, buildRegistrationHeader, buildChallengeHeader, readSessionResponseHeader, parseSessionSkippedHeader, REGISTRATION_HEADER, CHALLENGE_HEADER, LEGACY_REGISTRATION_HEADER, LEGACY_CHALLENGE_HEADER, NoopRateLimiter, emit, maybeEmitPolyfillMissing, parseCookieHeader, DbscProtocolError, DbscVerificationError, ErrorCodes, } from "../core/index.js";
1
+ import { handleRegistration, handleRefresh, handleBoundRegistration, handleBoundRefresh, issueChallenge, buildRegistrationHeader, buildChallengeHeader, readSessionResponseHeader, parseSessionSkippedHeader, REGISTRATION_HEADER, CHALLENGE_HEADER, LEGACY_REGISTRATION_HEADER, LEGACY_CHALLENGE_HEADER, NoopRateLimiter, emit, maybeEmitPolyfillMissing, parseCookieHeader, resolveCookieNames, cookieAttributesString, resolveCookieScope, DbscProtocolError, DbscVerificationError, ErrorCodes, } from "../core/index.js";
2
2
  export { requireBoundProof } from "./proof.js";
3
3
  export { requireProof } from "./require-proof.js";
4
4
  export { createDbsc } from "./create-dbsc.js";
5
5
  export const DBSC_INTERNAL = Symbol("dbsc-toolkit.express.internal");
6
- const cookieNames = (secure) => ({
7
- bound: secure ? "__Host-dbsc-session" : "dbsc-session",
8
- reg: secure ? "__Host-dbsc-reg" : "dbsc-reg",
9
- challenge: secure ? "__Host-dbsc-challenge" : "dbsc-challenge",
10
- });
6
+ const cookieNames = (s) => resolveCookieNames(s);
11
7
  const DEFAULT_BOUND_TTL = 10 * 60 * 1000;
12
8
  const DEFAULT_REG_TTL = 24 * 60 * 60 * 1000;
13
9
  const DEFAULT_SESSION_TTL = 24 * 60 * 60 * 1000;
14
- function cookieOpts(ttlMs, secure) {
10
+ function cookieOpts(ttlMs, scope) {
11
+ const { domain } = resolveCookieScope(scope);
15
12
  return {
16
13
  httpOnly: true,
17
- secure,
14
+ secure: scope.secure,
18
15
  sameSite: "lax",
19
16
  maxAge: ttlMs / 1000,
20
17
  path: "/",
18
+ ...(domain !== undefined && { domain }),
21
19
  };
22
20
  }
23
21
  function serializeCookie(name, value, opts) {
@@ -29,6 +27,8 @@ function serializeCookie(name, value, opts) {
29
27
  parts.push(`SameSite=${sameSite}`);
30
28
  parts.push(`Max-Age=${opts.maxAge}`);
31
29
  parts.push(`Path=${opts.path}`);
30
+ if (opts.domain)
31
+ parts.push(`Domain=${opts.domain}`);
32
32
  return parts.join("; ");
33
33
  }
34
34
  export async function bindSession(res, sessionId, storage, opts) {
@@ -36,7 +36,12 @@ export async function bindSession(res, sessionId, storage, opts) {
36
36
  const registrationPath = opts.registrationPath ?? "/dbsc/registration";
37
37
  const regCookieTtl = opts.registrationCookieTtl ?? DEFAULT_REG_TTL;
38
38
  const sessionTtl = opts.sessionTtl ?? DEFAULT_SESSION_TTL;
39
- const COOKIES = cookieNames(secure);
39
+ const scope = {
40
+ secure,
41
+ ...(opts.cookieScope !== undefined && { cookieScope: opts.cookieScope }),
42
+ ...(opts.cookieDomain !== undefined && { cookieDomain: opts.cookieDomain }),
43
+ };
44
+ const COOKIES = cookieNames(scope);
40
45
  const existing = await storage.getSession(sessionId);
41
46
  const now = Date.now();
42
47
  if (!existing) {
@@ -65,13 +70,21 @@ export async function bindSession(res, sessionId, storage, opts) {
65
70
  : [];
66
71
  res.setHeader("Set-Cookie", [
67
72
  ...priorList,
68
- serializeCookie(COOKIES.reg, sessionId, cookieOpts(regCookieTtl, secure)),
69
- serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, secure)),
73
+ serializeCookie(COOKIES.reg, sessionId, cookieOpts(regCookieTtl, scope)),
74
+ serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, scope)),
70
75
  ]);
71
76
  }
72
77
  export function dbsc(opts) {
73
- const { storage, registrationPath = "/dbsc/registration", refreshPath = "/dbsc/refresh", boundStatePath = "/dbsc-bound/state", boundChallengePath = "/dbsc-bound/challenge", boundRegistrationPath = "/dbsc-bound/registration", boundRefreshPath = "/dbsc-bound/refresh", boundCookieTtl = DEFAULT_BOUND_TTL, refreshGraceMs = 30_000, registrationCookieTtl = DEFAULT_REG_TTL, rateLimiter = new NoopRateLimiter(), replayCache, onEvent, autoBind, secure = true, } = opts;
74
- const COOKIES = cookieNames(secure);
78
+ const { storage, registrationPath = "/dbsc/registration", refreshPath = "/dbsc/refresh", boundStatePath = "/dbsc-bound/state", boundChallengePath = "/dbsc-bound/challenge", boundRegistrationPath = "/dbsc-bound/registration", boundRefreshPath = "/dbsc-bound/refresh", boundCookieTtl = DEFAULT_BOUND_TTL, refreshGraceMs = 30_000, registrationCookieTtl = DEFAULT_REG_TTL, rateLimiter = new NoopRateLimiter(), replayCache, onEvent, autoBind, secure = true, cookieScope, cookieDomain, } = opts;
79
+ const scope = {
80
+ secure,
81
+ ...(cookieScope !== undefined && { cookieScope }),
82
+ ...(cookieDomain !== undefined && { cookieDomain }),
83
+ };
84
+ // Fail-fast: rejects "site" without domain, mismatched secure flag, etc.
85
+ resolveCookieScope(scope);
86
+ const cookieAttrs = cookieAttributesString(scope);
87
+ const COOKIES = cookieNames(scope);
75
88
  // Per-middleware-instance dedup set for the polyfill_missing telemetry event.
76
89
  // Re-armed on process restart, which is fine: the signal is for ops alerting,
77
90
  // not for security enforcement.
@@ -104,8 +117,8 @@ export function dbsc(opts) {
104
117
  ip,
105
118
  });
106
119
  res.setHeader("Set-Cookie", [
107
- serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, secure)),
108
- serializeCookie(COOKIES.challenge, "", { ...cookieOpts(0, secure), maxAge: 0 }),
120
+ serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, scope)),
121
+ serializeCookie(COOKIES.challenge, "", { ...cookieOpts(0, scope), maxAge: 0 }),
109
122
  ]);
110
123
  res.setHeader("Content-Type", "application/json");
111
124
  const origin = `${req.protocol}://${req.get("host")}`;
@@ -121,7 +134,7 @@ export function dbsc(opts) {
121
134
  {
122
135
  type: "cookie",
123
136
  name: COOKIES.bound,
124
- attributes: "Path=/; Secure; HttpOnly; SameSite=Lax",
137
+ attributes: cookieAttrs,
125
138
  },
126
139
  ],
127
140
  });
@@ -162,7 +175,7 @@ export function dbsc(opts) {
162
175
  const challenge = await issueChallenge(sessionId, storage);
163
176
  res.setHeader(CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
164
177
  res.setHeader(LEGACY_CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
165
- res.setHeader("Set-Cookie", serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, secure)));
178
+ res.setHeader("Set-Cookie", serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, scope)));
166
179
  res.status(403).end();
167
180
  return;
168
181
  }
@@ -171,7 +184,7 @@ export function dbsc(opts) {
171
184
  const challenge = await issueChallenge(sessionId, storage);
172
185
  res.setHeader(CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
173
186
  res.setHeader(LEGACY_CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
174
- res.setHeader("Set-Cookie", serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, secure)));
187
+ res.setHeader("Set-Cookie", serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, scope)));
175
188
  res.status(403).end();
176
189
  return;
177
190
  }
@@ -185,8 +198,8 @@ export function dbsc(opts) {
185
198
  ip,
186
199
  });
187
200
  res.setHeader("Set-Cookie", [
188
- serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, secure)),
189
- serializeCookie(COOKIES.challenge, "", { ...cookieOpts(0, secure), maxAge: 0 }),
201
+ serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, scope)),
202
+ serializeCookie(COOKIES.challenge, "", { ...cookieOpts(0, scope), maxAge: 0 }),
190
203
  ]);
191
204
  res.setHeader("Content-Type", "application/json");
192
205
  const origin = `${req.protocol}://${req.get("host")}`;
@@ -202,7 +215,7 @@ export function dbsc(opts) {
202
215
  {
203
216
  type: "cookie",
204
217
  name: COOKIES.bound,
205
- attributes: "Path=/; Secure; HttpOnly; SameSite=Lax",
218
+ attributes: cookieAttrs,
206
219
  },
207
220
  ],
208
221
  });
@@ -231,7 +244,7 @@ export function dbsc(opts) {
231
244
  const challenge = await issueChallenge(sessionId, storage);
232
245
  res.setHeader(CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
233
246
  res.setHeader(LEGACY_CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
234
- res.setHeader("Set-Cookie", serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, secure)));
247
+ res.setHeader("Set-Cookie", serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, scope)));
235
248
  res.status(403).json({ error: err.message });
236
249
  return;
237
250
  }
@@ -339,7 +352,7 @@ export function dbsc(opts) {
339
352
  ip,
340
353
  });
341
354
  res.setHeader("Set-Cookie", [
342
- serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, secure)),
355
+ serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, scope)),
343
356
  ]);
344
357
  res.status(200).json({
345
358
  session_identifier: sessionId,
@@ -397,7 +410,7 @@ export function dbsc(opts) {
397
410
  ip,
398
411
  });
399
412
  res.setHeader("Set-Cookie", [
400
- serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, secure)),
413
+ serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, scope)),
401
414
  ]);
402
415
  res.status(200).json({
403
416
  session_identifier: sessionId,
@@ -470,7 +483,7 @@ export function dbsc(opts) {
470
483
  if (sessionId)
471
484
  await storage.revokeSession(sessionId);
472
485
  res.setHeader("Set-Cookie", [
473
- serializeCookie(COOKIES.bound, "", { ...cookieOpts(0, secure), maxAge: 0 }),
486
+ serializeCookie(COOKIES.bound, "", { ...cookieOpts(0, scope), maxAge: 0 }),
474
487
  ]);
475
488
  },
476
489
  };
@@ -507,6 +520,8 @@ export function dbsc(opts) {
507
520
  await bindSession(res, result.sessionId, storage, {
508
521
  userId: result.userId,
509
522
  secure,
523
+ ...(cookieScope !== undefined && { cookieScope }),
524
+ ...(cookieDomain !== undefined && { cookieDomain }),
510
525
  registrationPath,
511
526
  registrationCookieTtl,
512
527
  });