unjwt 0.7.2 → 0.7.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/dist/_chunks/index.d.mts +12 -10
- package/dist/_chunks/jwk.mjs +27 -26
- package/dist/_chunks/jws.mjs +1 -1
- package/dist/_chunks/libs/unsecure.mjs +2 -2
- package/dist/_chunks/utils.mjs +6 -4
- package/dist/adapters/elysia/index.mjs +2 -2
- package/dist/adapters/h3v1/index.mjs +2 -2
- package/dist/adapters/h3v2/index.mjs +2 -2
- package/dist/core/utils/index.d.mts +4 -1
- package/package.json +21 -17
package/dist/_chunks/index.d.mts
CHANGED
|
@@ -241,35 +241,35 @@ interface UnwrapKeyOptions {
|
|
|
241
241
|
*/
|
|
242
242
|
interface JWKParameters<Alg extends string = string> {
|
|
243
243
|
/** JWK "kty" (Key Type) Parameter */
|
|
244
|
-
kty: string;
|
|
244
|
+
"kty": string;
|
|
245
245
|
/**
|
|
246
246
|
* JWK "alg" (Algorithm) Parameter
|
|
247
247
|
*
|
|
248
248
|
* @see {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}
|
|
249
249
|
*/
|
|
250
|
-
alg?: Alg;
|
|
250
|
+
"alg"?: Alg;
|
|
251
251
|
/** JWK "key_ops" (Key Operations) Parameter */
|
|
252
|
-
key_ops?: KeyUsage[];
|
|
252
|
+
"key_ops"?: KeyUsage[];
|
|
253
253
|
/** JWK "ext" (Extractable) Parameter */
|
|
254
|
-
ext?: boolean;
|
|
254
|
+
"ext"?: boolean;
|
|
255
255
|
/** JWK "use" (Public Key Use) Parameter */
|
|
256
|
-
use?: string;
|
|
256
|
+
"use"?: string;
|
|
257
257
|
/** JWK "x5c" (X.509 Certificate Chain) Parameter */
|
|
258
|
-
x5c?: string[];
|
|
258
|
+
"x5c"?: string[];
|
|
259
259
|
/** JWK "x5t" (X.509 Certificate SHA-1 Thumbprint) Parameter */
|
|
260
|
-
x5t?: string;
|
|
260
|
+
"x5t"?: string;
|
|
261
261
|
/** JWK "x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Parameter */
|
|
262
262
|
"x5t#S256"?: string;
|
|
263
263
|
/** JWK "x5u" (X.509 URL) Parameter */
|
|
264
|
-
x5u?: string;
|
|
264
|
+
"x5u"?: string;
|
|
265
265
|
/** JWK "kid" (Key ID) Parameter */
|
|
266
|
-
kid?: string;
|
|
266
|
+
"kid"?: string;
|
|
267
267
|
/**
|
|
268
268
|
* Non-standard JWK content encryption algorithm hint.
|
|
269
269
|
* When `alg` is `"dir"`, the library reads this field to infer the
|
|
270
270
|
* content encryption algorithm (`enc`) when it is not provided in options.
|
|
271
271
|
*/
|
|
272
|
-
enc?: ContentEncryptionAlgorithm;
|
|
272
|
+
"enc"?: ContentEncryptionAlgorithm;
|
|
273
273
|
}
|
|
274
274
|
/** Public EC JSON Web Keys */
|
|
275
275
|
interface JWK_EC_Public<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
|
|
@@ -334,6 +334,8 @@ interface JWK_OKP_Private<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {})
|
|
|
334
334
|
type JWK_OKP<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> = JWK_OKP_Public<Alg> | JWK_OKP_Private<Alg>;
|
|
335
335
|
/** oct JSON Web Keys */
|
|
336
336
|
interface JWK_oct<Alg extends JWK_HMAC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_AES_CBC_HMAC | JWK_PBES2 | "dir" | (string & {}) = string> extends JWKParameters<Alg> {
|
|
337
|
+
/** Oct JWK "kty" (Key Type) Parameter */
|
|
338
|
+
kty: "oct";
|
|
337
339
|
/** Oct JWK "k" (Key Value) Parameter */
|
|
338
340
|
k: string;
|
|
339
341
|
}
|
package/dist/_chunks/jwk.mjs
CHANGED
|
@@ -110,20 +110,20 @@ function checkUsage$4(key, usage) {
|
|
|
110
110
|
if (usage && !key.usages.includes(usage)) throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
|
|
111
111
|
}
|
|
112
112
|
const IV_BIT_LENGTHS = {
|
|
113
|
-
A128GCM: 96,
|
|
114
|
-
A128GCMKW: 96,
|
|
115
|
-
A192GCM: 96,
|
|
116
|
-
A192GCMKW: 96,
|
|
117
|
-
A256GCM: 96,
|
|
118
|
-
A256GCMKW: 96,
|
|
113
|
+
"A128GCM": 96,
|
|
114
|
+
"A128GCMKW": 96,
|
|
115
|
+
"A192GCM": 96,
|
|
116
|
+
"A192GCMKW": 96,
|
|
117
|
+
"A256GCM": 96,
|
|
118
|
+
"A256GCMKW": 96,
|
|
119
119
|
"A128CBC-HS256": 128,
|
|
120
120
|
"A192CBC-HS384": 128,
|
|
121
121
|
"A256CBC-HS512": 128
|
|
122
122
|
};
|
|
123
123
|
const CEK_BIT_LENGTHS = {
|
|
124
|
-
A128GCM: 128,
|
|
125
|
-
A192GCM: 192,
|
|
126
|
-
A256GCM: 256,
|
|
124
|
+
"A128GCM": 128,
|
|
125
|
+
"A192GCM": 192,
|
|
126
|
+
"A256GCM": 256,
|
|
127
127
|
"A128CBC-HS256": 256,
|
|
128
128
|
"A192CBC-HS384": 384,
|
|
129
129
|
"A256CBC-HS512": 512
|
|
@@ -202,7 +202,7 @@ async function aesKwUnwrap(alg, key, encryptedKey) {
|
|
|
202
202
|
return new Uint8Array(await crypto.subtle.exportKey("raw", cryptoKeyCek));
|
|
203
203
|
}
|
|
204
204
|
async function gcmkwEncrypt(alg, key, plaintext, iv) {
|
|
205
|
-
const wrapped = await encrypt(alg.slice(0, 7), plaintext, key, iv, new Uint8Array(0));
|
|
205
|
+
const wrapped = await encrypt(alg.slice(0, 7), plaintext, key, iv, /* @__PURE__ */ new Uint8Array(0));
|
|
206
206
|
return {
|
|
207
207
|
encryptedKey: wrapped.ciphertext,
|
|
208
208
|
iv: base64UrlEncode(wrapped.iv),
|
|
@@ -210,7 +210,7 @@ async function gcmkwEncrypt(alg, key, plaintext, iv) {
|
|
|
210
210
|
};
|
|
211
211
|
}
|
|
212
212
|
async function gcmkwDecrypt(alg, key, ciphertext, iv, tag) {
|
|
213
|
-
return decrypt(alg.slice(0, 7), key, ciphertext, iv, tag, new Uint8Array(0));
|
|
213
|
+
return decrypt(alg.slice(0, 7), key, ciphertext, iv, tag, /* @__PURE__ */ new Uint8Array(0));
|
|
214
214
|
}
|
|
215
215
|
async function encrypt(enc, plaintext, cek, iv, aad) {
|
|
216
216
|
if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) throw new TypeError("Key must be one of type: CryptoKey or Uint8Array");
|
|
@@ -389,7 +389,7 @@ function writeUInt32BE$1(buf, value, offset) {
|
|
|
389
389
|
function uint64be(value) {
|
|
390
390
|
const high = Math.floor(value / 2 ** 32);
|
|
391
391
|
const low = value % 2 ** 32;
|
|
392
|
-
const buf = new Uint8Array(8);
|
|
392
|
+
const buf = /* @__PURE__ */ new Uint8Array(8);
|
|
393
393
|
writeUInt32BE$1(buf, high, 0);
|
|
394
394
|
writeUInt32BE$1(buf, low, 4);
|
|
395
395
|
return buf;
|
|
@@ -539,7 +539,7 @@ function getHashLength(hash) {
|
|
|
539
539
|
function checkUsage$2(key, usage) {
|
|
540
540
|
if (usage && !key.usages.includes(usage)) throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
|
|
541
541
|
}
|
|
542
|
-
async function deriveECDHESKey(publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
|
|
542
|
+
async function deriveECDHESKey(publicKey, privateKey, algorithm, keyLength, apu = /* @__PURE__ */ new Uint8Array(0), apv = /* @__PURE__ */ new Uint8Array(0)) {
|
|
543
543
|
checkECDHCryptoKey(publicKey, "ECDH");
|
|
544
544
|
checkECDHCryptoKey(privateKey, "ECDH", "deriveBits");
|
|
545
545
|
const value = concatUint8Arrays(lengthAndInput(textEncoder.encode(algorithm)), lengthAndInput(apu), lengthAndInput(apv), uint32be(keyLength));
|
|
@@ -599,7 +599,7 @@ function writeUInt32BE(buf, value, offset) {
|
|
|
599
599
|
], offset);
|
|
600
600
|
}
|
|
601
601
|
function uint32be(value) {
|
|
602
|
-
const buf = new Uint8Array(4);
|
|
602
|
+
const buf = /* @__PURE__ */ new Uint8Array(4);
|
|
603
603
|
writeUInt32BE(buf, value, 0);
|
|
604
604
|
return buf;
|
|
605
605
|
}
|
|
@@ -652,7 +652,7 @@ async function getPBKDF2CryptoKey(key, alg, options = {}) {
|
|
|
652
652
|
checkPBES2CryptoKey(key, alg, usage);
|
|
653
653
|
return key;
|
|
654
654
|
}
|
|
655
|
-
const PUBLIC_EPK_FIELDS = new Set([
|
|
655
|
+
const PUBLIC_EPK_FIELDS = /* @__PURE__ */ new Set([
|
|
656
656
|
"kty",
|
|
657
657
|
"crv",
|
|
658
658
|
"x",
|
|
@@ -823,7 +823,7 @@ const assertPEMLabel = (pem, descriptor) => {
|
|
|
823
823
|
}
|
|
824
824
|
};
|
|
825
825
|
const genericExport = async (keyType, keyFormat, key) => {
|
|
826
|
-
if (!isCryptoKey(key)) throw new TypeError(`Key must be
|
|
826
|
+
if (!isCryptoKey(key)) throw new TypeError(`Key must be of type CryptoKey, got ${typeof key}`);
|
|
827
827
|
if (!key.extractable) throw new TypeError("CryptoKey is not extractable");
|
|
828
828
|
if (key.type !== keyType) throw new TypeError(`key is not a ${keyType} key`);
|
|
829
829
|
return formatPEM(base64Encode(new Uint8Array(await crypto.subtle.exportKey(keyFormat, key))), `${keyType.toUpperCase()} KEY`);
|
|
@@ -1017,7 +1017,8 @@ const getSPKI = (x509) => {
|
|
|
1017
1017
|
type: "spki"
|
|
1018
1018
|
});
|
|
1019
1019
|
} catch {}
|
|
1020
|
-
|
|
1020
|
+
const raw = base64Decode(x509.replace(/(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g, ""), { returnAs: "uint8array" });
|
|
1021
|
+
return formatPEM(spkiFromX509(raw), "PUBLIC KEY");
|
|
1021
1022
|
};
|
|
1022
1023
|
async function generateKey(alg, options = {}) {
|
|
1023
1024
|
const exportToJWK = options.toJWK !== void 0 && options.toJWK !== false;
|
|
@@ -1201,7 +1202,7 @@ async function wrapKey(alg, keyToWrap, wrappingKey, options = {}) {
|
|
|
1201
1202
|
const cekBytes = keyToWrap instanceof Uint8Array ? keyToWrap : new Uint8Array(await crypto.subtle.exportKey("raw", keyToWrap));
|
|
1202
1203
|
const importedWrappingKey = await resolveWrappingKey(alg, wrappingKey, "public");
|
|
1203
1204
|
switch (alg) {
|
|
1204
|
-
case "dir": return { encryptedKey: new Uint8Array(0) };
|
|
1205
|
+
case "dir": return { encryptedKey: /* @__PURE__ */ new Uint8Array(0) };
|
|
1205
1206
|
case "A128KW":
|
|
1206
1207
|
case "A192KW":
|
|
1207
1208
|
case "A256KW": return { encryptedKey: await aesKwWrap(alg, importedWrappingKey, cekBytes) };
|
|
@@ -1232,8 +1233,8 @@ async function wrapKey(alg, keyToWrap, wrappingKey, options = {}) {
|
|
|
1232
1233
|
case "ECDH-ES+A256KW": {
|
|
1233
1234
|
if (!(importedWrappingKey instanceof CryptoKey)) throw new TypeError("ECDH-ES requires the wrapping key to be a CryptoKey (recipient's public key)");
|
|
1234
1235
|
if (!isECDHKeyAllowed(importedWrappingKey)) throw new JWTError("ECDH with the provided key is not allowed or not supported", "ERR_JWK_INVALID");
|
|
1235
|
-
const apu = options.ecdh?.partyUInfo ?? new Uint8Array(0);
|
|
1236
|
-
const apv = options.ecdh?.partyVInfo ?? new Uint8Array(0);
|
|
1236
|
+
const apu = options.ecdh?.partyUInfo ?? /* @__PURE__ */ new Uint8Array(0);
|
|
1237
|
+
const apv = options.ecdh?.partyVInfo ?? /* @__PURE__ */ new Uint8Array(0);
|
|
1237
1238
|
const { ephemeralPrivateKey, epkJwk } = await resolveECDHEphemeralPair(importedWrappingKey, options.ecdh?.ephemeralKey);
|
|
1238
1239
|
const infoAlg = alg === "ECDH-ES" ? (() => {
|
|
1239
1240
|
if (!options.ecdh?.enc) throw new JWTError("ECDH-ES direct key agreement requires options.ecdh.enc (the target content encryption algorithm)", "ERR_JWK_INVALID");
|
|
@@ -1241,7 +1242,7 @@ async function wrapKey(alg, keyToWrap, wrappingKey, options = {}) {
|
|
|
1241
1242
|
})() : alg;
|
|
1242
1243
|
const sharedSecret = await deriveECDHESKey(importedWrappingKey, ephemeralPrivateKey, infoAlg, alg === "ECDH-ES" ? bitLengthCEK(infoAlg) : Number.parseInt(alg.slice(-5, -2), 10), apu, apv);
|
|
1243
1244
|
const wrapResult = {
|
|
1244
|
-
encryptedKey: new Uint8Array(0),
|
|
1245
|
+
encryptedKey: /* @__PURE__ */ new Uint8Array(0),
|
|
1245
1246
|
epk: epkJwk
|
|
1246
1247
|
};
|
|
1247
1248
|
if (apu.length > 0) wrapResult.apu = base64UrlEncode(apu);
|
|
@@ -1306,8 +1307,8 @@ async function unwrapKey(alg, wrappedKey, unwrappingKey, options = {}) {
|
|
|
1306
1307
|
if (!isECDHKeyAllowed(importedUnwrappingKey)) throw new JWTError("ECDH with the provided key is not allowed or not supported", "ERR_JWK_INVALID");
|
|
1307
1308
|
const epkCandidate = options.epk instanceof CryptoKey ? options.epk : await normalizeKey(options.epk, alg);
|
|
1308
1309
|
if (!(epkCandidate instanceof CryptoKey)) throw new JWTError("Failed to normalize ECDH ephemeral public key", "ERR_JWK_INVALID");
|
|
1309
|
-
const apuBytes = typeof options.apu === "string" ? base64UrlDecode(options.apu, { returnAs: "uint8array" }) : options.apu ?? new Uint8Array(0);
|
|
1310
|
-
const apvBytes = typeof options.apv === "string" ? base64UrlDecode(options.apv, { returnAs: "uint8array" }) : options.apv ?? new Uint8Array(0);
|
|
1310
|
+
const apuBytes = typeof options.apu === "string" ? base64UrlDecode(options.apu, { returnAs: "uint8array" }) : options.apu ?? /* @__PURE__ */ new Uint8Array(0);
|
|
1311
|
+
const apvBytes = typeof options.apv === "string" ? base64UrlDecode(options.apv, { returnAs: "uint8array" }) : options.apv ?? /* @__PURE__ */ new Uint8Array(0);
|
|
1311
1312
|
const infoAlg = alg === "ECDH-ES" ? options.enc : alg;
|
|
1312
1313
|
if (!infoAlg) throw new JWTError("ECDH-ES requires content encryption algorithm ('enc') to derive the shared secret", "ERR_JWE_INVALID");
|
|
1313
1314
|
const sharedSecret = await deriveECDHESKey(epkCandidate, importedUnwrappingKey, infoAlg, alg === "ECDH-ES" ? bitLengthCEK(infoAlg) : Number.parseInt(alg.slice(-5, -2), 10), apuBytes, apvBytes);
|
|
@@ -1339,7 +1340,7 @@ async function importPEM(pem, alg, options) {
|
|
|
1339
1340
|
case "x509":
|
|
1340
1341
|
cryptoKey = await fromX509(pem, alg, { extractable });
|
|
1341
1342
|
break;
|
|
1342
|
-
default: throw new JWTError(`Unsupported PEM type: ${pemType}`, "ERR_JWK_UNSUPPORTED");
|
|
1343
|
+
default: throw new JWTError(`Unsupported PEM type: ${String(pemType)}`, "ERR_JWK_UNSUPPORTED");
|
|
1343
1344
|
}
|
|
1344
1345
|
return {
|
|
1345
1346
|
...await exportKey(cryptoKey, options?.jwkParams),
|
|
@@ -1373,7 +1374,7 @@ async function exportPEM(jwk, options) {
|
|
|
1373
1374
|
case "spki":
|
|
1374
1375
|
if (cryptoKey.type !== "public") throw new JWTError(`Only 'public' type CryptoKeys can be exported to SPKI PEM format. Key type is '${cryptoKey.type}'.`, "ERR_JWK_INVALID");
|
|
1375
1376
|
return toSPKI(cryptoKey);
|
|
1376
|
-
default: throw new JWTError(`Unsupported PEM format: ${pemFormat}`, "ERR_JWK_UNSUPPORTED");
|
|
1377
|
+
default: throw new JWTError(`Unsupported PEM format: ${String(pemFormat)}`, "ERR_JWK_UNSUPPORTED");
|
|
1377
1378
|
}
|
|
1378
1379
|
}
|
|
1379
1380
|
async function exportToPEM(jwk, pemFormat, algForCryptoKeyImport) {
|
|
@@ -1401,7 +1402,7 @@ async function deriveSharedSecret(publicKey, privateKey, alg, options) {
|
|
|
1401
1402
|
else if (alg === "ECDH-ES") throw new JWTError("deriveSharedSecret with alg \"ECDH-ES\" requires an explicit keyLength in options", "ERR_JWK_INVALID");
|
|
1402
1403
|
else if (alg.startsWith("ECDH-ES+")) keyLength = Number.parseInt(alg.slice(-5, -2), 10);
|
|
1403
1404
|
else keyLength = bitLengthCEK(alg);
|
|
1404
|
-
return deriveECDHESKey(pubCryptoKey, privCryptoKey, alg, keyLength, options?.partyUInfo ?? new Uint8Array(0), options?.partyVInfo ?? new Uint8Array(0));
|
|
1405
|
+
return deriveECDHESKey(pubCryptoKey, privCryptoKey, alg, keyLength, options?.partyUInfo ?? /* @__PURE__ */ new Uint8Array(0), options?.partyVInfo ?? /* @__PURE__ */ new Uint8Array(0));
|
|
1405
1406
|
}
|
|
1406
1407
|
function getJWKFromSet(jwkSet, kidOrProtectedHeader) {
|
|
1407
1408
|
if (!jwkSet || !isJWKSet(jwkSet)) throw new JWTError("Invalid JWK Set provided", "ERR_JWK_INVALID");
|
package/dist/_chunks/jws.mjs
CHANGED
|
@@ -327,7 +327,7 @@ async function verify(jws, key, options = {}) {
|
|
|
327
327
|
try {
|
|
328
328
|
payload = decodeJWSPayload(payloadEncoded, useB64, options.forceUint8Array);
|
|
329
329
|
} catch (error_) {
|
|
330
|
-
throw new JWTError(`Invalid JWS: Payload decoding failed (${error_ instanceof Error ? error_.message : error_})`, "ERR_JWS_INVALID");
|
|
330
|
+
throw new JWTError(`Invalid JWS: Payload decoding failed (${error_ instanceof Error ? error_.message : String(error_)})`, "ERR_JWS_INVALID");
|
|
331
331
|
}
|
|
332
332
|
validateCriticalHeadersJWS(protectedHeader, options.recognizedHeaders);
|
|
333
333
|
validateJwtClaimsIfJsonPayload(payload, options);
|
|
@@ -106,7 +106,7 @@ function base64Decode(data, options) {
|
|
|
106
106
|
const isBufferInput = data instanceof Uint8Array;
|
|
107
107
|
const str = isBufferInput ? textDecoder.decode(data) : data;
|
|
108
108
|
const decodeToString = (options?.returnAs ?? (isBufferInput ? "uint8array" : "string")) === "string";
|
|
109
|
-
if (!str) return decodeToString ? "" : new Uint8Array(0);
|
|
109
|
+
if (!str) return decodeToString ? "" : /* @__PURE__ */ new Uint8Array(0);
|
|
110
110
|
if (_hasBuffer) {
|
|
111
111
|
const buf = _Buffer.from(str, "base64");
|
|
112
112
|
return decodeToString ? buf.toString("utf8") : new Uint8Array(buf);
|
|
@@ -119,7 +119,7 @@ function base64UrlDecode(data, options) {
|
|
|
119
119
|
const isBufferInput = data instanceof Uint8Array;
|
|
120
120
|
let str = isBufferInput ? textDecoder.decode(data) : data;
|
|
121
121
|
const decodeToString = (options?.returnAs ?? (isBufferInput ? "uint8array" : "string")) === "string";
|
|
122
|
-
if (!str) return decodeToString ? "" : new Uint8Array(0);
|
|
122
|
+
if (!str) return decodeToString ? "" : /* @__PURE__ */ new Uint8Array(0);
|
|
123
123
|
if (_hasBuffer) {
|
|
124
124
|
const buf = _Buffer.from(str, "base64url");
|
|
125
125
|
return decodeToString ? buf.toString("utf8") : new Uint8Array(buf);
|
package/dist/_chunks/utils.mjs
CHANGED
|
@@ -209,7 +209,9 @@ function _parseDurationSeconds(value) {
|
|
|
209
209
|
if (typeof value === "string") {
|
|
210
210
|
const match = value.match(DURATION_REGEX);
|
|
211
211
|
if (!match || !match[1]) throw new TypeError("Invalid duration format. Must be an integer or a string like '10m', '2h', '7D', etc.");
|
|
212
|
-
|
|
212
|
+
const n = Number.parseInt(match[1], 10);
|
|
213
|
+
const unit = match[2] || "s";
|
|
214
|
+
return n * TIME_CONSTANTS[unit];
|
|
213
215
|
}
|
|
214
216
|
throw new TypeError("Duration must be a number or a string representing time.");
|
|
215
217
|
}
|
|
@@ -317,7 +319,7 @@ const BASE_PROCESSED_JWE = [
|
|
|
317
319
|
function validateCriticalHeadersJWS(protectedHeader, recognizedHeaders = []) {
|
|
318
320
|
if (!protectedHeader.crit) return;
|
|
319
321
|
const missingHeaderParams = /* @__PURE__ */ new Set();
|
|
320
|
-
const recognizedParams = new Set([...recognizedHeaders, ...BASE_PROCESSED_JWS]);
|
|
322
|
+
const recognizedParams = /* @__PURE__ */ new Set([...recognizedHeaders, ...BASE_PROCESSED_JWS]);
|
|
321
323
|
for (const param of protectedHeader.crit) {
|
|
322
324
|
if (recognizedParams.has(param) && (param in protectedHeader || param === "b64")) continue;
|
|
323
325
|
missingHeaderParams.add(param);
|
|
@@ -326,7 +328,7 @@ function validateCriticalHeadersJWS(protectedHeader, recognizedHeaders = []) {
|
|
|
326
328
|
}
|
|
327
329
|
function validateCriticalHeadersJWE(protectedHeader, recognizedHeaders) {
|
|
328
330
|
if (!protectedHeader.crit) return;
|
|
329
|
-
const understoodParams = new Set([...recognizedHeaders || [], ...BASE_PROCESSED_JWE]);
|
|
331
|
+
const understoodParams = /* @__PURE__ */ new Set([...recognizedHeaders || [], ...BASE_PROCESSED_JWE]);
|
|
330
332
|
for (const critParam of protectedHeader.crit) {
|
|
331
333
|
if (!Object.prototype.hasOwnProperty.call(protectedHeader, critParam)) throw new JWTError(`Critical header parameter "${critParam}" listed in "crit" but not present in the protected header.`, "ERR_JWE_INVALID");
|
|
332
334
|
if (!understoodParams.has(critParam)) throw new JWTError(`Unprocessed critical header parameters: ${critParam}`, "ERR_JWE_INVALID");
|
|
@@ -346,7 +348,7 @@ function maybeArray(item) {
|
|
|
346
348
|
return Array.isArray(item) ? item : [item];
|
|
347
349
|
}
|
|
348
350
|
function isJWK(key) {
|
|
349
|
-
return typeof key === "object" && key !== null && "kty"
|
|
351
|
+
return typeof key === "object" && key !== null && (key.kty === "oct" || key.kty === "RSA" || key.kty === "EC" || key.kty === "OKP");
|
|
350
352
|
}
|
|
351
353
|
function isJWKSet(key) {
|
|
352
354
|
return key && typeof key === "object" && "keys" in key && Array.isArray(key.keys);
|
|
@@ -268,7 +268,7 @@ async function verifySession(context, config, token) {
|
|
|
268
268
|
config
|
|
269
269
|
}) : getVerifyKey(config.key), {
|
|
270
270
|
...config.jws?.verifyOptions,
|
|
271
|
-
requiredClaims: [
|
|
271
|
+
requiredClaims: [.../* @__PURE__ */ new Set([
|
|
272
272
|
...config.jws?.verifyOptions?.requiredClaims || [],
|
|
273
273
|
"jti",
|
|
274
274
|
"iat"
|
|
@@ -534,7 +534,7 @@ async function unsealSession(context, config, sealed) {
|
|
|
534
534
|
const enc = config.jwe?.encryptOptions?.enc;
|
|
535
535
|
const { payload } = await decrypt(sealed, key, {
|
|
536
536
|
...config.jwe?.decryptOptions,
|
|
537
|
-
requiredClaims: [
|
|
537
|
+
requiredClaims: [.../* @__PURE__ */ new Set([
|
|
538
538
|
...config.jwe?.decryptOptions?.requiredClaims || [],
|
|
539
539
|
"jti",
|
|
540
540
|
"iat"
|
|
@@ -256,7 +256,7 @@ async function unsealJWESession(event, config, sealed) {
|
|
|
256
256
|
if (config.jwe?.encryptOptions?.protectedHeader?.typ && typeof config.jwe.encryptOptions.protectedHeader.typ === "string" && config.jwe.encryptOptions.protectedHeader.typ.toLowerCase().includes("jwt")) typ = config.jwe.encryptOptions.protectedHeader.typ;
|
|
257
257
|
const { payload } = await decrypt(sealed, key, {
|
|
258
258
|
...config.jwe?.decryptOptions,
|
|
259
|
-
requiredClaims: [
|
|
259
|
+
requiredClaims: [.../* @__PURE__ */ new Set([
|
|
260
260
|
...config.jwe?.decryptOptions?.requiredClaims || [],
|
|
261
261
|
"jti",
|
|
262
262
|
"iat"
|
|
@@ -579,7 +579,7 @@ async function verifyJWSSession(event, config, token) {
|
|
|
579
579
|
if (config.jws?.signOptions?.protectedHeader?.typ && typeof config.jws.signOptions.protectedHeader.typ === "string" && config.jws.signOptions.protectedHeader.typ.toLowerCase().includes("jwt")) typ = config.jws.signOptions.protectedHeader.typ;
|
|
580
580
|
const { payload } = await verify(token, jwk, {
|
|
581
581
|
...config.jws?.verifyOptions,
|
|
582
|
-
requiredClaims: [
|
|
582
|
+
requiredClaims: [.../* @__PURE__ */ new Set([
|
|
583
583
|
...config.jws?.verifyOptions?.requiredClaims || [],
|
|
584
584
|
"jti",
|
|
585
585
|
"iat"
|
|
@@ -241,7 +241,7 @@ async function unsealJWESession(event, config, sealed) {
|
|
|
241
241
|
if (config.jwe?.encryptOptions?.protectedHeader?.typ && typeof config.jwe.encryptOptions.protectedHeader.typ === "string" && config.jwe.encryptOptions.protectedHeader.typ.toLowerCase().includes("jwt")) typ = config.jwe.encryptOptions.protectedHeader.typ;
|
|
242
242
|
const { payload } = await decrypt(sealed, key, {
|
|
243
243
|
...config.jwe?.decryptOptions,
|
|
244
|
-
requiredClaims: [
|
|
244
|
+
requiredClaims: [.../* @__PURE__ */ new Set([
|
|
245
245
|
...config.jwe?.decryptOptions?.requiredClaims || [],
|
|
246
246
|
"jti",
|
|
247
247
|
"iat"
|
|
@@ -556,7 +556,7 @@ async function verifyJWSSession(event, config, token) {
|
|
|
556
556
|
if (config.jws?.signOptions?.protectedHeader?.typ && typeof config.jws.signOptions.protectedHeader.typ === "string" && config.jws.signOptions.protectedHeader.typ.toLowerCase().includes("jwt")) typ = config.jws.signOptions.protectedHeader.typ;
|
|
557
557
|
const { payload } = await verify(token, jwk, {
|
|
558
558
|
...config.jws?.verifyOptions,
|
|
559
|
-
requiredClaims: [
|
|
559
|
+
requiredClaims: [.../* @__PURE__ */ new Set([
|
|
560
560
|
...config.jws?.verifyOptions?.requiredClaims || [],
|
|
561
561
|
"jti",
|
|
562
562
|
"iat"
|
|
@@ -93,7 +93,10 @@ declare function validateCriticalHeadersJWE(protectedHeader: {
|
|
|
93
93
|
declare function concatUint8Arrays(...arrays: Readonly<Uint8Array<ArrayBuffer>[]>): Uint8Array<ArrayBuffer>;
|
|
94
94
|
/** Wrap a value in an array; returns the array unchanged if already an array. */
|
|
95
95
|
declare function maybeArray<T>(item: T | T[]): T[];
|
|
96
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Type guard for {@link JWK} — an object whose `kty` this library models
|
|
98
|
+
* (`"oct"`/`"RSA"`/`"EC"`/`"OKP"`).
|
|
99
|
+
*/
|
|
97
100
|
declare function isJWK(key: any): key is JWK;
|
|
98
101
|
/** Type guard for {@link JWKSet} — checks for an object with a `keys` array. */
|
|
99
102
|
declare function isJWKSet(key: any): key is JWKSet;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unjwt",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "Low-level JWT utilities",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -61,25 +61,24 @@
|
|
|
61
61
|
"@types/node": "^25",
|
|
62
62
|
"@types/supertest": "^7.2.0",
|
|
63
63
|
"@typescript/native-preview": "7.0.0-dev.20260611.2",
|
|
64
|
-
"@vitest/coverage-v8": "^4.1.
|
|
64
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
65
65
|
"automd": "^0.4.3",
|
|
66
|
-
"changelogen": "^0.6.2",
|
|
67
66
|
"cookie-esv1": "npm:cookie-es@^1.2.3",
|
|
68
67
|
"cookie-esv3": "npm:cookie-es@^3.1.1",
|
|
69
|
-
"elysia": "^1.4.
|
|
68
|
+
"elysia": "^1.4.29",
|
|
70
69
|
"h3v1": "npm:h3@^1.15.11",
|
|
71
70
|
"h3v2": "npm:h3@^2.0.1-rc.22",
|
|
72
71
|
"jose": "^6.2.3",
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"oxlint": "^
|
|
77
|
-
"rolldown": "1.1.
|
|
72
|
+
"obuild": "^0.4.37",
|
|
73
|
+
"oxfmt": "^0.57.0",
|
|
74
|
+
"oxlint": "^1.72.0",
|
|
75
|
+
"oxlint-tsgolint": "^0.24.0",
|
|
76
|
+
"rolldown": "1.1.4",
|
|
78
77
|
"simple-git-hooks": "^2.13.1",
|
|
79
78
|
"supertest": "^7.2.2",
|
|
80
79
|
"typescript": "^6.0.3",
|
|
81
80
|
"unsecure": "^0.2.2",
|
|
82
|
-
"vitest": "^4.1.
|
|
81
|
+
"vitest": "^4.1.9"
|
|
83
82
|
},
|
|
84
83
|
"peerDependencies": {
|
|
85
84
|
"cookie-es": "^1.2.3 || ^3.1.1",
|
|
@@ -105,12 +104,19 @@
|
|
|
105
104
|
"unjwt": "link:."
|
|
106
105
|
},
|
|
107
106
|
"simple-git-hooks": {
|
|
108
|
-
"pre-commit": "
|
|
107
|
+
"pre-commit": "pnpm build --stub && pnpm lint && pnpm typecheck"
|
|
109
108
|
},
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
|
|
109
|
+
"devEngines": {
|
|
110
|
+
"packageManager": {
|
|
111
|
+
"name": "pnpm",
|
|
112
|
+
"version": "11.9.0",
|
|
113
|
+
"onFail": "download"
|
|
114
|
+
},
|
|
115
|
+
"runtime": {
|
|
116
|
+
"name": "node",
|
|
117
|
+
"version": ">=24.17",
|
|
118
|
+
"onFail": "error"
|
|
119
|
+
}
|
|
114
120
|
},
|
|
115
121
|
"scripts": {
|
|
116
122
|
"build": "obuild",
|
|
@@ -118,8 +124,6 @@
|
|
|
118
124
|
"dev:prepare": "obuild --stub && pnpm simple-git-hooks",
|
|
119
125
|
"lint": "oxlint . && oxfmt --check .",
|
|
120
126
|
"fmt": "automd && oxlint --fix . && oxfmt .",
|
|
121
|
-
"release": "pnpm test && pnpm prepack && changelogen --release --push",
|
|
122
|
-
"stub": "obuild --stub",
|
|
123
127
|
"test": "vitest run --slowTestThreshold=1000",
|
|
124
128
|
"test:coverage": "vitest run --coverage --slowTestThreshold=1000",
|
|
125
129
|
"typecheck": "tsgo --noEmit",
|