dbsc-toolkit 2.9.12 → 2.11.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 +26 -8
- package/dist/core/protect-policy.d.ts +9 -0
- package/dist/core/protect-policy.d.ts.map +1 -1
- package/dist/core/protect-policy.js.map +1 -1
- package/dist/core/types.d.ts +10 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/express/index.d.ts +6 -0
- package/dist/express/index.d.ts.map +1 -1
- package/dist/express/index.js +25 -13
- package/dist/express/index.js.map +1 -1
- package/dist/express/require-proof.d.ts.map +1 -1
- package/dist/express/require-proof.js +5 -3
- package/dist/express/require-proof.js.map +1 -1
- package/dist/fastify/index.d.ts +2 -0
- package/dist/fastify/index.d.ts.map +1 -1
- package/dist/fastify/index.js +97 -90
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/require-proof.d.ts.map +1 -1
- package/dist/fastify/require-proof.js +3 -3
- package/dist/fastify/require-proof.js.map +1 -1
- package/dist/hono/index.d.ts +2 -0
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +7 -4
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/require-proof.d.ts.map +1 -1
- package/dist/hono/require-proof.js +3 -3
- package/dist/hono/require-proof.js.map +1 -1
- package/dist/koa/create-dbsc.d.ts +25 -0
- package/dist/koa/create-dbsc.d.ts.map +1 -0
- package/dist/koa/create-dbsc.js +32 -0
- package/dist/koa/create-dbsc.js.map +1 -0
- package/dist/koa/index.d.ts +19 -0
- package/dist/koa/index.d.ts.map +1 -0
- package/dist/koa/index.js +26 -0
- package/dist/koa/index.js.map +1 -0
- package/dist/koa/require-proof.d.ts +9 -0
- package/dist/koa/require-proof.d.ts.map +1 -0
- package/dist/koa/require-proof.js +69 -0
- package/dist/koa/require-proof.js.map +1 -0
- package/dist/nestjs/index.d.ts +45 -0
- package/dist/nestjs/index.d.ts.map +1 -0
- package/dist/nestjs/index.js +147 -0
- package/dist/nestjs/index.js.map +1 -0
- package/dist/nextjs/create-dbsc.d.ts.map +1 -1
- package/dist/nextjs/create-dbsc.js +1 -0
- package/dist/nextjs/create-dbsc.js.map +1 -1
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/index.js +9 -4
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/require-proof.d.ts.map +1 -1
- package/dist/nextjs/require-proof.js +3 -3
- package/dist/nextjs/require-proof.js.map +1 -1
- package/dist/node/create-dbsc.d.ts +29 -0
- package/dist/node/create-dbsc.d.ts.map +1 -0
- package/dist/node/create-dbsc.js +33 -0
- package/dist/node/create-dbsc.js.map +1 -0
- package/dist/node/index.d.ts +53 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +412 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/require-proof.d.ts +17 -0
- package/dist/node/require-proof.d.ts.map +1 -0
- package/dist/node/require-proof.js +74 -0
- package/dist/node/require-proof.js.map +1 -0
- package/dist/sveltekit/index.d.ts +48 -0
- package/dist/sveltekit/index.d.ts.map +1 -0
- package/dist/sveltekit/index.js +318 -0
- package/dist/sveltekit/index.js.map +1 -0
- package/dist/sveltekit/require-proof.d.ts +15 -0
- package/dist/sveltekit/require-proof.d.ts.map +1 -0
- package/dist/sveltekit/require-proof.js +52 -0
- package/dist/sveltekit/require-proof.js.map +1 -0
- package/package.json +41 -2
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { dbsc, bindSession, getDbscSession, } from "./index.js";
|
|
2
|
+
import { requireProof } from "./require-proof.js";
|
|
3
|
+
/**
|
|
4
|
+
* Builds a configured DBSC kit for raw `node:http`. There is no `install()`
|
|
5
|
+
* because raw http has no router — wire `handler()` at the top of your request
|
|
6
|
+
* listener and branch on its boolean return.
|
|
7
|
+
*/
|
|
8
|
+
export function createDbsc(opts) {
|
|
9
|
+
const secure = opts.secure ?? true;
|
|
10
|
+
const cookieScope = opts.cookieScope;
|
|
11
|
+
const cookieDomain = opts.cookieDomain;
|
|
12
|
+
const registrationPath = opts.registrationPath ?? "/dbsc/registration";
|
|
13
|
+
const handler = dbsc(opts);
|
|
14
|
+
async function bind(res, sessionId, bindOpts) {
|
|
15
|
+
await bindSession(res, sessionId, opts.storage, {
|
|
16
|
+
userId: bindOpts.userId,
|
|
17
|
+
secure,
|
|
18
|
+
...(cookieScope !== undefined && { cookieScope }),
|
|
19
|
+
...(cookieDomain !== undefined && { cookieDomain }),
|
|
20
|
+
registrationPath,
|
|
21
|
+
...(opts.registrationCookieTtl !== undefined && { registrationCookieTtl: opts.registrationCookieTtl }),
|
|
22
|
+
...(opts.sessionTtl !== undefined && { sessionTtl: opts.sessionTtl }),
|
|
23
|
+
});
|
|
24
|
+
return sessionId;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
handler: () => handler,
|
|
28
|
+
getSession: getDbscSession,
|
|
29
|
+
bind,
|
|
30
|
+
requireProof,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=create-dbsc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-dbsc.js","sourceRoot":"","sources":["../../src/node/create-dbsc.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,IAAI,EACJ,WAAW,EACX,cAAc,GAIf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAuB,MAAM,oBAAoB,CAAC;AAuBvE;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAAuB;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;IACnC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IACvC,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,oBAAoB,CAAC;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAE3B,KAAK,UAAU,IAAI,CAAC,GAAmB,EAAE,SAAiB,EAAE,QAAqB;QAC/E,MAAM,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE;YAC9C,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,MAAM;YACN,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC;YACjD,GAAG,CAAC,YAAY,KAAK,SAAS,IAAI,EAAE,YAAY,EAAE,CAAC;YACnD,gBAAgB;YAChB,GAAG,CAAC,IAAI,CAAC,qBAAqB,KAAK,SAAS,IAAI,EAAE,qBAAqB,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACtG,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;SACtE,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO;QACtB,UAAU,EAAE,cAAc;QAC1B,IAAI;QACJ,YAAY;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { type DbscOptions, type StorageAdapter, type ProofReplayCache, type ProtectionTier, type SkippedEntry, type CookieScope } from "../core/index.js";
|
|
3
|
+
export { requireProof } from "./require-proof.js";
|
|
4
|
+
export { createDbsc } from "./create-dbsc.js";
|
|
5
|
+
export type { CreateDbscOptions, DbscKit, BindOptions } from "./create-dbsc.js";
|
|
6
|
+
/** Internal carrier so `requireProof()` can reach storage without re-passing it. */
|
|
7
|
+
export interface DbscInternal {
|
|
8
|
+
storage: StorageAdapter;
|
|
9
|
+
secure: boolean;
|
|
10
|
+
/** When false, `requireProof()` auto-relaxes the native dbsc tier. */
|
|
11
|
+
boundEnabled: boolean;
|
|
12
|
+
replayCache?: ProofReplayCache;
|
|
13
|
+
}
|
|
14
|
+
export declare const DBSC_INTERNAL: unique symbol;
|
|
15
|
+
export interface DbscNodeOptions extends DbscOptions {
|
|
16
|
+
secure?: boolean;
|
|
17
|
+
boundStatePath?: string;
|
|
18
|
+
boundChallengePath?: string;
|
|
19
|
+
boundRegistrationPath?: string;
|
|
20
|
+
boundRefreshPath?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface DbscNodeSession {
|
|
23
|
+
sessionId: string | null;
|
|
24
|
+
tier: ProtectionTier;
|
|
25
|
+
skipped: SkippedEntry[];
|
|
26
|
+
revoke: () => Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The dbsc handler for raw `node:http`. Call it first in your request
|
|
30
|
+
* pipeline: it returns `true` when it has fully answered a DBSC protocol route
|
|
31
|
+
* (the response is ended — stop), and `false` otherwise, having attached the
|
|
32
|
+
* resolved session to the request. Read it back with `getDbscSession(req)`.
|
|
33
|
+
*/
|
|
34
|
+
export type DbscNodeHandler = (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
|
35
|
+
/** Reads the session the `dbsc()` handler attached to this request. */
|
|
36
|
+
export declare function getDbscSession(req: IncomingMessage): DbscNodeSession | undefined;
|
|
37
|
+
/** Reads and JSON-parses the raw request body. Returns `{}` on empty/invalid. */
|
|
38
|
+
export declare function readJsonBody(req: IncomingMessage): Promise<Record<string, unknown>>;
|
|
39
|
+
export interface BindSessionOptions {
|
|
40
|
+
userId: string;
|
|
41
|
+
/** Match the value passed to dbsc({ secure }). Defaults true. */
|
|
42
|
+
secure?: boolean;
|
|
43
|
+
/** Match the value passed to dbsc({ cookieScope }). Defaults "host". */
|
|
44
|
+
cookieScope?: CookieScope;
|
|
45
|
+
/** Match the value passed to dbsc({ cookieDomain }). Required for cookieScope: "site". */
|
|
46
|
+
cookieDomain?: string;
|
|
47
|
+
registrationPath?: string;
|
|
48
|
+
registrationCookieTtl?: number;
|
|
49
|
+
sessionTtl?: number;
|
|
50
|
+
}
|
|
51
|
+
export declare function bindSession(res: ServerResponse, sessionId: string, storage: StorageAdapter, opts: BindSessionOptions): Promise<void>;
|
|
52
|
+
export declare function dbsc(opts: DbscNodeOptions): DbscNodeHandler;
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,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,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,sEAAsE;IACtE,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AACD,eAAO,MAAM,aAAa,EAAE,OAAO,MAA6C,CAAC;AAejF,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,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,eAAe;IAC9B,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;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9F,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,eAAe,GAAG,SAAS,CAEhF;AAmED,iFAAiF;AACjF,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAiBzF;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,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,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe,CAwT3D"}
|
|
@@ -0,0 +1,412 @@
|
|
|
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
|
+
export { requireProof } from "./require-proof.js";
|
|
3
|
+
export { createDbsc } from "./create-dbsc.js";
|
|
4
|
+
export const DBSC_INTERNAL = Symbol("dbsc-toolkit.node.internal");
|
|
5
|
+
const DBSC_SESSION = Symbol("dbsc-toolkit.node.session");
|
|
6
|
+
const cookieNames = (s) => resolveCookieNames(s);
|
|
7
|
+
const DEFAULT_BOUND_TTL = 10 * 60 * 1000;
|
|
8
|
+
const DEFAULT_REG_TTL = 24 * 60 * 60 * 1000;
|
|
9
|
+
const DEFAULT_SESSION_TTL = 24 * 60 * 60 * 1000;
|
|
10
|
+
/** Reads the session the `dbsc()` handler attached to this request. */
|
|
11
|
+
export function getDbscSession(req) {
|
|
12
|
+
return req[DBSC_SESSION];
|
|
13
|
+
}
|
|
14
|
+
function cookieOpts(ttlMs, scope) {
|
|
15
|
+
const { domain } = resolveCookieScope(scope);
|
|
16
|
+
return {
|
|
17
|
+
httpOnly: true,
|
|
18
|
+
secure: scope.secure,
|
|
19
|
+
sameSite: "lax",
|
|
20
|
+
maxAge: ttlMs / 1000,
|
|
21
|
+
path: "/",
|
|
22
|
+
...(domain !== undefined && { domain }),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function serializeCookie(name, value, opts) {
|
|
26
|
+
const parts = [`${name}=${value}`, "HttpOnly"];
|
|
27
|
+
if (opts.secure)
|
|
28
|
+
parts.push("Secure");
|
|
29
|
+
const sameSite = opts.sameSite.charAt(0).toUpperCase() + opts.sameSite.slice(1);
|
|
30
|
+
parts.push(`SameSite=${sameSite}`);
|
|
31
|
+
parts.push(`Max-Age=${opts.maxAge}`);
|
|
32
|
+
parts.push(`Path=${opts.path}`);
|
|
33
|
+
if (opts.domain)
|
|
34
|
+
parts.push(`Domain=${opts.domain}`);
|
|
35
|
+
return parts.join("; ");
|
|
36
|
+
}
|
|
37
|
+
function appendSetCookie(res, cookies) {
|
|
38
|
+
const add = Array.isArray(cookies) ? cookies : [cookies];
|
|
39
|
+
const prior = res.getHeader("Set-Cookie");
|
|
40
|
+
const priorList = Array.isArray(prior)
|
|
41
|
+
? prior.map(String)
|
|
42
|
+
: prior !== undefined
|
|
43
|
+
? [String(prior)]
|
|
44
|
+
: [];
|
|
45
|
+
res.setHeader("Set-Cookie", [...priorList, ...add]);
|
|
46
|
+
}
|
|
47
|
+
function reqUrl(req) {
|
|
48
|
+
return new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
49
|
+
}
|
|
50
|
+
function reqOrigin(req) {
|
|
51
|
+
const xfp = req.headers["x-forwarded-proto"];
|
|
52
|
+
const proto = (Array.isArray(xfp) ? xfp[0] : xfp)?.split(",")[0]?.trim() ??
|
|
53
|
+
(req.socket.encrypted ? "https" : "http");
|
|
54
|
+
return `${proto}://${req.headers.host ?? "localhost"}`;
|
|
55
|
+
}
|
|
56
|
+
function reqIp(req) {
|
|
57
|
+
return req.socket?.remoteAddress ?? "unknown";
|
|
58
|
+
}
|
|
59
|
+
function reqCookies(req) {
|
|
60
|
+
return parseCookieHeader(req.headers.cookie);
|
|
61
|
+
}
|
|
62
|
+
function sendJson(res, status, body) {
|
|
63
|
+
res.setHeader("Content-Type", "application/json");
|
|
64
|
+
res.statusCode = status;
|
|
65
|
+
res.end(JSON.stringify(body));
|
|
66
|
+
}
|
|
67
|
+
function sendStatus(res, status) {
|
|
68
|
+
res.statusCode = status;
|
|
69
|
+
res.end();
|
|
70
|
+
}
|
|
71
|
+
/** Reads and JSON-parses the raw request body. Returns `{}` on empty/invalid. */
|
|
72
|
+
export async function readJsonBody(req) {
|
|
73
|
+
const cached = req["__dbscRawBody"];
|
|
74
|
+
let raw;
|
|
75
|
+
if (Buffer.isBuffer(cached)) {
|
|
76
|
+
raw = cached;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const chunks = [];
|
|
80
|
+
for await (const chunk of req)
|
|
81
|
+
chunks.push(chunk);
|
|
82
|
+
raw = Buffer.concat(chunks);
|
|
83
|
+
req["__dbscRawBody"] = raw;
|
|
84
|
+
}
|
|
85
|
+
if (raw.length === 0)
|
|
86
|
+
return {};
|
|
87
|
+
try {
|
|
88
|
+
return JSON.parse(raw.toString("utf8"));
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return {};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export async function bindSession(res, sessionId, storage, opts) {
|
|
95
|
+
const secure = opts.secure ?? true;
|
|
96
|
+
const registrationPath = opts.registrationPath ?? "/dbsc/registration";
|
|
97
|
+
const regCookieTtl = opts.registrationCookieTtl ?? DEFAULT_REG_TTL;
|
|
98
|
+
const sessionTtl = opts.sessionTtl ?? DEFAULT_SESSION_TTL;
|
|
99
|
+
const scope = {
|
|
100
|
+
secure,
|
|
101
|
+
...(opts.cookieScope !== undefined && { cookieScope: opts.cookieScope }),
|
|
102
|
+
...(opts.cookieDomain !== undefined && { cookieDomain: opts.cookieDomain }),
|
|
103
|
+
};
|
|
104
|
+
const COOKIES = cookieNames(scope);
|
|
105
|
+
const existing = await storage.getSession(sessionId);
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
if (!existing) {
|
|
108
|
+
await storage.setSession({
|
|
109
|
+
id: sessionId,
|
|
110
|
+
userId: opts.userId,
|
|
111
|
+
tier: "none",
|
|
112
|
+
createdAt: now,
|
|
113
|
+
expiresAt: now + sessionTtl,
|
|
114
|
+
lastRefreshAt: 0,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const challenge = await issueChallenge(sessionId, storage);
|
|
118
|
+
const regHeader = buildRegistrationHeader({
|
|
119
|
+
registrationPath,
|
|
120
|
+
challenge: challenge.jti,
|
|
121
|
+
cookieName: COOKIES.bound,
|
|
122
|
+
});
|
|
123
|
+
res.setHeader(REGISTRATION_HEADER, regHeader);
|
|
124
|
+
res.setHeader(LEGACY_REGISTRATION_HEADER, regHeader);
|
|
125
|
+
appendSetCookie(res, [
|
|
126
|
+
serializeCookie(COOKIES.reg, sessionId, cookieOpts(regCookieTtl, scope)),
|
|
127
|
+
serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, scope)),
|
|
128
|
+
]);
|
|
129
|
+
}
|
|
130
|
+
export function dbsc(opts) {
|
|
131
|
+
const { storage, registrationPath = "/dbsc/registration", refreshPath = "/dbsc/refresh", boundStatePath = "/dbsc-bound/state", boundChallengePath = "/dbsc-bound/challenge", boundRegistrationPath = "/dbsc-bound/registration", boundRefreshPath = "/dbsc-bound/refresh", bound = true, boundCookieTtl = DEFAULT_BOUND_TTL, refreshGraceMs = 30_000, registrationCookieTtl = DEFAULT_REG_TTL, rateLimiter = new NoopRateLimiter(), replayCache, onEvent, autoBind, secure = true, cookieScope, cookieDomain, } = opts;
|
|
132
|
+
const scope = {
|
|
133
|
+
secure,
|
|
134
|
+
...(cookieScope !== undefined && { cookieScope }),
|
|
135
|
+
...(cookieDomain !== undefined && { cookieDomain }),
|
|
136
|
+
};
|
|
137
|
+
resolveCookieScope(scope);
|
|
138
|
+
const cookieAttrs = cookieAttributesString(scope);
|
|
139
|
+
const COOKIES = cookieNames(scope);
|
|
140
|
+
const polyfillMissingEmitted = new Set();
|
|
141
|
+
function configBody(sessionId, origin, refreshUrl) {
|
|
142
|
+
return {
|
|
143
|
+
session_identifier: sessionId,
|
|
144
|
+
refresh_url: refreshUrl,
|
|
145
|
+
scope: { origin, include_site: true, scope_specification: [] },
|
|
146
|
+
credentials: [{ type: "cookie", name: COOKIES.bound, attributes: cookieAttrs }],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async function handleRegistrationRoute(req, res) {
|
|
150
|
+
const ip = reqIp(req);
|
|
151
|
+
const allowed = await rateLimiter.checkRegistration(ip);
|
|
152
|
+
if (!allowed)
|
|
153
|
+
return sendJson(res, 429, { error: "rate limited" });
|
|
154
|
+
const cookies = reqCookies(req);
|
|
155
|
+
const sessionId = cookies[COOKIES.reg];
|
|
156
|
+
const expectedJti = cookies[COOKIES.challenge];
|
|
157
|
+
if (!sessionId || !expectedJti) {
|
|
158
|
+
return sendJson(res, 400, { error: "missing session or challenge cookie" });
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
await handleRegistration({
|
|
162
|
+
sessionId,
|
|
163
|
+
secSessionResponseHeader: readSessionResponseHeader(req.headers),
|
|
164
|
+
expectedJti,
|
|
165
|
+
}, storage);
|
|
166
|
+
emit(onEvent, { type: "registration", sessionId, tier: "dbsc", timestamp: Date.now(), algorithm: "ES256", ip });
|
|
167
|
+
appendSetCookie(res, [
|
|
168
|
+
serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, scope)),
|
|
169
|
+
serializeCookie(COOKIES.challenge, "", { ...cookieOpts(0, scope), maxAge: 0 }),
|
|
170
|
+
]);
|
|
171
|
+
sendJson(res, 200, configBody(sessionId, reqOrigin(req), refreshPath));
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
await rateLimiter.recordFailure(ip, sessionId);
|
|
175
|
+
if (err instanceof DbscVerificationError || err instanceof DbscProtocolError) {
|
|
176
|
+
emit(onEvent, { type: "verification_failure", sessionId, tier: "dbsc", timestamp: Date.now(), reason: err.code, ip });
|
|
177
|
+
return sendJson(res, 400, { error: err.message });
|
|
178
|
+
}
|
|
179
|
+
throw err;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async function handleRefreshRoute(req, res) {
|
|
183
|
+
const ip = reqIp(req);
|
|
184
|
+
const cookies = reqCookies(req);
|
|
185
|
+
const idHeader = req.headers["sec-secure-session-id"];
|
|
186
|
+
const sessionId = (Array.isArray(idHeader) ? idHeader[0] : idHeader) ?? cookies[COOKIES.bound];
|
|
187
|
+
if (!sessionId)
|
|
188
|
+
return sendStatus(res, 403);
|
|
189
|
+
const allowed = await rateLimiter.checkRefresh(ip, sessionId);
|
|
190
|
+
if (!allowed)
|
|
191
|
+
return sendJson(res, 429, { error: "rate limited" });
|
|
192
|
+
const responseHeader = readSessionResponseHeader(req.headers);
|
|
193
|
+
const expectedJti = cookies[COOKIES.challenge];
|
|
194
|
+
if (!responseHeader || !expectedJti) {
|
|
195
|
+
const challenge = await issueChallenge(sessionId, storage);
|
|
196
|
+
res.setHeader(CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
|
|
197
|
+
res.setHeader(LEGACY_CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
|
|
198
|
+
appendSetCookie(res, serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, scope)));
|
|
199
|
+
return sendStatus(res, 403);
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
await handleRefresh({ sessionId, secSessionResponseHeader: responseHeader, expectedJti }, storage);
|
|
203
|
+
emit(onEvent, { type: "refresh", sessionId, tier: "dbsc", timestamp: Date.now(), ip });
|
|
204
|
+
appendSetCookie(res, [
|
|
205
|
+
serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, scope)),
|
|
206
|
+
serializeCookie(COOKIES.challenge, "", { ...cookieOpts(0, scope), maxAge: 0 }),
|
|
207
|
+
]);
|
|
208
|
+
sendJson(res, 200, configBody(sessionId, reqOrigin(req), refreshPath));
|
|
209
|
+
}
|
|
210
|
+
catch (err) {
|
|
211
|
+
await rateLimiter.recordFailure(ip, sessionId);
|
|
212
|
+
const stolenCheck = await storage.getBoundKey(sessionId);
|
|
213
|
+
if (stolenCheck && err instanceof DbscVerificationError && err.code === ErrorCodes.SIGNATURE_INVALID) {
|
|
214
|
+
emit(onEvent, { type: "session_stolen", sessionId, tier: "dbsc", timestamp: Date.now(), ip });
|
|
215
|
+
}
|
|
216
|
+
if (err instanceof DbscVerificationError || err instanceof DbscProtocolError) {
|
|
217
|
+
emit(onEvent, { type: "verification_failure", sessionId, tier: "dbsc", timestamp: Date.now(), reason: err.code, ip });
|
|
218
|
+
const challenge = await issueChallenge(sessionId, storage);
|
|
219
|
+
res.setHeader(CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
|
|
220
|
+
res.setHeader(LEGACY_CHALLENGE_HEADER, buildChallengeHeader(challenge.jti, sessionId));
|
|
221
|
+
appendSetCookie(res, serializeCookie(COOKIES.challenge, challenge.jti, cookieOpts(5 * 60 * 1000, scope)));
|
|
222
|
+
return sendJson(res, 403, { error: err.message });
|
|
223
|
+
}
|
|
224
|
+
throw err;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function readBoundSessionId(cookies) {
|
|
228
|
+
return cookies[COOKIES.bound] ?? cookies[COOKIES.reg];
|
|
229
|
+
}
|
|
230
|
+
async function handleBoundStateRoute(req, res) {
|
|
231
|
+
res.setHeader("X-Server-Time", String(Date.now()));
|
|
232
|
+
const skipped = parseSessionSkippedHeader(req.headers);
|
|
233
|
+
const nativeSkipped = skipped.length ? skipped.map((s) => s.reason) : undefined;
|
|
234
|
+
const sessionId = readBoundSessionId(reqCookies(req));
|
|
235
|
+
if (!sessionId)
|
|
236
|
+
return sendJson(res, 200, { phase: "unbound", sessionId: null, ...(nativeSkipped && { nativeSkipped }) });
|
|
237
|
+
const session = await storage.getSession(sessionId);
|
|
238
|
+
if (!session)
|
|
239
|
+
return sendJson(res, 200, { phase: "unbound", sessionId: null, ...(nativeSkipped && { nativeSkipped }) });
|
|
240
|
+
const nativeKey = await storage.getBoundKey(sessionId, "native");
|
|
241
|
+
const boundKey = await storage.getBoundKey(sessionId, "bound");
|
|
242
|
+
if (!nativeKey && !boundKey) {
|
|
243
|
+
const challenge = await issueChallenge(sessionId, storage);
|
|
244
|
+
return sendJson(res, 200, { phase: "needs-registration", sessionId, challenge: challenge.jti, ...(nativeSkipped && { nativeSkipped }) });
|
|
245
|
+
}
|
|
246
|
+
if (nativeKey && !boundKey) {
|
|
247
|
+
const challenge = await issueChallenge(sessionId, storage);
|
|
248
|
+
return sendJson(res, 200, {
|
|
249
|
+
phase: "needs-bound-registration",
|
|
250
|
+
sessionId,
|
|
251
|
+
tier: session.tier,
|
|
252
|
+
challenge: challenge.jti,
|
|
253
|
+
refreshIntervalMs: boundCookieTtl,
|
|
254
|
+
...(nativeSkipped && { nativeSkipped }),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
sendJson(res, 200, { phase: "bound", sessionId, tier: session.tier, refreshIntervalMs: boundCookieTtl, ...(nativeSkipped && { nativeSkipped }) });
|
|
258
|
+
}
|
|
259
|
+
async function handleBoundChallengeRoute(req, res) {
|
|
260
|
+
res.setHeader("X-Server-Time", String(Date.now()));
|
|
261
|
+
const sessionId = readBoundSessionId(reqCookies(req));
|
|
262
|
+
if (!sessionId)
|
|
263
|
+
return sendJson(res, 403, { error: "no session" });
|
|
264
|
+
const session = await storage.getSession(sessionId);
|
|
265
|
+
if (!session)
|
|
266
|
+
return sendJson(res, 403, { error: "no session" });
|
|
267
|
+
const challenge = await issueChallenge(sessionId, storage);
|
|
268
|
+
sendJson(res, 200, { challenge: challenge.jti });
|
|
269
|
+
}
|
|
270
|
+
async function handleBoundRegistrationRoute(req, res) {
|
|
271
|
+
res.setHeader("X-Server-Time", String(Date.now()));
|
|
272
|
+
const ip = reqIp(req);
|
|
273
|
+
const allowed = await rateLimiter.checkRegistration(ip);
|
|
274
|
+
if (!allowed)
|
|
275
|
+
return sendJson(res, 429, { error: "rate limited" });
|
|
276
|
+
const sessionId = readBoundSessionId(reqCookies(req));
|
|
277
|
+
if (!sessionId)
|
|
278
|
+
return sendJson(res, 400, { error: "missing session cookie" });
|
|
279
|
+
const body = await readJsonBody(req);
|
|
280
|
+
if (!body.publicKey || !body.signature || !body.challenge) {
|
|
281
|
+
return sendJson(res, 400, { error: "publicKey, signature, and challenge are required in JSON body" });
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
await handleBoundRegistration({ sessionId, publicKey: body.publicKey, signature: body.signature, expectedJti: body.challenge }, storage);
|
|
285
|
+
emit(onEvent, { type: "registration", sessionId, tier: "bound", timestamp: Date.now(), algorithm: "ES256", ip });
|
|
286
|
+
appendSetCookie(res, serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, scope)));
|
|
287
|
+
sendJson(res, 200, { session_identifier: sessionId, refresh_url: boundRefreshPath, tier: "bound" });
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
await rateLimiter.recordFailure(ip, sessionId);
|
|
291
|
+
if (err instanceof DbscVerificationError || err instanceof DbscProtocolError) {
|
|
292
|
+
emit(onEvent, { type: "verification_failure", sessionId, tier: "bound", timestamp: Date.now(), reason: err.code, ip });
|
|
293
|
+
return sendJson(res, 400, { error: err.message });
|
|
294
|
+
}
|
|
295
|
+
throw err;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
async function handleBoundRefreshRoute(req, res) {
|
|
299
|
+
res.setHeader("X-Server-Time", String(Date.now()));
|
|
300
|
+
const ip = reqIp(req);
|
|
301
|
+
const sessionId = readBoundSessionId(reqCookies(req));
|
|
302
|
+
if (!sessionId)
|
|
303
|
+
return sendJson(res, 403, { error: "no session" });
|
|
304
|
+
const allowed = await rateLimiter.checkRefresh(ip, sessionId);
|
|
305
|
+
if (!allowed)
|
|
306
|
+
return sendJson(res, 429, { error: "rate limited" });
|
|
307
|
+
const body = await readJsonBody(req);
|
|
308
|
+
if (!body.challenge || !body.signature || typeof body.timestamp !== "number") {
|
|
309
|
+
return sendJson(res, 400, { error: "challenge, signature, and timestamp are required" });
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
await handleBoundRefresh({ sessionId, signature: body.signature, expectedJti: body.challenge, timestamp: body.timestamp }, storage);
|
|
313
|
+
emit(onEvent, { type: "refresh", sessionId, tier: "bound", timestamp: Date.now(), ip });
|
|
314
|
+
appendSetCookie(res, serializeCookie(COOKIES.bound, sessionId, cookieOpts(boundCookieTtl, scope)));
|
|
315
|
+
sendJson(res, 200, { session_identifier: sessionId, refresh_url: boundRefreshPath, tier: "bound" });
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
await rateLimiter.recordFailure(ip, sessionId);
|
|
319
|
+
const keyStillThere = await storage.getBoundKey(sessionId);
|
|
320
|
+
if (keyStillThere && err instanceof DbscVerificationError && err.code === ErrorCodes.SIGNATURE_INVALID) {
|
|
321
|
+
emit(onEvent, { type: "session_stolen", sessionId, tier: "bound", timestamp: Date.now(), ip });
|
|
322
|
+
}
|
|
323
|
+
if (err instanceof DbscVerificationError || err instanceof DbscProtocolError) {
|
|
324
|
+
emit(onEvent, { type: "verification_failure", sessionId, tier: "bound", timestamp: Date.now(), reason: err.code, ip });
|
|
325
|
+
return sendJson(res, 401, { error: err.message });
|
|
326
|
+
}
|
|
327
|
+
throw err;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return async (req, res) => {
|
|
331
|
+
const url = reqUrl(req);
|
|
332
|
+
const method = req.method ?? "GET";
|
|
333
|
+
if (method === "POST" && url.pathname === registrationPath) {
|
|
334
|
+
await handleRegistrationRoute(req, res);
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
if (method === "POST" && url.pathname === refreshPath) {
|
|
338
|
+
await handleRefreshRoute(req, res);
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
if (method === "GET" && url.pathname === boundStatePath) {
|
|
342
|
+
if (bound) {
|
|
343
|
+
await handleBoundStateRoute(req, res);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
res.setHeader("X-Server-Time", String(Date.now()));
|
|
347
|
+
sendJson(res, 200, { phase: "unbound", sessionId: null });
|
|
348
|
+
}
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
if (bound) {
|
|
352
|
+
if (method === "GET" && url.pathname === boundChallengePath) {
|
|
353
|
+
await handleBoundChallengeRoute(req, res);
|
|
354
|
+
return true;
|
|
355
|
+
}
|
|
356
|
+
if (method === "POST" && url.pathname === boundRegistrationPath) {
|
|
357
|
+
await handleBoundRegistrationRoute(req, res);
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
if (method === "POST" && url.pathname === boundRefreshPath) {
|
|
361
|
+
await handleBoundRefreshRoute(req, res);
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
const cookies = reqCookies(req);
|
|
366
|
+
const sessionId = cookies[COOKIES.bound];
|
|
367
|
+
const skipped = parseSessionSkippedHeader(req.headers);
|
|
368
|
+
const session = {
|
|
369
|
+
sessionId: sessionId ?? null,
|
|
370
|
+
tier: "none",
|
|
371
|
+
skipped,
|
|
372
|
+
revoke: async () => {
|
|
373
|
+
if (sessionId)
|
|
374
|
+
await storage.revokeSession(sessionId);
|
|
375
|
+
appendSetCookie(res, serializeCookie(COOKIES.bound, "", { ...cookieOpts(0, scope), maxAge: 0 }));
|
|
376
|
+
},
|
|
377
|
+
};
|
|
378
|
+
session[DBSC_INTERNAL] = {
|
|
379
|
+
storage,
|
|
380
|
+
secure,
|
|
381
|
+
boundEnabled: bound,
|
|
382
|
+
...(replayCache !== undefined && { replayCache }),
|
|
383
|
+
};
|
|
384
|
+
if (sessionId) {
|
|
385
|
+
const stored = await storage.getSession(sessionId);
|
|
386
|
+
if (stored) {
|
|
387
|
+
const staleAfter = stored.lastRefreshAt + boundCookieTtl + refreshGraceMs;
|
|
388
|
+
const refreshable = stored.tier === "dbsc" || stored.tier === "bound";
|
|
389
|
+
session.tier = refreshable && Date.now() > staleAfter ? "none" : stored.tier;
|
|
390
|
+
if (onEvent) {
|
|
391
|
+
await maybeEmitPolyfillMissing({ storage, session: stored, ip: reqIp(req), emitted: polyfillMissingEmitted, onEvent });
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
else if (autoBind && !cookies[COOKIES.reg]) {
|
|
396
|
+
const result = await autoBind(req);
|
|
397
|
+
if (result) {
|
|
398
|
+
await bindSession(res, result.sessionId, storage, {
|
|
399
|
+
userId: result.userId,
|
|
400
|
+
secure,
|
|
401
|
+
...(cookieScope !== undefined && { cookieScope }),
|
|
402
|
+
...(cookieDomain !== undefined && { cookieDomain }),
|
|
403
|
+
registrationPath,
|
|
404
|
+
registrationCookieTtl,
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
req[DBSC_SESSION] = session;
|
|
409
|
+
return false;
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { type RequireProofOptions } from "../core/index.js";
|
|
3
|
+
/** A node:http proof guard: `true` if the request passed, `false` if it was rejected (403 already written). */
|
|
4
|
+
export type NodeProofGuard = (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
|
5
|
+
/**
|
|
6
|
+
* The route guard for raw `node:http`. Run `dbsc()` first so the session is
|
|
7
|
+
* attached, then:
|
|
8
|
+
*
|
|
9
|
+
* const guard = requireProof();
|
|
10
|
+
* if (!(await guard(req, res))) return; // 403 already written
|
|
11
|
+
*
|
|
12
|
+
* Requires a bound device + a per-request proof. The verified raw body is
|
|
13
|
+
* cached on the request, so a downstream handler can re-read it via
|
|
14
|
+
* `readJsonBody(req)`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function requireProof(opts?: RequireProofOptions): NodeProofGuard;
|
|
17
|
+
//# sourceMappingURL=require-proof.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-proof.d.ts","sourceRoot":"","sources":["../../src/node/require-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAG1B,+GAA+G;AAC/G,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAY7F;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,cAAc,CAsD3E"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { verifyBoundProof, noBindingReason, DbscVerificationError, } from "../core/index.js";
|
|
2
|
+
import { getDbscSession, DBSC_INTERNAL } from "./index.js";
|
|
3
|
+
async function readRawBody(req) {
|
|
4
|
+
const cached = req["__dbscRawBody"];
|
|
5
|
+
if (Buffer.isBuffer(cached))
|
|
6
|
+
return new Uint8Array(cached);
|
|
7
|
+
const chunks = [];
|
|
8
|
+
for await (const chunk of req)
|
|
9
|
+
chunks.push(chunk);
|
|
10
|
+
const raw = Buffer.concat(chunks);
|
|
11
|
+
req["__dbscRawBody"] = raw;
|
|
12
|
+
return new Uint8Array(raw);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The route guard for raw `node:http`. Run `dbsc()` first so the session is
|
|
16
|
+
* attached, then:
|
|
17
|
+
*
|
|
18
|
+
* const guard = requireProof();
|
|
19
|
+
* if (!(await guard(req, res))) return; // 403 already written
|
|
20
|
+
*
|
|
21
|
+
* Requires a bound device + a per-request proof. The verified raw body is
|
|
22
|
+
* cached on the request, so a downstream handler can re-read it via
|
|
23
|
+
* `readJsonBody(req)`.
|
|
24
|
+
*/
|
|
25
|
+
export function requireProof(opts = {}) {
|
|
26
|
+
return async (req, res) => {
|
|
27
|
+
const session = getDbscSession(req);
|
|
28
|
+
const tier = session?.tier ?? "none";
|
|
29
|
+
const skipped = session?.skipped ?? [];
|
|
30
|
+
if (!session?.sessionId || tier === "none") {
|
|
31
|
+
res.setHeader("Content-Type", "application/json");
|
|
32
|
+
res.statusCode = 403;
|
|
33
|
+
res.end(JSON.stringify({ error: "device-bound session required", currentTier: "none", reason: noBindingReason(skipped), skipped }));
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const internal = session[DBSC_INTERNAL];
|
|
37
|
+
const storage = opts.storage ?? internal?.storage;
|
|
38
|
+
if (!storage) {
|
|
39
|
+
res.setHeader("Content-Type", "application/json");
|
|
40
|
+
res.statusCode = 500;
|
|
41
|
+
res.end(JSON.stringify({ error: "requireProof: storage unavailable — run dbsc() before the guard, or pass { storage }" }));
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const allowDbscWithoutProof = opts.allowDbscWithoutProof ?? (internal?.boundEnabled === false ? true : undefined);
|
|
45
|
+
if (tier === "dbsc" && allowDbscWithoutProof)
|
|
46
|
+
return true;
|
|
47
|
+
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
48
|
+
const proofHeaderRaw = req.headers["x-dbsc-bound-proof"];
|
|
49
|
+
const proofHeader = Array.isArray(proofHeaderRaw) ? proofHeaderRaw[0] : proofHeaderRaw;
|
|
50
|
+
try {
|
|
51
|
+
await verifyBoundProof({
|
|
52
|
+
sessionId: session.sessionId,
|
|
53
|
+
proofHeader,
|
|
54
|
+
method: req.method ?? "GET",
|
|
55
|
+
path: url.pathname,
|
|
56
|
+
signBody: true,
|
|
57
|
+
bodyBytes: await readRawBody(req),
|
|
58
|
+
...(opts.timestampWindowMs !== undefined && { timestampWindowMs: opts.timestampWindowMs }),
|
|
59
|
+
...(internal?.replayCache !== undefined && { replayCache: internal.replayCache }),
|
|
60
|
+
}, storage);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (err instanceof DbscVerificationError) {
|
|
65
|
+
res.setHeader("Content-Type", "application/json");
|
|
66
|
+
res.statusCode = 403;
|
|
67
|
+
res.end(JSON.stringify({ error: err.message, code: err.code }));
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=require-proof.js.map
|