dbsc-toolkit 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +132 -0
- package/README.md +205 -0
- package/dist/client/detect.d.ts +3 -0
- package/dist/client/detect.d.ts.map +1 -0
- package/dist/client/detect.js +20 -0
- package/dist/client/detect.js.map +1 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/signals.d.ts +9 -0
- package/dist/client/signals.d.ts.map +1 -0
- package/dist/client/signals.js +13 -0
- package/dist/client/signals.js.map +1 -0
- package/dist/client/webauthn.d.ts +3 -0
- package/dist/client/webauthn.d.ts.map +1 -0
- package/dist/client/webauthn.js +8 -0
- package/dist/client/webauthn.js.map +1 -0
- package/dist/core/crypto/jwk.d.ts +3 -0
- package/dist/core/crypto/jwk.d.ts.map +1 -0
- package/dist/core/crypto/jwk.js +36 -0
- package/dist/core/crypto/jwk.js.map +1 -0
- package/dist/core/crypto/jws.d.ts +15 -0
- package/dist/core/crypto/jws.d.ts.map +1 -0
- package/dist/core/crypto/jws.js +89 -0
- package/dist/core/crypto/jws.js.map +1 -0
- package/dist/core/errors.d.ts +27 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +39 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/fallback/hmac.d.ts +9 -0
- package/dist/core/fallback/hmac.d.ts.map +1 -0
- package/dist/core/fallback/hmac.js +37 -0
- package/dist/core/fallback/hmac.js.map +1 -0
- package/dist/core/fallback/negotiate.d.ts +9 -0
- package/dist/core/fallback/negotiate.d.ts.map +1 -0
- package/dist/core/fallback/negotiate.js +22 -0
- package/dist/core/fallback/negotiate.js.map +1 -0
- package/dist/core/fallback/webauthn.d.ts +10 -0
- package/dist/core/fallback/webauthn.d.ts.map +1 -0
- package/dist/core/fallback/webauthn.js +41 -0
- package/dist/core/fallback/webauthn.js.map +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/protocol/challenge.d.ts +4 -0
- package/dist/core/protocol/challenge.d.ts.map +1 -0
- package/dist/core/protocol/challenge.js +18 -0
- package/dist/core/protocol/challenge.js.map +1 -0
- package/dist/core/protocol/headers.d.ts +21 -0
- package/dist/core/protocol/headers.d.ts.map +1 -0
- package/dist/core/protocol/headers.js +33 -0
- package/dist/core/protocol/headers.js.map +1 -0
- package/dist/core/protocol/refresh.d.ts +8 -0
- package/dist/core/protocol/refresh.d.ts.map +1 -0
- package/dist/core/protocol/refresh.js +37 -0
- package/dist/core/protocol/refresh.js.map +1 -0
- package/dist/core/protocol/registration.d.ts +11 -0
- package/dist/core/protocol/registration.d.ts.map +1 -0
- package/dist/core/protocol/registration.js +40 -0
- package/dist/core/protocol/registration.js.map +1 -0
- package/dist/core/ratelimit/interface.d.ts +7 -0
- package/dist/core/ratelimit/interface.d.ts.map +1 -0
- package/dist/core/ratelimit/interface.js +11 -0
- package/dist/core/ratelimit/interface.js.map +1 -0
- package/dist/core/telemetry/hooks.d.ts +4 -0
- package/dist/core/telemetry/hooks.d.ts.map +1 -0
- package/dist/core/telemetry/hooks.js +11 -0
- package/dist/core/telemetry/hooks.js.map +1 -0
- package/dist/core/testing/memory-storage-stub.d.ts +18 -0
- package/dist/core/testing/memory-storage-stub.d.ts.map +1 -0
- package/dist/core/testing/memory-storage-stub.js +50 -0
- package/dist/core/testing/memory-storage-stub.js.map +1 -0
- package/dist/core/types.d.ts +92 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/express/index.d.ts +20 -0
- package/dist/express/index.d.ts.map +1 -0
- package/dist/express/index.js +217 -0
- package/dist/express/index.js.map +1 -0
- package/dist/fastify/index.d.ts +17 -0
- package/dist/fastify/index.d.ts.map +1 -0
- package/dist/fastify/index.js +115 -0
- package/dist/fastify/index.js.map +1 -0
- package/dist/hono/index.d.ts +13 -0
- package/dist/hono/index.d.ts.map +1 -0
- package/dist/hono/index.js +107 -0
- package/dist/hono/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/nextjs/index.d.ts +13 -0
- package/dist/nextjs/index.d.ts.map +1 -0
- package/dist/nextjs/index.js +126 -0
- package/dist/nextjs/index.js.map +1 -0
- package/dist/storage/memory/index.d.ts +20 -0
- package/dist/storage/memory/index.d.ts.map +1 -0
- package/dist/storage/memory/index.js +79 -0
- package/dist/storage/memory/index.js.map +1 -0
- package/dist/storage/postgres/index.d.ts +19 -0
- package/dist/storage/postgres/index.d.ts.map +1 -0
- package/dist/storage/postgres/index.js +89 -0
- package/dist/storage/postgres/index.js.map +1 -0
- package/dist/storage/redis/index.d.ts +18 -0
- package/dist/storage/redis/index.d.ts.map +1 -0
- package/dist/storage/redis/index.js +88 -0
- package/dist/storage/redis/index.js.map +1 -0
- package/migrations/001_initial.sql +41 -0
- package/package.json +124 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export class DbscProtocolError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(code, message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "DbscProtocolError";
|
|
6
|
+
this.code = code;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class DbscVerificationError extends Error {
|
|
10
|
+
code;
|
|
11
|
+
constructor(code, message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "DbscVerificationError";
|
|
14
|
+
this.code = code;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class DbscStorageError extends Error {
|
|
18
|
+
code;
|
|
19
|
+
constructor(code, message) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "DbscStorageError";
|
|
22
|
+
this.code = code;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export const ErrorCodes = {
|
|
26
|
+
MISSING_RESPONSE_HEADER: "MISSING_RESPONSE_HEADER",
|
|
27
|
+
MALFORMED_JWS: "MALFORMED_JWS",
|
|
28
|
+
INVALID_JWK: "INVALID_JWK",
|
|
29
|
+
UNKNOWN_ALGORITHM: "UNKNOWN_ALGORITHM",
|
|
30
|
+
CHALLENGE_NOT_FOUND: "CHALLENGE_NOT_FOUND",
|
|
31
|
+
CHALLENGE_EXPIRED: "CHALLENGE_EXPIRED",
|
|
32
|
+
CHALLENGE_CONSUMED: "CHALLENGE_CONSUMED",
|
|
33
|
+
JTI_MISMATCH: "JTI_MISMATCH",
|
|
34
|
+
SIGNATURE_INVALID: "SIGNATURE_INVALID",
|
|
35
|
+
KEY_NOT_FOUND: "KEY_NOT_FOUND",
|
|
36
|
+
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
37
|
+
RATE_LIMITED: "RATE_LIMITED",
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +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,YAAY,EAAE,cAAc;CACpB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface HmacSignalBundle {
|
|
2
|
+
userAgent: string;
|
|
3
|
+
acceptLanguage: string;
|
|
4
|
+
secureContext: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function collectSignals(headers: Record<string, string | string[] | undefined>): HmacSignalBundle;
|
|
7
|
+
export declare function generateHmacToken(signals: HmacSignalBundle, secret: Buffer): string;
|
|
8
|
+
export declare function verifyHmacToken(token: string, signals: HmacSignalBundle, secret: Buffer): boolean;
|
|
9
|
+
//# sourceMappingURL=hmac.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../../../src/core/fallback/hmac.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,gBAAgB,CAMvG;AAQD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKnF;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAeT"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
// This tier binds a cookie to a set of browser signals via HMAC.
|
|
3
|
+
// It does NOT provide hardware-level binding. Use only when DBSC and WebAuthn
|
|
4
|
+
// are both unavailable. Document this limitation to end users.
|
|
5
|
+
const SIGNAL_SEPARATOR = "|";
|
|
6
|
+
export function collectSignals(headers) {
|
|
7
|
+
return {
|
|
8
|
+
userAgent: headers["user-agent"] ?? "",
|
|
9
|
+
acceptLanguage: headers["accept-language"] ?? "",
|
|
10
|
+
secureContext: headers["x-forwarded-proto"] === "https",
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function serializeSignals(bundle) {
|
|
14
|
+
return [bundle.userAgent, bundle.acceptLanguage, String(bundle.secureContext)].join(SIGNAL_SEPARATOR);
|
|
15
|
+
}
|
|
16
|
+
export function generateHmacToken(signals, secret) {
|
|
17
|
+
const nonce = randomBytes(16).toString("base64url");
|
|
18
|
+
const data = `${nonce}${SIGNAL_SEPARATOR}${serializeSignals(signals)}`;
|
|
19
|
+
const mac = createHmac("sha256", secret).update(data).digest("base64url");
|
|
20
|
+
return `${nonce}.${mac}`;
|
|
21
|
+
}
|
|
22
|
+
export function verifyHmacToken(token, signals, secret) {
|
|
23
|
+
const dot = token.indexOf(".");
|
|
24
|
+
if (dot === -1)
|
|
25
|
+
return false;
|
|
26
|
+
const nonce = token.slice(0, dot);
|
|
27
|
+
const providedMac = token.slice(dot + 1);
|
|
28
|
+
const data = `${nonce}${SIGNAL_SEPARATOR}${serializeSignals(signals)}`;
|
|
29
|
+
const expectedMac = createHmac("sha256", secret).update(data).digest("base64url");
|
|
30
|
+
try {
|
|
31
|
+
return timingSafeEqual(Buffer.from(providedMac), Buffer.from(expectedMac));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=hmac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmac.js","sourceRoot":"","sources":["../../../src/core/fallback/hmac.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvE,iEAAiE;AACjE,8EAA8E;AAC9E,+DAA+D;AAE/D,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAQ7B,MAAM,UAAU,cAAc,CAAC,OAAsD;IACnF,OAAO;QACL,SAAS,EAAG,OAAO,CAAC,YAAY,CAAY,IAAI,EAAE;QAClD,cAAc,EAAG,OAAO,CAAC,iBAAiB,CAAY,IAAI,EAAE;QAC5D,aAAa,EAAG,OAAO,CAAC,mBAAmB,CAAY,KAAK,OAAO;KACpE,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAwB;IAChD,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CACjF,gBAAgB,CACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAyB,EAAE,MAAc;IACzE,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,GAAG,KAAK,GAAG,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IACvE,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC1E,OAAO,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,OAAyB,EACzB,MAAc;IAEd,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAE7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAEzC,MAAM,IAAI,GAAG,GAAG,KAAK,GAAG,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IACvE,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAElF,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ProtectionTier } from "../types.js";
|
|
2
|
+
export interface NegotiationContext {
|
|
3
|
+
acceptsDbsc: boolean;
|
|
4
|
+
supportsWebAuthn: boolean;
|
|
5
|
+
hmacAllowed: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function negotiateTier(ctx: NegotiationContext): ProtectionTier;
|
|
8
|
+
export declare function detectDbscSupport(headers: Record<string, string | string[] | undefined>): boolean;
|
|
9
|
+
//# sourceMappingURL=negotiate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"negotiate.d.ts","sourceRoot":"","sources":["../../../src/core/fallback/negotiate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,kBAAkB,GAAG,cAAc,CAKrE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,OAAO,CAWjG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function negotiateTier(ctx) {
|
|
2
|
+
if (ctx.acceptsDbsc)
|
|
3
|
+
return "dbsc";
|
|
4
|
+
if (ctx.supportsWebAuthn)
|
|
5
|
+
return "webauthn";
|
|
6
|
+
if (ctx.hmacAllowed)
|
|
7
|
+
return "hmac";
|
|
8
|
+
return "none";
|
|
9
|
+
}
|
|
10
|
+
export function detectDbscSupport(headers) {
|
|
11
|
+
const secFetch = headers["sec-fetch-site"];
|
|
12
|
+
const ua = (headers["user-agent"] ?? "");
|
|
13
|
+
// Chrome 146+ on Windows carries DBSC support
|
|
14
|
+
// The definitive signal is whether the browser responds to Secure-Session-Registration
|
|
15
|
+
// This header is set by the server; we detect support by checking Chrome version
|
|
16
|
+
const chromeMatch = /Chrome\/(\d+)/.exec(ua);
|
|
17
|
+
if (!chromeMatch)
|
|
18
|
+
return false;
|
|
19
|
+
const version = parseInt(chromeMatch[1] ?? "0", 10);
|
|
20
|
+
return version >= 146 && !!secFetch;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=negotiate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"negotiate.js","sourceRoot":"","sources":["../../../src/core/fallback/negotiate.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,aAAa,CAAC,GAAuB;IACnD,IAAI,GAAG,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IACnC,IAAI,GAAG,CAAC,gBAAgB;QAAE,OAAO,UAAU,CAAC;IAC5C,IAAI,GAAG,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAsD;IACtF,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3C,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,CAAW,CAAC;IAEnD,8CAA8C;IAC9C,uFAAuF;IACvF,iFAAiF;IACjF,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACpD,OAAO,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { generateRegistrationOptions, verifyRegistrationResponse, generateAuthenticationOptions, verifyAuthenticationResponse, type VerifiedRegistrationResponse, type VerifyAuthenticationResponseOpts } from "@simplewebauthn/server";
|
|
2
|
+
export interface WebAuthnRegistrationChallenge {
|
|
3
|
+
options: Awaited<ReturnType<typeof generateRegistrationOptions>>;
|
|
4
|
+
challenge: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function generateWebAuthnRegistration(rpName: string, rpId: string, userId: string, userName: string): Promise<WebAuthnRegistrationChallenge>;
|
|
7
|
+
export declare function verifyWebAuthnRegistration(response: Parameters<typeof verifyRegistrationResponse>[0]["response"], expectedChallenge: string, expectedOrigin: string, rpId: string): Promise<VerifiedRegistrationResponse>;
|
|
8
|
+
export declare function generateWebAuthnAuthentication(rpId: string, allowedCredentialIds: string[]): Promise<Awaited<ReturnType<typeof generateAuthenticationOptions>>>;
|
|
9
|
+
export declare function verifyWebAuthnAuthentication(opts: VerifyAuthenticationResponseOpts): Promise<Awaited<ReturnType<typeof verifyAuthenticationResponse>>>;
|
|
10
|
+
//# sourceMappingURL=webauthn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webauthn.d.ts","sourceRoot":"","sources":["../../../src/core/fallback/webauthn.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAE5B,KAAK,4BAA4B,EACjC,KAAK,gCAAgC,EACtC,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC,CAAC;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,6BAA6B,CAAC,CAkBxC;AAED,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EACtE,iBAAiB,EAAE,MAAM,EACzB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,4BAA4B,CAAC,CAOvC;AAED,wBAAsB,8BAA8B,CAClD,IAAI,EAAE,MAAM,EACZ,oBAAoB,EAAE,MAAM,EAAE,GAC7B,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,6BAA6B,CAAC,CAAC,CAAC,CASpE;AAED,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,gCAAgC,GACrC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAAC,CAEnE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { generateRegistrationOptions, verifyRegistrationResponse, generateAuthenticationOptions, verifyAuthenticationResponse, } from "@simplewebauthn/server";
|
|
2
|
+
export async function generateWebAuthnRegistration(rpName, rpId, userId, userName) {
|
|
3
|
+
const opts = {
|
|
4
|
+
rpName,
|
|
5
|
+
rpID: rpId,
|
|
6
|
+
userID: new TextEncoder().encode(userId),
|
|
7
|
+
userName,
|
|
8
|
+
authenticatorSelection: {
|
|
9
|
+
residentKey: "required",
|
|
10
|
+
userVerification: "preferred",
|
|
11
|
+
},
|
|
12
|
+
attestationType: "none",
|
|
13
|
+
};
|
|
14
|
+
const options = await generateRegistrationOptions(opts);
|
|
15
|
+
return {
|
|
16
|
+
options,
|
|
17
|
+
challenge: options.challenge,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export async function verifyWebAuthnRegistration(response, expectedChallenge, expectedOrigin, rpId) {
|
|
21
|
+
return verifyRegistrationResponse({
|
|
22
|
+
response,
|
|
23
|
+
expectedChallenge,
|
|
24
|
+
expectedOrigin,
|
|
25
|
+
expectedRPID: rpId,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export async function generateWebAuthnAuthentication(rpId, allowedCredentialIds) {
|
|
29
|
+
return generateAuthenticationOptions({
|
|
30
|
+
rpID: rpId,
|
|
31
|
+
allowCredentials: allowedCredentialIds.map((id) => ({
|
|
32
|
+
id,
|
|
33
|
+
transports: ["internal"],
|
|
34
|
+
})),
|
|
35
|
+
userVerification: "preferred",
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export async function verifyWebAuthnAuthentication(opts) {
|
|
39
|
+
return verifyAuthenticationResponse(opts);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=webauthn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webauthn.js","sourceRoot":"","sources":["../../../src/core/fallback/webauthn.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,GAI7B,MAAM,wBAAwB,CAAC;AAOhC,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,MAAc,EACd,IAAY,EACZ,MAAc,EACd,QAAgB;IAEhB,MAAM,IAAI,GAAoC;QAC5C,MAAM;QACN,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;QACxC,QAAQ;QACR,sBAAsB,EAAE;YACtB,WAAW,EAAE,UAAU;YACvB,gBAAgB,EAAE,WAAW;SAC9B;QACD,eAAe,EAAE,MAAM;KACxB,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,2BAA2B,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO;QACL,OAAO;QACP,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,QAAsE,EACtE,iBAAyB,EACzB,cAAsB,EACtB,IAAY;IAEZ,OAAO,0BAA0B,CAAC;QAChC,QAAQ;QACR,iBAAiB;QACjB,cAAc;QACd,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,IAAY,EACZ,oBAA8B;IAE9B,OAAO,6BAA6B,CAAC;QACnC,IAAI,EAAE,IAAI;QACV,gBAAgB,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAClD,EAAE;YACF,UAAU,EAAE,CAAC,UAAU,CAAC;SACzB,CAAC,CAAC;QACH,gBAAgB,EAAE,WAAW;KAC9B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,IAAsC;IAEtC,OAAO,4BAA4B,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type { ProtectionTier, BoundKey, Session, Challenge, RegistrationProof, RefreshProof, StorageAdapter, RateLimiter, DbscOptions, AnyTelemetryEvent, TelemetryEvent, RegistrationEvent, RefreshEvent, VerificationFailureEvent, SessionStolenEvent, FallbackTierEvent, } from "./types.js";
|
|
2
|
+
export { DbscProtocolError, DbscVerificationError, DbscStorageError, ErrorCodes } from "./errors.js";
|
|
3
|
+
export { validateJwk, detectAlgorithm } from "./crypto/jwk.js";
|
|
4
|
+
export { verifyDbscJws, parseRegistrationJws } from "./crypto/jws.js";
|
|
5
|
+
export { generateJti, issueChallenge } from "./protocol/challenge.js";
|
|
6
|
+
export { buildRegistrationHeader, buildChallengeHeader, parseSessionResponseHeader, buildSessionIdCookie, readSessionResponseHeader, REGISTRATION_HEADER, RESPONSE_HEADER, CHALLENGE_HEADER, LEGACY_REGISTRATION_HEADER, LEGACY_RESPONSE_HEADER, LEGACY_CHALLENGE_HEADER, } from "./protocol/headers.js";
|
|
7
|
+
export { handleRegistration } from "./protocol/registration.js";
|
|
8
|
+
export { handleRefresh } from "./protocol/refresh.js";
|
|
9
|
+
export { negotiateTier, detectDbscSupport } from "./fallback/negotiate.js";
|
|
10
|
+
export { generateWebAuthnRegistration, verifyWebAuthnRegistration, generateWebAuthnAuthentication, verifyWebAuthnAuthentication, } from "./fallback/webauthn.js";
|
|
11
|
+
export { collectSignals, generateHmacToken, verifyHmacToken } from "./fallback/hmac.js";
|
|
12
|
+
export { NoopRateLimiter } from "./ratelimit/interface.js";
|
|
13
|
+
export { emit } from "./telemetry/hooks.js";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,GAClB,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,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,8BAA8B,EAC9B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { DbscProtocolError, DbscVerificationError, DbscStorageError, ErrorCodes } from "./errors.js";
|
|
2
|
+
export { validateJwk, detectAlgorithm } from "./crypto/jwk.js";
|
|
3
|
+
export { verifyDbscJws, parseRegistrationJws } from "./crypto/jws.js";
|
|
4
|
+
export { generateJti, issueChallenge } from "./protocol/challenge.js";
|
|
5
|
+
export { buildRegistrationHeader, buildChallengeHeader, parseSessionResponseHeader, buildSessionIdCookie, readSessionResponseHeader, REGISTRATION_HEADER, RESPONSE_HEADER, CHALLENGE_HEADER, LEGACY_REGISTRATION_HEADER, LEGACY_RESPONSE_HEADER, LEGACY_CHALLENGE_HEADER, } from "./protocol/headers.js";
|
|
6
|
+
export { handleRegistration } from "./protocol/registration.js";
|
|
7
|
+
export { handleRefresh } from "./protocol/refresh.js";
|
|
8
|
+
export { negotiateTier, detectDbscSupport } from "./fallback/negotiate.js";
|
|
9
|
+
export { generateWebAuthnRegistration, verifyWebAuthnRegistration, generateWebAuthnAuthentication, verifyWebAuthnAuthentication, } from "./fallback/webauthn.js";
|
|
10
|
+
export { collectSignals, generateHmacToken, verifyHmacToken } from "./fallback/hmac.js";
|
|
11
|
+
export { NoopRateLimiter } from "./ratelimit/interface.js";
|
|
12
|
+
export { emit } from "./telemetry/hooks.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAmBA,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,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,8BAA8B,EAC9B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Challenge, StorageAdapter } from "../types.js";
|
|
2
|
+
export declare function generateJti(): string;
|
|
3
|
+
export declare function issueChallenge(sessionId: string, storage: StorageAdapter, ttlMs?: number): Promise<Challenge>;
|
|
4
|
+
//# sourceMappingURL=challenge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../../src/core/protocol/challenge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI7D,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,KAAK,GAAE,MAAuB,GAC7B,OAAO,CAAC,SAAS,CAAC,CAWpB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
const DEFAULT_TTL_MS = 5 * 60 * 1000;
|
|
3
|
+
export function generateJti() {
|
|
4
|
+
return randomBytes(32).toString("base64url");
|
|
5
|
+
}
|
|
6
|
+
export async function issueChallenge(sessionId, storage, ttlMs = DEFAULT_TTL_MS) {
|
|
7
|
+
const now = Date.now();
|
|
8
|
+
const challenge = {
|
|
9
|
+
jti: generateJti(),
|
|
10
|
+
sessionId,
|
|
11
|
+
createdAt: now,
|
|
12
|
+
expiresAt: now + ttlMs,
|
|
13
|
+
consumed: false,
|
|
14
|
+
};
|
|
15
|
+
await storage.setChallenge(challenge);
|
|
16
|
+
return challenge;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=challenge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"challenge.js","sourceRoot":"","sources":["../../../src/core/protocol/challenge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAErC,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,SAAiB,EACjB,OAAuB,EACvB,QAAgB,cAAc;IAE9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,SAAS,GAAc;QAC3B,GAAG,EAAE,WAAW,EAAE;QAClB,SAAS;QACT,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG,GAAG,KAAK;QACtB,QAAQ,EAAE,KAAK;KAChB,CAAC;IACF,MAAM,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACtC,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface RegistrationHeaderOptions {
|
|
2
|
+
algorithm?: "ES256" | "RS256";
|
|
3
|
+
refreshPath: string;
|
|
4
|
+
challenge: string;
|
|
5
|
+
cookieName?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function buildRegistrationHeader(opts: RegistrationHeaderOptions): string;
|
|
8
|
+
export declare function buildChallengeHeader(jti: string): string;
|
|
9
|
+
export declare function parseSessionResponseHeader(raw: string): string;
|
|
10
|
+
export declare function buildSessionIdCookie(sessionId: string, opts: {
|
|
11
|
+
secure: boolean;
|
|
12
|
+
sameSite: string;
|
|
13
|
+
}): string;
|
|
14
|
+
export declare const REGISTRATION_HEADER = "Secure-Session-Registration";
|
|
15
|
+
export declare const RESPONSE_HEADER = "Secure-Session-Response";
|
|
16
|
+
export declare const CHALLENGE_HEADER = "Secure-Session-Challenge";
|
|
17
|
+
export declare const LEGACY_REGISTRATION_HEADER = "Sec-Session-Registration";
|
|
18
|
+
export declare const LEGACY_RESPONSE_HEADER = "Sec-Session-Response";
|
|
19
|
+
export declare const LEGACY_CHALLENGE_HEADER = "Sec-Session-Challenge";
|
|
20
|
+
export declare function readSessionResponseHeader(headers: Record<string, string | string[] | undefined>): string | undefined;
|
|
21
|
+
//# sourceMappingURL=headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../../src/core/protocol/headers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,yBAAyB,GAAG,MAAM,CAK/E;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1C,MAAM,CAKR;AAED,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AACjE,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAE3D,eAAO,MAAM,0BAA0B,6BAA6B,CAAC;AACrE,eAAO,MAAM,sBAAsB,yBAAyB,CAAC;AAC7D,eAAO,MAAM,uBAAuB,0BAA0B,CAAC;AAE/D,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,MAAM,GAAG,SAAS,CAIpB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function buildRegistrationHeader(opts) {
|
|
2
|
+
const alg = opts.algorithm ?? "ES256";
|
|
3
|
+
const parts = [`(${alg})`, `path="${opts.refreshPath}"`, `challenge="${opts.challenge}"`];
|
|
4
|
+
if (opts.cookieName)
|
|
5
|
+
parts.push(`id="${opts.cookieName}"`);
|
|
6
|
+
return parts.join(";");
|
|
7
|
+
}
|
|
8
|
+
export function buildChallengeHeader(jti) {
|
|
9
|
+
return `"${jti}"`;
|
|
10
|
+
}
|
|
11
|
+
export function parseSessionResponseHeader(raw) {
|
|
12
|
+
return raw.trim();
|
|
13
|
+
}
|
|
14
|
+
export function buildSessionIdCookie(sessionId, opts) {
|
|
15
|
+
const parts = [`__Secure-Session-Id=${sessionId}`, "HttpOnly", "Path=/"];
|
|
16
|
+
if (opts.secure)
|
|
17
|
+
parts.push("Secure");
|
|
18
|
+
parts.push(`SameSite=${opts.sameSite}`);
|
|
19
|
+
return parts.join("; ");
|
|
20
|
+
}
|
|
21
|
+
export const REGISTRATION_HEADER = "Secure-Session-Registration";
|
|
22
|
+
export const RESPONSE_HEADER = "Secure-Session-Response";
|
|
23
|
+
export const CHALLENGE_HEADER = "Secure-Session-Challenge";
|
|
24
|
+
export const LEGACY_REGISTRATION_HEADER = "Sec-Session-Registration";
|
|
25
|
+
export const LEGACY_RESPONSE_HEADER = "Sec-Session-Response";
|
|
26
|
+
export const LEGACY_CHALLENGE_HEADER = "Sec-Session-Challenge";
|
|
27
|
+
export function readSessionResponseHeader(headers) {
|
|
28
|
+
const v = headers["secure-session-response"] ?? headers["sec-session-response"];
|
|
29
|
+
if (Array.isArray(v))
|
|
30
|
+
return v[0];
|
|
31
|
+
return v;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../../src/core/protocol/headers.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,uBAAuB,CAAC,IAA+B;IACrE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,SAAS,IAAI,CAAC,WAAW,GAAG,EAAE,cAAc,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;IAC1F,IAAI,IAAI,CAAC,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;IAC3D,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,OAAO,IAAI,GAAG,GAAG,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,GAAW;IACpD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,IAA2C;IAE3C,MAAM,KAAK,GAAG,CAAC,uBAAuB,SAAS,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IACzE,IAAI,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,6BAA6B,CAAC;AACjE,MAAM,CAAC,MAAM,eAAe,GAAG,yBAAyB,CAAC;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAE3D,MAAM,CAAC,MAAM,0BAA0B,GAAG,0BAA0B,CAAC;AACrE,MAAM,CAAC,MAAM,sBAAsB,GAAG,sBAAsB,CAAC;AAC7D,MAAM,CAAC,MAAM,uBAAuB,GAAG,uBAAuB,CAAC;AAE/D,MAAM,UAAU,yBAAyB,CACvC,OAAsD;IAEtD,MAAM,CAAC,GAAG,OAAO,CAAC,yBAAyB,CAAC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAChF,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RefreshProof, StorageAdapter } from "../types.js";
|
|
2
|
+
export interface RefreshRequest {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
secSessionResponseHeader: string | undefined;
|
|
5
|
+
expectedJti: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function handleRefresh(req: RefreshRequest, storage: StorageAdapter): Promise<RefreshProof>;
|
|
8
|
+
//# sourceMappingURL=refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/core/protocol/refresh.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,YAAY,CAAC,CA6CvB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { verifyDbscJws } from "../crypto/jws.js";
|
|
2
|
+
import { DbscProtocolError, DbscVerificationError, ErrorCodes } from "../errors.js";
|
|
3
|
+
export async function handleRefresh(req, storage) {
|
|
4
|
+
if (!req.secSessionResponseHeader) {
|
|
5
|
+
throw new DbscProtocolError(ErrorCodes.MISSING_RESPONSE_HEADER, "Secure-Session-Response header is required for refresh");
|
|
6
|
+
}
|
|
7
|
+
const key = await storage.getBoundKey(req.sessionId);
|
|
8
|
+
if (!key) {
|
|
9
|
+
throw new DbscVerificationError(ErrorCodes.KEY_NOT_FOUND, "no bound key for session");
|
|
10
|
+
}
|
|
11
|
+
const challenge = await storage.getChallenge(req.expectedJti);
|
|
12
|
+
if (!challenge) {
|
|
13
|
+
throw new DbscVerificationError(ErrorCodes.CHALLENGE_NOT_FOUND, "challenge not found");
|
|
14
|
+
}
|
|
15
|
+
if (challenge.consumed) {
|
|
16
|
+
throw new DbscVerificationError(ErrorCodes.CHALLENGE_CONSUMED, "challenge already consumed");
|
|
17
|
+
}
|
|
18
|
+
if (Date.now() > challenge.expiresAt) {
|
|
19
|
+
throw new DbscVerificationError(ErrorCodes.CHALLENGE_EXPIRED, "challenge expired");
|
|
20
|
+
}
|
|
21
|
+
const token = req.secSessionResponseHeader.trim();
|
|
22
|
+
await verifyDbscJws(token, key.jwk, req.expectedJti);
|
|
23
|
+
const consumed = await storage.consumeChallenge(req.expectedJti);
|
|
24
|
+
if (!consumed) {
|
|
25
|
+
throw new DbscVerificationError(ErrorCodes.CHALLENGE_CONSUMED, "challenge already consumed");
|
|
26
|
+
}
|
|
27
|
+
const session = await storage.getSession(req.sessionId);
|
|
28
|
+
if (session) {
|
|
29
|
+
await storage.setSession({ ...session, lastRefreshAt: Date.now() });
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
sessionId: req.sessionId,
|
|
33
|
+
jti: req.expectedJti,
|
|
34
|
+
verified: true,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=refresh.js.map
|
|
@@ -0,0 +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;IACrD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,aAAa,EACxB,0BAA0B,CAC3B,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,MAAM,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IAErD,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,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,GAAG,EAAE,GAAG,CAAC,WAAW;QACpB,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BoundKey, StorageAdapter } from "../types.js";
|
|
2
|
+
export interface RegistrationRequest {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
secSessionResponseHeader: string | undefined;
|
|
5
|
+
expectedJti: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RegistrationResult {
|
|
8
|
+
boundKey: BoundKey;
|
|
9
|
+
}
|
|
10
|
+
export declare function handleRegistration(req: RegistrationRequest, storage: StorageAdapter): Promise<RegistrationResult>;
|
|
11
|
+
//# sourceMappingURL=registration.d.ts.map
|
|
@@ -0,0 +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,CA8C7B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { parseRegistrationJws } from "../crypto/jws.js";
|
|
2
|
+
import { DbscProtocolError, DbscVerificationError, ErrorCodes } from "../errors.js";
|
|
3
|
+
export async function handleRegistration(req, storage) {
|
|
4
|
+
if (!req.secSessionResponseHeader) {
|
|
5
|
+
throw new DbscProtocolError(ErrorCodes.MISSING_RESPONSE_HEADER, "Secure-Session-Response header is required");
|
|
6
|
+
}
|
|
7
|
+
const token = req.secSessionResponseHeader.trim();
|
|
8
|
+
const { jwk, algorithm, claims } = await parseRegistrationJws(token);
|
|
9
|
+
const challenge = await storage.getChallenge(req.expectedJti);
|
|
10
|
+
if (!challenge) {
|
|
11
|
+
throw new DbscVerificationError(ErrorCodes.CHALLENGE_NOT_FOUND, "challenge not found");
|
|
12
|
+
}
|
|
13
|
+
if (challenge.consumed) {
|
|
14
|
+
throw new DbscVerificationError(ErrorCodes.CHALLENGE_CONSUMED, "challenge already consumed");
|
|
15
|
+
}
|
|
16
|
+
if (Date.now() > challenge.expiresAt) {
|
|
17
|
+
throw new DbscVerificationError(ErrorCodes.CHALLENGE_EXPIRED, "challenge expired");
|
|
18
|
+
}
|
|
19
|
+
if (claims.jti !== req.expectedJti) {
|
|
20
|
+
throw new DbscVerificationError(ErrorCodes.JTI_MISMATCH, "jti does not match challenge");
|
|
21
|
+
}
|
|
22
|
+
const consumed = await storage.consumeChallenge(req.expectedJti);
|
|
23
|
+
if (!consumed) {
|
|
24
|
+
throw new DbscVerificationError(ErrorCodes.CHALLENGE_CONSUMED, "challenge already consumed");
|
|
25
|
+
}
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const boundKey = {
|
|
28
|
+
sessionId: req.sessionId,
|
|
29
|
+
jwk,
|
|
30
|
+
createdAt: now,
|
|
31
|
+
algorithm,
|
|
32
|
+
};
|
|
33
|
+
await storage.setBoundKey(boundKey);
|
|
34
|
+
const session = await storage.getSession(req.sessionId);
|
|
35
|
+
if (session) {
|
|
36
|
+
await storage.setSession({ ...session, tier: "dbsc", lastRefreshAt: now });
|
|
37
|
+
}
|
|
38
|
+
return { boundKey };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=registration.js.map
|
|
@@ -0,0 +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,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,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,7 @@
|
|
|
1
|
+
import type { RateLimiter } from "../types.js";
|
|
2
|
+
export declare class NoopRateLimiter implements RateLimiter {
|
|
3
|
+
checkRegistration(_ip: string): Promise<boolean>;
|
|
4
|
+
checkRefresh(_ip: string, _sessionId: string): Promise<boolean>;
|
|
5
|
+
recordFailure(_ip: string, _sessionId?: string): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/core/ratelimit/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,qBAAa,eAAgB,YAAW,WAAW;IAC3C,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIhD,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI/D,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CACrE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Default no-op limiter. Replace with a real implementation in production.
|
|
2
|
+
export class NoopRateLimiter {
|
|
3
|
+
async checkRegistration(_ip) {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
async checkRefresh(_ip, _sessionId) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
async recordFailure(_ip, _sessionId) { }
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../src/core/ratelimit/interface.ts"],"names":[],"mappings":"AAEA,2EAA2E;AAC3E,MAAM,OAAO,eAAe;IAC1B,KAAK,CAAC,iBAAiB,CAAC,GAAW;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW,EAAE,UAAkB;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAW,EAAE,UAAmB,IAAkB,CAAC;CACxE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/core/telemetry/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAE9D,wBAAgB,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,EAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAOtF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../src/core/telemetry/hooks.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,IAAI,CAAC,OAAiC,EAAE,KAAwB;IAC9E,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;IACtD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StorageAdapter, Session, BoundKey, Challenge } from "../types.js";
|
|
2
|
+
export declare class MemoryStorage implements StorageAdapter {
|
|
3
|
+
private sessions;
|
|
4
|
+
private keys;
|
|
5
|
+
private challenges;
|
|
6
|
+
getSession(id: string): Promise<Session | null>;
|
|
7
|
+
setSession(session: Session): Promise<void>;
|
|
8
|
+
deleteSession(id: string): Promise<void>;
|
|
9
|
+
getBoundKey(sessionId: string): Promise<BoundKey | null>;
|
|
10
|
+
setBoundKey(key: BoundKey): Promise<void>;
|
|
11
|
+
deleteBoundKey(sessionId: string): Promise<void>;
|
|
12
|
+
getChallenge(jti: string): Promise<Challenge | null>;
|
|
13
|
+
setChallenge(challenge: Challenge): Promise<void>;
|
|
14
|
+
consumeChallenge(jti: string): Promise<boolean>;
|
|
15
|
+
revokeSession(sessionId: string): Promise<void>;
|
|
16
|
+
revokeAllForUser(userId: string): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=memory-storage-stub.d.ts.map
|
|
@@ -0,0 +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;AAEhF,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;IAKxC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAIxD,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,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;IAK/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQtD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export class MemoryStorage {
|
|
2
|
+
sessions = new Map();
|
|
3
|
+
keys = new Map();
|
|
4
|
+
challenges = new Map();
|
|
5
|
+
async getSession(id) {
|
|
6
|
+
return this.sessions.get(id) ?? null;
|
|
7
|
+
}
|
|
8
|
+
async setSession(session) {
|
|
9
|
+
this.sessions.set(session.id, session);
|
|
10
|
+
}
|
|
11
|
+
async deleteSession(id) {
|
|
12
|
+
this.sessions.delete(id);
|
|
13
|
+
this.keys.delete(id);
|
|
14
|
+
}
|
|
15
|
+
async getBoundKey(sessionId) {
|
|
16
|
+
return this.keys.get(sessionId) ?? null;
|
|
17
|
+
}
|
|
18
|
+
async setBoundKey(key) {
|
|
19
|
+
this.keys.set(key.sessionId, key);
|
|
20
|
+
}
|
|
21
|
+
async deleteBoundKey(sessionId) {
|
|
22
|
+
this.keys.delete(sessionId);
|
|
23
|
+
}
|
|
24
|
+
async getChallenge(jti) {
|
|
25
|
+
return this.challenges.get(jti) ?? null;
|
|
26
|
+
}
|
|
27
|
+
async setChallenge(challenge) {
|
|
28
|
+
this.challenges.set(challenge.jti, challenge);
|
|
29
|
+
}
|
|
30
|
+
async consumeChallenge(jti) {
|
|
31
|
+
const ch = this.challenges.get(jti);
|
|
32
|
+
if (!ch || ch.consumed)
|
|
33
|
+
return false;
|
|
34
|
+
ch.consumed = true;
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
async revokeSession(sessionId) {
|
|
38
|
+
this.sessions.delete(sessionId);
|
|
39
|
+
this.keys.delete(sessionId);
|
|
40
|
+
}
|
|
41
|
+
async revokeAllForUser(userId) {
|
|
42
|
+
for (const [id, sess] of this.sessions.entries()) {
|
|
43
|
+
if (sess.userId === userId) {
|
|
44
|
+
this.sessions.delete(id);
|
|
45
|
+
this.keys.delete(id);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=memory-storage-stub.js.map
|
|
@@ -0,0 +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;IACvB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,SAAiB;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAa;QAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,SAAiB;QACpC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC5B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,SAAoB;QACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,GAAW;QAChC,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAc;QACnC,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|