@sourceregistry/node-jwt 1.5.2 → 1.5.3
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 +11 -1
- package/dist/{index-CQO8xUW-.js → index-DNa3e1QZ.js} +110 -96
- package/dist/index-DNa3e1QZ.js.map +1 -0
- package/dist/{index-CJ4L1o5I.cjs → index-YbdG9jsh.cjs} +2 -2
- package/dist/index-YbdG9jsh.cjs.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +7 -6
- package/dist/jwks/index.d.ts +14 -10
- package/dist/promises.cjs.js +1 -1
- package/dist/promises.es.js +2 -2
- package/package.json +1 -1
- package/dist/index-CJ4L1o5I.cjs.map +0 -1
- package/dist/index-CQO8xUW-.js.map +0 -1
package/README.md
CHANGED
|
@@ -164,12 +164,13 @@ const jwks = await JWKS.fromWeb('https://issuer.example', {
|
|
|
164
164
|
});
|
|
165
165
|
|
|
166
166
|
const jwk = await jwks.key('my-kid');
|
|
167
|
+
const keyObject = jwk?.toKeyObject();
|
|
167
168
|
const keys = await jwks.list();
|
|
168
169
|
const rsaKeys = await jwks.find({ kty: 'RSA' });
|
|
169
170
|
const firstSigKey = await jwks.findFirst({ use: 'sig' });
|
|
170
171
|
|
|
171
172
|
// Force refresh
|
|
172
|
-
await jwks.refresh();
|
|
173
|
+
await jwks.refresh(); // returns resolver for chaining
|
|
173
174
|
|
|
174
175
|
// Access cached JWKS snapshot
|
|
175
176
|
const current = jwks.export();
|
|
@@ -184,6 +185,15 @@ const current = jwks.export();
|
|
|
184
185
|
* `overrideEndpointCheck` — skip automatic `/.well-known/jwks.json` append
|
|
185
186
|
* `cache` — custom cache backend with `{ get(key), set(key, value) }`
|
|
186
187
|
|
|
188
|
+
`fromWeb()` resolver methods:
|
|
189
|
+
|
|
190
|
+
* `key(kid)` — returns a normalized key (or `undefined`) extended with `toKeyObject()`
|
|
191
|
+
* `list()` — returns all normalized keys
|
|
192
|
+
* `find(query)` — returns normalized matching keys
|
|
193
|
+
* `findFirst(query)` — returns first normalized match or `undefined`
|
|
194
|
+
* `refresh()` — forces reload and returns the resolver instance
|
|
195
|
+
* `export()` — returns the current cached JWKS snapshot
|
|
196
|
+
|
|
187
197
|
### 🔹 Local Examples
|
|
188
198
|
|
|
189
199
|
See runnable examples in:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import w, { sign as
|
|
1
|
+
import w, { sign as C, createSign as m, createHmac as I, verify as M, createVerify as v, timingSafeEqual as G, createPrivateKey as _, createSecretKey as N, createPublicKey as R, createHash as O } from "crypto";
|
|
2
2
|
const K = {
|
|
3
3
|
encode: (e) => Buffer.from(e).toString("base64url"),
|
|
4
4
|
decode: (e) => Buffer.from(e, "base64url").toString()
|
|
5
|
-
},
|
|
6
|
-
function
|
|
5
|
+
}, J = (e, t) => e.length !== t.length ? !1 : G(Buffer.from(e), Buffer.from(t));
|
|
6
|
+
function W(e) {
|
|
7
7
|
switch (e) {
|
|
8
8
|
case "ES256":
|
|
9
9
|
case "ES256K":
|
|
@@ -19,14 +19,14 @@ function R(e) {
|
|
|
19
19
|
throw new Error(`Unsupported ECDSA alg for JOSE conversion: ${e}`);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
function
|
|
22
|
+
function V(e, t) {
|
|
23
23
|
let r = 0;
|
|
24
24
|
if (e[r++] !== 48) throw new Error("Invalid DER ECDSA signature");
|
|
25
25
|
let n = e[r++];
|
|
26
26
|
if (n & 128) {
|
|
27
|
-
const
|
|
27
|
+
const h = n & 127;
|
|
28
28
|
n = 0;
|
|
29
|
-
for (let o = 0; o <
|
|
29
|
+
for (let o = 0; o < h; o++) n = n << 8 | e[r++];
|
|
30
30
|
}
|
|
31
31
|
if (e[r++] !== 2) throw new Error("Invalid DER ECDSA signature (r)");
|
|
32
32
|
const s = e[r++];
|
|
@@ -39,7 +39,7 @@ function G(e, t) {
|
|
|
39
39
|
const d = Buffer.concat([Buffer.alloc(t / 2 - a.length, 0), a]), f = Buffer.concat([Buffer.alloc(t / 2 - i.length, 0), i]);
|
|
40
40
|
return Buffer.concat([d, f]);
|
|
41
41
|
}
|
|
42
|
-
function
|
|
42
|
+
function k(e) {
|
|
43
43
|
const t = e.length / 2;
|
|
44
44
|
let r = e.subarray(0, t), n = e.subarray(t);
|
|
45
45
|
for (; r.length > 1 && r[0] === 0 && (r[1] & 128) === 0; ) r = r.subarray(1);
|
|
@@ -67,21 +67,21 @@ const p = {
|
|
|
67
67
|
sign: (e, t) => I("sha256", t).update(e).digest("base64url"),
|
|
68
68
|
verify: (e, t, r) => {
|
|
69
69
|
const n = I("sha256", t).update(e).digest("base64url");
|
|
70
|
-
return
|
|
70
|
+
return J(n, r);
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
HS384: {
|
|
74
74
|
sign: (e, t) => I("sha384", t).update(e).digest("base64url"),
|
|
75
75
|
verify: (e, t, r) => {
|
|
76
76
|
const n = I("sha384", t).update(e).digest("base64url");
|
|
77
|
-
return
|
|
77
|
+
return J(n, r);
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
HS512: {
|
|
81
81
|
sign: (e, t) => I("sha512", t).update(e).digest("base64url"),
|
|
82
82
|
verify: (e, t, r) => {
|
|
83
83
|
const n = I("sha512", t).update(e).digest("base64url");
|
|
84
|
-
return
|
|
84
|
+
return J(n, r);
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
87
|
// RSA (DER-encoded signatures, base64url)
|
|
@@ -217,10 +217,10 @@ const p = {
|
|
|
217
217
|
}
|
|
218
218
|
},
|
|
219
219
|
EdDSA: {
|
|
220
|
-
sign: (e, t) =>
|
|
220
|
+
sign: (e, t) => C(null, typeof e == "string" ? Buffer.from(e, "utf8") : e, t).toString("base64url"),
|
|
221
221
|
verify: (e, t, r) => {
|
|
222
222
|
try {
|
|
223
|
-
return
|
|
223
|
+
return M(
|
|
224
224
|
null,
|
|
225
225
|
typeof e == "string" ? Buffer.from(e, "utf8") : e,
|
|
226
226
|
t,
|
|
@@ -231,8 +231,8 @@ const p = {
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
|
-
},
|
|
235
|
-
function
|
|
234
|
+
}, te = Object.keys(p);
|
|
235
|
+
function j(e) {
|
|
236
236
|
if (e.type === "secret") return "HS256";
|
|
237
237
|
if (e.type !== "private") throw new Error("Only private or symmetric keys can be used to sign JWTs");
|
|
238
238
|
const t = e.asymmetricKeyType, r = e.asymmetricKeyDetails;
|
|
@@ -279,12 +279,12 @@ function V(e) {
|
|
|
279
279
|
function q(e) {
|
|
280
280
|
if (typeof e == "object" && "type" in e) return e;
|
|
281
281
|
try {
|
|
282
|
-
return
|
|
282
|
+
return _(e);
|
|
283
283
|
} catch {
|
|
284
284
|
const t = typeof e == "string" ? Buffer.from(e, "utf8") : Buffer.isBuffer(e) ? e : (() => {
|
|
285
285
|
throw new Error("Unsupported key type");
|
|
286
286
|
})();
|
|
287
|
-
return
|
|
287
|
+
return N(t);
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
290
|
const x = (e) => {
|
|
@@ -301,18 +301,18 @@ const x = (e) => {
|
|
|
301
301
|
throw new Error(`Invalid JWT: malformed header or payload (${a.message})`);
|
|
302
302
|
}
|
|
303
303
|
}, F = (e, t, r = {}) => {
|
|
304
|
-
const n = q(t), s = r.alg ??
|
|
304
|
+
const n = q(t), s = r.alg ?? j(n), a = r.signatureFormat ?? "der", c = r.typ ?? "JWT";
|
|
305
305
|
if (!(s in p)) throw new Error(`Unsupported algorithm: ${s}`);
|
|
306
306
|
const i = { alg: s, typ: c };
|
|
307
307
|
r.kid && (i.kid = r.kid);
|
|
308
|
-
const d = K.encode(JSON.stringify(i)), f = K.encode(JSON.stringify(e)),
|
|
309
|
-
let o = p[s].sign(
|
|
308
|
+
const d = K.encode(JSON.stringify(i)), f = K.encode(JSON.stringify(e)), h = `${d}.${f}`;
|
|
309
|
+
let o = p[s].sign(h, t);
|
|
310
310
|
if (a === "jose" && $(s)) {
|
|
311
311
|
const y = Buffer.from(o, "base64url");
|
|
312
|
-
o =
|
|
312
|
+
o = V(y, W(s)).toString("base64url");
|
|
313
313
|
}
|
|
314
314
|
return `${d}.${f}.${o}`;
|
|
315
|
-
},
|
|
315
|
+
}, z = (e, t, r = {}) => {
|
|
316
316
|
let n;
|
|
317
317
|
try {
|
|
318
318
|
n = x(e);
|
|
@@ -356,7 +356,7 @@ const x = (e) => {
|
|
|
356
356
|
let y;
|
|
357
357
|
if (o === "jose")
|
|
358
358
|
try {
|
|
359
|
-
const S = Buffer.from(c, "base64url"), l =
|
|
359
|
+
const S = Buffer.from(c, "base64url"), l = k(S).toString("base64url");
|
|
360
360
|
y = p[i].verify(d, t, l);
|
|
361
361
|
} catch {
|
|
362
362
|
y = !1;
|
|
@@ -366,8 +366,8 @@ const x = (e) => {
|
|
|
366
366
|
else if (y = p[i].verify(d, t, c), !y)
|
|
367
367
|
try {
|
|
368
368
|
const S = Buffer.from(c, "base64url");
|
|
369
|
-
if (S.length ===
|
|
370
|
-
const l =
|
|
369
|
+
if (S.length === W(i)) {
|
|
370
|
+
const l = k(S).toString("base64url");
|
|
371
371
|
y = p[i].verify(d, t, l);
|
|
372
372
|
}
|
|
373
373
|
} catch {
|
|
@@ -376,8 +376,8 @@ const x = (e) => {
|
|
|
376
376
|
return { valid: !1, error: { reason: "Signature verification failed", code: "INVALID_SIGNATURE" } };
|
|
377
377
|
} else if (!p[i].verify(d, t, c))
|
|
378
378
|
return { valid: !1, error: { reason: "Signature verification failed", code: "INVALID_SIGNATURE" } };
|
|
379
|
-
const f = Math.floor(Date.now() / 1e3),
|
|
380
|
-
if (!r.ignoreExpiration && a.exp !== void 0 && f > a.exp +
|
|
379
|
+
const f = Math.floor(Date.now() / 1e3), h = r.clockSkew ?? 0;
|
|
380
|
+
if (!r.ignoreExpiration && a.exp !== void 0 && f > a.exp + h)
|
|
381
381
|
return {
|
|
382
382
|
valid: !1,
|
|
383
383
|
error: {
|
|
@@ -385,7 +385,7 @@ const x = (e) => {
|
|
|
385
385
|
code: "TOKEN_EXPIRED"
|
|
386
386
|
}
|
|
387
387
|
};
|
|
388
|
-
if (a.nbf !== void 0 && f +
|
|
388
|
+
if (a.nbf !== void 0 && f + h < a.nbf)
|
|
389
389
|
return {
|
|
390
390
|
valid: !1,
|
|
391
391
|
error: {
|
|
@@ -393,7 +393,7 @@ const x = (e) => {
|
|
|
393
393
|
code: "TOKEN_NOT_ACTIVE"
|
|
394
394
|
}
|
|
395
395
|
};
|
|
396
|
-
if (a.iat !== void 0 && f +
|
|
396
|
+
if (a.iat !== void 0 && f + h < a.iat)
|
|
397
397
|
return {
|
|
398
398
|
valid: !1,
|
|
399
399
|
error: {
|
|
@@ -487,39 +487,39 @@ const x = (e) => {
|
|
|
487
487
|
};
|
|
488
488
|
}
|
|
489
489
|
return { valid: !0, header: s, payload: a, signature: c };
|
|
490
|
-
},
|
|
490
|
+
}, ne = {
|
|
491
491
|
sign: F,
|
|
492
|
-
verify:
|
|
492
|
+
verify: z,
|
|
493
493
|
decode: x,
|
|
494
494
|
algorithms: p
|
|
495
495
|
};
|
|
496
|
-
function
|
|
496
|
+
function X(e) {
|
|
497
497
|
if (!e || typeof e != "object") throw new Error("Invalid KeyObject");
|
|
498
498
|
return e.export({ format: "jwk" });
|
|
499
499
|
}
|
|
500
|
-
function
|
|
500
|
+
function P(e) {
|
|
501
501
|
if (!e || typeof e != "object") throw new Error("Invalid JWK");
|
|
502
502
|
switch (e.kty) {
|
|
503
503
|
case "oct": {
|
|
504
504
|
if (!("k" in e) || typeof e.k != "string")
|
|
505
505
|
throw new Error('Invalid oct JWK: missing "k"');
|
|
506
|
-
return
|
|
506
|
+
return N(Buffer.from(e.k, "base64url"));
|
|
507
507
|
}
|
|
508
508
|
case "RSA":
|
|
509
509
|
case "EC":
|
|
510
510
|
case "OKP":
|
|
511
|
-
return "d" in e && typeof e.d == "string" ?
|
|
511
|
+
return "d" in e && typeof e.d == "string" ? _({ format: "jwk", key: e }) : R({ format: "jwk", key: e });
|
|
512
512
|
default:
|
|
513
513
|
throw new Error(`Unsupported JWK key type: ${e.kty}`);
|
|
514
514
|
}
|
|
515
515
|
}
|
|
516
|
-
function
|
|
516
|
+
function Y(e) {
|
|
517
517
|
if (!e || typeof e != "object")
|
|
518
518
|
throw new Error("Invalid KeyObject");
|
|
519
|
-
const r = (e.type === "private" ?
|
|
519
|
+
const r = (e.type === "private" ? R(e) : e).export({ format: "jwk" });
|
|
520
520
|
return delete r.d, delete r.p, delete r.q, delete r.dp, delete r.dq, delete r.qi, r;
|
|
521
521
|
}
|
|
522
|
-
function
|
|
522
|
+
function H(e, t = "sha256") {
|
|
523
523
|
if (!e || typeof e != "object")
|
|
524
524
|
throw new Error("Invalid JWK");
|
|
525
525
|
let r;
|
|
@@ -542,34 +542,45 @@ function W(e, t = "sha256") {
|
|
|
542
542
|
const n = JSON.stringify(
|
|
543
543
|
Object.keys(r).sort().reduce((s, a) => (s[a] = r[a], s), {})
|
|
544
544
|
);
|
|
545
|
-
return
|
|
545
|
+
return O(t).update(n).digest("base64url");
|
|
546
546
|
}
|
|
547
|
-
function
|
|
547
|
+
function Q(e) {
|
|
548
548
|
if (e.x5c?.length)
|
|
549
|
-
return
|
|
549
|
+
return O("sha1").update(Buffer.from(e.x5c[0], "base64")).digest("base64url");
|
|
550
550
|
}
|
|
551
|
-
const
|
|
552
|
-
export:
|
|
553
|
-
import:
|
|
554
|
-
toPublic:
|
|
555
|
-
thumbprint:
|
|
551
|
+
const ae = {
|
|
552
|
+
export: X,
|
|
553
|
+
import: P,
|
|
554
|
+
toPublic: Y,
|
|
555
|
+
thumbprint: H
|
|
556
556
|
};
|
|
557
|
-
function
|
|
557
|
+
function Z(e, t) {
|
|
558
558
|
if (!e || !Array.isArray(e.keys)) throw new Error("Invalid JWKS");
|
|
559
559
|
let r;
|
|
560
560
|
if (t && (r = e.keys.find((n) => n.kid === t)), !r && e.keys.length === 1 && (r = e.keys[0]), !r) throw new Error("Key not found in JWKS");
|
|
561
|
-
return
|
|
561
|
+
return P(r);
|
|
562
562
|
}
|
|
563
563
|
function D(e) {
|
|
564
564
|
return {
|
|
565
|
-
keys: e.keys
|
|
566
|
-
...t,
|
|
567
|
-
kid: t.kid ?? W(t),
|
|
568
|
-
x5t: t.x5t ?? Y(t)
|
|
569
|
-
}))
|
|
565
|
+
keys: T(...e.keys)
|
|
570
566
|
};
|
|
571
567
|
}
|
|
572
|
-
|
|
568
|
+
function T(...e) {
|
|
569
|
+
return e.map((t) => {
|
|
570
|
+
const r = {
|
|
571
|
+
...t,
|
|
572
|
+
kid: t.kid ?? H(t),
|
|
573
|
+
x5t: t.x5t ?? Q(t)
|
|
574
|
+
};
|
|
575
|
+
return Object.defineProperty(r, "toKeyObject", {
|
|
576
|
+
enumerable: !1,
|
|
577
|
+
configurable: !1,
|
|
578
|
+
writable: !1,
|
|
579
|
+
value: () => P(r)
|
|
580
|
+
}), r;
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
const ee = async (e, t = {}) => {
|
|
573
584
|
const r = typeof e == "string" ? e : e.toString(), n = t.fetch ?? globalThis.fetch, s = Math.max(0, t.ttl ?? 5 * 6e4), a = Math.max(0, t.timeoutMs ?? 5e3), c = "/.well-known/jwks.json";
|
|
574
585
|
if (!n)
|
|
575
586
|
throw new Error("No fetch implementation available");
|
|
@@ -588,69 +599,71 @@ const Z = async (e, t = {}) => {
|
|
|
588
599
|
let l;
|
|
589
600
|
return {
|
|
590
601
|
get: () => l,
|
|
591
|
-
set: (u,
|
|
592
|
-
l =
|
|
602
|
+
set: (u, g) => {
|
|
603
|
+
l = g;
|
|
593
604
|
}
|
|
594
605
|
};
|
|
595
606
|
})();
|
|
596
|
-
let f,
|
|
607
|
+
let f, h = 0, o, y = 0;
|
|
597
608
|
const S = async (l) => {
|
|
598
609
|
if (o) return o;
|
|
599
610
|
o = (async () => {
|
|
600
611
|
const u = new AbortController();
|
|
601
|
-
let
|
|
602
|
-
a > 0 && (
|
|
603
|
-
let
|
|
612
|
+
let g;
|
|
613
|
+
a > 0 && (g = setTimeout(() => u.abort(), a));
|
|
614
|
+
let b;
|
|
604
615
|
try {
|
|
605
|
-
|
|
616
|
+
b = await n(i, { signal: u.signal });
|
|
606
617
|
} catch (E) {
|
|
607
618
|
throw u.signal.aborted ? new Error(`JWKS fetch timed out after ${a}ms`) : E;
|
|
608
619
|
} finally {
|
|
609
|
-
|
|
620
|
+
g && clearTimeout(g);
|
|
610
621
|
}
|
|
611
|
-
if (!
|
|
612
|
-
throw new Error(`Failed to fetch JWKS: ${
|
|
613
|
-
const
|
|
614
|
-
if (!
|
|
622
|
+
if (!b.ok)
|
|
623
|
+
throw new Error(`Failed to fetch JWKS: ${b.status} ${b.statusText}`);
|
|
624
|
+
const A = await b.json();
|
|
625
|
+
if (!A || typeof A != "object" || !Array.isArray(A.keys))
|
|
615
626
|
throw new Error("Invalid JWKS");
|
|
616
|
-
return D(
|
|
627
|
+
return D(A);
|
|
617
628
|
})();
|
|
618
629
|
try {
|
|
619
630
|
const u = await o;
|
|
620
|
-
return f = u, await d.set(i, u), y = 0, s > 0 && (
|
|
631
|
+
return f = u, await d.set(i, u), y = 0, s > 0 && (h = Date.now() + s), u;
|
|
621
632
|
} catch (u) {
|
|
622
633
|
if (!l || !f)
|
|
623
634
|
throw u;
|
|
624
635
|
if (y += 1, s > 0) {
|
|
625
|
-
const
|
|
636
|
+
const g = Math.min(
|
|
626
637
|
Math.max(s, 3e4) * Math.pow(2, y - 1),
|
|
627
638
|
9e5
|
|
628
639
|
);
|
|
629
|
-
|
|
640
|
+
h = Date.now() + g;
|
|
630
641
|
}
|
|
631
642
|
return console.warn(`JWKS refresh failed for "${i}", using stale cache.`, u), f;
|
|
632
643
|
} finally {
|
|
633
644
|
o = void 0;
|
|
634
645
|
}
|
|
635
646
|
};
|
|
636
|
-
return f = await d.get(i), f ? (f = D(f), s > 0 && (
|
|
647
|
+
return f = await d.get(i), f ? (f = D(f), s > 0 && (h = Date.now() + s)) : f = await S(!1), {
|
|
637
648
|
async list() {
|
|
638
|
-
return s > 0 && Date.now() >=
|
|
649
|
+
return s > 0 && Date.now() >= h && await S(!0), T(...f.keys);
|
|
639
650
|
},
|
|
640
651
|
async refresh() {
|
|
641
|
-
return await S(!1),
|
|
652
|
+
return await S(!1), this;
|
|
642
653
|
},
|
|
643
654
|
async key(l) {
|
|
644
|
-
|
|
655
|
+
const g = (await this.list()).find((b) => b.kid === l);
|
|
656
|
+
if (g)
|
|
657
|
+
return T(g)[0];
|
|
645
658
|
},
|
|
646
659
|
async find(l) {
|
|
647
|
-
const u = await this.list(),
|
|
648
|
-
return
|
|
649
|
-
(
|
|
650
|
-
const
|
|
651
|
-
return Array.isArray(E) ? Array.isArray(
|
|
660
|
+
const u = await this.list(), g = Object.entries(l);
|
|
661
|
+
return g.length === 0 ? T(...u) : T(...u.filter(
|
|
662
|
+
(b) => g.every(([A, E]) => {
|
|
663
|
+
const B = b[A];
|
|
664
|
+
return Array.isArray(E) ? Array.isArray(B) && B.length === E.length && B.every((U, L) => U === E[L]) : B === E;
|
|
652
665
|
})
|
|
653
|
-
);
|
|
666
|
+
));
|
|
654
667
|
},
|
|
655
668
|
async findFirst(l) {
|
|
656
669
|
return this.find(l).then(([u]) => u);
|
|
@@ -659,29 +672,30 @@ const Z = async (e, t = {}) => {
|
|
|
659
672
|
return f;
|
|
660
673
|
}
|
|
661
674
|
};
|
|
662
|
-
},
|
|
663
|
-
toKeyObject:
|
|
675
|
+
}, se = {
|
|
676
|
+
toKeyObject: Z,
|
|
664
677
|
normalize: D,
|
|
665
|
-
fromWeb:
|
|
678
|
+
fromWeb: ee
|
|
666
679
|
};
|
|
667
680
|
export {
|
|
668
|
-
|
|
669
|
-
|
|
681
|
+
j as A,
|
|
682
|
+
ne as J,
|
|
670
683
|
p as S,
|
|
671
|
-
|
|
684
|
+
te as a,
|
|
672
685
|
K as b,
|
|
673
|
-
|
|
686
|
+
Q as c,
|
|
674
687
|
x as d,
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
688
|
+
X as e,
|
|
689
|
+
ae as f,
|
|
690
|
+
H as g,
|
|
691
|
+
Z as h,
|
|
692
|
+
P as i,
|
|
693
|
+
T as j,
|
|
694
|
+
ee as k,
|
|
695
|
+
se as l,
|
|
682
696
|
D as n,
|
|
683
697
|
F as s,
|
|
684
|
-
|
|
685
|
-
|
|
698
|
+
Y as t,
|
|
699
|
+
z as v
|
|
686
700
|
};
|
|
687
|
-
//# sourceMappingURL=index-
|
|
701
|
+
//# sourceMappingURL=index-DNa3e1QZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-DNa3e1QZ.js","sources":["../src/jwt/index.ts","../src/jwks/index.ts"],"sourcesContent":["import crypto, {\n createHmac,\n createSign,\n createVerify,\n createPrivateKey,\n createSecretKey,\n sign as cryptoSign,\n verify as cryptoVerify,\n timingSafeEqual,\n type BinaryLike,\n type KeyLike,\n type KeyObject\n} from 'crypto';\n\n// Base64URL helpers (padding-safe)\nexport const base64Url = {\n encode: (input: string | Buffer): string => Buffer.from(input).toString('base64url'),\n decode: (input: string): string => Buffer.from(input, 'base64url').toString()\n};\n\n/**\n * Timing-safe string comparison to prevent timing attacks\n * @param a\n * @param b\n */\nconst timingSafeCompare = (a: string, b: string): boolean => {\n if (a.length !== b.length) {\n return false;\n }\n return timingSafeEqual(Buffer.from(a), Buffer.from(b));\n};\n\n// Standard JWT payload claims\nexport interface JWTPayload {\n /**\n * Issuer\n */\n iss?: string;\n /**\n * Subject\n */\n sub?: string;\n /**\n * Audience\n */\n aud?: string | string[];\n /**\n * Expiration Time (as UNIX timestamp)\n */\n exp?: number;\n /**\n * Not Before (as UNIX timestamp)\n */\n nbf?: number;\n /**\n * Issued At (as UNIX timestamp)\n */\n iat?: number;\n /**\n * JWT ID\n */\n jti?: string;\n /**\n * Session ID\n */\n sid?: string;\n\n /**\n * Custom claims\n */\n [key: string]: unknown;\n}\n\nexport interface JWTHeader {\n alg: string; // Allow unknown algs during decode\n typ?: string;\n kid?: string;\n}\n\nexport interface JWT {\n header: JWTHeader;\n payload: JWTPayload;\n signature: string;\n}\n\n\n//JOSE-helpers\nfunction joseLenForAlg(alg: string): number {\n switch (alg) {\n case 'ES256':\n case 'ES256K':\n return 64; // 32 + 32\n case 'ES384':\n return 96; // 48 + 48\n case 'ES512':\n return 132; // 66 + 66 (P-521)\n default:\n throw new Error(`Unsupported ECDSA alg for JOSE conversion: ${alg}`);\n }\n}\n\nfunction derToJose(der: Buffer, outLen: number): Buffer {\n let i = 0;\n if (der[i++] !== 0x30) throw new Error('Invalid DER ECDSA signature');\n\n // seq length (short/long form)\n let seqLen = der[i++];\n if (seqLen & 0x80) {\n const n = seqLen & 0x7f;\n seqLen = 0;\n for (let k = 0; k < n; k++) seqLen = (seqLen << 8) | der[i++];\n }\n\n if (der[i++] !== 0x02) throw new Error('Invalid DER ECDSA signature (r)');\n const rLen = der[i++];\n let r = der.subarray(i, i + rLen);\n i += rLen;\n\n if (der[i++] !== 0x02) throw new Error('Invalid DER ECDSA signature (s)');\n const sLen = der[i++];\n let s = der.subarray(i, i + sLen);\n\n // strip leading zeros\n while (r.length > outLen / 2 && r[0] === 0x00) r = r.subarray(1);\n while (s.length > outLen / 2 && s[0] === 0x00) s = s.subarray(1);\n\n const rPad = Buffer.concat([Buffer.alloc(outLen / 2 - r.length, 0), r]);\n const sPad = Buffer.concat([Buffer.alloc(outLen / 2 - s.length, 0), s]);\n return Buffer.concat([rPad, sPad]);\n}\n\nfunction joseToDer(jose: Buffer): Buffer {\n const half = jose.length / 2;\n let r = jose.subarray(0, half);\n let s = jose.subarray(half);\n\n // trim leading zeros\n while (r.length > 1 && r[0] === 0x00 && (r[1] & 0x80) === 0) r = r.subarray(1);\n while (s.length > 1 && s[0] === 0x00 && (s[1] & 0x80) === 0) s = s.subarray(1);\n\n // if high bit set, prepend 0x00\n if (r[0] & 0x80) r = Buffer.concat([Buffer.from([0x00]), r]);\n if (s[0] & 0x80) s = Buffer.concat([Buffer.from([0x00]), s]);\n\n const rPart = Buffer.concat([Buffer.from([0x02, r.length]), r]);\n const sPart = Buffer.concat([Buffer.from([0x02, s.length]), s]);\n\n const seqLen = rPart.length + sPart.length;\n\n let lenBytes: Buffer;\n if (seqLen < 0x80) {\n lenBytes = Buffer.from([seqLen]);\n } else {\n const tmp: number[] = [];\n let n = seqLen;\n while (n > 0) {\n tmp.unshift(n & 0xff);\n n >>= 8;\n }\n lenBytes = Buffer.from([0x80 | tmp.length, ...tmp]);\n }\n\n return Buffer.concat([Buffer.from([0x30]), lenBytes, rPart, sPart]);\n}\n\nfunction isEcdsaAlg(alg: string): boolean {\n return alg === 'ES256' || alg === 'ES384' || alg === 'ES512' || alg === 'ES256K';\n}\n\n\n// Signature algorithms\nexport const SignatureAlgorithm = {\n // HMAC\n HS256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha256', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n const expected = createHmac('sha256', secret).update(data).digest('base64url');\n return timingSafeCompare(expected, signature);\n }\n },\n HS384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha384', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n const expected = createHmac('sha384', secret).update(data).digest('base64url');\n return timingSafeCompare(expected, signature);\n }\n },\n HS512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha512', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n const expected = createHmac('sha512', secret).update(data).digest('base64url');\n return timingSafeCompare(expected, signature);\n }\n },\n\n // RSA (DER-encoded signatures, base64url)\n RS256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA256').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA256')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n RS384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA384').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA384')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n RS512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA512').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA512')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n\n // ECDSA (DER-encoded by default — no dsaEncoding!)\n ES256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA256').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('SHA256')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n ES384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA384').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('SHA384')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n ES512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA512').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('SHA512')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n ES256K: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA256').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('SHA256')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n PS256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA256')\n .update(data)\n .end()\n .sign({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 32\n })\n .toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA256')\n .update(data)\n .end()\n .verify({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 32\n }, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n PS384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA384')\n .update(data)\n .end()\n .sign({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 48\n })\n .toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA384')\n .update(data)\n .end()\n .verify({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 48\n }, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n PS512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA512')\n .update(data)\n .end()\n .sign({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 64\n })\n .toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA512')\n .update(data)\n .end()\n .verify({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 64\n }, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n EdDSA: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n cryptoSign(null, typeof data === 'string' ? Buffer.from(data, 'utf8') : data, secret)\n .toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return cryptoVerify(\n null,\n typeof data === 'string' ? Buffer.from(data, 'utf8') : data,\n secret,\n Buffer.from(signature, 'base64url')\n );\n } catch {\n return false;\n }\n }\n }\n} as const;\n\nexport type SupportedAlgorithm = keyof typeof SignatureAlgorithm;\n\nexport const SupportedAlgorithms = Object.keys(SignatureAlgorithm) as Array<SupportedAlgorithm>;\n\n/**\n * Autodetection of algorithm for KeyObjects\n * @param key\n * @constructor\n */\nexport function AutodetectAlgorithm(key: KeyObject): SupportedAlgorithm {\n if (key.type === 'secret') return 'HS256';\n if (key.type !== 'private') throw new Error('Only private or symmetric keys can be used to sign JWTs');\n\n const asymKeyType = key.asymmetricKeyType;\n const details = key.asymmetricKeyDetails;\n\n switch (asymKeyType) {\n case 'rsa':\n return 'RS256';\n case 'rsa-pss': {\n const hash = details?.hashAlgorithm ?? 'sha256';\n switch (hash) {\n case 'sha256':\n return 'PS256';\n case 'sha384':\n return 'PS384';\n case 'sha512':\n return 'PS512';\n default:\n throw new Error(`Unsupported RSA-PSS hash algorithm: ${hash}`);\n }\n }\n case 'ec': {\n const curve = details?.namedCurve;\n switch (curve) {\n case 'P-256':\n case 'prime256v1':\n return 'ES256';\n case 'P-384':\n case 'secp384r1':\n return 'ES384';\n case 'P-521':\n case 'secp521r1':\n return 'ES512';\n case 'secp256k1':\n return 'ES256K';\n default:\n throw new Error(`Unsupported EC curve: ${curve}`);\n }\n }\n case 'ed25519':\n return 'EdDSA';\n default:\n throw new Error(`Unsupported asymmetric key type: ${asymKeyType}`);\n }\n}\n\n/**\n * Normalize KeyLike input to a KeyObject\n * @param key\n */\nfunction toKeyObject(key: KeyLike): KeyObject {\n // Already a KeyObject (private, public, or secret)\n if (typeof key === 'object' && 'type' in key) return key as KeyObject;\n\n // Try asymmetric private key (PEM / DER / JWK)\n try {\n return createPrivateKey(key);\n } catch {\n // Fallback: symmetric key (HMAC)\n const buffer =\n typeof key === 'string'\n ? Buffer.from(key, 'utf8')\n : Buffer.isBuffer(key)\n ? key\n : (() => {\n throw new Error('Unsupported key type');\n })();\n\n return createSecretKey(buffer);\n }\n}\n\n/**\n * Decode a JWT string into its parts (without verification)\n * @param token\n */\nexport const decode = (token: string): JWT => {\n const parts = token.split('.');\n if (parts.length !== 3) {\n throw new Error('Invalid JWT: must contain exactly 3 parts separated by \".\"');\n }\n\n const [headerPart, payloadPart, signature] = parts;\n\n if (!headerPart || !payloadPart || !signature) {\n throw new Error('Invalid JWT: empty part detected');\n }\n\n try {\n const header = JSON.parse(base64Url.decode(headerPart)) as JWTHeader;\n const payload = JSON.parse(base64Url.decode(payloadPart)) as JWTPayload;\n return {header, payload, signature};\n } catch (err) {\n throw new Error(`Invalid JWT: malformed header or payload (${(err as Error).message})`);\n }\n};\n\n/**\n * Sign a JWT\n * @param payload\n * @param secret\n * @param options\n */\nexport const sign = (\n payload: JWTPayload,\n secret: KeyLike,\n options: {\n alg?: SupportedAlgorithm;\n kid?: string;\n typ?: string;\n /**\n * default 'der'\n */\n signatureFormat?: 'der' | 'jose';\n } = {}\n): string => {\n const key = toKeyObject(secret);\n const alg = options.alg ?? AutodetectAlgorithm(key);\n const signatureFormat = options.signatureFormat ?? 'der';\n const typ = options.typ ?? 'JWT';\n\n if (!(alg in SignatureAlgorithm)) throw new Error(`Unsupported algorithm: ${alg}`);\n\n const header: JWTHeader = {alg, typ};\n if (options.kid) header.kid = options.kid;\n\n const headerEncoded = base64Url.encode(JSON.stringify(header));\n const payloadEncoded = base64Url.encode(JSON.stringify(payload));\n\n const signingInput = `${headerEncoded}.${payloadEncoded}`;\n\n // existing DER/base64url signature from algorithms\n let signature = SignatureAlgorithm[alg].sign(signingInput, secret);\n\n // If ES* and caller requested JOSE, convert the DER signature bytes to JOSE bytes\n if (signatureFormat === 'jose' && isEcdsaAlg(alg)) {\n const der = Buffer.from(signature, 'base64url');\n const jose = derToJose(der, joseLenForAlg(alg));\n signature = jose.toString('base64url');\n }\n\n return `${headerEncoded}.${payloadEncoded}.${signature}`;\n\n};\n\n/**\n * Verify and validate a JWT\n * @param token\n * @param secret\n * @param options\n */\nexport const verify = (\n token: string,\n secret: KeyLike,\n options: {\n algorithms?: SupportedAlgorithm[]; // Whitelist of allowed algorithms\n issuer?: string;\n subject?: string;\n audience?: string | string[];\n jwtId?: string;\n ignoreExpiration?: boolean;\n clockSkew?: number; // in seconds, default 0\n maxTokenAge?: number; // Maximum age in seconds\n signatureFormat?: 'der' | 'jose';\n } = {}\n):\n | { valid: true; header: JWTHeader; payload: JWTPayload; signature: string }\n | { valid: false; error: { reason: string; code: string } } => {\n let decoded: JWT;\n try {\n decoded = decode(token);\n } catch (err) {\n return {\n valid: false,\n error: {\n reason: (err as Error).message,\n code: 'INVALID_TOKEN'\n }\n };\n }\n\n const {header, payload, signature} = decoded;\n\n // Validate algorithm\n const alg = header.alg as SupportedAlgorithm;\n if (!(alg in SignatureAlgorithm)) {\n return {\n valid: false,\n error: {\n reason: `Unsupported or unknown algorithm: ${header.alg}`,\n code: 'INVALID_ALGORITHM'\n }\n };\n }\n\n // Algorithm whitelist validation (prevents algorithm confusion attacks)\n if (options.algorithms && options.algorithms.length > 0) {\n if (!options.algorithms.includes(alg)) {\n return {\n valid: false,\n error: {\n reason: `Algorithm \"${alg}\" is not in the allowed algorithms list`,\n code: 'ALGORITHM_NOT_ALLOWED'\n }\n };\n }\n }\n\n // Validate 'typ' header (must be 'JWT' if present)\n if (header.typ !== undefined && header.typ !== 'JWT') {\n return {\n valid: false,\n error: {\n reason: `Invalid token type: expected 'JWT', got '${header.typ}'`,\n code: 'INVALID_TYPE'\n }\n };\n }\n\n // Verify signature\n const signingInput = `${base64Url.encode(JSON.stringify(header))}.${base64Url.encode(JSON.stringify(payload))}`;\n\n if (!isEcdsaAlg(alg)) {\n // non-ES* algorithms unchanged\n const isValidSignature = SignatureAlgorithm[alg].verify(signingInput, secret, signature);\n if (!isValidSignature) {\n return {valid: false, error: {reason: \"Signature verification failed\", code: 'INVALID_SIGNATURE'}};\n }\n } else {\n // ES* algorithms: verify DER by default, but allow JOSE + auto-detect\n const format = options.signatureFormat; // undefined means \"auto\"\n\n let ok: boolean;\n\n // 1) If explicitly JOSE -> convert to DER for verification\n if (format === 'jose') {\n try {\n const jose = Buffer.from(signature, 'base64url');\n const derSigB64Url = joseToDer(jose).toString('base64url');\n ok = SignatureAlgorithm[alg].verify(signingInput, secret, derSigB64Url);\n } catch {\n ok = false;\n }\n }\n // 2) If explicitly DER -> verify as-is\n else if (format === 'der') {\n ok = SignatureAlgorithm[alg].verify(signingInput, secret, signature);\n }\n // 3) Auto-detect: try DER first, then JOSE\n else {\n ok = SignatureAlgorithm[alg].verify(signingInput, secret, signature);\n if (!ok) {\n try {\n const jose = Buffer.from(signature, 'base64url');\n // quick sanity: only attempt conversion if size matches expected\n if (jose.length === joseLenForAlg(alg)) {\n const derSigB64Url = joseToDer(jose).toString('base64url');\n ok = SignatureAlgorithm[alg].verify(signingInput, secret, derSigB64Url);\n }\n } catch {\n // ignore\n }\n }\n }\n\n if (!ok) {\n return {valid: false, error: {reason: \"Signature verification failed\", code: 'INVALID_SIGNATURE'}};\n }\n }\n\n // Time validation\n const now = Math.floor(Date.now() / 1000);\n const skew = options.clockSkew ?? 0;\n\n if (!options.ignoreExpiration) {\n if (payload.exp !== undefined && now > payload.exp + skew) {\n return {\n valid: false,\n error: {\n reason: 'Token expired',\n code: 'TOKEN_EXPIRED'\n }\n };\n }\n }\n\n if (payload.nbf !== undefined && now + skew < payload.nbf) {\n return {\n valid: false,\n error: {\n reason: 'Token not yet valid',\n code: 'TOKEN_NOT_ACTIVE'\n }\n };\n }\n\n if (payload.iat !== undefined && now + skew < payload.iat) {\n return {\n valid: false,\n error: {\n reason: 'Token issued in the future',\n code: 'TOKEN_FUTURE_ISSUED'\n }\n };\n }\n\n // Maximum token age validation\n if (options.maxTokenAge !== undefined && payload.iat !== undefined) {\n const tokenAge = now - payload.iat;\n if (tokenAge > options.maxTokenAge) {\n return {\n valid: false,\n error: {\n reason: `Token age (${tokenAge}s) exceeds maximum allowed age (${options.maxTokenAge}s)`,\n code: 'TOKEN_TOO_OLD'\n }\n };\n }\n }\n\n // --- Claim validations (only if options provided) ---\n\n // Issuer (`iss`)\n if (options.issuer !== undefined) {\n if (payload.iss === undefined) {\n return {\n valid: false,\n error: {\n reason: 'Token missing required issuer claim (\"iss\")',\n code: 'MISSING_ISSUER'\n }\n };\n }\n if (options.issuer !== payload.iss) {\n return {\n valid: false,\n error: {\n reason: `Invalid token issuer: expected \"${options.issuer}\", got \"${payload.iss}\"`,\n code: 'INVALID_ISSUER'\n }\n };\n }\n }\n\n // Subject (`sub`)\n if (options.subject !== undefined) {\n if (payload.sub === undefined) {\n return {\n valid: false,\n error: {\n reason: 'Token missing required subject claim (\"sub\")',\n code: 'MISSING_SUBJECT'\n }\n };\n }\n if (options.subject !== payload.sub) {\n return {\n valid: false,\n error: {\n reason: `Invalid token subject: expected \"${options.subject}\", got \"${payload.sub}\"`,\n code: 'INVALID_SUBJECT'\n }\n };\n }\n }\n\n // Audience (`aud`)\n if (options.audience !== undefined) {\n const aud = payload.aud;\n if (aud === undefined) {\n return {\n valid: false,\n error: {\n reason: 'Token missing required audience claim (\"aud\")',\n code: 'MISSING_AUDIENCE'\n }\n };\n }\n\n const expectedAud = Array.isArray(options.audience) ? options.audience : [options.audience];\n const tokenAud = Array.isArray(aud) ? aud : [aud];\n\n const hasMatch = expectedAud.some(a => tokenAud.includes(a));\n if (!hasMatch) {\n return {\n valid: false,\n error: {\n reason: 'Audience claim mismatch',\n code: 'INVALID_AUDIENCE'\n }\n };\n }\n }\n\n // JWT ID (`jti`)\n if (options.jwtId !== undefined) {\n if (payload.jti === undefined) {\n return {\n valid: false,\n error: {\n reason: 'Token missing required JWT ID claim (\"jti\")',\n code: 'MISSING_JTI'\n }\n };\n }\n if (options.jwtId !== payload.jti) {\n return {\n valid: false,\n error: {\n reason: `Invalid JWT ID: expected \"${options.jwtId}\", got \"${payload.jti}\"`,\n code: 'INVALID_JTI'\n }\n };\n }\n }\n\n return {valid: true, header, payload, signature};\n};\n\n//namespace export\nexport const JWT = {\n sign,\n verify,\n decode,\n algorithms: SignatureAlgorithm\n};\n\n","import {\n createPrivateKey,\n createPublicKey,\n createSecretKey,\n createHash,\n type KeyObject\n} from 'crypto';\n\n// JWK Types\nexport type JWK =\n | RSAJWK\n | ECJWK\n | OKPJWK\n | OctJWK;\n\nexport type JWKWithHelpers = JWK & {\n toKeyObject(): KeyObject;\n};\n\ninterface BaseJWK {\n kty: string;\n kid?: string;\n alg?: string;\n use?: 'sig' | 'enc';\n key_ops?: Array<'sign' | 'verify'>;\n x5c?: string[]; // X.509 cert chain\n x5t?: string; // Base64url thumbprint\n}\n\nexport interface RSAJWK extends BaseJWK {\n kty: 'RSA';\n n: string;\n e: string;\n d?: string;\n p?: string;\n q?: string;\n dp?: string;\n dq?: string;\n qi?: string;\n}\n\nexport interface ECJWK extends BaseJWK {\n kty: 'EC';\n crv: 'P-256' | 'P-384' | 'P-521' | 'secp256k1';\n x: string;\n y: string;\n d?: string;\n}\n\nexport interface OKPJWK extends BaseJWK {\n kty: 'OKP';\n crv: 'Ed25519';\n x: string;\n d?: string;\n}\n\nexport interface OctJWK extends BaseJWK {\n kty: 'oct';\n k: string;\n}\n\n/**\n * Export KeyObject to JWK\n * @param key\n */\nexport function exportJWK(key: KeyObject): JWK {\n if (!key || typeof key !== 'object') throw new Error('Invalid KeyObject');\n return key.export({format: 'jwk'}) as JWK;\n}\n\n/**\n * Import JWK to KeyObject\n * @param jwk\n */\nexport function importJWK(jwk: JWK): KeyObject {\n if (!jwk || typeof jwk !== 'object') throw new Error('Invalid JWK');\n\n switch (jwk.kty) {\n case 'oct': {\n if (!('k' in jwk) || typeof jwk.k !== 'string') {\n throw new Error('Invalid oct JWK: missing \"k\"');\n }\n\n return createSecretKey(Buffer.from(jwk.k, 'base64url'));\n }\n\n case 'RSA':\n case 'EC':\n case 'OKP': {\n // private key\n if ('d' in jwk && typeof (jwk as any).d === 'string') {\n // @ts-ignore\n return createPrivateKey({format: 'jwk', key: jwk});\n }\n\n // public key\n // @ts-ignore\n return createPublicKey({format: 'jwk', key: jwk});\n }\n\n default:\n throw new Error(`Unsupported JWK key type: ${(jwk as any).kty}`);\n }\n}\n\n/**\n * Export public-only JWK\n * @param key\n */\nexport function toPublicJWK(key: KeyObject): JWK {\n if (!key || typeof key !== 'object') {\n throw new Error('Invalid KeyObject');\n }\n\n const publicKey =\n key.type === 'private'\n ? createPublicKey(key)\n : key;\n\n const jwk = publicKey.export({format: 'jwk'}) as JWK;\n\n // Ensure private fields are not present\n delete (jwk as any).d;\n delete (jwk as any).p;\n delete (jwk as any).q;\n delete (jwk as any).dp;\n delete (jwk as any).dq;\n delete (jwk as any).qi;\n return jwk;\n}\n\n/**\n * RFC 7638 JWK thumbprint\n * @param jwk\n * @param hashAlg\n */\nexport function getJWKThumbprint(jwk: JWK, hashAlg: 'sha256' = 'sha256'): string {\n if (!jwk || typeof jwk !== 'object') {\n throw new Error('Invalid JWK');\n }\n\n let fields: Record<string, string>;\n\n switch (jwk.kty) {\n case 'RSA':\n fields = {e: jwk.e, kty: jwk.kty, n: jwk.n};\n break;\n\n case 'EC':\n fields = {crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y};\n break;\n\n case 'OKP':\n fields = {crv: jwk.crv, kty: jwk.kty, x: jwk.x};\n break;\n\n case 'oct':\n fields = {k: jwk.k, kty: jwk.kty};\n break;\n\n default:\n throw new Error(`Unsupported JWK key type: ${(jwk as any).kty}`);\n }\n\n // Lexicographically sorted JSON\n const json = JSON.stringify(\n Object.keys(fields)\n .sort()\n .reduce((acc, k) => {\n acc[k] = fields[k];\n return acc;\n }, {} as Record<string, string>)\n );\n\n return createHash(hashAlg)\n .update(json)\n .digest('base64url');\n}\n\n\n/**\n * Compute x5t (SHA-1) from first cert in x5c if not set\n * @param jwk\n */\nexport function computeX5T(jwk: JWK): string | undefined {\n if (!jwk.x5c?.length) return undefined;\n return createHash('sha1').update(Buffer.from(jwk.x5c[0], 'base64')).digest('base64url');\n}\n\nexport const JWK = {\n export: exportJWK,\n import: importJWK,\n toPublic: toPublicJWK,\n thumbprint: getJWKThumbprint,\n}\n\nexport interface JWKS {\n keys: JWK[];\n}\n\n/**\n * Convert JWKS specific key of first key to KeyObject\n * @param jwks\n * @param kid\n * @constructor\n */\nexport function JWKSToKeyObject(\n jwks: JWKS,\n kid?: string\n): KeyObject {\n if (!jwks || !Array.isArray(jwks.keys)) throw new Error('Invalid JWKS');\n\n let jwk: JWK | undefined;\n\n if (kid) jwk = jwks.keys.find(k => k.kid === kid);\n\n // Fallback: single-key JWKS\n if (!jwk && jwks.keys.length === 1) jwk = jwks.keys[0];\n\n if (!jwk) throw new Error('Key not found in JWKS');\n return importJWK(jwk);\n}\n\n/**\n * Normalize JWKS\n * @param jwks\n */\nexport function normalizeJWKS(jwks: JWKS): JWKS {\n return {\n keys: normalizeJWK(...jwks.keys)\n };\n}\n\nexport function normalizeJWK(...keys: JWK[]): JWKWithHelpers[] {\n return keys.map((jwk) => {\n const normalized = {\n ...jwk,\n kid: jwk.kid ?? getJWKThumbprint(jwk),\n x5t: jwk.x5t ?? computeX5T(jwk)\n } as JWKWithHelpers;\n\n // Keep helper API out of object enumeration/serialization.\n Object.defineProperty(normalized, 'toKeyObject', {\n enumerable: false,\n configurable: false,\n writable: false,\n value: () => importJWK(normalized)\n });\n\n return normalized;\n })\n}\n\nexport const fromWeb = async (\n url: string | URL,\n options: Partial<{\n fetch: typeof fetch;\n ttl: number;\n timeoutMs: number;\n endpointOverride: string;\n overrideEndpointCheck: boolean;\n cache: {\n get: (key: string) => JWKS | undefined | Promise<JWKS | undefined>;\n set: (key: string, value: JWKS) => void | Promise<void>;\n };\n }> = {}\n) => {\n const baseUrl = typeof url === 'string' ? url : url.toString();\n const fetchFn = options.fetch ?? globalThis.fetch;\n const ttl = Math.max(0, options.ttl ?? 5 * 60_000);\n const timeoutMs = Math.max(0, options.timeoutMs ?? 5_000);\n const wellKnownPath = '/.well-known/jwks.json';\n\n if (!fetchFn) {\n throw new Error('No fetch implementation available');\n }\n\n const endpoint = (() => {\n if (options.endpointOverride) {\n const override = options.endpointOverride;\n try {\n return new URL(override, baseUrl).toString();\n } catch {\n return override;\n }\n }\n\n if (options.overrideEndpointCheck) {\n return baseUrl;\n }\n\n if (baseUrl.endsWith(wellKnownPath)) {\n return baseUrl;\n }\n\n return `${baseUrl.replace(/\\/+$/, '')}${wellKnownPath}`;\n })();\n\n const cache = (() => {\n if (options.cache) return options.cache;\n let memoryValue: JWKS | undefined;\n return {\n get: () => memoryValue,\n set: (_key: string, value: JWKS) => {\n memoryValue = value;\n }\n };\n })();\n\n let cachedJWKS: JWKS | undefined;\n let nextRefreshAt = 0;\n let refreshInFlight: Promise<JWKS> | undefined;\n let consecutiveFailures = 0;\n\n const fetchJWKS = async (allowStaleOnFailure: boolean): Promise<JWKS> => {\n if (refreshInFlight) return refreshInFlight;\n\n refreshInFlight = (async () => {\n const controller = new AbortController();\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n\n if (timeoutMs > 0) {\n timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);\n }\n\n let response: Response;\n try {\n response = await fetchFn(endpoint, {signal: controller.signal});\n } catch (error) {\n if (controller.signal.aborted) {\n throw new Error(`JWKS fetch timed out after ${timeoutMs}ms`);\n }\n throw error;\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n\n if (!response.ok) {\n throw new Error(`Failed to fetch JWKS: ${response.status} ${response.statusText}`);\n }\n\n const body = await response.json();\n if (!body || typeof body !== 'object' || !Array.isArray((body as any).keys)) {\n throw new Error('Invalid JWKS');\n }\n\n return normalizeJWKS(body as JWKS);\n })();\n\n try {\n const fresh = await refreshInFlight;\n cachedJWKS = fresh;\n await cache.set(endpoint, fresh);\n consecutiveFailures = 0;\n if (ttl > 0) nextRefreshAt = Date.now() + ttl;\n return fresh;\n } catch (error) {\n if (!allowStaleOnFailure || !cachedJWKS) {\n throw error;\n }\n\n consecutiveFailures += 1;\n if (ttl > 0) {\n const backoff = Math.min(\n Math.max(ttl, 30_000) * Math.pow(2, consecutiveFailures - 1),\n 15 * 60_000\n );\n nextRefreshAt = Date.now() + backoff;\n }\n console.warn(`JWKS refresh failed for \"${endpoint}\", using stale cache.`, error);\n return cachedJWKS;\n } finally {\n refreshInFlight = undefined;\n }\n };\n\n cachedJWKS = await cache.get(endpoint);\n if (!cachedJWKS) {\n cachedJWKS = await fetchJWKS(false);\n } else {\n cachedJWKS = normalizeJWKS(cachedJWKS);\n if (ttl > 0) nextRefreshAt = Date.now() + ttl;\n }\n\n\n return ({\n async list(): Promise<JWKWithHelpers[]> {\n if (ttl > 0 && Date.now() >= nextRefreshAt) {\n await fetchJWKS(true);\n }\n return normalizeJWK(...(cachedJWKS as JWKS).keys);\n },\n async refresh() {\n await fetchJWKS(false);\n return this;\n },\n async key(kid: string): Promise<JWKWithHelpers | undefined> {\n const keys = await this.list();\n const key = keys.find((v) => v.kid === kid)\n if (!key) return undefined;\n return normalizeJWK(key)[0];\n },\n async find(input: Partial<BaseJWK>): Promise<JWKWithHelpers[]> {\n const keys = await this.list();\n const entries = Object.entries(input) as Array<[keyof BaseJWK, BaseJWK[keyof BaseJWK]]>;\n\n if (entries.length === 0) return normalizeJWK(...keys);\n\n return normalizeJWK(...keys.filter((key) =>\n entries.every(([field, expected]) => {\n const value = key[field];\n if (Array.isArray(expected)) {\n return Array.isArray(value)\n && value.length === expected.length\n && value.every((item, i) => item === expected[i]);\n }\n return value === expected;\n })\n ));\n },\n async findFirst(input: Partial<BaseJWK>): Promise<JWKWithHelpers | undefined> {\n return this.find(input).then(([key]) => key);\n },\n export(): JWKS | undefined {\n return cachedJWKS;\n }\n });\n}\n\nexport const JWKS = {\n toKeyObject: JWKSToKeyObject,\n normalize: normalizeJWKS,\n fromWeb\n}\n"],"names":["base64Url","input","timingSafeCompare","a","b","timingSafeEqual","joseLenForAlg","alg","derToJose","der","outLen","i","seqLen","n","k","rLen","r","sLen","s","rPad","sPad","joseToDer","jose","half","rPart","sPart","lenBytes","tmp","isEcdsaAlg","SignatureAlgorithm","data","secret","createHmac","signature","expected","createSign","createVerify","crypto","cryptoSign","cryptoVerify","SupportedAlgorithms","AutodetectAlgorithm","key","asymKeyType","details","hash","curve","toKeyObject","createPrivateKey","buffer","createSecretKey","decode","token","parts","headerPart","payloadPart","header","payload","err","sign","options","signatureFormat","typ","headerEncoded","payloadEncoded","signingInput","verify","decoded","format","ok","derSigB64Url","now","skew","tokenAge","aud","expectedAud","tokenAud","JWT","exportJWK","importJWK","jwk","createPublicKey","toPublicJWK","getJWKThumbprint","hashAlg","fields","json","acc","createHash","computeX5T","JWK","JWKSToKeyObject","jwks","kid","normalizeJWKS","normalizeJWK","keys","normalized","fromWeb","url","baseUrl","fetchFn","ttl","timeoutMs","wellKnownPath","endpoint","override","cache","memoryValue","_key","value","cachedJWKS","nextRefreshAt","refreshInFlight","consecutiveFailures","fetchJWKS","allowStaleOnFailure","controller","timeoutHandle","response","error","body","fresh","backoff","v","entries","field","item","JWKS"],"mappings":"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"}
|