@zuplo/cli 6.74.2 → 6.74.6
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/dist/cmds/test.d.ts.map +1 -1
- package/dist/cmds/test.js +8 -0
- package/dist/cmds/test.js.map +1 -1
- package/dist/common/utils/pnpm-lifecycle.d.ts.map +1 -1
- package/dist/common/utils/pnpm-lifecycle.js +1 -4
- package/dist/common/utils/pnpm-lifecycle.js.map +1 -1
- package/dist/common/utils/pnpm-lifecycle.test.js +23 -4
- package/dist/common/utils/pnpm-lifecycle.test.js.map +1 -1
- package/dist/test/handler.d.ts +2 -1
- package/dist/test/handler.d.ts.map +1 -1
- package/dist/test/handler.js.map +1 -1
- package/dist/test/invoke-test.d.ts +3 -2
- package/dist/test/invoke-test.d.ts.map +1 -1
- package/dist/test/invoke-test.js +26 -0
- package/dist/test/invoke-test.js.map +1 -1
- package/dist/test/invoke-test.test.js +16 -0
- package/dist/test/invoke-test.test.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +12 -12
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/general/encrypt.js +50 -51
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/local.js +10 -31
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/remote.js +17 -26
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/compact/verify.js +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/flattened/sign.js +1 -9
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/general/sign.js +12 -21
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/general/verify.js +13 -11
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/decrypt.js +3 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/verify.js +4 -4
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/export.js +3 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/generate_key_pair.js +7 -6
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/asn1.js +29 -62
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/content_encryption.js +16 -34
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/crypto_key.js +6 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/invalid_key_input.js +0 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_algorithms.js +44 -71
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +46 -41
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +14 -13
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwk_to_key.js +5 -10
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_algorithms.js +20 -18
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_sign.js +12 -6
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_verify.js +26 -27
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +60 -102
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key.js +61 -99
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_algorithm.js +2 -8
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_descriptor.js +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_management.js +74 -161
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/options.js +11 -14
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/signing.js +6 -16
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/type_checks.js +13 -18
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/util/base64url.js +4 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/package.json +1 -1
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +3 -3
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/out/esm/{chunk-B5LJC45G.js → chunk-CKGECOOJ.js} +88 -88
- package/node_modules/@zuplo/runtime/out/esm/chunk-CKGECOOJ.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/types/index.d.ts +5 -1
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/package.json +6 -6
- package/node_modules/@zuplo/runtime/out/esm/chunk-B5LJC45G.js.map +0 -1
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-B5LJC45G.js.LEGAL.txt → chunk-CKGECOOJ.js.LEGAL.txt} +0 -0
package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_encrypt.js
CHANGED
|
@@ -9,7 +9,7 @@ import { prepareKey } from './key.js';
|
|
|
9
9
|
import { jweAlgorithm, jweEncryption } from './jwe_algorithms.js';
|
|
10
10
|
import { compress } from './deflate.js';
|
|
11
11
|
export function checkEncryptHeaders(input) {
|
|
12
|
-
const
|
|
12
|
+
const [, protectedHeader, unprotectedHeader, sharedUnprotectedHeader, , , , , crit] = input;
|
|
13
13
|
if (!isDisjoint(protectedHeader, unprotectedHeader, sharedUnprotectedHeader)) {
|
|
14
14
|
throw new JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint');
|
|
15
15
|
}
|
|
@@ -18,7 +18,7 @@ export function checkEncryptHeaders(input) {
|
|
|
18
18
|
...unprotectedHeader,
|
|
19
19
|
...sharedUnprotectedHeader,
|
|
20
20
|
};
|
|
21
|
-
validateCrit(JWEInvalid, JWE_RECOGNIZED,
|
|
21
|
+
validateCrit(JWEInvalid, JWE_RECOGNIZED, crit, protectedHeader, joseHeader);
|
|
22
22
|
if (joseHeader.zip !== undefined && joseHeader.zip !== 'DEF') {
|
|
23
23
|
throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value.');
|
|
24
24
|
}
|
|
@@ -32,20 +32,21 @@ export function checkEncryptHeaders(input) {
|
|
|
32
32
|
if (typeof enc !== 'string' || !enc) {
|
|
33
33
|
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
|
|
34
34
|
}
|
|
35
|
-
return
|
|
35
|
+
return [joseHeader, alg, enc, jweEncryption(enc)];
|
|
36
36
|
}
|
|
37
37
|
export async function encryptJWE(input, checked, key) {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
const [joseHeader, alg, , encEntry] = checked;
|
|
39
|
+
const [inputPlaintext, inputProtectedHeader, inputUnprotectedHeader, sharedUnprotectedHeader, aad, providedCek, inputIv, keyManagementParameters, , unprotectedParameters,] = input;
|
|
40
|
+
let protectedHeader = inputProtectedHeader;
|
|
41
|
+
let unprotectedHeader = inputUnprotectedHeader;
|
|
42
|
+
if (providedCek && (alg === 'dir' || alg === 'ECDH-ES')) {
|
|
42
43
|
throw new TypeError(`setContentEncryptionKey cannot be called with JWE "alg" (Algorithm) Header ${alg}`);
|
|
43
44
|
}
|
|
44
45
|
const algEntry = jweAlgorithm(alg);
|
|
45
46
|
const k = await prepareKey(alg === 'dir' ? encEntry : algEntry, key, 'encrypt');
|
|
46
|
-
const
|
|
47
|
+
const [cek, encryptedKey, parameters] = await encryptKeyManagement(alg, encEntry, k, providedCek, keyManagementParameters);
|
|
47
48
|
if (parameters) {
|
|
48
|
-
if (
|
|
49
|
+
if (unprotectedParameters) {
|
|
49
50
|
unprotectedHeader = unprotectedHeader ? { ...unprotectedHeader, ...parameters } : parameters;
|
|
50
51
|
}
|
|
51
52
|
else {
|
|
@@ -64,20 +65,20 @@ export async function encryptJWE(input, checked, key) {
|
|
|
64
65
|
}
|
|
65
66
|
let additionalData;
|
|
66
67
|
let aadMember;
|
|
67
|
-
if (
|
|
68
|
-
aadMember = b64u(
|
|
68
|
+
if (aad?.byteLength) {
|
|
69
|
+
aadMember = b64u(aad);
|
|
69
70
|
additionalData = concat(protectedHeaderB, encode('.'), encode(aadMember));
|
|
70
71
|
}
|
|
71
72
|
else {
|
|
72
73
|
additionalData = protectedHeaderB;
|
|
73
74
|
}
|
|
74
|
-
let plaintext =
|
|
75
|
+
let plaintext = inputPlaintext;
|
|
75
76
|
if (joseHeader.zip === 'DEF') {
|
|
76
77
|
plaintext = await compress(plaintext).catch((cause) => {
|
|
77
78
|
throw new JWEInvalid('Failed to compress plaintext', { cause });
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
|
-
const { ciphertext, tag, iv } = await encrypt(encEntry, plaintext, cek,
|
|
81
|
+
const { ciphertext, tag, iv } = await encrypt(encEntry, plaintext, cek, inputIv, additionalData);
|
|
81
82
|
const jwe = {
|
|
82
83
|
ciphertext: b64u(ciphertext),
|
|
83
84
|
};
|
package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwk_to_key.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
import { JOSENotSupported } from '../util/errors.js';
|
|
2
|
-
const unsupportedAlg = 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value';
|
|
3
|
-
function subtleParams(entry, jwk) {
|
|
4
|
-
if (!entry.kty.includes(jwk.kty)) {
|
|
5
|
-
throw new JOSENotSupported(unsupportedAlg);
|
|
6
|
-
}
|
|
7
|
-
return entry.subtleFor?.({ kty: jwk.kty, crv: jwk.crv }) ?? entry.subtle;
|
|
8
|
-
}
|
|
9
2
|
export async function jwkToKey(entry, jwk) {
|
|
10
3
|
if (jwk.kty === 'RSA' && 'oth' in jwk && jwk.oth !== undefined) {
|
|
11
4
|
throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
|
|
12
5
|
}
|
|
13
|
-
|
|
6
|
+
if (!entry.kty.includes(jwk.kty)) {
|
|
7
|
+
throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
|
8
|
+
}
|
|
9
|
+
const algorithm = entry.resolve?.({ kty: jwk.kty, crv: jwk.crv }) ?? entry.subtle;
|
|
14
10
|
const isPrivate = !!(jwk.d || jwk.priv);
|
|
15
|
-
const keyUsages = isPrivate ? entry.usages.private : entry.usages.public;
|
|
16
11
|
const keyData = { ...jwk };
|
|
17
12
|
if (keyData.kty !== 'AKP') {
|
|
18
13
|
delete keyData.alg;
|
|
19
14
|
}
|
|
20
15
|
delete keyData.use;
|
|
21
|
-
return crypto.subtle.importKey('jwk', keyData, algorithm, jwk.ext ??
|
|
16
|
+
return crypto.subtle.importKey('jwk', keyData, algorithm, jwk.ext ?? !isPrivate, jwk.key_ops ?? entry.usages[isPrivate ? 1 : 0]);
|
|
22
17
|
}
|
package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_algorithms.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { JOSENotSupported } from '../util/errors.js';
|
|
2
2
|
import { table } from './key_descriptor.js';
|
|
3
|
-
const sig =
|
|
3
|
+
const sig = [['verify'], ['sign']];
|
|
4
4
|
function hmac(bits) {
|
|
5
5
|
const subtle = { name: 'HMAC', hash: `SHA-${bits}` };
|
|
6
|
-
return { kty: ['oct'],
|
|
6
|
+
return { kty: ['oct'], secret: true, subtle, signing: subtle, usages: sig };
|
|
7
7
|
}
|
|
8
|
-
function rsa(
|
|
8
|
+
function rsa(bits, saltLength) {
|
|
9
|
+
const name = saltLength ? 'RSA-PSS' : 'RSASSA-PKCS1-v1_5';
|
|
9
10
|
const subtle = { name, hash: `SHA-${bits}` };
|
|
10
11
|
return {
|
|
11
12
|
kty: ['RSA'],
|
|
12
13
|
subtle,
|
|
13
|
-
|
|
14
|
+
signing: saltLength ? { ...subtle, saltLength } : subtle,
|
|
14
15
|
usages: sig,
|
|
15
|
-
|
|
16
|
+
minRsaBits: 2048,
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
function ecdsa(crv, bits) {
|
|
@@ -20,7 +21,7 @@ function ecdsa(crv, bits) {
|
|
|
20
21
|
kty: ['EC'],
|
|
21
22
|
crv,
|
|
22
23
|
subtle: { name: 'ECDSA', namedCurve: crv },
|
|
23
|
-
|
|
24
|
+
signing: { name: 'ECDSA', hash: `SHA-${bits}` },
|
|
24
25
|
usages: sig,
|
|
25
26
|
};
|
|
26
27
|
}
|
|
@@ -30,16 +31,17 @@ function eddsa() {
|
|
|
30
31
|
kty: ['OKP'],
|
|
31
32
|
crv: 'Ed25519',
|
|
32
33
|
subtle,
|
|
33
|
-
|
|
34
|
+
signing: subtle,
|
|
34
35
|
usages: sig,
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
|
-
function mldsa(
|
|
38
|
+
function mldsa(bits) {
|
|
39
|
+
const name = `ML-DSA-${bits}`;
|
|
38
40
|
const subtle = { name };
|
|
39
41
|
return {
|
|
40
42
|
kty: ['AKP'],
|
|
41
43
|
subtle,
|
|
42
|
-
|
|
44
|
+
signing: subtle,
|
|
43
45
|
usages: sig,
|
|
44
46
|
};
|
|
45
47
|
}
|
|
@@ -47,20 +49,20 @@ const JWS = table({
|
|
|
47
49
|
HS256: hmac(256),
|
|
48
50
|
HS384: hmac(384),
|
|
49
51
|
HS512: hmac(512),
|
|
50
|
-
RS256: rsa(
|
|
51
|
-
RS384: rsa(
|
|
52
|
-
RS512: rsa(
|
|
53
|
-
PS256: rsa(
|
|
54
|
-
PS384: rsa(
|
|
55
|
-
PS512: rsa(
|
|
52
|
+
RS256: rsa(256),
|
|
53
|
+
RS384: rsa(384),
|
|
54
|
+
RS512: rsa(512),
|
|
55
|
+
PS256: rsa(256, 32),
|
|
56
|
+
PS384: rsa(384, 48),
|
|
57
|
+
PS512: rsa(512, 64),
|
|
56
58
|
ES256: ecdsa('P-256', 256),
|
|
57
59
|
ES384: ecdsa('P-384', 384),
|
|
58
60
|
ES512: ecdsa('P-521', 512),
|
|
59
61
|
EdDSA: eddsa(),
|
|
60
62
|
Ed25519: eddsa(),
|
|
61
|
-
'ML-DSA-44': mldsa(
|
|
62
|
-
'ML-DSA-65': mldsa(
|
|
63
|
-
'ML-DSA-87': mldsa(
|
|
63
|
+
'ML-DSA-44': mldsa(44),
|
|
64
|
+
'ML-DSA-65': mldsa(65),
|
|
65
|
+
'ML-DSA-87': mldsa(87),
|
|
64
66
|
});
|
|
65
67
|
export function jwsAlgorithm(alg) {
|
|
66
68
|
const entry = JWS[alg];
|
package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_sign.js
CHANGED
|
@@ -13,6 +13,9 @@ export function unencodedPayload(protectedHeader) {
|
|
|
13
13
|
}
|
|
14
14
|
export async function createSignature(input, key) {
|
|
15
15
|
const { protectedHeader, unprotectedHeader } = input;
|
|
16
|
+
if (!protectedHeader && !unprotectedHeader) {
|
|
17
|
+
throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
|
|
18
|
+
}
|
|
16
19
|
if (!isDisjoint(protectedHeader, unprotectedHeader)) {
|
|
17
20
|
throw new JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');
|
|
18
21
|
}
|
|
@@ -20,7 +23,7 @@ export async function createSignature(input, key) {
|
|
|
20
23
|
validateCritDuplicates(JWSInvalid, protectedHeader);
|
|
21
24
|
const extensions = validateCrit(JWSInvalid, JWS_RECOGNIZED, input.crit, protectedHeader, joseHeader);
|
|
22
25
|
let b64 = true;
|
|
23
|
-
if (extensions.
|
|
26
|
+
if (extensions.includes('b64')) {
|
|
24
27
|
b64 = protectedHeader.b64;
|
|
25
28
|
if (typeof b64 !== 'boolean') {
|
|
26
29
|
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
@@ -34,11 +37,11 @@ export async function createSignature(input, key) {
|
|
|
34
37
|
let payloadS;
|
|
35
38
|
let payloadB;
|
|
36
39
|
if (b64) {
|
|
37
|
-
const encoded = (input.encoded ??=
|
|
38
|
-
encoded
|
|
39
|
-
encoded
|
|
40
|
-
payloadS = encoded
|
|
41
|
-
payloadB = encoded
|
|
40
|
+
const encoded = (input.encoded ??= []);
|
|
41
|
+
encoded[0] ??= b64u(input.payload);
|
|
42
|
+
encoded[1] ??= encode(encoded[0]);
|
|
43
|
+
payloadS = encoded[0];
|
|
44
|
+
payloadB = encoded[1];
|
|
42
45
|
}
|
|
43
46
|
else {
|
|
44
47
|
payloadB = input.payload;
|
|
@@ -64,5 +67,8 @@ export async function createSignature(input, key) {
|
|
|
64
67
|
if (protectedHeader) {
|
|
65
68
|
jws.protected = protectedHeaderString;
|
|
66
69
|
}
|
|
70
|
+
if (unprotectedHeader) {
|
|
71
|
+
jws.header = unprotectedHeader;
|
|
72
|
+
}
|
|
67
73
|
return jws;
|
|
68
74
|
}
|
package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_verify.js
CHANGED
|
@@ -7,42 +7,41 @@ import { isDisjoint } from './type_checks.js';
|
|
|
7
7
|
import { validateCrit, validateAlgorithms, JWS_RECOGNIZED } from './options.js';
|
|
8
8
|
import { prepareKey } from './key.js';
|
|
9
9
|
export function verifyResult(jws, verified) {
|
|
10
|
-
const
|
|
10
|
+
const [payload, parsedProt, , key, resolvedKey] = verified;
|
|
11
|
+
const result = { payload };
|
|
11
12
|
if (jws.protected !== undefined) {
|
|
12
|
-
result.protectedHeader =
|
|
13
|
+
result.protectedHeader = parsedProt;
|
|
13
14
|
}
|
|
14
15
|
if (jws.header !== undefined) {
|
|
15
16
|
result.unprotectedHeader = jws.header;
|
|
16
17
|
}
|
|
17
|
-
if (
|
|
18
|
-
return { ...result, key
|
|
18
|
+
if (resolvedKey) {
|
|
19
|
+
return { ...result, key };
|
|
19
20
|
}
|
|
20
21
|
return result;
|
|
21
22
|
}
|
|
22
23
|
export function prepareVerify(options) {
|
|
23
|
-
return
|
|
24
|
-
algorithms: options && validateAlgorithms('algorithms', options.algorithms),
|
|
25
|
-
crit: options?.crit,
|
|
26
|
-
};
|
|
24
|
+
return [options && validateAlgorithms('algorithms', options.algorithms), options?.crit];
|
|
27
25
|
}
|
|
28
26
|
export async function verifySignature(jws, shared, key) {
|
|
27
|
+
const { protected: encodedProtected, header, payload: inputPayload } = jws;
|
|
29
28
|
let parsedProt = {};
|
|
30
|
-
if (
|
|
31
|
-
parsedProt = parseJoseHeader(
|
|
29
|
+
if (encodedProtected) {
|
|
30
|
+
parsedProt = parseJoseHeader(encodedProtected, JWSInvalid, 'JWS Protected Header is invalid');
|
|
32
31
|
}
|
|
33
32
|
let joseHeader;
|
|
34
|
-
if (
|
|
35
|
-
if (!isDisjoint(parsedProt,
|
|
33
|
+
if (header !== undefined) {
|
|
34
|
+
if (!isDisjoint(parsedProt, header)) {
|
|
36
35
|
throw new JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');
|
|
37
36
|
}
|
|
38
|
-
joseHeader = { ...parsedProt, ...
|
|
37
|
+
joseHeader = { ...parsedProt, ...header };
|
|
39
38
|
}
|
|
40
39
|
else {
|
|
41
40
|
joseHeader = parsedProt;
|
|
42
41
|
}
|
|
43
|
-
const extensions = validateCrit(JWSInvalid, JWS_RECOGNIZED, shared
|
|
42
|
+
const extensions = validateCrit(JWSInvalid, JWS_RECOGNIZED, shared[1], parsedProt, joseHeader);
|
|
44
43
|
let b64 = true;
|
|
45
|
-
if (extensions.
|
|
44
|
+
if (extensions.includes('b64')) {
|
|
46
45
|
b64 = parsedProt.b64;
|
|
47
46
|
if (typeof b64 !== 'boolean') {
|
|
48
47
|
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
@@ -52,15 +51,15 @@ export async function verifySignature(jws, shared, key) {
|
|
|
52
51
|
if (typeof alg !== 'string' || !alg) {
|
|
53
52
|
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
54
53
|
}
|
|
55
|
-
if (shared
|
|
54
|
+
if (shared[0] && !shared[0].has(alg)) {
|
|
56
55
|
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
|
|
57
56
|
}
|
|
58
57
|
if (b64) {
|
|
59
|
-
if (typeof
|
|
58
|
+
if (typeof inputPayload !== 'string') {
|
|
60
59
|
throw new JWSInvalid('JWS Payload must be a string');
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
|
-
else if (typeof
|
|
62
|
+
else if (typeof inputPayload !== 'string' && !(inputPayload instanceof Uint8Array)) {
|
|
64
63
|
throw new JWSInvalid('JWS Payload must be a string or an Uint8Array instance');
|
|
65
64
|
}
|
|
66
65
|
let resolvedKey = false;
|
|
@@ -69,12 +68,12 @@ export async function verifySignature(jws, shared, key) {
|
|
|
69
68
|
resolvedKey = true;
|
|
70
69
|
}
|
|
71
70
|
const entry = jwsAlgorithm(alg);
|
|
72
|
-
const data = concat(
|
|
71
|
+
const data = concat(encodedProtected !== undefined ? encode(encodedProtected) : new Uint8Array(), encode('.'), typeof inputPayload === 'string'
|
|
73
72
|
? b64
|
|
74
73
|
?
|
|
75
|
-
(shared
|
|
76
|
-
: encoder.encode(
|
|
77
|
-
:
|
|
74
|
+
(shared[2] ??= encodeBase64url(inputPayload, 'payload', JWSInvalid))
|
|
75
|
+
: encoder.encode(inputPayload)
|
|
76
|
+
: inputPayload);
|
|
78
77
|
const signature = decodeBase64url(jws.signature, 'signature', JWSInvalid);
|
|
79
78
|
const k = await prepareKey(entry, key, 'verify');
|
|
80
79
|
const verified = await verify(entry, k, signature, data);
|
|
@@ -83,15 +82,15 @@ export async function verifySignature(jws, shared, key) {
|
|
|
83
82
|
}
|
|
84
83
|
let payload;
|
|
85
84
|
if (b64) {
|
|
86
|
-
payload = decodeBase64url(
|
|
85
|
+
payload = decodeBase64url(inputPayload, 'payload', JWSInvalid);
|
|
87
86
|
}
|
|
88
|
-
else if (typeof
|
|
89
|
-
payload = encoder.encode(
|
|
87
|
+
else if (typeof inputPayload === 'string') {
|
|
88
|
+
payload = encoder.encode(inputPayload);
|
|
90
89
|
}
|
|
91
90
|
else {
|
|
92
|
-
payload =
|
|
91
|
+
payload = inputPayload;
|
|
93
92
|
}
|
|
94
|
-
return
|
|
93
|
+
return [payload, parsedProt, b64, k, resolvedKey];
|
|
95
94
|
}
|
|
96
95
|
export async function verifyCompact(jws, shared, key) {
|
|
97
96
|
if (jws instanceof Uint8Array) {
|
package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwt_claims_set.js
CHANGED
|
@@ -2,56 +2,23 @@ import { JWTClaimValidationFailed, JWTExpired, JWTInvalid } from '../util/errors
|
|
|
2
2
|
import { encoder, strictDecoder } from './buffer_utils.js';
|
|
3
3
|
import { isObject } from './type_checks.js';
|
|
4
4
|
const epoch = (date) => Math.floor(date.getTime() / 1000);
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const multipliers = {
|
|
6
|
+
s: 1,
|
|
7
|
+
m: 60,
|
|
8
|
+
h: 3600,
|
|
9
|
+
d: 86400,
|
|
10
|
+
w: 604800,
|
|
11
|
+
y: 31557600,
|
|
12
|
+
};
|
|
10
13
|
const REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;
|
|
14
|
+
const checkFailed = 'check_failed';
|
|
11
15
|
export function secs(str) {
|
|
12
16
|
const matched = REGEX.exec(str);
|
|
13
17
|
if (!matched || (matched[4] && matched[1])) {
|
|
14
18
|
throw new TypeError('Invalid time period format');
|
|
15
19
|
}
|
|
16
20
|
const value = parseFloat(matched[2]);
|
|
17
|
-
const
|
|
18
|
-
let numericDate;
|
|
19
|
-
switch (unit) {
|
|
20
|
-
case 'sec':
|
|
21
|
-
case 'secs':
|
|
22
|
-
case 'second':
|
|
23
|
-
case 'seconds':
|
|
24
|
-
case 's':
|
|
25
|
-
numericDate = Math.round(value);
|
|
26
|
-
break;
|
|
27
|
-
case 'minute':
|
|
28
|
-
case 'minutes':
|
|
29
|
-
case 'min':
|
|
30
|
-
case 'mins':
|
|
31
|
-
case 'm':
|
|
32
|
-
numericDate = Math.round(value * minute);
|
|
33
|
-
break;
|
|
34
|
-
case 'hour':
|
|
35
|
-
case 'hours':
|
|
36
|
-
case 'hr':
|
|
37
|
-
case 'hrs':
|
|
38
|
-
case 'h':
|
|
39
|
-
numericDate = Math.round(value * hour);
|
|
40
|
-
break;
|
|
41
|
-
case 'day':
|
|
42
|
-
case 'days':
|
|
43
|
-
case 'd':
|
|
44
|
-
numericDate = Math.round(value * day);
|
|
45
|
-
break;
|
|
46
|
-
case 'week':
|
|
47
|
-
case 'weeks':
|
|
48
|
-
case 'w':
|
|
49
|
-
numericDate = Math.round(value * week);
|
|
50
|
-
break;
|
|
51
|
-
default:
|
|
52
|
-
numericDate = Math.round(value * year);
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
21
|
+
const numericDate = Math.round(value * multipliers[matched[3][0].toLowerCase()]);
|
|
55
22
|
if (matched[1] === '-' || matched[4] === 'ago') {
|
|
56
23
|
return -numericDate;
|
|
57
24
|
}
|
|
@@ -63,6 +30,13 @@ function validateInput(label, input) {
|
|
|
63
30
|
}
|
|
64
31
|
return input;
|
|
65
32
|
}
|
|
33
|
+
function numericDate(value, label) {
|
|
34
|
+
if (typeof value === 'number')
|
|
35
|
+
return validateInput(label, value);
|
|
36
|
+
if (value instanceof Date)
|
|
37
|
+
return validateInput(label, epoch(value));
|
|
38
|
+
return epoch(new Date()) + secs(value);
|
|
39
|
+
}
|
|
66
40
|
const normalizeTyp = (value) => {
|
|
67
41
|
if (value.includes('/')) {
|
|
68
42
|
return value.toLowerCase();
|
|
@@ -74,10 +48,22 @@ const checkAudiencePresence = (audPayload, audOption) => {
|
|
|
74
48
|
return audOption.includes(audPayload);
|
|
75
49
|
}
|
|
76
50
|
if (Array.isArray(audPayload)) {
|
|
77
|
-
return audOption.some(
|
|
51
|
+
return audOption.some((aud) => audPayload.includes(aud));
|
|
78
52
|
}
|
|
79
53
|
return false;
|
|
80
54
|
};
|
|
55
|
+
function validateNumericDate(payload, claim, required = false) {
|
|
56
|
+
const value = payload[claim];
|
|
57
|
+
if (value === undefined && !required)
|
|
58
|
+
return undefined;
|
|
59
|
+
if (typeof value !== 'number') {
|
|
60
|
+
throw new JWTClaimValidationFailed(`"${claim}" claim must be a number`, payload, claim, 'invalid');
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
function unexpectedClaim(payload, claim) {
|
|
65
|
+
throw new JWTClaimValidationFailed(`unexpected "${claim}" claim value`, payload, claim, checkFailed);
|
|
66
|
+
}
|
|
81
67
|
export function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
|
|
82
68
|
let payload;
|
|
83
69
|
try {
|
|
@@ -92,7 +78,7 @@ export function validateClaimsSet(protectedHeader, encodedPayload, options = {})
|
|
|
92
78
|
if (typ &&
|
|
93
79
|
(typeof protectedHeader.typ !== 'string' ||
|
|
94
80
|
normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) {
|
|
95
|
-
throw new JWTClaimValidationFailed('unexpected "typ" JWT header value', payload, 'typ',
|
|
81
|
+
throw new JWTClaimValidationFailed('unexpected "typ" JWT header value', payload, 'typ', checkFailed);
|
|
96
82
|
}
|
|
97
83
|
const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options;
|
|
98
84
|
const presenceCheck = [...requiredClaims];
|
|
@@ -105,65 +91,56 @@ export function validateClaimsSet(protectedHeader, encodedPayload, options = {})
|
|
|
105
91
|
if (issuer !== undefined)
|
|
106
92
|
presenceCheck.push('iss');
|
|
107
93
|
for (const claim of new Set(presenceCheck.reverse())) {
|
|
108
|
-
if (!(claim
|
|
94
|
+
if (!Object.hasOwn(payload, claim)) {
|
|
109
95
|
throw new JWTClaimValidationFailed(`missing required "${claim}" claim`, payload, claim, 'missing');
|
|
110
96
|
}
|
|
111
97
|
}
|
|
112
98
|
if (issuer !== undefined &&
|
|
113
99
|
!(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss)) {
|
|
114
|
-
|
|
100
|
+
unexpectedClaim(payload, 'iss');
|
|
115
101
|
}
|
|
116
102
|
if (subject !== undefined && payload.sub !== subject) {
|
|
117
|
-
|
|
103
|
+
unexpectedClaim(payload, 'sub');
|
|
118
104
|
}
|
|
119
105
|
if (audience !== undefined &&
|
|
120
106
|
!checkAudiencePresence(payload.aud, typeof audience === 'string' ? [audience] : audience)) {
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
break;
|
|
131
|
-
case 'undefined':
|
|
132
|
-
tolerance = 0;
|
|
133
|
-
break;
|
|
134
|
-
default:
|
|
107
|
+
unexpectedClaim(payload, 'aud');
|
|
108
|
+
}
|
|
109
|
+
const { clockTolerance } = options;
|
|
110
|
+
let tolerance = 0;
|
|
111
|
+
if (typeof clockTolerance === 'string') {
|
|
112
|
+
tolerance = secs(clockTolerance);
|
|
113
|
+
}
|
|
114
|
+
else if (clockTolerance !== undefined) {
|
|
115
|
+
if (typeof clockTolerance !== 'number') {
|
|
135
116
|
throw new TypeError('Invalid clockTolerance option type');
|
|
117
|
+
}
|
|
118
|
+
tolerance = clockTolerance;
|
|
136
119
|
}
|
|
137
120
|
validateInput('clockTolerance option', tolerance);
|
|
138
121
|
const { currentDate } = options;
|
|
139
122
|
const now = validateInput('currentDate option', epoch(currentDate || new Date()));
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
throw new JWTClaimValidationFailed('"nbf" claim must be a number', payload, 'nbf', 'invalid');
|
|
146
|
-
}
|
|
147
|
-
if (payload.nbf > now + tolerance) {
|
|
148
|
-
throw new JWTClaimValidationFailed('"nbf" claim timestamp check failed', payload, 'nbf', 'check_failed');
|
|
123
|
+
const iat = validateNumericDate(payload, 'iat', maxTokenAge !== undefined);
|
|
124
|
+
const nbf = validateNumericDate(payload, 'nbf');
|
|
125
|
+
if (nbf !== undefined) {
|
|
126
|
+
if (nbf > now + tolerance) {
|
|
127
|
+
throw new JWTClaimValidationFailed('"nbf" claim timestamp check failed', payload, 'nbf', checkFailed);
|
|
149
128
|
}
|
|
150
129
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (payload.exp <= now - tolerance) {
|
|
156
|
-
throw new JWTExpired('"exp" claim timestamp check failed', payload, 'exp', 'check_failed');
|
|
130
|
+
const exp = validateNumericDate(payload, 'exp');
|
|
131
|
+
if (exp !== undefined) {
|
|
132
|
+
if (exp <= now - tolerance) {
|
|
133
|
+
throw new JWTExpired('"exp" claim timestamp check failed', payload, 'exp', checkFailed);
|
|
157
134
|
}
|
|
158
135
|
}
|
|
159
136
|
if (maxTokenAge !== undefined) {
|
|
160
|
-
const age = now -
|
|
137
|
+
const age = now - iat;
|
|
161
138
|
const max = typeof maxTokenAge === 'number' ? maxTokenAge : secs(maxTokenAge);
|
|
162
139
|
if (age - tolerance > max) {
|
|
163
|
-
throw new JWTExpired('"iat" claim timestamp check failed (too far in the past)', payload, 'iat',
|
|
140
|
+
throw new JWTExpired('"iat" claim timestamp check failed (too far in the past)', payload, 'iat', checkFailed);
|
|
164
141
|
}
|
|
165
142
|
if (age < 0 - tolerance) {
|
|
166
|
-
throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', payload, 'iat',
|
|
143
|
+
throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', payload, 'iat', checkFailed);
|
|
167
144
|
}
|
|
168
145
|
}
|
|
169
146
|
return payload;
|
|
@@ -201,39 +178,20 @@ export class JWTClaimsBuilder {
|
|
|
201
178
|
this.#payload.jti = value;
|
|
202
179
|
}
|
|
203
180
|
set nbf(value) {
|
|
204
|
-
|
|
205
|
-
this.#payload.nbf = validateInput('setNotBefore', value);
|
|
206
|
-
}
|
|
207
|
-
else if (value instanceof Date) {
|
|
208
|
-
this.#payload.nbf = validateInput('setNotBefore', epoch(value));
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
this.#payload.nbf = epoch(new Date()) + secs(value);
|
|
212
|
-
}
|
|
181
|
+
this.#payload.nbf = numericDate(value, 'setNotBefore');
|
|
213
182
|
}
|
|
214
183
|
set exp(value) {
|
|
215
|
-
|
|
216
|
-
this.#payload.exp = validateInput('setExpirationTime', value);
|
|
217
|
-
}
|
|
218
|
-
else if (value instanceof Date) {
|
|
219
|
-
this.#payload.exp = validateInput('setExpirationTime', epoch(value));
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
this.#payload.exp = epoch(new Date()) + secs(value);
|
|
223
|
-
}
|
|
184
|
+
this.#payload.exp = numericDate(value, 'setExpirationTime');
|
|
224
185
|
}
|
|
225
186
|
set iat(value) {
|
|
226
187
|
if (value === undefined) {
|
|
227
188
|
this.#payload.iat = epoch(new Date());
|
|
228
189
|
}
|
|
229
|
-
else if (value instanceof Date) {
|
|
230
|
-
this.#payload.iat = validateInput('setIssuedAt', epoch(value));
|
|
231
|
-
}
|
|
232
190
|
else if (typeof value === 'string') {
|
|
233
191
|
this.#payload.iat = validateInput('setIssuedAt', epoch(new Date()) + secs(value));
|
|
234
192
|
}
|
|
235
193
|
else {
|
|
236
|
-
this.#payload.iat =
|
|
194
|
+
this.#payload.iat = numericDate(value, 'setIssuedAt');
|
|
237
195
|
}
|
|
238
196
|
}
|
|
239
197
|
}
|