unjwt 0.5.39 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -13
- package/dist/_chunks/_crypto.mjs +1014 -0
- package/dist/_chunks/error.d.mts +67 -0
- package/dist/_chunks/index.d.mts +631 -219
- package/dist/_chunks/jwk.d.mts +220 -87
- package/dist/_chunks/jws.mjs +729 -682
- package/dist/_chunks/utils.mjs +74 -69
- package/dist/adapters/h3v1/index.d.mts +282 -0
- package/dist/{_chunks/h3v1.mjs → adapters/h3v1/index.mjs} +204 -91
- package/dist/adapters/h3v2/index.d.mts +213 -0
- package/dist/adapters/{h3v2.mjs → h3v2/index.mjs} +215 -113
- package/dist/core/_crypto/index.d.mts +71 -0
- package/dist/core/_crypto/index.mjs +2 -0
- package/dist/core/jwe.d.mts +40 -0
- package/dist/{_chunks → core}/jwe.mjs +61 -32
- package/dist/core/jwk.d.mts +231 -0
- package/dist/core/jwk.mjs +686 -0
- package/dist/core/jws.d.mts +31 -0
- package/dist/core/jws.mjs +104 -0
- package/dist/{_chunks/index2.d.mts → core/utils/index.d.mts} +13 -12
- package/dist/core/utils/index.mjs +2 -0
- package/dist/index.d.mts +7 -6
- package/dist/index.mjs +5 -5
- package/package.json +50 -41
- package/dist/_chunks/chunk.mjs +0 -13
- package/dist/_chunks/jwe.d.mts +0 -43
- package/dist/_chunks/jwk.mjs +0 -1592
- package/dist/_chunks/jws.d.mts +0 -46
- package/dist/adapters/h3.d.mts +0 -3
- package/dist/adapters/h3.mjs +0 -3
- package/dist/adapters/h3v1.d.mts +0 -3
- package/dist/adapters/h3v1.mjs +0 -3
- package/dist/adapters/h3v2.d.mts +0 -184
- package/dist/jwe.d.mts +0 -3
- package/dist/jwe.mjs +0 -4
- package/dist/jwk.d.mts +0 -3
- package/dist/jwk.mjs +0 -3
- package/dist/jws.d.mts +0 -3
- package/dist/jws.mjs +0 -4
- package/dist/utils.d.mts +0 -3
- package/dist/utils.mjs +0 -2
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { a as deriveJWKFromPassword, c as
|
|
1
|
+
import { a as deriveJWKFromPassword, c as importFromPEM, d as isSymmetricJWK, f as computeExpiresInSeconds, i as encrypt, l as isPrivateJWK, m as isJWTError, n as verify, o as exportToPEM, p as JWTError, r as decrypt, s as generateJWK, t as sign, u as isPublicJWK } from "../../_chunks/jws.mjs";
|
|
2
2
|
import { getChunkedCookie, getEventContext, setChunkedCookie } from "h3";
|
|
3
3
|
import { NullProtoObj } from "rou3";
|
|
4
4
|
//#region src/adapters/h3v2/session/jwe.ts
|
|
5
5
|
const kGetSessionPromise$1 = Symbol("h3_jwe_getSession");
|
|
6
|
-
const kSessionToken$1 = Symbol("h3_jwe_sessionToken");
|
|
7
6
|
const DEFAULT_NAME$1 = "h3-jwe";
|
|
8
7
|
const DEFAULT_COOKIE$1 = {
|
|
9
8
|
path: "/",
|
|
@@ -30,7 +29,7 @@ async function useJWESession(event, config) {
|
|
|
30
29
|
return getSessionFromContext$1(event, sessionName)?.data || {};
|
|
31
30
|
},
|
|
32
31
|
get token() {
|
|
33
|
-
return getSessionFromContext$1(event, sessionName)?.
|
|
32
|
+
return getSessionFromContext$1(event, sessionName)?.token ?? getJWESessionToken(event, config);
|
|
34
33
|
},
|
|
35
34
|
update: async (update) => {
|
|
36
35
|
await updateJWESession(event, config, update);
|
|
@@ -58,17 +57,44 @@ async function getJWESession(event, config) {
|
|
|
58
57
|
* unless we have a read-only event in which case we just return it as it was valid at the time of reading
|
|
59
58
|
* the cookie/header (like in a websocket upgrade)
|
|
60
59
|
*/
|
|
61
|
-
if (session.expiresAt !== void 0 && session.expiresAt < Date.now()
|
|
60
|
+
if (session.expiresAt !== void 0 && session.expiresAt < Date.now()) {
|
|
62
61
|
await config.hooks?.onExpire?.({
|
|
62
|
+
session: {
|
|
63
|
+
id: session.id,
|
|
64
|
+
createdAt: session.createdAt,
|
|
65
|
+
expiresAt: session.expiresAt,
|
|
66
|
+
token: session.token
|
|
67
|
+
},
|
|
63
68
|
event,
|
|
64
|
-
error:
|
|
69
|
+
error: new JWTError(`JWT "exp" (Expiration Time) Claim validation failed: Token has expired (exp: ${(/* @__PURE__ */ new Date(session.expiresAt * 1e3)).toISOString()})`, "ERR_JWT_EXPIRED", {
|
|
70
|
+
jti: session.id,
|
|
71
|
+
exp: session.expiresAt / 1e3
|
|
72
|
+
}),
|
|
65
73
|
config
|
|
66
74
|
});
|
|
67
|
-
|
|
75
|
+
delete context.sessions[sessionName];
|
|
76
|
+
if (config.cookie !== false) if (hasWritableResponse$1(event)) setChunkedCookie(event, sessionName, "", {
|
|
77
|
+
...DEFAULT_COOKIE$1,
|
|
78
|
+
...config.cookie,
|
|
79
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
80
|
+
maxAge: void 0
|
|
81
|
+
});
|
|
82
|
+
else console.warn("[unjwt/h3] Session expired but cookie cannot be cleared on a read-only event.");
|
|
83
|
+
const freshNow = config.jwe?.encryptOptions?.currentDate?.getTime() ?? Date.now();
|
|
84
|
+
const freshCreatedAt = freshNow - freshNow % 1e3;
|
|
85
|
+
const freshSession = {
|
|
86
|
+
id: void 0,
|
|
87
|
+
createdAt: freshCreatedAt,
|
|
88
|
+
expiresAt: config.maxAge === void 0 ? void 0 : freshCreatedAt + computeExpiresInSeconds(config.maxAge) * 1e3,
|
|
89
|
+
data: new NullProtoObj(),
|
|
90
|
+
token: void 0
|
|
91
|
+
};
|
|
92
|
+
context.sessions[sessionName] = freshSession;
|
|
93
|
+
return freshSession;
|
|
68
94
|
}
|
|
69
|
-
await config.hooks?.onRead?.({
|
|
70
|
-
event,
|
|
95
|
+
if (session.id !== void 0 && session.token !== void 0) await config.hooks?.onRead?.({
|
|
71
96
|
session,
|
|
97
|
+
event,
|
|
72
98
|
config
|
|
73
99
|
});
|
|
74
100
|
return session;
|
|
@@ -79,25 +105,29 @@ async function getJWESession(event, config) {
|
|
|
79
105
|
id: void 0,
|
|
80
106
|
createdAt,
|
|
81
107
|
expiresAt: config.maxAge === void 0 ? void 0 : createdAt + computeExpiresInSeconds(config.maxAge) * 1e3,
|
|
82
|
-
data: new NullProtoObj()
|
|
108
|
+
data: new NullProtoObj(),
|
|
109
|
+
token: void 0
|
|
83
110
|
};
|
|
84
111
|
context.sessions[sessionName] = session;
|
|
85
112
|
const token = getJWESessionToken(event, config);
|
|
113
|
+
let exclusiveHookFired = false;
|
|
86
114
|
if (token) {
|
|
87
|
-
session
|
|
115
|
+
session.token = token;
|
|
88
116
|
const promise = unsealJWESession(event, config, token).catch(async (error_) => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
exclusiveHookFired = true;
|
|
118
|
+
if (isJWTError(error_, "ERR_JWT_EXPIRED")) await config.hooks?.onExpire?.({
|
|
119
|
+
session: {
|
|
120
|
+
id: error_.cause.jti,
|
|
121
|
+
createdAt: error_.cause.iat ? error_.cause.iat * 1e3 : void 0,
|
|
122
|
+
expiresAt: error_.cause.exp ? error_.cause.exp * 1e3 : void 0,
|
|
123
|
+
token
|
|
124
|
+
},
|
|
125
|
+
event,
|
|
126
|
+
error: error_,
|
|
127
|
+
config
|
|
128
|
+
});
|
|
129
|
+
else await config.hooks?.onError?.({
|
|
130
|
+
session,
|
|
101
131
|
event,
|
|
102
132
|
error: error_,
|
|
103
133
|
config
|
|
@@ -110,9 +140,9 @@ async function getJWESession(event, config) {
|
|
|
110
140
|
session[kGetSessionPromise$1] = promise;
|
|
111
141
|
await promise;
|
|
112
142
|
}
|
|
113
|
-
await config.hooks?.onRead?.({
|
|
114
|
-
event,
|
|
143
|
+
if (!exclusiveHookFired && session.id !== void 0 && session.token !== void 0) await config.hooks?.onRead?.({
|
|
115
144
|
session,
|
|
145
|
+
event,
|
|
116
146
|
config
|
|
117
147
|
});
|
|
118
148
|
return session;
|
|
@@ -136,22 +166,16 @@ function getJWESessionToken(event, config) {
|
|
|
136
166
|
* Update the session data for the current request.
|
|
137
167
|
*/
|
|
138
168
|
async function updateJWESession(event, config, update) {
|
|
169
|
+
const canWriteCookie = hasWritableResponse$1(event);
|
|
170
|
+
if (config.cookie !== false && !canWriteCookie) throw new Error("[unjwt/h3] Cannot update session on read-only event.");
|
|
139
171
|
const sessionName = config.name || DEFAULT_NAME$1;
|
|
140
172
|
const session = getEventContext(event).sessions?.[sessionName] || await getJWESession(event, config);
|
|
141
173
|
if (typeof update === "function") update = update(session.data);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
Object.assign(session.data, update);
|
|
148
|
-
await config.hooks?.onUpdate?.({
|
|
149
|
-
oldSession,
|
|
150
|
-
session,
|
|
151
|
-
event,
|
|
152
|
-
config
|
|
153
|
-
});
|
|
154
|
-
}
|
|
174
|
+
const oldSession = {
|
|
175
|
+
...session,
|
|
176
|
+
data: { ...session.data }
|
|
177
|
+
};
|
|
178
|
+
if (update) Object.assign(session.data, update);
|
|
155
179
|
const now = config.jwe?.encryptOptions?.currentDate?.getTime() ?? Date.now();
|
|
156
180
|
const createdAt = now - now % 1e3;
|
|
157
181
|
Object.assign(session, {
|
|
@@ -159,15 +183,36 @@ async function updateJWESession(event, config, update) {
|
|
|
159
183
|
createdAt,
|
|
160
184
|
expiresAt: config.maxAge === void 0 ? void 0 : createdAt + computeExpiresInSeconds(config.maxAge) * 1e3
|
|
161
185
|
});
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
186
|
+
let sealed;
|
|
187
|
+
try {
|
|
188
|
+
sealed = await sealJWESession(event, config);
|
|
189
|
+
} catch (error_) {
|
|
190
|
+
Object.assign(session, {
|
|
191
|
+
id: oldSession.id,
|
|
192
|
+
createdAt: oldSession.createdAt,
|
|
193
|
+
expiresAt: oldSession.expiresAt
|
|
169
194
|
});
|
|
195
|
+
session.token = oldSession.token;
|
|
196
|
+
await config.hooks?.onError?.({
|
|
197
|
+
session,
|
|
198
|
+
event,
|
|
199
|
+
error: error_,
|
|
200
|
+
config
|
|
201
|
+
});
|
|
202
|
+
throw error_;
|
|
170
203
|
}
|
|
204
|
+
session.token = sealed;
|
|
205
|
+
if (config.cookie !== false && canWriteCookie) setChunkedCookie(event, sessionName, sealed, {
|
|
206
|
+
...DEFAULT_COOKIE$1,
|
|
207
|
+
expires: config.maxAge === void 0 ? void 0 : new Date(session.createdAt + computeExpiresInSeconds(config.maxAge) * 1e3),
|
|
208
|
+
...config.cookie
|
|
209
|
+
});
|
|
210
|
+
await config.hooks?.onUpdate?.({
|
|
211
|
+
session,
|
|
212
|
+
oldSession,
|
|
213
|
+
event,
|
|
214
|
+
config
|
|
215
|
+
});
|
|
171
216
|
return session;
|
|
172
217
|
}
|
|
173
218
|
/**
|
|
@@ -224,7 +269,7 @@ async function unsealJWESession(event, config, sealed) {
|
|
|
224
269
|
unwrappedKeyAlgorithm: void 0,
|
|
225
270
|
keyUsage: void 0,
|
|
226
271
|
forceUint8Array: false,
|
|
227
|
-
|
|
272
|
+
validateClaims: true
|
|
228
273
|
}).catch((error_) => {
|
|
229
274
|
if (error_ instanceof Error) throw error_;
|
|
230
275
|
throw new Error(String(error_));
|
|
@@ -241,24 +286,28 @@ async function unsealJWESession(event, config, sealed) {
|
|
|
241
286
|
* Clear the session (delete from context and drop cookie).
|
|
242
287
|
*/
|
|
243
288
|
async function clearJWESession(event, config) {
|
|
289
|
+
const canWriteCookie = hasWritableResponse$1(event);
|
|
290
|
+
if (config.cookie !== false && !canWriteCookie) throw new Error("[unjwt/h3] Cannot clear session on read-only event.");
|
|
244
291
|
const context = getEventContext(event);
|
|
245
292
|
const sessionName = config.name || DEFAULT_NAME$1;
|
|
246
293
|
let session = context.sessions?.[sessionName];
|
|
247
294
|
if (session && session[kGetSessionPromise$1]) session = await session[kGetSessionPromise$1];
|
|
295
|
+
const oldSession = session ? {
|
|
296
|
+
...session,
|
|
297
|
+
data: { ...session.data }
|
|
298
|
+
} : void 0;
|
|
248
299
|
if (context.sessions?.[sessionName]) delete context.sessions[sessionName];
|
|
249
|
-
if (config.cookie !== false &&
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
});
|
|
261
|
-
}
|
|
300
|
+
if (config.cookie !== false && canWriteCookie) setChunkedCookie(event, sessionName, "", {
|
|
301
|
+
...DEFAULT_COOKIE$1,
|
|
302
|
+
...config.cookie,
|
|
303
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
304
|
+
maxAge: void 0
|
|
305
|
+
});
|
|
306
|
+
await config.hooks?.onClear?.({
|
|
307
|
+
oldSession,
|
|
308
|
+
event,
|
|
309
|
+
config
|
|
310
|
+
});
|
|
262
311
|
}
|
|
263
312
|
function getSessionFromContext$1(event, sessionName) {
|
|
264
313
|
return getEventContext(event).sessions?.[sessionName];
|
|
@@ -293,7 +342,6 @@ function findSetCookie$1(setCookie, name) {
|
|
|
293
342
|
//#endregion
|
|
294
343
|
//#region src/adapters/h3v2/session/jws.ts
|
|
295
344
|
const kGetSessionPromise = Symbol("h3_jws_getSession");
|
|
296
|
-
const kSessionToken = Symbol("h3_jws_sessionToken");
|
|
297
345
|
const DEFAULT_NAME = "h3-jws";
|
|
298
346
|
const DEFAULT_COOKIE = {
|
|
299
347
|
path: "/",
|
|
@@ -317,7 +365,7 @@ async function useJWSSession(event, config) {
|
|
|
317
365
|
return getSessionFromContext(event, sessionName)?.data || {};
|
|
318
366
|
},
|
|
319
367
|
get token() {
|
|
320
|
-
return getSessionFromContext(event, sessionName)?.
|
|
368
|
+
return getSessionFromContext(event, sessionName)?.token ?? getJWSSessionToken(event, config);
|
|
321
369
|
},
|
|
322
370
|
update: async (update) => {
|
|
323
371
|
await updateJWSSession(event, config, update);
|
|
@@ -337,17 +385,44 @@ async function getJWSSession(event, config) {
|
|
|
337
385
|
const existingSession = context.sessions[sessionName];
|
|
338
386
|
if (existingSession) {
|
|
339
387
|
const session = existingSession[kGetSessionPromise] ? await existingSession[kGetSessionPromise] : existingSession;
|
|
340
|
-
if (session.expiresAt !== void 0 && session.expiresAt < Date.now()
|
|
388
|
+
if (session.expiresAt !== void 0 && session.expiresAt < Date.now()) {
|
|
341
389
|
await config.hooks?.onExpire?.({
|
|
390
|
+
session: {
|
|
391
|
+
id: session.id,
|
|
392
|
+
createdAt: session.createdAt,
|
|
393
|
+
expiresAt: session.expiresAt,
|
|
394
|
+
token: session.token
|
|
395
|
+
},
|
|
342
396
|
event,
|
|
343
|
-
error:
|
|
397
|
+
error: new JWTError(`JWT "exp" (Expiration Time) Claim validation failed: Token has expired (exp: ${(/* @__PURE__ */ new Date(session.expiresAt * 1e3)).toISOString()})`, "ERR_JWT_EXPIRED", {
|
|
398
|
+
jti: session.id,
|
|
399
|
+
exp: session.expiresAt / 1e3
|
|
400
|
+
}),
|
|
344
401
|
config
|
|
345
402
|
});
|
|
346
|
-
|
|
403
|
+
delete context.sessions[sessionName];
|
|
404
|
+
if (config.cookie !== false) if (hasWritableResponse(event)) setChunkedCookie(event, sessionName, "", {
|
|
405
|
+
...DEFAULT_COOKIE,
|
|
406
|
+
...config.cookie,
|
|
407
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
408
|
+
maxAge: void 0
|
|
409
|
+
});
|
|
410
|
+
else console.warn("[unjwt/h3] Session expired but cookie cannot be cleared on a read-only event.");
|
|
411
|
+
const freshNow = config.jws?.signOptions?.currentDate?.getTime() ?? Date.now();
|
|
412
|
+
const freshCreatedAt = freshNow - freshNow % 1e3;
|
|
413
|
+
const freshSession = {
|
|
414
|
+
id: void 0,
|
|
415
|
+
createdAt: freshCreatedAt,
|
|
416
|
+
expiresAt: config.maxAge === void 0 ? void 0 : freshCreatedAt + computeExpiresInSeconds(config.maxAge) * 1e3,
|
|
417
|
+
data: new NullProtoObj(),
|
|
418
|
+
token: void 0
|
|
419
|
+
};
|
|
420
|
+
context.sessions[sessionName] = freshSession;
|
|
421
|
+
return freshSession;
|
|
347
422
|
}
|
|
348
|
-
await config.hooks?.onRead?.({
|
|
349
|
-
event,
|
|
423
|
+
if (session.id !== void 0 && session.token !== void 0) await config.hooks?.onRead?.({
|
|
350
424
|
session,
|
|
425
|
+
event,
|
|
351
426
|
config
|
|
352
427
|
});
|
|
353
428
|
return session;
|
|
@@ -358,22 +433,29 @@ async function getJWSSession(event, config) {
|
|
|
358
433
|
id: void 0,
|
|
359
434
|
createdAt,
|
|
360
435
|
expiresAt: config.maxAge === void 0 ? void 0 : createdAt + computeExpiresInSeconds(config.maxAge) * 1e3,
|
|
361
|
-
data: new NullProtoObj()
|
|
436
|
+
data: new NullProtoObj(),
|
|
437
|
+
token: void 0
|
|
362
438
|
};
|
|
363
439
|
context.sessions[sessionName] = session;
|
|
364
440
|
const token = getJWSSessionToken(event, config);
|
|
441
|
+
let exclusiveHookFired = false;
|
|
365
442
|
if (token) {
|
|
366
|
-
session
|
|
443
|
+
session.token = token;
|
|
367
444
|
const promise = verifyJWSSession(event, config, token).catch(async (error_) => {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
445
|
+
exclusiveHookFired = true;
|
|
446
|
+
if (isJWTError(error_, "ERR_JWT_EXPIRED")) await config.hooks?.onExpire?.({
|
|
447
|
+
session: {
|
|
448
|
+
id: error_.cause.jti,
|
|
449
|
+
createdAt: error_.cause.iat ? error_.cause.iat * 1e3 : void 0,
|
|
450
|
+
expiresAt: error_.cause.exp ? error_.cause.exp * 1e3 : void 0,
|
|
451
|
+
token
|
|
452
|
+
},
|
|
453
|
+
event,
|
|
454
|
+
error: error_,
|
|
455
|
+
config
|
|
456
|
+
});
|
|
457
|
+
else await config.hooks?.onError?.({
|
|
458
|
+
session,
|
|
377
459
|
event,
|
|
378
460
|
error: error_,
|
|
379
461
|
config
|
|
@@ -386,9 +468,9 @@ async function getJWSSession(event, config) {
|
|
|
386
468
|
session[kGetSessionPromise] = promise;
|
|
387
469
|
await promise;
|
|
388
470
|
}
|
|
389
|
-
await config.hooks?.onRead?.({
|
|
390
|
-
event,
|
|
471
|
+
if (!exclusiveHookFired && session.id !== void 0 && session.token !== void 0) await config.hooks?.onRead?.({
|
|
391
472
|
session,
|
|
473
|
+
event,
|
|
392
474
|
config
|
|
393
475
|
});
|
|
394
476
|
return session;
|
|
@@ -409,22 +491,16 @@ function getJWSSessionToken(event, config) {
|
|
|
409
491
|
return token;
|
|
410
492
|
}
|
|
411
493
|
async function updateJWSSession(event, config, update) {
|
|
494
|
+
const canWriteCookie = hasWritableResponse(event);
|
|
495
|
+
if (config.cookie !== false && !canWriteCookie) throw new Error("[unjwt/h3] Cannot update session on read-only event.");
|
|
412
496
|
const sessionName = config.name || DEFAULT_NAME;
|
|
413
497
|
const session = getEventContext(event).sessions?.[sessionName] || await getJWSSession(event, config);
|
|
414
498
|
if (typeof update === "function") update = update(session.data);
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
Object.assign(session.data, update);
|
|
421
|
-
await config.hooks?.onUpdate?.({
|
|
422
|
-
session,
|
|
423
|
-
oldSession,
|
|
424
|
-
event,
|
|
425
|
-
config
|
|
426
|
-
});
|
|
427
|
-
}
|
|
499
|
+
const oldSession = {
|
|
500
|
+
...session,
|
|
501
|
+
data: { ...session.data }
|
|
502
|
+
};
|
|
503
|
+
if (update) Object.assign(session.data, update);
|
|
428
504
|
const now = config.jws?.signOptions?.currentDate?.getTime() ?? Date.now();
|
|
429
505
|
const createdAt = now - now % 1e3;
|
|
430
506
|
Object.assign(session, {
|
|
@@ -432,15 +508,36 @@ async function updateJWSSession(event, config, update) {
|
|
|
432
508
|
createdAt,
|
|
433
509
|
expiresAt: config.maxAge === void 0 ? void 0 : createdAt + computeExpiresInSeconds(config.maxAge) * 1e3
|
|
434
510
|
});
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
511
|
+
let token;
|
|
512
|
+
try {
|
|
513
|
+
token = await signJWSSession(event, config);
|
|
514
|
+
} catch (error_) {
|
|
515
|
+
Object.assign(session, {
|
|
516
|
+
id: oldSession.id,
|
|
517
|
+
createdAt: oldSession.createdAt,
|
|
518
|
+
expiresAt: oldSession.expiresAt
|
|
519
|
+
});
|
|
520
|
+
session.token = oldSession.token;
|
|
521
|
+
await config.hooks?.onError?.({
|
|
522
|
+
session,
|
|
523
|
+
event,
|
|
524
|
+
error: error_,
|
|
525
|
+
config
|
|
442
526
|
});
|
|
527
|
+
throw error_;
|
|
443
528
|
}
|
|
529
|
+
session.token = token;
|
|
530
|
+
if (config.cookie !== false && canWriteCookie) setChunkedCookie(event, sessionName, token, {
|
|
531
|
+
...DEFAULT_COOKIE,
|
|
532
|
+
expires: config.maxAge === void 0 ? void 0 : new Date(session.createdAt + computeExpiresInSeconds(config.maxAge) * 1e3),
|
|
533
|
+
...config.cookie
|
|
534
|
+
});
|
|
535
|
+
await config.hooks?.onUpdate?.({
|
|
536
|
+
session,
|
|
537
|
+
oldSession,
|
|
538
|
+
event,
|
|
539
|
+
config
|
|
540
|
+
});
|
|
444
541
|
return session;
|
|
445
542
|
}
|
|
446
543
|
async function signJWSSession(event, config) {
|
|
@@ -487,8 +584,9 @@ async function verifyJWSSession(event, config, token) {
|
|
|
487
584
|
typ: typ || "JWT",
|
|
488
585
|
algorithms: alg ? [alg] : void 0,
|
|
489
586
|
forceUint8Array: false,
|
|
490
|
-
|
|
587
|
+
validateClaims: true
|
|
491
588
|
}).catch((error_) => {
|
|
589
|
+
if (isJWTError(error_, "ERR_JWT_EXPIRED")) throw error_;
|
|
492
590
|
const message = error_ instanceof Error ? error_.message : String(error_);
|
|
493
591
|
throw new Error(`Invalid session token: ${message}`);
|
|
494
592
|
});
|
|
@@ -501,24 +599,28 @@ async function verifyJWSSession(event, config, token) {
|
|
|
501
599
|
};
|
|
502
600
|
}
|
|
503
601
|
async function clearJWSSession(event, config) {
|
|
602
|
+
const canWriteCookie = hasWritableResponse(event);
|
|
603
|
+
if (config.cookie !== false && !canWriteCookie) throw new Error("[unjwt/h3] Cannot clear session on read-only event.");
|
|
504
604
|
const context = getEventContext(event);
|
|
505
605
|
const sessionName = config.name || DEFAULT_NAME;
|
|
506
606
|
let session = context.sessions?.[sessionName];
|
|
507
607
|
if (session && session[kGetSessionPromise]) session = await session[kGetSessionPromise];
|
|
608
|
+
const oldSession = session ? {
|
|
609
|
+
...session,
|
|
610
|
+
data: { ...session.data }
|
|
611
|
+
} : void 0;
|
|
508
612
|
if (context.sessions?.[sessionName]) delete context.sessions[sessionName];
|
|
509
|
-
if (config.cookie !== false &&
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
});
|
|
521
|
-
}
|
|
613
|
+
if (config.cookie !== false && canWriteCookie) setChunkedCookie(event, sessionName, "", {
|
|
614
|
+
...DEFAULT_COOKIE,
|
|
615
|
+
...config.cookie,
|
|
616
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
617
|
+
maxAge: void 0
|
|
618
|
+
});
|
|
619
|
+
await config.hooks?.onClear?.({
|
|
620
|
+
oldSession,
|
|
621
|
+
event,
|
|
622
|
+
config
|
|
623
|
+
});
|
|
522
624
|
}
|
|
523
625
|
function getSessionFromContext(event, sessionName) {
|
|
524
626
|
return getEventContext(event).sessions?.[sessionName];
|
|
@@ -558,4 +660,4 @@ function findSetCookie(setCookie, name) {
|
|
|
558
660
|
return match ? match[1] : void 0;
|
|
559
661
|
}
|
|
560
662
|
//#endregion
|
|
561
|
-
export { clearJWESession, clearJWSSession, deriveJWKFromPassword,
|
|
663
|
+
export { clearJWESession, clearJWSSession, deriveJWKFromPassword, exportToPEM, generateJWK, getJWESession, getJWESessionToken, getJWSSession, importFromPEM, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { A as JWK, o as JWEHeaderParameters, s as JWEKeyManagementHeaderParameters } from "../../_chunks/index.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/_crypto/_sign-verify.d.ts
|
|
4
|
+
declare function sign(alg: string, key: CryptoKey, data: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
5
|
+
declare function verify(alg: string, key: CryptoKey, signature: Uint8Array<ArrayBuffer>, data: Uint8Array<ArrayBuffer>): Promise<boolean>;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/core/_crypto/_aes.d.ts
|
|
8
|
+
declare function generateIV(alg: string): Uint8Array<ArrayBuffer>;
|
|
9
|
+
declare function bitLengthCEK(alg: string): number;
|
|
10
|
+
declare function generateCEK(alg: string): Uint8Array<ArrayBuffer>;
|
|
11
|
+
declare function aesKwWrap(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, cek: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
12
|
+
declare function aesKwUnwrap(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, encryptedKey: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
13
|
+
declare function gcmkwEncrypt(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, plaintext: Uint8Array<ArrayBuffer>, iv?: Uint8Array<ArrayBuffer>): Promise<{
|
|
14
|
+
encryptedKey: Uint8Array<ArrayBuffer>;
|
|
15
|
+
iv: string;
|
|
16
|
+
tag: string;
|
|
17
|
+
}>;
|
|
18
|
+
declare function gcmkwDecrypt(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, ciphertext: Uint8Array<ArrayBuffer>, iv: Uint8Array<ArrayBuffer>, tag: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
19
|
+
declare function encrypt(enc: string, plaintext: Uint8Array<ArrayBuffer>, cek: Uint8Array<ArrayBuffer> | CryptoKey, iv: Uint8Array<ArrayBuffer> | undefined, aad: Uint8Array<ArrayBuffer>): Promise<{
|
|
20
|
+
ciphertext: Uint8Array<ArrayBuffer>;
|
|
21
|
+
tag: Uint8Array<ArrayBuffer> | undefined;
|
|
22
|
+
iv: Uint8Array<ArrayBuffer> | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
declare function decrypt(enc: string, cek: Uint8Array<ArrayBuffer> | CryptoKey, ciphertext: Uint8Array<ArrayBuffer>, iv: Uint8Array<ArrayBuffer> | undefined, tag: Uint8Array<ArrayBuffer> | undefined, aad: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/core/_crypto/_key-encryption.d.ts
|
|
27
|
+
declare function encryptKey(alg: string, enc: string, key: CryptoKey | Uint8Array<ArrayBuffer>, providedCek?: Uint8Array<ArrayBuffer>, providedParameters?: JWEKeyManagementHeaderParameters): Promise<{
|
|
28
|
+
cek: CryptoKey | Uint8Array<ArrayBuffer>;
|
|
29
|
+
encryptedKey?: Uint8Array<ArrayBuffer>;
|
|
30
|
+
parameters?: JWEHeaderParameters;
|
|
31
|
+
}>;
|
|
32
|
+
declare function normalizeKey(key: CryptoKey | JWK | Uint8Array<ArrayBuffer>, alg: string): Promise<CryptoKey | Uint8Array<ArrayBuffer>>;
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/core/_crypto/_key-codec.d.ts
|
|
35
|
+
declare function jwkTokey(jwk: JWK): Promise<CryptoKey>;
|
|
36
|
+
declare function keyToJWK<T extends JWK>(key: Uint8Array<ArrayBuffer> | CryptoKey): Promise<T>;
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/core/_crypto/_pbes2.d.ts
|
|
39
|
+
declare function pbes2Wrap(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, cek: Uint8Array<ArrayBuffer>, p2c: number, p2s: Uint8Array<ArrayBuffer>): Promise<{
|
|
40
|
+
encryptedKey: Uint8Array<ArrayBuffer>;
|
|
41
|
+
p2c: number;
|
|
42
|
+
p2s: string;
|
|
43
|
+
}>;
|
|
44
|
+
declare function pbes2Unwrap(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, encryptedKey: Uint8Array<ArrayBuffer>, p2c: number, p2s: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
45
|
+
declare function deriveKey(p2s: Uint8Array<ArrayBuffer>, alg: string, p2c: number, key: CryptoKey | Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/core/_crypto/_ecdh.d.ts
|
|
48
|
+
declare function deriveECDHESKey(publicKey: CryptoKey, privateKey: CryptoKey, algorithm: string, keyLength: number, apu?: Uint8Array<ArrayBuffer>, apv?: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
49
|
+
declare function isECDHKeyAllowed(key: CryptoKey): boolean;
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/core/_crypto/_rsa.d.ts
|
|
52
|
+
declare function encryptRSAES(alg: string, key: CryptoKey, cek: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
53
|
+
declare function decryptRSAES(alg: string, key: CryptoKey, encryptedKey: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/core/_crypto/_pem.d.ts
|
|
56
|
+
/** Key Import Function options. */
|
|
57
|
+
interface KeyImportOptions {
|
|
58
|
+
/**
|
|
59
|
+
* The value to use as {@link !SubtleCrypto.importKey} `extractable` argument. Default is false for
|
|
60
|
+
* private keys, true otherwise.
|
|
61
|
+
*/
|
|
62
|
+
extractable?: boolean;
|
|
63
|
+
}
|
|
64
|
+
declare const toSPKI: (key: unknown) => Promise<string>;
|
|
65
|
+
declare const toPKCS8: (key: unknown) => Promise<string>;
|
|
66
|
+
declare const fromPKCS8: PEMImportFunction;
|
|
67
|
+
declare const fromSPKI: PEMImportFunction;
|
|
68
|
+
declare const fromX509: PEMImportFunction;
|
|
69
|
+
type PEMImportFunction = (pem: string, alg: string, options?: KeyImportOptions) => Promise<CryptoKey>;
|
|
70
|
+
//#endregion
|
|
71
|
+
export { type KeyImportOptions, aesKwUnwrap, aesKwWrap, bitLengthCEK, decrypt, decryptRSAES, deriveECDHESKey, deriveKey as deriveKeyPBES2, encrypt, encryptKey, encryptRSAES, fromPKCS8, fromSPKI, fromX509, gcmkwDecrypt, gcmkwEncrypt, generateCEK, generateIV, isECDHKeyAllowed, jwkTokey, keyToJWK, normalizeKey, pbes2Unwrap, pbes2Wrap, sign, toPKCS8, toSPKI, verify };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { C as gcmkwEncrypt, D as verify, E as sign, S as gcmkwDecrypt, T as generateIV, _ as aesKwUnwrap, a as toSPKI, b as decrypt, c as deriveKey, d as deriveECDHESKey, f as isECDHKeyAllowed, g as keyToJWK, h as jwkTokey, i as toPKCS8, l as pbes2Unwrap, m as encryptRSAES, n as fromSPKI, o as encryptKey, p as decryptRSAES, r as fromX509, s as normalizeKey, t as fromPKCS8, u as pbes2Wrap, v as aesKwWrap, w as generateCEK, x as encrypt, y as bitLengthCEK } from "../../_chunks/_crypto.mjs";
|
|
2
|
+
export { aesKwUnwrap, aesKwWrap, bitLengthCEK, decrypt, decryptRSAES, deriveECDHESKey, deriveKey as deriveKeyPBES2, encrypt, encryptKey, encryptRSAES, fromPKCS8, fromSPKI, fromX509, gcmkwDecrypt, gcmkwEncrypt, generateCEK, generateIV, isECDHKeyAllowed, jwkTokey, keyToJWK, normalizeKey, pbes2Unwrap, pbes2Wrap, sign, toPKCS8, toSPKI, verify };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { A as JWK, L as JWKSet, N as JWKLookupFunction, S as ContentEncryptionAlgorithm, a as JWEEncryptOptions, c as JWEProtectedHeader, g as JOSEPayload, i as JWEDecryptResult, nt as JWK_Private, o as JWEHeaderParameters, pt as KeyManagementAlgorithm, r as JWEDecryptOptions, s as JWEKeyManagementHeaderParameters, ut as JWK_Symmetric } from "../_chunks/index.mjs";
|
|
2
|
+
import { i as isJWTError, n as JWTErrorCauseMap, r as JWTErrorCode, t as JWTError } from "../_chunks/error.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/core/jwe.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Encrypts a payload to produce a JWE Compact Serialization string.
|
|
7
|
+
*
|
|
8
|
+
* @param payload The payload to encrypt. Can be a string, Uint8Array, or a JSON-serializable object.
|
|
9
|
+
* @param key The key encryption key (KEK). Can be a CryptoKey, JWK, or for PBES2, a password string/Uint8Array.
|
|
10
|
+
* @param options JWE encryption options, including `alg` (key management algorithm) and `enc` (content encryption algorithm).
|
|
11
|
+
* @returns A Promise resolving to the JWE Compact Serialization string.
|
|
12
|
+
*/
|
|
13
|
+
declare function encrypt(payload: JOSEPayload, key: JWK | string | Uint8Array<ArrayBuffer>, options?: JWEEncryptOptions): Promise<string>;
|
|
14
|
+
declare function encrypt(payload: JOSEPayload, key: CryptoKey | JWK_Symmetric | Uint8Array<ArrayBuffer>, options: JWEEncryptOptions & {
|
|
15
|
+
alg: "dir";
|
|
16
|
+
enc: ContentEncryptionAlgorithm;
|
|
17
|
+
}): Promise<string>;
|
|
18
|
+
declare function encrypt(payload: JOSEPayload, key: CryptoKey, options: JWEEncryptOptions & {
|
|
19
|
+
alg: KeyManagementAlgorithm;
|
|
20
|
+
enc: ContentEncryptionAlgorithm;
|
|
21
|
+
}): Promise<string>;
|
|
22
|
+
declare function encrypt(payload: JOSEPayload, key: CryptoKey | JWK | string | Uint8Array<ArrayBuffer>, options: JWEEncryptOptions & {
|
|
23
|
+
alg: KeyManagementAlgorithm;
|
|
24
|
+
enc: ContentEncryptionAlgorithm;
|
|
25
|
+
}): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Decrypts a JWE Compact Serialization string.
|
|
28
|
+
*
|
|
29
|
+
* @param jwe The JWE Compact Serialization string.
|
|
30
|
+
* @param key The key decryption key (KEK) or a function to look up the key.
|
|
31
|
+
* @param options JWE decryption options.
|
|
32
|
+
* @returns A Promise resolving to an object containing the decrypted plaintext, protected header, CEK, and AAD.
|
|
33
|
+
* @throws If JWE is invalid, decryption fails, or options are not met.
|
|
34
|
+
*/
|
|
35
|
+
declare function decrypt<T extends JOSEPayload>(jwe: string, key: CryptoKey | JWKSet | JWK_Private | JWK_Symmetric | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWEDecryptOptions): Promise<JWEDecryptResult<T>>;
|
|
36
|
+
declare function decrypt(jwe: string, key: CryptoKey | JWKSet | JWK_Private | JWK_Symmetric | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options: JWEDecryptOptions & {
|
|
37
|
+
forceUint8Array: true;
|
|
38
|
+
}): Promise<JWEDecryptResult<Uint8Array<ArrayBuffer>>>;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { JWEDecryptOptions, JWEDecryptResult, JWEEncryptOptions, JWEHeaderParameters, JWEKeyManagementHeaderParameters, JWEProtectedHeader, JWTError, type JWTErrorCauseMap, type JWTErrorCode, decrypt, encrypt, isJWTError };
|