unjwt 0.5.22 → 0.5.23
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/h3.d.mts +19 -18
- package/dist/h3.mjs +139 -101
- package/dist/index.mjs +4 -4
- package/dist/jwe.mjs +3 -3
- package/dist/jwk.mjs +2 -2
- package/dist/jws.mjs +3 -3
- package/dist/shared/{unjwt.DCiTNyCM.mjs → unjwt.C86hA0o-.mjs} +1 -1
- package/dist/shared/{unjwt.CXl9FD-V.mjs → unjwt.CiBEuvtQ.mjs} +2 -2
- package/dist/shared/{unjwt.DmRAjMp8.mjs → unjwt.D-FATaw1.mjs} +2 -2
- package/dist/shared/{unjwt.Vg02PZWw.mjs → unjwt.epPK1KFr.mjs} +5 -2
- package/dist/utils.mjs +1 -1
- package/package.json +2 -2
package/dist/h3.d.mts
CHANGED
|
@@ -9,7 +9,7 @@ export { d as deriveJWKFromPassword, e as exportJWKToPEM, g as generateJWK, i as
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* This is a fork of h3 library's session utility functions.
|
|
12
|
-
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/
|
|
12
|
+
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/src/utils/session.ts
|
|
13
13
|
* @license MIT https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/LICENSE
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -24,11 +24,11 @@ interface SessionJWE<T extends SessionDataT$1 = SessionDataT$1> {
|
|
|
24
24
|
[kGetSessionPromise$1]?: Promise<SessionJWE<T>>;
|
|
25
25
|
}
|
|
26
26
|
interface SessionHooksJWE {
|
|
27
|
-
onRead?: (session: SessionJWE, event: H3Event) => void | Promise<void>;
|
|
28
|
-
onUpdate?: (session: SessionJWE, event: H3Event) => void | Promise<void>;
|
|
29
|
-
onClear?: (event: H3Event) => void | Promise<void>;
|
|
30
|
-
onExpire?: (event: H3Event, error: any | undefined) => void | Promise<void>;
|
|
31
|
-
onError?: (event: H3Event, error: any) => void | Promise<void>;
|
|
27
|
+
onRead?: (session: SessionJWE, event: H3Event, config: SessionConfigJWE) => void | Promise<void>;
|
|
28
|
+
onUpdate?: (session: SessionJWE, event: H3Event, config: SessionConfigJWE) => void | Promise<void>;
|
|
29
|
+
onClear?: (event: H3Event, config: Partial<SessionConfigJWE>) => void | Promise<void>;
|
|
30
|
+
onExpire?: (event: H3Event, error: any | undefined, config: SessionConfigJWE) => void | Promise<void>;
|
|
31
|
+
onError?: (event: H3Event, error: any, config: SessionConfigJWE) => void | Promise<void>;
|
|
32
32
|
}
|
|
33
33
|
interface SessionManager<T extends SessionDataT$1 = SessionDataT$1> {
|
|
34
34
|
readonly id: string | undefined;
|
|
@@ -39,8 +39,13 @@ interface SessionManager<T extends SessionDataT$1 = SessionDataT$1> {
|
|
|
39
39
|
clear: () => Promise<SessionManager<T>>;
|
|
40
40
|
}
|
|
41
41
|
interface SessionConfigJWE {
|
|
42
|
-
/**
|
|
43
|
-
secret
|
|
42
|
+
/** @deprecated use `key` instead */
|
|
43
|
+
secret?: string | JWK_Symmetric | {
|
|
44
|
+
privateKey: JWK_Private | JWK_Symmetric;
|
|
45
|
+
publicKey?: JWK_Public;
|
|
46
|
+
};
|
|
47
|
+
/** Shared key used, string for PBES2 or Json Web Key (JWK) */
|
|
48
|
+
key: string | JWK_Symmetric | JWK_Private | {
|
|
44
49
|
privateKey: JWK_Private | JWK_Symmetric;
|
|
45
50
|
publicKey?: JWK_Public;
|
|
46
51
|
};
|
|
@@ -52,8 +57,6 @@ interface SessionConfigJWE {
|
|
|
52
57
|
cookie?: false | CookieSerializeOptions;
|
|
53
58
|
/** Default is x-h3-session / x-{name}-session */
|
|
54
59
|
sessionHeader?: false | string;
|
|
55
|
-
/** Optional WebCrypto implementation override */
|
|
56
|
-
crypto?: Crypto;
|
|
57
60
|
/** Default is crypto.randomUUID */
|
|
58
61
|
generateId?: () => string;
|
|
59
62
|
/** JWE configuration overrides */
|
|
@@ -111,7 +114,7 @@ declare function clearJWESession(event: H3Event, config: Partial<SessionConfigJW
|
|
|
111
114
|
|
|
112
115
|
/**
|
|
113
116
|
* This is a fork of h3 library's session utility functions.
|
|
114
|
-
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/
|
|
117
|
+
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/src/utils/session.ts
|
|
115
118
|
* @license MIT https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/LICENSE
|
|
116
119
|
*/
|
|
117
120
|
|
|
@@ -125,11 +128,11 @@ interface SessionJWS<T extends SessionDataT = SessionDataT> {
|
|
|
125
128
|
[kGetSessionPromise]?: Promise<SessionJWS<T>>;
|
|
126
129
|
}
|
|
127
130
|
interface SessionHooksJWS {
|
|
128
|
-
onRead?: (session: SessionJWS, event: H3Event) => void | Promise<void>;
|
|
129
|
-
onUpdate?: (session: SessionJWS, event: H3Event) => void | Promise<void>;
|
|
130
|
-
onClear?: (event: H3Event) => void | Promise<void>;
|
|
131
|
-
onExpire?: (event: H3Event, error: any | undefined) => void | Promise<void>;
|
|
132
|
-
onError?: (event: H3Event, error: any) => void | Promise<void>;
|
|
131
|
+
onRead?: (session: SessionJWS, event: H3Event, config: SessionConfigJWS) => void | Promise<void>;
|
|
132
|
+
onUpdate?: (session: SessionJWS, event: H3Event, config: SessionConfigJWS) => void | Promise<void>;
|
|
133
|
+
onClear?: (event: H3Event, config: Partial<SessionConfigJWS>) => void | Promise<void>;
|
|
134
|
+
onExpire?: (event: H3Event, error: any | undefined, config: SessionConfigJWS) => void | Promise<void>;
|
|
135
|
+
onError?: (event: H3Event, error: any, config: SessionConfigJWS) => void | Promise<void>;
|
|
133
136
|
}
|
|
134
137
|
interface SessionConfigJWS {
|
|
135
138
|
/**
|
|
@@ -147,8 +150,6 @@ interface SessionConfigJWS {
|
|
|
147
150
|
cookie?: false | CookieSerializeOptions;
|
|
148
151
|
/** Custom header (false to disable header lookup) */
|
|
149
152
|
sessionHeader?: false | string;
|
|
150
|
-
/** Provide a custom WebCrypto (if needed for algorithm operations) */
|
|
151
|
-
crypto?: Crypto;
|
|
152
153
|
/** Custom ID generator (defaults to crypto.randomUUID) */
|
|
153
154
|
generateId?: () => string;
|
|
154
155
|
/** JWS customization */
|
package/dist/h3.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export { k as deriveJWKFromPassword, h as exportJWKToPEM, c as generateJWK, f as importJWKFromPEM } from './shared/unjwt.
|
|
1
|
+
export { k as deriveJWKFromPassword, h as exportJWKToPEM, c as generateJWK, f as importJWKFromPEM } from './shared/unjwt.epPK1KFr.mjs';
|
|
2
2
|
import { isEvent, setCookie } from 'h3';
|
|
3
3
|
import { parse } from 'cookie-es';
|
|
4
|
-
import { e as encrypt, d as decrypt } from './shared/unjwt.
|
|
5
|
-
import { p as isSymmetricJWK, q as isPrivateJWK, u as
|
|
6
|
-
import { s as sign, v as verify } from './shared/unjwt.
|
|
4
|
+
import { e as encrypt, d as decrypt } from './shared/unjwt.CiBEuvtQ.mjs';
|
|
5
|
+
import { p as isSymmetricJWK, q as isPrivateJWK, u as isPublicJWK } from './shared/unjwt.C86hA0o-.mjs';
|
|
6
|
+
import { s as sign, v as verify } from './shared/unjwt.D-FATaw1.mjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* This is a fork of h3 library's session utility functions.
|
|
10
|
-
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/
|
|
10
|
+
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/src/utils/session.ts
|
|
11
11
|
* @license MIT https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/LICENSE
|
|
12
12
|
*/
|
|
13
13
|
const kGetSessionPromise$1 = Symbol("h3_jwe_getSession");
|
|
@@ -57,22 +57,15 @@ async function getJWESession(event, config) {
|
|
|
57
57
|
}
|
|
58
58
|
const existingSession = event.context.sessions[sessionName];
|
|
59
59
|
if (existingSession) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
await config.hooks?.
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
await config.hooks?.onExpire?.(event, void 0);
|
|
67
|
-
return clearJWESession(event, config).then(
|
|
68
|
-
() => getJWESession(event, config)
|
|
69
|
-
);
|
|
70
|
-
} else {
|
|
71
|
-
const session2 = existingSession[kGetSessionPromise$1] || existingSession;
|
|
72
|
-
await config.hooks?.onRead?.(await session2, event);
|
|
73
|
-
return session2;
|
|
74
|
-
}
|
|
60
|
+
const session2 = existingSession[kGetSessionPromise$1] ? await existingSession[kGetSessionPromise$1] : existingSession;
|
|
61
|
+
if (session2.expiresAt !== void 0 && session2.expiresAt < Date.now() && isEvent(event)) {
|
|
62
|
+
await config.hooks?.onExpire?.(event, void 0, config);
|
|
63
|
+
return clearJWESession(event, config).then(
|
|
64
|
+
() => getJWESession(event, config)
|
|
65
|
+
);
|
|
75
66
|
}
|
|
67
|
+
await config.hooks?.onRead?.(session2, event, config);
|
|
68
|
+
return session2;
|
|
76
69
|
}
|
|
77
70
|
const session = {
|
|
78
71
|
id: "",
|
|
@@ -97,14 +90,11 @@ async function getJWESession(event, config) {
|
|
|
97
90
|
}
|
|
98
91
|
if (jweToken) {
|
|
99
92
|
const promise = unsealJWESession(event, config, jweToken).catch(async (error_) => {
|
|
100
|
-
if (error_ instanceof Error) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
await config.hooks?.onExpire?.(event, error_);
|
|
104
|
-
return void 0;
|
|
105
|
-
}
|
|
93
|
+
if (error_ instanceof Error && (error_.message.includes("Token has expired") || error_.message.includes("Token is too old"))) {
|
|
94
|
+
await config.hooks?.onExpire?.(event, error_, config);
|
|
95
|
+
return void 0;
|
|
106
96
|
}
|
|
107
|
-
await config.hooks?.onError?.(event, error_);
|
|
97
|
+
await config.hooks?.onError?.(event, error_, config);
|
|
108
98
|
return void 0;
|
|
109
99
|
}).then((unsealed) => {
|
|
110
100
|
if (unsealed) {
|
|
@@ -122,13 +112,12 @@ async function getJWESession(event, config) {
|
|
|
122
112
|
"Cannot initialize a new session. Use `useSession(event)` within the main handler."
|
|
123
113
|
);
|
|
124
114
|
}
|
|
125
|
-
session.id = config.generateId?.() ??
|
|
126
|
-
session.createdAt = config.jwe?.encryptOptions?.currentDate
|
|
115
|
+
session.id = config.generateId?.() ?? crypto.randomUUID();
|
|
116
|
+
session.createdAt = config.jwe?.encryptOptions?.currentDate?.getTime() ?? Date.now();
|
|
127
117
|
session.expiresAt = config.maxAge ? session.createdAt + config.maxAge * 1e3 : void 0;
|
|
128
|
-
session.data = /* @__PURE__ */ Object.create(null);
|
|
129
118
|
await updateJWESession(event, config);
|
|
130
119
|
}
|
|
131
|
-
await config.hooks?.onRead?.(session, event);
|
|
120
|
+
await config.hooks?.onRead?.(session, event, config);
|
|
132
121
|
return session;
|
|
133
122
|
}
|
|
134
123
|
function _getReqHeader$1(event, name) {
|
|
@@ -150,7 +139,7 @@ async function updateJWESession(event, config, update) {
|
|
|
150
139
|
}
|
|
151
140
|
if (update) {
|
|
152
141
|
Object.assign(session.data, update);
|
|
153
|
-
await config.hooks?.onUpdate?.(session, event);
|
|
142
|
+
await config.hooks?.onUpdate?.(session, event, config);
|
|
154
143
|
}
|
|
155
144
|
if (config.cookie !== false) {
|
|
156
145
|
const sealed = await sealJWESession(event, config);
|
|
@@ -166,12 +155,7 @@ async function updateJWESession(event, config, update) {
|
|
|
166
155
|
return session;
|
|
167
156
|
}
|
|
168
157
|
async function sealJWESession(event, config) {
|
|
169
|
-
const key = getEncryptKey(config.secret);
|
|
170
|
-
if (typeof key !== "string" && !isSymmetricJWK(key) && !isPrivateJWK(key)) {
|
|
171
|
-
throw new Error(
|
|
172
|
-
"Session: JWE secret must be a password string or a private JWK."
|
|
173
|
-
);
|
|
174
|
-
}
|
|
158
|
+
const key = getEncryptKey(config.key || config.secret);
|
|
175
159
|
const sessionName = config.name || DEFAULT_NAME$1;
|
|
176
160
|
const session = event.context.sessions?.[sessionName] || await getJWESession(event, config);
|
|
177
161
|
const iatSeconds = Math.floor(session.createdAt / 1e3);
|
|
@@ -184,25 +168,30 @@ async function sealJWESession(event, config) {
|
|
|
184
168
|
if (expSeconds) {
|
|
185
169
|
payload.exp = expSeconds;
|
|
186
170
|
}
|
|
171
|
+
let typ = void 0;
|
|
172
|
+
if (config.jwe?.encryptOptions?.protectedHeader?.typ && typeof config.jwe.encryptOptions.protectedHeader.typ === "string" && config.jwe.encryptOptions.protectedHeader.typ.toLowerCase().includes("jwt")) {
|
|
173
|
+
typ = config.jwe.encryptOptions.protectedHeader.typ;
|
|
174
|
+
}
|
|
187
175
|
const token = await encrypt(payload, key, {
|
|
188
176
|
...config.jwe?.encryptOptions,
|
|
177
|
+
expiresIn: void 0,
|
|
178
|
+
// controlled via 'exp' claim
|
|
189
179
|
protectedHeader: {
|
|
190
180
|
...config.jwe?.encryptOptions?.protectedHeader,
|
|
191
|
-
|
|
181
|
+
kid: typeof key === "string" ? void 0 : key.kid,
|
|
182
|
+
typ: typ || "JWT",
|
|
192
183
|
cty: "application/json"
|
|
193
184
|
}
|
|
194
185
|
});
|
|
195
186
|
return token;
|
|
196
187
|
}
|
|
197
188
|
async function unsealJWESession(_event, config, sealed) {
|
|
198
|
-
const key = getDecryptKey(config.secret);
|
|
199
|
-
if (typeof key !== "string" && !isSymmetricJWK(key) && !isPrivateJWK(key)) {
|
|
200
|
-
throw new Error(
|
|
201
|
-
"Session: JWE secret must be a password string or a private JWK."
|
|
202
|
-
);
|
|
203
|
-
}
|
|
189
|
+
const key = getDecryptKey(config.key || config.secret);
|
|
204
190
|
const alg = config.jwe?.encryptOptions?.alg;
|
|
205
191
|
const enc = config.jwe?.encryptOptions?.enc;
|
|
192
|
+
if (config.jwe?.encryptOptions?.protectedHeader?.typ && typeof config.jwe.encryptOptions.protectedHeader.typ === "string" && config.jwe.encryptOptions.protectedHeader.typ.toLowerCase().includes("jwt")) {
|
|
193
|
+
config.jwe.encryptOptions.protectedHeader.typ;
|
|
194
|
+
}
|
|
206
195
|
const { payload } = await decrypt(sealed, key, {
|
|
207
196
|
...config.jwe?.decryptOptions,
|
|
208
197
|
requiredClaims: [
|
|
@@ -243,32 +232,57 @@ async function clearJWESession(event, config) {
|
|
|
243
232
|
setCookie(event, sessionName, "", {
|
|
244
233
|
...DEFAULT_COOKIE$1,
|
|
245
234
|
...config.cookie,
|
|
246
|
-
// Optionally set expires in the past
|
|
247
235
|
expires: /* @__PURE__ */ new Date(0),
|
|
248
236
|
maxAge: void 0
|
|
249
237
|
});
|
|
250
|
-
await config.hooks?.onClear?.(event);
|
|
238
|
+
await config.hooks?.onClear?.(event, config);
|
|
251
239
|
}
|
|
252
|
-
function getEncryptKey(
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
|
|
240
|
+
function getEncryptKey(key) {
|
|
241
|
+
if (!key) {
|
|
242
|
+
throw new Error("Session: JWE key is required.");
|
|
243
|
+
}
|
|
244
|
+
let _key;
|
|
245
|
+
if (typeof key === "string") {
|
|
246
|
+
_key = key;
|
|
247
|
+
} else if (isSymmetricJWK(key) || isPrivateJWK(key)) {
|
|
248
|
+
_key = key;
|
|
249
|
+
} else if ("publicKey" in key && isPublicJWK(key.publicKey)) {
|
|
250
|
+
_key = key.publicKey;
|
|
251
|
+
} else if ("privateKey" in key && isPrivateJWK(key.privateKey)) {
|
|
252
|
+
_key = key.privateKey;
|
|
253
|
+
}
|
|
254
|
+
if (!_key) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
"Session: Invalid JWE key. It must be a password string or valid JWK.",
|
|
257
|
+
{ cause: key }
|
|
258
|
+
);
|
|
257
259
|
}
|
|
258
|
-
return
|
|
260
|
+
return _key;
|
|
259
261
|
}
|
|
260
|
-
function getDecryptKey(
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
262
|
+
function getDecryptKey(key) {
|
|
263
|
+
if (!key) {
|
|
264
|
+
throw new Error("Session: JWE key is required.");
|
|
265
|
+
}
|
|
266
|
+
let _key = void 0;
|
|
267
|
+
if (typeof key === "string") {
|
|
268
|
+
_key = key;
|
|
269
|
+
} else if (isSymmetricJWK(key)) {
|
|
270
|
+
_key = key;
|
|
271
|
+
} else if ("privateKey" in key) {
|
|
272
|
+
_key = key.privateKey;
|
|
273
|
+
}
|
|
274
|
+
if (!_key) {
|
|
275
|
+
throw new Error(
|
|
276
|
+
"Session: Invalid JWE key. It must be a password string or a valid private JWK.",
|
|
277
|
+
{ cause: key }
|
|
278
|
+
);
|
|
265
279
|
}
|
|
266
|
-
return
|
|
280
|
+
return _key;
|
|
267
281
|
}
|
|
268
282
|
|
|
269
283
|
/**
|
|
270
284
|
* This is a fork of h3 library's session utility functions.
|
|
271
|
-
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/
|
|
285
|
+
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/src/utils/session.ts
|
|
272
286
|
* @license MIT https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/LICENSE
|
|
273
287
|
*/
|
|
274
288
|
const kGetSessionPromise = Symbol("h3_jws_getSession");
|
|
@@ -318,22 +332,15 @@ async function getJWSSession(event, config) {
|
|
|
318
332
|
}
|
|
319
333
|
const existingSession = event.context.sessions[sessionName];
|
|
320
334
|
if (existingSession) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
await config.hooks?.
|
|
324
|
-
return
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
await config.hooks?.onExpire?.(event, void 0);
|
|
328
|
-
return clearJWSSession(event, config).then(
|
|
329
|
-
() => getJWSSession(event, config)
|
|
330
|
-
);
|
|
331
|
-
} else {
|
|
332
|
-
const session2 = existingSession[kGetSessionPromise] || existingSession;
|
|
333
|
-
await config.hooks?.onRead?.(await session2, event);
|
|
334
|
-
return session2;
|
|
335
|
-
}
|
|
335
|
+
const session2 = existingSession[kGetSessionPromise] ? await existingSession[kGetSessionPromise] : existingSession;
|
|
336
|
+
if (session2.expiresAt !== void 0 && session2.expiresAt < Date.now() && isEvent(event)) {
|
|
337
|
+
await config.hooks?.onExpire?.(event, void 0, config);
|
|
338
|
+
return clearJWSSession(event, config).then(
|
|
339
|
+
() => getJWSSession(event, config)
|
|
340
|
+
);
|
|
336
341
|
}
|
|
342
|
+
await config.hooks?.onRead?.(session2, event, config);
|
|
343
|
+
return session2;
|
|
337
344
|
}
|
|
338
345
|
const session = {
|
|
339
346
|
id: "",
|
|
@@ -358,14 +365,11 @@ async function getJWSSession(event, config) {
|
|
|
358
365
|
}
|
|
359
366
|
if (token) {
|
|
360
367
|
const promise = verifyJWSSession(event, config, token).catch(async (error_) => {
|
|
361
|
-
if (error_ instanceof Error) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
await config.hooks?.onExpire?.(event, error_);
|
|
365
|
-
return void 0;
|
|
366
|
-
}
|
|
368
|
+
if (error_ instanceof Error && (error_.message.includes("Token has expired") || error_.message.includes("Token is too old"))) {
|
|
369
|
+
await config.hooks?.onExpire?.(event, error_, config);
|
|
370
|
+
return void 0;
|
|
367
371
|
}
|
|
368
|
-
await config.hooks?.onError?.(event, error_);
|
|
372
|
+
await config.hooks?.onError?.(event, error_, config);
|
|
369
373
|
return void 0;
|
|
370
374
|
}).then((unsealed) => {
|
|
371
375
|
if (unsealed) {
|
|
@@ -383,13 +387,12 @@ async function getJWSSession(event, config) {
|
|
|
383
387
|
"Cannot initialize a new session outside main handler. Use `useJWSSession(event)` properly."
|
|
384
388
|
);
|
|
385
389
|
}
|
|
386
|
-
session.id = config.generateId?.() ??
|
|
387
|
-
session.createdAt = config.jws?.signOptions?.currentDate
|
|
390
|
+
session.id = config.generateId?.() ?? crypto.randomUUID();
|
|
391
|
+
session.createdAt = config.jws?.signOptions?.currentDate?.getTime() ?? Date.now();
|
|
388
392
|
session.expiresAt = config.maxAge ? session.createdAt + config.maxAge * 1e3 : void 0;
|
|
389
|
-
session.data = /* @__PURE__ */ Object.create(null);
|
|
390
393
|
await updateJWSSession(event, config);
|
|
391
394
|
}
|
|
392
|
-
await config.hooks?.onRead?.(session, event);
|
|
395
|
+
await config.hooks?.onRead?.(session, event, config);
|
|
393
396
|
return session;
|
|
394
397
|
}
|
|
395
398
|
function _getReqHeader(event, name) {
|
|
@@ -411,7 +414,7 @@ async function updateJWSSession(event, config, update) {
|
|
|
411
414
|
}
|
|
412
415
|
if (update) {
|
|
413
416
|
Object.assign(session.data, update);
|
|
414
|
-
await config.hooks?.onUpdate?.(session, event);
|
|
417
|
+
await config.hooks?.onUpdate?.(session, event, config);
|
|
415
418
|
}
|
|
416
419
|
if (config.cookie !== false) {
|
|
417
420
|
const token = await signJWSSession(event, config);
|
|
@@ -425,9 +428,6 @@ async function updateJWSSession(event, config, update) {
|
|
|
425
428
|
}
|
|
426
429
|
async function signJWSSession(event, config) {
|
|
427
430
|
const key = getSignKey(config.key);
|
|
428
|
-
if (isAsymmetricJWK(key) && !isPrivateJWK(key)) {
|
|
429
|
-
throw new Error("Session: JWS key cannot be a public asymmetric JWK.");
|
|
430
|
-
}
|
|
431
431
|
const sessionName = config.name || DEFAULT_NAME;
|
|
432
432
|
const session = event.context.sessions?.[sessionName] || await getJWSSession(event, config);
|
|
433
433
|
const iatSeconds = Math.floor(session.createdAt / 1e3);
|
|
@@ -440,11 +440,19 @@ async function signJWSSession(event, config) {
|
|
|
440
440
|
if (expSeconds) {
|
|
441
441
|
payload.exp = expSeconds;
|
|
442
442
|
}
|
|
443
|
+
let typ = void 0;
|
|
444
|
+
if (config.jws?.signOptions?.protectedHeader?.typ && typeof config.jws.signOptions.protectedHeader.typ === "string" && config.jws.signOptions.protectedHeader.typ.toLowerCase().includes("jwt")) {
|
|
445
|
+
typ = config.jws.signOptions.protectedHeader.typ;
|
|
446
|
+
}
|
|
443
447
|
const token = await sign(payload, key, {
|
|
444
448
|
...config.jws?.signOptions,
|
|
449
|
+
expiresIn: void 0,
|
|
450
|
+
// controlled via 'exp' claim
|
|
445
451
|
protectedHeader: {
|
|
446
452
|
...config.jws?.signOptions?.protectedHeader,
|
|
447
|
-
|
|
453
|
+
kid: key.kid,
|
|
454
|
+
typ: typ || "JWT",
|
|
455
|
+
cty: "application/json"
|
|
448
456
|
}
|
|
449
457
|
});
|
|
450
458
|
return token;
|
|
@@ -452,8 +460,9 @@ async function signJWSSession(event, config) {
|
|
|
452
460
|
async function verifyJWSSession(_event, config, token) {
|
|
453
461
|
const alg = config.jws?.signOptions?.alg;
|
|
454
462
|
const jwk = getVerifyKey(config.key);
|
|
455
|
-
|
|
456
|
-
|
|
463
|
+
let typ = void 0;
|
|
464
|
+
if (config.jws?.signOptions?.protectedHeader?.typ && typeof config.jws.signOptions.protectedHeader.typ === "string" && config.jws.signOptions.protectedHeader.typ.toLowerCase().includes("jwt")) {
|
|
465
|
+
typ = config.jws.signOptions.protectedHeader.typ;
|
|
457
466
|
}
|
|
458
467
|
const { payload } = await verify(token, jwk, {
|
|
459
468
|
...config.jws?.verifyOptions,
|
|
@@ -464,7 +473,7 @@ async function verifyJWSSession(_event, config, token) {
|
|
|
464
473
|
"jti",
|
|
465
474
|
"iat"
|
|
466
475
|
],
|
|
467
|
-
typ: "JWT",
|
|
476
|
+
typ: typ || "JWT",
|
|
468
477
|
algorithms: alg ? [alg] : void 0,
|
|
469
478
|
forceUint8Array: false,
|
|
470
479
|
validateJWT: true
|
|
@@ -492,19 +501,48 @@ async function clearJWSSession(event, config) {
|
|
|
492
501
|
expires: /* @__PURE__ */ new Date(0),
|
|
493
502
|
maxAge: void 0
|
|
494
503
|
});
|
|
495
|
-
await config.hooks?.onClear?.(event);
|
|
504
|
+
await config.hooks?.onClear?.(event, config);
|
|
496
505
|
}
|
|
497
506
|
function getSignKey(key) {
|
|
498
|
-
if (
|
|
499
|
-
|
|
507
|
+
if (!key) {
|
|
508
|
+
throw new Error("Session: JWS key is required.");
|
|
509
|
+
}
|
|
510
|
+
let _key = void 0;
|
|
511
|
+
if (isSymmetricJWK(key)) {
|
|
512
|
+
_key = key;
|
|
513
|
+
} else if ("privateKey" in key && isPrivateJWK(key.privateKey)) {
|
|
514
|
+
_key = key.privateKey;
|
|
500
515
|
}
|
|
501
|
-
|
|
516
|
+
if (!_key) {
|
|
517
|
+
throw new Error(
|
|
518
|
+
"Session: Invalid JWS key. It must be a symmetric JWK or a private JWK.",
|
|
519
|
+
{ cause: key }
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
return _key;
|
|
502
523
|
}
|
|
503
524
|
function getVerifyKey(key) {
|
|
504
|
-
if (
|
|
505
|
-
|
|
525
|
+
if (!key) {
|
|
526
|
+
throw new Error("Session: JWS key is required.");
|
|
527
|
+
}
|
|
528
|
+
let _key = void 0;
|
|
529
|
+
if (isSymmetricJWK(key)) {
|
|
530
|
+
_key = key;
|
|
531
|
+
} else if ("publicKey" in key && isPublicJWK(key.publicKey)) {
|
|
532
|
+
_key = key.publicKey;
|
|
533
|
+
} else if ("publicKey" in key && Array.isArray(key.publicKey)) {
|
|
534
|
+
const keys = key.publicKey.filter((k) => isPublicJWK(k));
|
|
535
|
+
if (keys && keys.length > 0) {
|
|
536
|
+
_key = { keys };
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (!_key) {
|
|
540
|
+
throw new Error(
|
|
541
|
+
"Session: Invalid JWS key. It must be a symmetric JWK or a public JWK/set.",
|
|
542
|
+
{ cause: key }
|
|
543
|
+
);
|
|
506
544
|
}
|
|
507
|
-
return
|
|
545
|
+
return _key;
|
|
508
546
|
}
|
|
509
547
|
|
|
510
548
|
export { clearJWESession, clearJWSSession, getJWESession, getJWSSession, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { i as utils } from './shared/unjwt.
|
|
2
|
-
export { j as jwe } from './shared/unjwt.
|
|
3
|
-
export { j as jwk } from './shared/unjwt.
|
|
4
|
-
export { j as jws } from './shared/unjwt.
|
|
1
|
+
export { i as utils } from './shared/unjwt.C86hA0o-.mjs';
|
|
2
|
+
export { j as jwe } from './shared/unjwt.CiBEuvtQ.mjs';
|
|
3
|
+
export { j as jwk } from './shared/unjwt.epPK1KFr.mjs';
|
|
4
|
+
export { j as jws } from './shared/unjwt.D-FATaw1.mjs';
|
package/dist/jwe.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import './shared/unjwt.
|
|
2
|
-
import './shared/unjwt.
|
|
3
|
-
export { d as decrypt, e as encrypt } from './shared/unjwt.
|
|
1
|
+
import './shared/unjwt.epPK1KFr.mjs';
|
|
2
|
+
import './shared/unjwt.C86hA0o-.mjs';
|
|
3
|
+
export { d as decrypt, e as encrypt } from './shared/unjwt.CiBEuvtQ.mjs';
|
package/dist/jwk.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import './shared/unjwt.
|
|
2
|
-
export { k as deriveJWKFromPassword, m as deriveKeyFromPassword, h as exportJWKToPEM, n as exportKey, c as generateJWK, l as generateKey, b as getJWKFromSet, f as importJWKFromPEM, i as importKey, u as unwrapKey, w as wrapKey } from './shared/unjwt.
|
|
1
|
+
import './shared/unjwt.C86hA0o-.mjs';
|
|
2
|
+
export { k as deriveJWKFromPassword, m as deriveKeyFromPassword, h as exportJWKToPEM, n as exportKey, c as generateJWK, l as generateKey, b as getJWKFromSet, f as importJWKFromPEM, i as importKey, u as unwrapKey, w as wrapKey } from './shared/unjwt.epPK1KFr.mjs';
|
package/dist/jws.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import './shared/unjwt.
|
|
2
|
-
import './shared/unjwt.
|
|
3
|
-
export { s as sign, v as verify } from './shared/unjwt.
|
|
1
|
+
import './shared/unjwt.epPK1KFr.mjs';
|
|
2
|
+
import './shared/unjwt.C86hA0o-.mjs';
|
|
3
|
+
export { s as sign, v as verify } from './shared/unjwt.D-FATaw1.mjs';
|
|
@@ -435,4 +435,4 @@ const index = {
|
|
|
435
435
|
validateJwtClaims: validateJwtClaims
|
|
436
436
|
};
|
|
437
437
|
|
|
438
|
-
export {
|
|
438
|
+
export { isAsymmetricJWK as A, maybeArray as B, isJWTContent as C, decodeMaybeJWTString as D, computeExpiresInSeconds as E, computeMaxTokenAgeSeconds as F, isJWK as a, applyTypCtyDefaults as b, computeJwtTimeClaims as c, base64UrlEncode as d, base64UrlDecode as e, decodePayloadFromBytes as f, getPlaintextBytes as g, validateJwtClaims as h, index as i, isCryptoKeyPair as j, isCryptoKey as k, textDecoder as l, isJWKSet as m, decodePayloadFromB64UrlSegment as n, validateCriticalHeadersJWS as o, isSymmetricJWK as p, isPrivateJWK as q, randomBytes as r, sanitizeObject as s, textEncoder as t, isPublicJWK as u, validateCriticalHeadersJWE as v, concatUint8Arrays as w, base64Decode as x, base64Encode as y, assertCryptoKey as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as importKey, e as encryptKey, g as generateIV, a as encrypt$1, u as unwrapKey, d as decrypt$1 } from './unjwt.
|
|
2
|
-
import { r as randomBytes, a as isJWK, s as sanitizeObject, b as applyTypCtyDefaults, c as computeJwtTimeClaims, g as getPlaintextBytes, d as base64UrlEncode, t as textEncoder, e as base64UrlDecode, f as decodePayloadFromBytes, v as validateCriticalHeadersJWE, h as validateJwtClaims, j as isCryptoKeyPair, k as isCryptoKey } from './unjwt.
|
|
1
|
+
import { i as importKey, e as encryptKey, g as generateIV, a as encrypt$1, u as unwrapKey, d as decrypt$1 } from './unjwt.epPK1KFr.mjs';
|
|
2
|
+
import { r as randomBytes, a as isJWK, s as sanitizeObject, b as applyTypCtyDefaults, c as computeJwtTimeClaims, g as getPlaintextBytes, d as base64UrlEncode, t as textEncoder, e as base64UrlDecode, f as decodePayloadFromBytes, v as validateCriticalHeadersJWE, h as validateJwtClaims, j as isCryptoKeyPair, k as isCryptoKey } from './unjwt.C86hA0o-.mjs';
|
|
3
3
|
|
|
4
4
|
async function encrypt(payload, key, options = {}) {
|
|
5
5
|
const {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as importKey, s as sign$1, b as getJWKFromSet, v as verify$1 } from './unjwt.
|
|
2
|
-
import { s as sanitizeObject, a as isJWK, b as applyTypCtyDefaults, c as computeJwtTimeClaims, d as base64UrlEncode, t as textEncoder, l as textDecoder, e as base64UrlDecode, m as isJWKSet, n as decodePayloadFromB64UrlSegment, o as validateCriticalHeadersJWS, h as validateJwtClaims } from './unjwt.
|
|
1
|
+
import { i as importKey, s as sign$1, b as getJWKFromSet, v as verify$1 } from './unjwt.epPK1KFr.mjs';
|
|
2
|
+
import { s as sanitizeObject, a as isJWK, b as applyTypCtyDefaults, c as computeJwtTimeClaims, d as base64UrlEncode, t as textEncoder, l as textDecoder, e as base64UrlDecode, m as isJWKSet, n as decodePayloadFromB64UrlSegment, o as validateCriticalHeadersJWS, h as validateJwtClaims } from './unjwt.C86hA0o-.mjs';
|
|
3
3
|
|
|
4
4
|
async function sign(payload, key, options = {}) {
|
|
5
5
|
const { protectedHeader: additionalProtectedHeader } = options;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { k as isCryptoKey, w as concatUint8Arrays, d as base64UrlEncode, x as base64Decode, y as base64Encode, t as textEncoder, s as sanitizeObject, z as assertCryptoKey, a as isJWK, e as base64UrlDecode,
|
|
1
|
+
import { k as isCryptoKey, w as concatUint8Arrays, d as base64UrlEncode, x as base64Decode, y as base64Encode, t as textEncoder, s as sanitizeObject, z as assertCryptoKey, a as isJWK, e as base64UrlDecode, A as isAsymmetricJWK, r as randomBytes, m as isJWKSet } from './unjwt.C86hA0o-.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This is a fork of Jose library's utility functions.
|
|
@@ -1482,7 +1482,10 @@ async function generateJWK(alg, jwkParams, options = {}) {
|
|
|
1482
1482
|
} = options;
|
|
1483
1483
|
return generateKey(alg, {
|
|
1484
1484
|
...opts,
|
|
1485
|
-
toJWK:
|
|
1485
|
+
toJWK: {
|
|
1486
|
+
kid: typeof jwkParams?.kid === "string" ? jwkParams.kid : crypto.randomUUID(),
|
|
1487
|
+
...jwkParams
|
|
1488
|
+
}
|
|
1486
1489
|
});
|
|
1487
1490
|
}
|
|
1488
1491
|
async function deriveKeyFromPassword(password, alg, options) {
|
package/dist/utils.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { b as applyTypCtyDefaults, z as assertCryptoKey, x as base64Decode, y as base64Encode, e as base64UrlDecode, d as base64UrlEncode, E as computeExpiresInSeconds, c as computeJwtTimeClaims, F as computeMaxTokenAgeSeconds, w as concatUint8Arrays, D as decodeMaybeJWTString, n as decodePayloadFromB64UrlSegment, f as decodePayloadFromBytes, g as getPlaintextBytes,
|
|
1
|
+
export { b as applyTypCtyDefaults, z as assertCryptoKey, x as base64Decode, y as base64Encode, e as base64UrlDecode, d as base64UrlEncode, E as computeExpiresInSeconds, c as computeJwtTimeClaims, F as computeMaxTokenAgeSeconds, w as concatUint8Arrays, D as decodeMaybeJWTString, n as decodePayloadFromB64UrlSegment, f as decodePayloadFromBytes, g as getPlaintextBytes, A as isAsymmetricJWK, k as isCryptoKey, j as isCryptoKeyPair, a as isJWK, m as isJWKSet, C as isJWTContent, q as isPrivateJWK, u as isPublicJWK, p as isSymmetricJWK, B as maybeArray, r as randomBytes, s as sanitizeObject, l as textDecoder, t as textEncoder, v as validateCriticalHeadersJWE, o as validateCriticalHeadersJWS, h as validateJwtClaims } from './shared/unjwt.C86hA0o-.mjs';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unjwt",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.23",
|
|
4
4
|
"description": "Low-level JWT utilities",
|
|
5
5
|
"repository": "sandros94/unjwt",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
],
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "unbuild",
|
|
47
|
-
"dev": "
|
|
47
|
+
"dev": "bun --watch ./playground/main.ts",
|
|
48
48
|
"lint": "eslint . && prettier -c .",
|
|
49
49
|
"lint:fix": "automd && eslint . --fix && prettier -w .",
|
|
50
50
|
"prepack": "pnpm build",
|