unjwt 0.8.1 → 0.8.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 +4 -4
- package/dist/THIRD-PARTY-LICENSES.md.gz +0 -0
- package/dist/_chunks/_codec-jwe.d.mts +101 -22
- package/dist/_chunks/_codec-jws.mjs +306 -232
- package/dist/_chunks/_cookie-attributes.d.mts +12 -0
- package/dist/_chunks/_jwt-internal.mjs +9 -6
- package/dist/_chunks/digest.d.mts +8 -0
- package/dist/_chunks/{algorithms.mjs → digest.mjs} +78 -8
- package/dist/_chunks/index.d.mts +313 -268
- package/dist/_chunks/index2.d.mts +2 -1
- package/dist/_chunks/index3.d.mts +1 -0
- package/dist/_chunks/jwe.d.mts +4 -4
- package/dist/_chunks/jwe.mjs +21 -3
- package/dist/_chunks/jwk.mjs +219 -173
- package/dist/_chunks/jws.d.mts +10 -10
- package/dist/_chunks/jws.mjs +18 -6
- package/dist/_chunks/jwt.d.mts +2 -1
- package/dist/_chunks/libs/cookie-es.mjs +255 -0
- package/dist/adapters/elysia/index.d.mts +32 -15
- package/dist/adapters/elysia/index.mjs +46 -67
- package/dist/adapters/h3/index.d.mts +135 -0
- package/dist/adapters/h3/index.mjs +119 -0
- package/dist/adapters/h3v1/index.d.mts +100 -27
- package/dist/adapters/h3v1/index.mjs +59 -76
- package/dist/core/jwe.d.mts +2 -2
- package/dist/core/jwk.d.mts +22 -14
- package/dist/core/jwk.mjs +2 -2
- package/dist/core/jws.d.mts +2 -2
- package/dist/core/utils/index.d.mts +2 -1
- package/dist/core/utils/index.mjs +2 -2
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +3 -3
- package/dist/session/index.d.mts +44 -0
- package/dist/session/index.mjs +113 -0
- package/package.json +37 -18
- package/dist/adapters/h3v2/index.d.mts +0 -65
- package/dist/adapters/h3v2/index.mjs +0 -139
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** The `Set-Cookie` attributes of a session cookie (RFC 6265, RFC 6265bis, CHIPS). */
|
|
2
|
+
export interface CookieAttributes {
|
|
3
|
+
domain?: string;
|
|
4
|
+
expires?: Date;
|
|
5
|
+
httpOnly?: boolean;
|
|
6
|
+
maxAge?: number;
|
|
7
|
+
path?: string;
|
|
8
|
+
priority?: "low" | "medium" | "high";
|
|
9
|
+
sameSite?: boolean | "lax" | "strict" | "none";
|
|
10
|
+
secure?: boolean;
|
|
11
|
+
partitioned?: boolean;
|
|
12
|
+
}
|
|
@@ -283,29 +283,32 @@ function getPlaintextBytes(payload) {
|
|
|
283
283
|
throw new JWTError("Plaintext must be a string, Uint8Array, or a JSON-serializable object.", "ERR_INVALID_OPTION");
|
|
284
284
|
}
|
|
285
285
|
function computeJwtTimeClaims(payload, options) {
|
|
286
|
-
const { currentDate, expiresIn, expiresAt, notBeforeIn, notBeforeAt } = options ?? {};
|
|
286
|
+
const { currentDate, issuedAt, expiresIn, expiresAt, notBeforeIn, notBeforeAt } = options ?? {};
|
|
287
|
+
if (issuedAt !== void 0 && typeof issuedAt !== "boolean" && !(issuedAt instanceof Date)) throw new JWTError("\"issuedAt\" must be a boolean or a Date.", "ERR_INVALID_OPTION");
|
|
287
288
|
if (expiresIn !== void 0 && expiresAt !== void 0) throw new JWTError("\"expiresIn\" and \"expiresAt\" are mutually exclusive; pass only one.", "ERR_JWT_CLAIM_INVALID");
|
|
288
289
|
if (notBeforeIn !== void 0 && notBeforeAt !== void 0) throw new JWTError("\"notBeforeIn\" and \"notBeforeAt\" are mutually exclusive; pass only one.", "ERR_JWT_CLAIM_INVALID");
|
|
289
290
|
const hasExpHint = expiresIn !== void 0 || expiresAt !== void 0;
|
|
290
291
|
const hasNbfHint = notBeforeIn !== void 0 || notBeforeAt !== void 0;
|
|
291
|
-
|
|
292
|
+
const hasIatHint = issuedAt === true || issuedAt instanceof Date;
|
|
293
|
+
if (!hasExpHint && !hasNbfHint && !hasIatHint) return void 0;
|
|
292
294
|
if (!payload || typeof payload !== "object" || payload instanceof Uint8Array) return void 0;
|
|
293
295
|
const wantsExp = hasExpHint && (!("exp" in payload) || payload.exp === void 0);
|
|
294
296
|
const wantsNbf = hasNbfHint && (!("nbf" in payload) || payload.nbf === void 0);
|
|
295
|
-
|
|
297
|
+
const wantsIat = hasIatHint && (!("iat" in payload) || payload.iat === void 0);
|
|
298
|
+
if (!wantsExp && !wantsNbf && !wantsIat) return void 0;
|
|
296
299
|
const now = Math.round((currentDate ?? /* @__PURE__ */ new Date()).getTime() / 1e3);
|
|
297
300
|
const claims = { ...payload };
|
|
298
|
-
claims.iat ||= now;
|
|
301
|
+
claims.iat ||= issuedAt instanceof Date ? Math.floor(_instantOf(issuedAt, "issuedAt") / 1e3) : now;
|
|
299
302
|
if (wantsExp) {
|
|
300
303
|
if (expiresAt !== void 0) claims.exp = Math.floor(_instantOf(expiresAt, "expiresAt") / 1e3);
|
|
301
|
-
else if (expiresIn !== void 0) claims.exp =
|
|
304
|
+
else if (expiresIn !== void 0) claims.exp = now + computeDurationInSeconds(expiresIn);
|
|
302
305
|
}
|
|
303
306
|
if (wantsNbf) {
|
|
304
307
|
if (notBeforeAt !== void 0) claims.nbf = Math.floor(_instantOf(notBeforeAt, "notBeforeAt") / 1e3);
|
|
305
308
|
else if (notBeforeIn !== void 0) {
|
|
306
309
|
const offset = parseDurationSeconds(notBeforeIn);
|
|
307
310
|
if (offset < 0) throw new JWTError("\"notBeforeIn\" must be zero or a positive duration.", "ERR_JWT_CLAIM_INVALID");
|
|
308
|
-
claims.nbf =
|
|
311
|
+
claims.nbf = now + offset;
|
|
309
312
|
}
|
|
310
313
|
}
|
|
311
314
|
return claims;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Hash functions the JOSE specs name for digests carried in tokens. */
|
|
2
|
+
export type DigestHash = "SHA-256" | "SHA-384" | "SHA-512";
|
|
3
|
+
/**
|
|
4
|
+
* The base64url digest of text or bytes, SHA-256 unless `hash` says otherwise: a DPoP `ath`
|
|
5
|
+
* (RFC 9449 §4.2) over the access token, an `x5t#S256` over a certificate, the last step of a
|
|
6
|
+
* JWK thumbprint. Text is digested as UTF-8.
|
|
7
|
+
*/
|
|
8
|
+
export declare function digestUrl(data: string | Uint8Array<ArrayBuffer>, hash?: DigestHash): Promise<string>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { textEncoder } from "./libs/unsecure.mjs";
|
|
2
|
+
import { JWTError, base64UrlStringify, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet } from "./_jwt-internal.mjs";
|
|
2
3
|
const ECDSA_CURVES = /* @__PURE__ */ Object.freeze({
|
|
3
4
|
ES256: "P-256",
|
|
4
5
|
ES384: "P-384",
|
|
@@ -7,8 +8,26 @@ const ECDSA_CURVES = /* @__PURE__ */ Object.freeze({
|
|
|
7
8
|
function jwsHashOf(alg) {
|
|
8
9
|
return `SHA-${alg.slice(-3)}`;
|
|
9
10
|
}
|
|
11
|
+
const RSA_OAEP_HASH = /* @__PURE__ */ Object.freeze({
|
|
12
|
+
"RSA-OAEP": "SHA-1",
|
|
13
|
+
"RSA-OAEP-256": "SHA-256",
|
|
14
|
+
"RSA-OAEP-384": "SHA-384",
|
|
15
|
+
"RSA-OAEP-512": "SHA-512"
|
|
16
|
+
});
|
|
10
17
|
function rsaOaepHashOf(alg) {
|
|
11
|
-
return
|
|
18
|
+
return RSA_OAEP_HASH[alg];
|
|
19
|
+
}
|
|
20
|
+
function pbes2HashOf(alg) {
|
|
21
|
+
return `SHA-${alg.slice(8, 11)}`;
|
|
22
|
+
}
|
|
23
|
+
const SHA_BITS = /* @__PURE__ */ Object.freeze({
|
|
24
|
+
"SHA-1": 1,
|
|
25
|
+
"SHA-256": 256,
|
|
26
|
+
"SHA-384": 384,
|
|
27
|
+
"SHA-512": 512
|
|
28
|
+
});
|
|
29
|
+
function shaBitsOf(sha) {
|
|
30
|
+
return SHA_BITS[sha];
|
|
12
31
|
}
|
|
13
32
|
function aesBitsOf(alg) {
|
|
14
33
|
return Number.parseInt(alg.slice(1, 4), 10);
|
|
@@ -51,12 +70,62 @@ const PBES2_ALGORITHMS = [
|
|
|
51
70
|
"PBES2-HS384+A192KW",
|
|
52
71
|
"PBES2-HS512+A256KW"
|
|
53
72
|
];
|
|
73
|
+
const PBES2_ALGORITHM_SET = /* @__PURE__ */ new Set(PBES2_ALGORITHMS);
|
|
74
|
+
function isPBES2Algorithm(alg) {
|
|
75
|
+
return PBES2_ALGORITHM_SET.has(alg);
|
|
76
|
+
}
|
|
77
|
+
const JWS_ALGORITHMS = /* @__PURE__ */ new Set(Object.keys({
|
|
78
|
+
HS256: true,
|
|
79
|
+
HS384: true,
|
|
80
|
+
HS512: true,
|
|
81
|
+
RS256: true,
|
|
82
|
+
RS384: true,
|
|
83
|
+
RS512: true,
|
|
84
|
+
PS256: true,
|
|
85
|
+
PS384: true,
|
|
86
|
+
PS512: true,
|
|
87
|
+
ES256: true,
|
|
88
|
+
ES384: true,
|
|
89
|
+
ES512: true,
|
|
90
|
+
Ed25519: true,
|
|
91
|
+
EdDSA: true
|
|
92
|
+
}));
|
|
93
|
+
function isJWSAlgorithm(alg) {
|
|
94
|
+
return JWS_ALGORITHMS.has(alg);
|
|
95
|
+
}
|
|
96
|
+
const KEY_MANAGEMENT_ALGORITHMS = /* @__PURE__ */ new Set(Object.keys({
|
|
97
|
+
"dir": true,
|
|
98
|
+
"A128KW": true,
|
|
99
|
+
"A192KW": true,
|
|
100
|
+
"A256KW": true,
|
|
101
|
+
"A128GCMKW": true,
|
|
102
|
+
"A192GCMKW": true,
|
|
103
|
+
"A256GCMKW": true,
|
|
104
|
+
"PBES2-HS256+A128KW": true,
|
|
105
|
+
"PBES2-HS384+A192KW": true,
|
|
106
|
+
"PBES2-HS512+A256KW": true,
|
|
107
|
+
"RSA-OAEP": true,
|
|
108
|
+
"RSA-OAEP-256": true,
|
|
109
|
+
"RSA-OAEP-384": true,
|
|
110
|
+
"RSA-OAEP-512": true,
|
|
111
|
+
"ECDH-ES": true,
|
|
112
|
+
"ECDH-ES+A128KW": true,
|
|
113
|
+
"ECDH-ES+A192KW": true,
|
|
114
|
+
"ECDH-ES+A256KW": true
|
|
115
|
+
}));
|
|
116
|
+
function isKeyManagementAlgorithm(alg) {
|
|
117
|
+
return KEY_MANAGEMENT_ALGORITHMS.has(alg);
|
|
118
|
+
}
|
|
54
119
|
const ECDH_ES_ALGORITHMS = [
|
|
55
120
|
"ECDH-ES",
|
|
56
121
|
"ECDH-ES+A128KW",
|
|
57
122
|
"ECDH-ES+A192KW",
|
|
58
123
|
"ECDH-ES+A256KW"
|
|
59
124
|
];
|
|
125
|
+
const ECDH_ES_ALGORITHM_SET = /* @__PURE__ */ new Set(ECDH_ES_ALGORITHMS);
|
|
126
|
+
function isECDHESAlgorithm(alg) {
|
|
127
|
+
return ECDH_ES_ALGORITHM_SET.has(alg);
|
|
128
|
+
}
|
|
60
129
|
function inferJWSAllowedAlgorithms(key, options) {
|
|
61
130
|
if (!key || typeof key === "function") return void 0;
|
|
62
131
|
if (typeof key === "string" || key instanceof Uint8Array) return void 0;
|
|
@@ -92,7 +161,7 @@ function isEd25519Signature(alg) {
|
|
|
92
161
|
}
|
|
93
162
|
function jwsAlgsFromJWK(jwk) {
|
|
94
163
|
if (jwk.alg && isEd25519Signature(jwk.alg)) return ["EdDSA", "Ed25519"];
|
|
95
|
-
if (jwk.alg) return
|
|
164
|
+
if (jwk.alg) return isJWSAlgorithm(jwk.alg) ? [jwk.alg] : void 0;
|
|
96
165
|
if (jwk.kty === "EC") {
|
|
97
166
|
const crv = jwk.crv;
|
|
98
167
|
if (crv === "P-256") return ["ES256"];
|
|
@@ -105,7 +174,7 @@ function jwsAlgsFromJWK(jwk) {
|
|
|
105
174
|
}
|
|
106
175
|
function jweAlgsFromJWK(jwk) {
|
|
107
176
|
if (jwk.kty === "oct") return jweAlgsFromOctJWK(jwk);
|
|
108
|
-
if (jwk.alg) return
|
|
177
|
+
if (jwk.alg) return isKeyManagementAlgorithm(jwk.alg) ? [jwk.alg] : void 0;
|
|
109
178
|
if (jwk.kty === "EC") {
|
|
110
179
|
const crv = jwk.crv;
|
|
111
180
|
if (crv === "P-256" || crv === "P-384" || crv === "P-521") return [...ECDH_ES_ALGORITHMS];
|
|
@@ -118,7 +187,7 @@ function jweAlgsFromOctJWK(jwk) {
|
|
|
118
187
|
const alg = jwk.alg;
|
|
119
188
|
if (!alg) return void 0;
|
|
120
189
|
if (isContentEncryptionAlgorithm(alg)) return ["dir"];
|
|
121
|
-
return
|
|
190
|
+
return isKeyManagementAlgorithm(alg) ? [alg] : void 0;
|
|
122
191
|
}
|
|
123
192
|
function isContentEncryptionAlgorithm(alg) {
|
|
124
193
|
return CONTENT_ENCRYPTION_ALGORITHMS.has(alg);
|
|
@@ -180,7 +249,8 @@ function jwsHashBits(hashName) {
|
|
|
180
249
|
if (hashName === "SHA-384") return "384";
|
|
181
250
|
if (hashName === "SHA-512") return "512";
|
|
182
251
|
}
|
|
183
|
-
function
|
|
184
|
-
|
|
252
|
+
async function digestUrl(data, hash = "SHA-256") {
|
|
253
|
+
const bytes = typeof data === "string" ? textEncoder.encode(data) : data;
|
|
254
|
+
return base64UrlStringify(new Uint8Array(await crypto.subtle.digest(hash, bytes)));
|
|
185
255
|
}
|
|
186
|
-
export { ECDSA_CURVES, PBES2_ALGORITHMS, aesBitsOf, checkKeyUsage, cryptoKeyCurve, hashBitsOf, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, innerKeyWrapAlg, isAlgorithm, isContentEncryptionAlgorithm, isEd25519Signature, jwsHashOf, lengthOf, modulusLengthOf, namedCurveOf, rsaOaepHashOf, unusableKey };
|
|
256
|
+
export { ECDSA_CURVES, PBES2_ALGORITHMS, aesBitsOf, checkKeyUsage, cryptoKeyCurve, digestUrl, hashBitsOf, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, innerKeyWrapAlg, isAlgorithm, isContentEncryptionAlgorithm, isECDHESAlgorithm, isEd25519Signature, isJWSAlgorithm, isKeyManagementAlgorithm, isPBES2Algorithm, jwsHashOf, lengthOf, modulusLengthOf, namedCurveOf, pbes2HashOf, rsaOaepHashOf, shaBitsOf, unusableKey };
|