dbsc-toolkit 2.6.0 → 2.7.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 +12 -5
- package/dist/client/index.d.ts +6 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +48 -0
- package/dist/client/index.js.map +1 -1
- package/dist/core/bound/proof.d.ts.map +1 -1
- package/dist/core/bound/proof.js +5 -2
- package/dist/core/bound/proof.js.map +1 -1
- package/dist/core/bound/refresh.d.ts.map +1 -1
- package/dist/core/bound/refresh.js +7 -3
- package/dist/core/bound/refresh.js.map +1 -1
- package/dist/core/bound/registration.d.ts.map +1 -1
- package/dist/core/bound/registration.js +14 -3
- package/dist/core/bound/registration.js.map +1 -1
- package/dist/core/crypto/jwk.js +3 -1
- package/dist/core/crypto/jwk.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/protect-policy.d.ts +10 -9
- package/dist/core/protect-policy.d.ts.map +1 -1
- package/dist/core/protect-policy.js.map +1 -1
- package/dist/core/protocol/cookies.d.ts.map +1 -1
- package/dist/core/protocol/cookies.js +3 -1
- package/dist/core/protocol/cookies.js.map +1 -1
- package/dist/core/protocol/refresh.js +2 -2
- package/dist/core/protocol/refresh.js.map +1 -1
- package/dist/core/protocol/registration.d.ts.map +1 -1
- package/dist/core/protocol/registration.js +3 -2
- package/dist/core/protocol/registration.js.map +1 -1
- package/dist/core/testing/memory-storage-stub.d.ts +3 -3
- package/dist/core/testing/memory-storage-stub.d.ts.map +1 -1
- package/dist/core/testing/memory-storage-stub.js +20 -8
- package/dist/core/testing/memory-storage-stub.js.map +1 -1
- package/dist/core/types.d.ts +28 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/express/create-dbsc.d.ts +6 -1
- package/dist/express/create-dbsc.d.ts.map +1 -1
- package/dist/express/create-dbsc.js +36 -5
- package/dist/express/create-dbsc.js.map +1 -1
- package/dist/express/index.d.ts.map +1 -1
- package/dist/express/index.js +18 -2
- package/dist/express/index.js.map +1 -1
- package/dist/express/proof.d.ts +8 -1
- package/dist/express/proof.d.ts.map +1 -1
- package/dist/express/proof.js +1 -1
- package/dist/express/proof.js.map +1 -1
- package/dist/fastify/create-dbsc.d.ts +4 -1
- package/dist/fastify/create-dbsc.d.ts.map +1 -1
- package/dist/fastify/create-dbsc.js +30 -4
- package/dist/fastify/create-dbsc.js.map +1 -1
- package/dist/fastify/index.d.ts.map +1 -1
- package/dist/fastify/index.js +14 -2
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/proof.d.ts +5 -1
- package/dist/fastify/proof.d.ts.map +1 -1
- package/dist/fastify/proof.js +1 -1
- package/dist/fastify/proof.js.map +1 -1
- package/dist/hono/create-dbsc.d.ts +4 -1
- package/dist/hono/create-dbsc.d.ts.map +1 -1
- package/dist/hono/create-dbsc.js +31 -4
- package/dist/hono/create-dbsc.js.map +1 -1
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +14 -2
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/proof.d.ts +5 -1
- package/dist/hono/proof.d.ts.map +1 -1
- package/dist/hono/proof.js +1 -1
- package/dist/hono/proof.js.map +1 -1
- package/dist/nextjs/create-dbsc.d.ts +12 -1
- package/dist/nextjs/create-dbsc.d.ts.map +1 -1
- package/dist/nextjs/create-dbsc.js +27 -4
- package/dist/nextjs/create-dbsc.js.map +1 -1
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/index.js +16 -2
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/proof.d.ts +5 -1
- package/dist/nextjs/proof.d.ts.map +1 -1
- package/dist/nextjs/proof.js +1 -1
- package/dist/nextjs/proof.js.map +1 -1
- package/dist/storage/memory/index.d.ts +3 -3
- package/dist/storage/memory/index.d.ts.map +1 -1
- package/dist/storage/memory/index.js +22 -8
- package/dist/storage/memory/index.js.map +1 -1
- package/dist/storage/postgres/index.d.ts +3 -3
- package/dist/storage/postgres/index.d.ts.map +1 -1
- package/dist/storage/postgres/index.js +24 -7
- package/dist/storage/postgres/index.js.map +1 -1
- package/dist/storage/redis/index.d.ts +3 -3
- package/dist/storage/redis/index.d.ts.map +1 -1
- package/dist/storage/redis/index.js +48 -10
- package/dist/storage/redis/index.js.map +1 -1
- package/migrations/002_bound_key_kind.sql +26 -0
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export class MemoryStorage {
|
|
2
2
|
sessions = new Map();
|
|
3
|
+
// Keyed by `${sessionId}:${kind}`. A session can hold up to two rows
|
|
4
|
+
// (one per kind) — see BoundKey.kind in core/types.ts.
|
|
3
5
|
keys = new Map();
|
|
4
6
|
challenges = new Map();
|
|
5
7
|
revoked = new Set();
|
|
@@ -18,16 +20,26 @@ export class MemoryStorage {
|
|
|
18
20
|
}
|
|
19
21
|
async deleteSession(id) {
|
|
20
22
|
this.sessions.delete(id);
|
|
21
|
-
this.keys.delete(id);
|
|
23
|
+
this.keys.delete(`${id}:native`);
|
|
24
|
+
this.keys.delete(`${id}:bound`);
|
|
22
25
|
}
|
|
23
|
-
async getBoundKey(sessionId) {
|
|
24
|
-
|
|
26
|
+
async getBoundKey(sessionId, kind) {
|
|
27
|
+
if (kind)
|
|
28
|
+
return this.keys.get(`${sessionId}:${kind}`) ?? null;
|
|
29
|
+
return (this.keys.get(`${sessionId}:native`) ??
|
|
30
|
+
this.keys.get(`${sessionId}:bound`) ??
|
|
31
|
+
null);
|
|
25
32
|
}
|
|
26
33
|
async setBoundKey(key) {
|
|
27
|
-
this.keys.set(key.sessionId
|
|
34
|
+
this.keys.set(`${key.sessionId}:${key.kind}`, key);
|
|
28
35
|
}
|
|
29
|
-
async deleteBoundKey(sessionId) {
|
|
30
|
-
|
|
36
|
+
async deleteBoundKey(sessionId, kind) {
|
|
37
|
+
if (kind) {
|
|
38
|
+
this.keys.delete(`${sessionId}:${kind}`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
this.keys.delete(`${sessionId}:native`);
|
|
42
|
+
this.keys.delete(`${sessionId}:bound`);
|
|
31
43
|
}
|
|
32
44
|
async getChallenge(jti) {
|
|
33
45
|
const challenge = this.challenges.get(jti);
|
|
@@ -52,14 +64,16 @@ export class MemoryStorage {
|
|
|
52
64
|
async revokeSession(sessionId) {
|
|
53
65
|
this.revoked.add(sessionId);
|
|
54
66
|
this.sessions.delete(sessionId);
|
|
55
|
-
this.keys.delete(sessionId);
|
|
67
|
+
this.keys.delete(`${sessionId}:native`);
|
|
68
|
+
this.keys.delete(`${sessionId}:bound`);
|
|
56
69
|
}
|
|
57
70
|
async revokeAllForUser(userId) {
|
|
58
71
|
for (const [id, sess] of this.sessions.entries()) {
|
|
59
72
|
if (sess.userId === userId) {
|
|
60
73
|
this.revoked.add(id);
|
|
61
74
|
this.sessions.delete(id);
|
|
62
|
-
this.keys.delete(id);
|
|
75
|
+
this.keys.delete(`${id}:native`);
|
|
76
|
+
this.keys.delete(`${id}:bound`);
|
|
63
77
|
}
|
|
64
78
|
}
|
|
65
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/memory/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/memory/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { Pool } from "pg";
|
|
2
|
-
import type { StorageAdapter, Session, BoundKey, Challenge } from "../../core/index.js";
|
|
2
|
+
import type { StorageAdapter, Session, BoundKey, BoundKeyKind, Challenge } from "../../core/index.js";
|
|
3
3
|
export declare class PostgresStorage implements StorageAdapter {
|
|
4
4
|
private readonly pool;
|
|
5
5
|
constructor(pool: Pool);
|
|
6
6
|
getSession(id: string): Promise<Session | null>;
|
|
7
7
|
setSession(session: Session): Promise<void>;
|
|
8
8
|
deleteSession(id: string): Promise<void>;
|
|
9
|
-
getBoundKey(sessionId: string): Promise<BoundKey | null>;
|
|
9
|
+
getBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<BoundKey | null>;
|
|
10
10
|
setBoundKey(key: BoundKey): Promise<void>;
|
|
11
|
-
deleteBoundKey(sessionId: string): Promise<void>;
|
|
11
|
+
deleteBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<void>;
|
|
12
12
|
getChallenge(jti: string): Promise<Challenge | null>;
|
|
13
13
|
setChallenge(challenge: Challenge): Promise<void>;
|
|
14
14
|
consumeChallenge(jti: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AAC3C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AAC3C,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,SAAS,EACV,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,eAAgB,YAAW,cAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEjC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IA6B/C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAqC7E,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASzC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAwBpD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CASrC"}
|
|
@@ -28,24 +28,41 @@ export class PostgresStorage {
|
|
|
28
28
|
async deleteSession(id) {
|
|
29
29
|
await this.pool.query("DELETE FROM dbsc_sessions WHERE id = $1", [id]);
|
|
30
30
|
}
|
|
31
|
-
async getBoundKey(sessionId) {
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
async getBoundKey(sessionId, kind) {
|
|
32
|
+
let row;
|
|
33
|
+
if (kind) {
|
|
34
|
+
const { rows } = await this.pool.query("SELECT session_id, kind, jwk, algorithm, created_at FROM dbsc_bound_keys WHERE session_id = $1 AND kind = $2", [sessionId, kind]);
|
|
35
|
+
row = rows[0];
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Prefer "native" over "bound" so the v2.6 single-key callers keep
|
|
39
|
+
// their previous behavior on Chromium-style sessions.
|
|
40
|
+
const { rows } = await this.pool.query(`SELECT session_id, kind, jwk, algorithm, created_at FROM dbsc_bound_keys
|
|
41
|
+
WHERE session_id = $1
|
|
42
|
+
ORDER BY CASE kind WHEN 'native' THEN 0 ELSE 1 END
|
|
43
|
+
LIMIT 1`, [sessionId]);
|
|
44
|
+
row = rows[0];
|
|
45
|
+
}
|
|
34
46
|
if (!row)
|
|
35
47
|
return null;
|
|
36
48
|
return {
|
|
37
49
|
sessionId: row.session_id,
|
|
50
|
+
kind: row.kind ?? "native",
|
|
38
51
|
jwk: row.jwk,
|
|
39
52
|
algorithm: row.algorithm,
|
|
40
53
|
createdAt: parseInt(row.created_at, 10),
|
|
41
54
|
};
|
|
42
55
|
}
|
|
43
56
|
async setBoundKey(key) {
|
|
44
|
-
await this.pool.query(`INSERT INTO dbsc_bound_keys (session_id, jwk, algorithm, created_at)
|
|
45
|
-
VALUES ($1, $2, $3, $4)
|
|
46
|
-
ON CONFLICT (session_id) DO UPDATE SET jwk = $
|
|
57
|
+
await this.pool.query(`INSERT INTO dbsc_bound_keys (session_id, kind, jwk, algorithm, created_at)
|
|
58
|
+
VALUES ($1, $2, $3, $4, $5)
|
|
59
|
+
ON CONFLICT (session_id, kind) DO UPDATE SET jwk = $3, algorithm = $4`, [key.sessionId, key.kind, JSON.stringify(key.jwk), key.algorithm, key.createdAt]);
|
|
47
60
|
}
|
|
48
|
-
async deleteBoundKey(sessionId) {
|
|
61
|
+
async deleteBoundKey(sessionId, kind) {
|
|
62
|
+
if (kind) {
|
|
63
|
+
await this.pool.query("DELETE FROM dbsc_bound_keys WHERE session_id = $1 AND kind = $2", [sessionId, kind]);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
49
66
|
await this.pool.query("DELETE FROM dbsc_bound_keys WHERE session_id = $1", [sessionId]);
|
|
50
67
|
}
|
|
51
68
|
async getChallenge(jti) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/postgres/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/postgres/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { Redis } from "ioredis";
|
|
2
|
-
import type { StorageAdapter, Session, BoundKey, Challenge } from "../../core/index.js";
|
|
2
|
+
import type { StorageAdapter, Session, BoundKey, BoundKeyKind, Challenge } from "../../core/index.js";
|
|
3
3
|
export declare class RedisStorage implements StorageAdapter {
|
|
4
4
|
private readonly client;
|
|
5
5
|
constructor(client: Redis);
|
|
6
6
|
getSession(id: string): Promise<Session | null>;
|
|
7
7
|
setSession(session: Session): Promise<void>;
|
|
8
8
|
deleteSession(id: string): Promise<void>;
|
|
9
|
-
getBoundKey(sessionId: string): Promise<BoundKey | null>;
|
|
9
|
+
getBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<BoundKey | null>;
|
|
10
10
|
setBoundKey(key: BoundKey): Promise<void>;
|
|
11
|
-
deleteBoundKey(sessionId: string): Promise<void>;
|
|
11
|
+
deleteBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<void>;
|
|
12
12
|
getChallenge(jti: string): Promise<Challenge | null>;
|
|
13
13
|
setChallenge(challenge: Challenge): Promise<void>;
|
|
14
14
|
consumeChallenge(jti: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,SAAS,EACV,MAAM,qBAAqB,CAAC;AA8B7B,qBAAa,YAAa,YAAW,cAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,KAAK;IAEpC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAM/C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA6B7E,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAarE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAMpD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CActD"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const KEY = {
|
|
2
2
|
session: (id) => `dbsc:session:${id}`,
|
|
3
|
-
|
|
3
|
+
// v2.7+ keys include the kind suffix. The unsuffixed v2.6 layout is read once
|
|
4
|
+
// as a back-compat fallback in getBoundKey and rewritten under the new layout
|
|
5
|
+
// the next time the key is set.
|
|
6
|
+
key: (sessionId, kind) => `dbsc:key:${sessionId}:${kind}`,
|
|
7
|
+
legacyKey: (sessionId) => `dbsc:key:${sessionId}`,
|
|
4
8
|
challenge: (jti) => `dbsc:challenge:${jti}`,
|
|
5
9
|
userSessions: (userId) => `dbsc:user:${userId}:sessions`,
|
|
6
10
|
};
|
|
@@ -41,19 +45,51 @@ export class RedisStorage {
|
|
|
41
45
|
const sess = JSON.parse(raw);
|
|
42
46
|
await this.client.srem(KEY.userSessions(sess.userId), id);
|
|
43
47
|
}
|
|
44
|
-
await this.client.del(KEY.session(id), KEY.key(id));
|
|
48
|
+
await this.client.del(KEY.session(id), KEY.key(id, "native"), KEY.key(id, "bound"), KEY.legacyKey(id));
|
|
45
49
|
}
|
|
46
|
-
async getBoundKey(sessionId) {
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
async getBoundKey(sessionId, kind) {
|
|
51
|
+
if (kind) {
|
|
52
|
+
const raw = await this.client.get(KEY.key(sessionId, kind));
|
|
53
|
+
if (raw)
|
|
54
|
+
return JSON.parse(raw);
|
|
55
|
+
// v2.6 back-compat: an unsuffixed row was always a native key.
|
|
56
|
+
if (kind === "native") {
|
|
57
|
+
const legacy = await this.client.get(KEY.legacyKey(sessionId));
|
|
58
|
+
if (legacy) {
|
|
59
|
+
const parsed = JSON.parse(legacy);
|
|
60
|
+
// Older rows may not carry `kind`; treat as native.
|
|
61
|
+
return { ...parsed, kind: "native" };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
49
64
|
return null;
|
|
50
|
-
|
|
65
|
+
}
|
|
66
|
+
const [n, b] = await this.client.mget(KEY.key(sessionId, "native"), KEY.key(sessionId, "bound"));
|
|
67
|
+
if (n)
|
|
68
|
+
return JSON.parse(n);
|
|
69
|
+
if (b)
|
|
70
|
+
return JSON.parse(b);
|
|
71
|
+
const legacy = await this.client.get(KEY.legacyKey(sessionId));
|
|
72
|
+
if (legacy) {
|
|
73
|
+
const parsed = JSON.parse(legacy);
|
|
74
|
+
return { ...parsed, kind: "native" };
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
51
77
|
}
|
|
52
78
|
async setBoundKey(key) {
|
|
53
|
-
await this.client.set(KEY.key(key.sessionId), JSON.stringify(key));
|
|
79
|
+
await this.client.set(KEY.key(key.sessionId, key.kind), JSON.stringify(key));
|
|
80
|
+
// Stamp out the legacy unsuffixed key so a future read can't shadow the new layout.
|
|
81
|
+
if (key.kind === "native") {
|
|
82
|
+
await this.client.del(KEY.legacyKey(key.sessionId));
|
|
83
|
+
}
|
|
54
84
|
}
|
|
55
|
-
async deleteBoundKey(sessionId) {
|
|
56
|
-
|
|
85
|
+
async deleteBoundKey(sessionId, kind) {
|
|
86
|
+
if (kind) {
|
|
87
|
+
await this.client.del(KEY.key(sessionId, kind));
|
|
88
|
+
if (kind === "native")
|
|
89
|
+
await this.client.del(KEY.legacyKey(sessionId));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
await this.client.del(KEY.key(sessionId, "native"), KEY.key(sessionId, "bound"), KEY.legacyKey(sessionId));
|
|
57
93
|
}
|
|
58
94
|
async getChallenge(jti) {
|
|
59
95
|
const raw = await this.client.get(KEY.challenge(jti));
|
|
@@ -79,7 +115,9 @@ export class RedisStorage {
|
|
|
79
115
|
const pipeline = this.client.pipeline();
|
|
80
116
|
for (const id of sessionIds) {
|
|
81
117
|
pipeline.del(KEY.session(id));
|
|
82
|
-
pipeline.del(KEY.key(id));
|
|
118
|
+
pipeline.del(KEY.key(id, "native"));
|
|
119
|
+
pipeline.del(KEY.key(id, "bound"));
|
|
120
|
+
pipeline.del(KEY.legacyKey(id));
|
|
83
121
|
}
|
|
84
122
|
pipeline.del(KEY.userSessions(userId));
|
|
85
123
|
await pipeline.exec();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/redis/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/redis/index.ts"],"names":[],"mappings":"AAUA,MAAM,GAAG,GAAG;IACV,OAAO,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,gBAAgB,EAAE,EAAE;IAC7C,8EAA8E;IAC9E,8EAA8E;IAC9E,gCAAgC;IAChC,GAAG,EAAE,CAAC,SAAiB,EAAE,IAAkB,EAAE,EAAE,CAAC,YAAY,SAAS,IAAI,IAAI,EAAE;IAC/E,SAAS,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,YAAY,SAAS,EAAE;IACzD,SAAS,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,kBAAkB,GAAG,EAAE;IACnD,YAAY,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,aAAa,MAAM,WAAW;CACjE,CAAC;AAEF,uFAAuF;AACvF,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;CAahC,CAAC;AAEF,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,MAAa;QAAb,WAAM,GAAN,MAAM,CAAO;IAAG,CAAC;IAE9C,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAgB;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QACnF,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QAC1F,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,EAAU;QAC5B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACnD,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;YACxC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CACnB,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EACf,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,EACrB,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,EACpB,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAClB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,SAAiB,EAAE,IAAmB;QACtD,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;YAC5D,IAAI,GAAG;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAC;YAC5C,+DAA+D;YAC/D,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC/D,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAa,CAAC;oBAC9C,oDAAoD;oBACpD,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;gBACvC,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CACnC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,EAC5B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAC5B,CAAC;QACF,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;QACxC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/D,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAa,CAAC;YAC9C,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QACvC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAa;QAC7B,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7E,oFAAoF;QACpF,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,SAAiB,EAAE,IAAmB;QACzD,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;YAChD,IAAI,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CACnB,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,EAC5B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,EAC3B,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CACzB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC5B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,SAAoB;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QACrF,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACnG,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,GAAW;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACvF,OAAO,MAAM,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAc;QACnC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QACxE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxC,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9B,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;YACpC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YACnC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QACvC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- v2.7.0: a single session can hold two bound keys — one TPM/native key used
|
|
2
|
+
-- by /dbsc/refresh, and one polyfill ECDSA key used by requireProof() on
|
|
3
|
+
-- every guarded request and by /dbsc-bound/refresh. The composite primary
|
|
4
|
+
-- key (session_id, kind) replaces session_id alone.
|
|
5
|
+
--
|
|
6
|
+
-- The migration is non-destructive: every existing row was a native key
|
|
7
|
+
-- (Chromium TPM) or a polyfill key written by the same code path, and v2.6
|
|
8
|
+
-- never wrote two rows per session — so back-filling kind='native' matches
|
|
9
|
+
-- the prior call-site semantics. Apps that ran the bound polyfill before
|
|
10
|
+
-- v2.7 will read those rows under kind='native' once; the next refresh
|
|
11
|
+
-- rewrites them under kind='bound'. The kind-less getBoundKey() in the
|
|
12
|
+
-- v2.7 adapter prefers native then falls back to bound, which is what every
|
|
13
|
+
-- old call site expected.
|
|
14
|
+
|
|
15
|
+
BEGIN;
|
|
16
|
+
|
|
17
|
+
ALTER TABLE dbsc_bound_keys
|
|
18
|
+
ADD COLUMN IF NOT EXISTS kind TEXT NOT NULL DEFAULT 'native'
|
|
19
|
+
CHECK (kind IN ('native', 'bound'));
|
|
20
|
+
|
|
21
|
+
ALTER TABLE dbsc_bound_keys DROP CONSTRAINT IF EXISTS dbsc_bound_keys_pkey;
|
|
22
|
+
|
|
23
|
+
ALTER TABLE dbsc_bound_keys
|
|
24
|
+
ADD CONSTRAINT dbsc_bound_keys_pkey PRIMARY KEY (session_id, kind);
|
|
25
|
+
|
|
26
|
+
COMMIT;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbsc-toolkit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Server-side Device Bound Session Credentials (DBSC) for Node.js plus a Web Crypto polyfill for Firefox, Safari, and older Chromium. Cookie-theft protection on every modern browser.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|