unjwt 0.5.37 → 0.5.39
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 +142 -663
- package/dist/_chunks/chunk.mjs +13 -0
- package/dist/_chunks/h3v1.mjs +598 -0
- package/dist/_chunks/index.d.mts +250 -0
- package/dist/_chunks/index2.d.mts +108 -0
- package/dist/_chunks/jwe.d.mts +43 -0
- package/dist/_chunks/jwe.mjs +132 -0
- package/dist/_chunks/jwk.d.mts +575 -0
- package/dist/_chunks/jwk.mjs +1592 -0
- package/dist/_chunks/jws.d.mts +46 -0
- package/dist/_chunks/jws.mjs +2069 -0
- package/dist/_chunks/utils.mjs +374 -0
- package/dist/adapters/h3.d.mts +3 -265
- package/dist/adapters/h3.mjs +3 -706
- package/dist/adapters/h3v1.d.mts +3 -8
- package/dist/adapters/h3v1.mjs +3 -7
- package/dist/adapters/h3v2.d.mts +145 -146
- package/dist/adapters/h3v2.mjs +505 -596
- package/dist/index.d.mts +6 -8
- package/dist/index.mjs +5 -4
- package/dist/jwe.d.mts +3 -4
- package/dist/jwe.mjs +4 -3
- package/dist/jwk.d.mts +3 -2
- package/dist/jwk.mjs +3 -2
- package/dist/jws.d.mts +3 -3
- package/dist/jws.mjs +4 -3
- package/dist/utils.d.mts +3 -3
- package/dist/utils.mjs +2 -1
- package/package.json +33 -31
- package/dist/shared/unjwt.4JQCoID_.d.mts +0 -161
- package/dist/shared/unjwt.B-v62plj.mjs +0 -249
- package/dist/shared/unjwt.BCi3FEWr.d.mts +0 -328
- package/dist/shared/unjwt.BYDTEWa-.d.mts +0 -269
- package/dist/shared/unjwt.Be8NxwFK.mjs +0 -438
- package/dist/shared/unjwt.BqdNUKDr.d.mts +0 -64
- package/dist/shared/unjwt.CMNtw8ek.d.mts +0 -155
- package/dist/shared/unjwt.Cy2MlkUe.d.mts +0 -174
- package/dist/shared/unjwt.D0_ccT7g.d.mts +0 -166
- package/dist/shared/unjwt.DdLN9vwI.mjs +0 -163
- package/dist/shared/unjwt.Dpl__ZAR.mjs +0 -2121
- package/dist/shared/unjwt.JdKqVANs.d.mts +0 -5
package/dist/adapters/h3v2.mjs
CHANGED
|
@@ -1,652 +1,561 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { NullProtoObj } from
|
|
4
|
-
|
|
5
|
-
import { p as computeExpiresInSeconds, q as isSymmetricJWK, u as isPrivateJWK, w as isPublicJWK } from '../shared/unjwt.Be8NxwFK.mjs';
|
|
6
|
-
import { s as sign, v as verify } from '../shared/unjwt.DdLN9vwI.mjs';
|
|
7
|
-
|
|
1
|
+
import { a as deriveJWKFromPassword, c as importJWKFromPEM, d as isSymmetricJWK, f as computeExpiresInSeconds, i as encrypt, l as isPrivateJWK, n as verify, o as exportJWKToPEM, r as decrypt, s as generateJWK, t as sign, u as isPublicJWK } from "../_chunks/jws.mjs";
|
|
2
|
+
import { getChunkedCookie, getEventContext, setChunkedCookie } from "h3";
|
|
3
|
+
import { NullProtoObj } from "rou3";
|
|
4
|
+
//#region src/adapters/h3v2/session/jwe.ts
|
|
8
5
|
const kGetSessionPromise$1 = Symbol("h3_jwe_getSession");
|
|
6
|
+
const kSessionToken$1 = Symbol("h3_jwe_sessionToken");
|
|
9
7
|
const DEFAULT_NAME$1 = "h3-jwe";
|
|
10
8
|
const DEFAULT_COOKIE$1 = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
path: "/",
|
|
10
|
+
secure: true,
|
|
11
|
+
httpOnly: true
|
|
14
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Create a session manager for the current request.
|
|
15
|
+
*/
|
|
15
16
|
async function useJWESession(event, config) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
17
|
+
const sessionName = config.name || DEFAULT_NAME$1;
|
|
18
|
+
await getJWESession(event, config);
|
|
19
|
+
const sessionManager = {
|
|
20
|
+
get id() {
|
|
21
|
+
return getSessionFromContext$1(event, sessionName)?.id;
|
|
22
|
+
},
|
|
23
|
+
get createdAt() {
|
|
24
|
+
return getSessionFromContext$1(event, sessionName)?.createdAt ?? Date.now();
|
|
25
|
+
},
|
|
26
|
+
get expiresAt() {
|
|
27
|
+
return getSessionFromContext$1(event, sessionName)?.expiresAt;
|
|
28
|
+
},
|
|
29
|
+
get data() {
|
|
30
|
+
return getSessionFromContext$1(event, sessionName)?.data || {};
|
|
31
|
+
},
|
|
32
|
+
get token() {
|
|
33
|
+
return getSessionFromContext$1(event, sessionName)?.[kSessionToken$1] ?? getJWESessionToken(event, config);
|
|
34
|
+
},
|
|
35
|
+
update: async (update) => {
|
|
36
|
+
await updateJWESession(event, config, update);
|
|
37
|
+
return sessionManager;
|
|
38
|
+
},
|
|
39
|
+
clear: async () => {
|
|
40
|
+
await clearJWESession(event, config);
|
|
41
|
+
return sessionManager;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return sessionManager;
|
|
44
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Get the session for the current request.
|
|
48
|
+
*/
|
|
45
49
|
async function getJWESession(event, config) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
session,
|
|
116
|
-
config
|
|
117
|
-
});
|
|
118
|
-
return session;
|
|
50
|
+
const sessionName = config.name || DEFAULT_NAME$1;
|
|
51
|
+
const context = getEventContext(event);
|
|
52
|
+
if (!context.sessions) context.sessions = new NullProtoObj();
|
|
53
|
+
const existingSession = context.sessions[sessionName];
|
|
54
|
+
if (existingSession) {
|
|
55
|
+
const session = existingSession[kGetSessionPromise$1] ? await existingSession[kGetSessionPromise$1] : existingSession;
|
|
56
|
+
/**
|
|
57
|
+
* We check if a session is expired before returning it. If it is expired we clear it and create a new one,
|
|
58
|
+
* unless we have a read-only event in which case we just return it as it was valid at the time of reading
|
|
59
|
+
* the cookie/header (like in a websocket upgrade)
|
|
60
|
+
*/
|
|
61
|
+
if (session.expiresAt !== void 0 && session.expiresAt < Date.now() && hasWritableResponse$1(event)) {
|
|
62
|
+
await config.hooks?.onExpire?.({
|
|
63
|
+
event,
|
|
64
|
+
error: /* @__PURE__ */ new Error(`JWT "exp" (Expiration Time) Claim validation failed: Token has expired (exp: ${(/* @__PURE__ */ new Date(session.expiresAt * 1e3)).toISOString()})`),
|
|
65
|
+
config
|
|
66
|
+
});
|
|
67
|
+
return clearJWESession(event, config).then(() => getJWESession(event, config));
|
|
68
|
+
}
|
|
69
|
+
await config.hooks?.onRead?.({
|
|
70
|
+
event,
|
|
71
|
+
session,
|
|
72
|
+
config
|
|
73
|
+
});
|
|
74
|
+
return session;
|
|
75
|
+
}
|
|
76
|
+
const now = config.jwe?.encryptOptions?.currentDate?.getTime() ?? Date.now();
|
|
77
|
+
const createdAt = now - now % 1e3;
|
|
78
|
+
const session = {
|
|
79
|
+
id: void 0,
|
|
80
|
+
createdAt,
|
|
81
|
+
expiresAt: config.maxAge === void 0 ? void 0 : createdAt + computeExpiresInSeconds(config.maxAge) * 1e3,
|
|
82
|
+
data: new NullProtoObj()
|
|
83
|
+
};
|
|
84
|
+
context.sessions[sessionName] = session;
|
|
85
|
+
const token = getJWESessionToken(event, config);
|
|
86
|
+
if (token) {
|
|
87
|
+
session[kSessionToken$1] = token;
|
|
88
|
+
const promise = unsealJWESession(event, config, token).catch(async (error_) => {
|
|
89
|
+
if (error_ instanceof Error) {
|
|
90
|
+
const message = error_.message;
|
|
91
|
+
if (message.includes("Token has expired") || message.includes("Token is too old")) {
|
|
92
|
+
await config.hooks?.onExpire?.({
|
|
93
|
+
event,
|
|
94
|
+
error: error_,
|
|
95
|
+
config
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
await config.hooks?.onError?.({
|
|
101
|
+
event,
|
|
102
|
+
error: error_,
|
|
103
|
+
config
|
|
104
|
+
});
|
|
105
|
+
}).then((unsealed) => {
|
|
106
|
+
if (unsealed) Object.assign(session, unsealed);
|
|
107
|
+
delete session[kGetSessionPromise$1];
|
|
108
|
+
return session;
|
|
109
|
+
});
|
|
110
|
+
session[kGetSessionPromise$1] = promise;
|
|
111
|
+
await promise;
|
|
112
|
+
}
|
|
113
|
+
await config.hooks?.onRead?.({
|
|
114
|
+
event,
|
|
115
|
+
session,
|
|
116
|
+
config
|
|
117
|
+
});
|
|
118
|
+
return session;
|
|
119
119
|
}
|
|
120
120
|
function getJWESessionToken(event, config) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (!token) {
|
|
137
|
-
token = getChunkedCookie(event, sessionName);
|
|
138
|
-
}
|
|
139
|
-
return token;
|
|
121
|
+
const sessionName = config.name || DEFAULT_NAME$1;
|
|
122
|
+
let token;
|
|
123
|
+
if (config.sessionHeader !== false) {
|
|
124
|
+
const headerName = typeof config.sessionHeader === "string" ? config.sessionHeader.toLowerCase() : `x-${sessionName.toLowerCase()}-session`;
|
|
125
|
+
const headerValue = event.req.headers.get(headerName);
|
|
126
|
+
if (typeof headerValue === "string") token = headerValue.startsWith("Bearer ") ? headerValue.slice(7).trim() : headerValue;
|
|
127
|
+
}
|
|
128
|
+
if (config.cookie !== false && hasWritableResponse$1(event)) {
|
|
129
|
+
const setCookie = event.res.headers.get("set-cookie");
|
|
130
|
+
if (typeof setCookie === "string") token = findSetCookie$1(setCookie, sessionName);
|
|
131
|
+
}
|
|
132
|
+
if (!token) token = getChunkedCookie(event, sessionName);
|
|
133
|
+
return token;
|
|
140
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Update the session data for the current request.
|
|
137
|
+
*/
|
|
141
138
|
async function updateJWESession(event, config, update) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
return session;
|
|
139
|
+
const sessionName = config.name || DEFAULT_NAME$1;
|
|
140
|
+
const session = getEventContext(event).sessions?.[sessionName] || await getJWESession(event, config);
|
|
141
|
+
if (typeof update === "function") update = update(session.data);
|
|
142
|
+
if (update) {
|
|
143
|
+
const oldSession = {
|
|
144
|
+
...session,
|
|
145
|
+
data: { ...session.data }
|
|
146
|
+
};
|
|
147
|
+
Object.assign(session.data, update);
|
|
148
|
+
await config.hooks?.onUpdate?.({
|
|
149
|
+
oldSession,
|
|
150
|
+
session,
|
|
151
|
+
event,
|
|
152
|
+
config
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
const now = config.jwe?.encryptOptions?.currentDate?.getTime() ?? Date.now();
|
|
156
|
+
const createdAt = now - now % 1e3;
|
|
157
|
+
Object.assign(session, {
|
|
158
|
+
id: config.generateId?.() || crypto.randomUUID(),
|
|
159
|
+
createdAt,
|
|
160
|
+
expiresAt: config.maxAge === void 0 ? void 0 : createdAt + computeExpiresInSeconds(config.maxAge) * 1e3
|
|
161
|
+
});
|
|
162
|
+
if (config.cookie !== false && hasWritableResponse$1(event)) {
|
|
163
|
+
const sealed = await sealJWESession(event, config);
|
|
164
|
+
session[kSessionToken$1] = sealed;
|
|
165
|
+
setChunkedCookie(event, sessionName, sealed, {
|
|
166
|
+
...DEFAULT_COOKIE$1,
|
|
167
|
+
expires: config.maxAge === void 0 ? void 0 : new Date(session.createdAt + computeExpiresInSeconds(config.maxAge) * 1e3),
|
|
168
|
+
...config.cookie
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return session;
|
|
176
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Produce a JWE for the current session.
|
|
175
|
+
*/
|
|
177
176
|
async function sealJWESession(event, config) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
protectedHeader: {
|
|
201
|
-
...config.jwe?.encryptOptions?.protectedHeader,
|
|
202
|
-
typ: typ || "JWT",
|
|
203
|
-
cty: "application/json"
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
return token;
|
|
177
|
+
const key = getEncryptKey(config.key);
|
|
178
|
+
const sessionName = config.name || DEFAULT_NAME$1;
|
|
179
|
+
const session = getEventContext(event).sessions?.[sessionName] || await getJWESession(event, config);
|
|
180
|
+
const iat = Math.floor(session.createdAt / 1e3);
|
|
181
|
+
const exp = session.expiresAt ? Math.floor(session.expiresAt / 1e3) : void 0;
|
|
182
|
+
const payload = {
|
|
183
|
+
...session.data,
|
|
184
|
+
jti: session.id,
|
|
185
|
+
iat
|
|
186
|
+
};
|
|
187
|
+
if (exp) payload.exp = exp;
|
|
188
|
+
let typ = void 0;
|
|
189
|
+
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;
|
|
190
|
+
return await encrypt(payload, key, {
|
|
191
|
+
...config.jwe?.encryptOptions,
|
|
192
|
+
expiresIn: void 0,
|
|
193
|
+
protectedHeader: {
|
|
194
|
+
...config.jwe?.encryptOptions?.protectedHeader,
|
|
195
|
+
typ: typ || "JWT",
|
|
196
|
+
cty: "application/json"
|
|
197
|
+
}
|
|
198
|
+
});
|
|
207
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Decrypt the JWE and return a Session-compatible object.
|
|
202
|
+
*/
|
|
208
203
|
async function unsealJWESession(event, config, sealed) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
createdAt: iat * 1e3,
|
|
245
|
-
expiresAt: exp ? exp * 1e3 : void 0,
|
|
246
|
-
data: data && typeof data === "object" ? data : new NullProtoObj()
|
|
247
|
-
};
|
|
204
|
+
const key = config.hooks?.onUnsealKeyLookup ? (header) => config.hooks.onUnsealKeyLookup({
|
|
205
|
+
header,
|
|
206
|
+
event,
|
|
207
|
+
config
|
|
208
|
+
}) : getDecryptKey(config.key);
|
|
209
|
+
const alg = config.jwe?.encryptOptions?.alg;
|
|
210
|
+
const enc = config.jwe?.encryptOptions?.enc;
|
|
211
|
+
let typ = void 0;
|
|
212
|
+
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;
|
|
213
|
+
const { payload } = await decrypt(sealed, key, {
|
|
214
|
+
...config.jwe?.decryptOptions,
|
|
215
|
+
requiredClaims: [...new Set([
|
|
216
|
+
...config.jwe?.decryptOptions?.requiredClaims || [],
|
|
217
|
+
"jti",
|
|
218
|
+
"iat"
|
|
219
|
+
])],
|
|
220
|
+
typ: typ || "JWT",
|
|
221
|
+
maxTokenAge: config.maxAge,
|
|
222
|
+
algorithms: alg ? [alg] : void 0,
|
|
223
|
+
encryptionAlgorithms: enc ? [enc] : void 0,
|
|
224
|
+
unwrappedKeyAlgorithm: void 0,
|
|
225
|
+
keyUsage: void 0,
|
|
226
|
+
forceUint8Array: false,
|
|
227
|
+
validateJWT: true
|
|
228
|
+
}).catch((error_) => {
|
|
229
|
+
if (error_ instanceof Error) throw error_;
|
|
230
|
+
throw new Error(String(error_));
|
|
231
|
+
});
|
|
232
|
+
const { jti, iat, exp, ...data } = payload;
|
|
233
|
+
return {
|
|
234
|
+
id: jti,
|
|
235
|
+
createdAt: iat * 1e3,
|
|
236
|
+
expiresAt: exp ? exp * 1e3 : void 0,
|
|
237
|
+
data: data && typeof data === "object" ? data : new NullProtoObj()
|
|
238
|
+
};
|
|
248
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Clear the session (delete from context and drop cookie).
|
|
242
|
+
*/
|
|
249
243
|
async function clearJWESession(event, config) {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
event,
|
|
269
|
-
config
|
|
270
|
-
});
|
|
271
|
-
}
|
|
244
|
+
const context = getEventContext(event);
|
|
245
|
+
const sessionName = config.name || DEFAULT_NAME$1;
|
|
246
|
+
let session = context.sessions?.[sessionName];
|
|
247
|
+
if (session && session[kGetSessionPromise$1]) session = await session[kGetSessionPromise$1];
|
|
248
|
+
if (context.sessions?.[sessionName]) delete context.sessions[sessionName];
|
|
249
|
+
if (config.cookie !== false && hasWritableResponse$1(event)) {
|
|
250
|
+
setChunkedCookie(event, sessionName, "", {
|
|
251
|
+
...DEFAULT_COOKIE$1,
|
|
252
|
+
...config.cookie,
|
|
253
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
254
|
+
maxAge: void 0
|
|
255
|
+
});
|
|
256
|
+
await config.hooks?.onClear?.({
|
|
257
|
+
session,
|
|
258
|
+
event,
|
|
259
|
+
config
|
|
260
|
+
});
|
|
261
|
+
}
|
|
272
262
|
}
|
|
273
263
|
function getSessionFromContext$1(event, sessionName) {
|
|
274
|
-
|
|
275
|
-
return context.sessions?.[sessionName];
|
|
264
|
+
return getEventContext(event).sessions?.[sessionName];
|
|
276
265
|
}
|
|
277
266
|
function hasWritableResponse$1(event) {
|
|
278
|
-
|
|
267
|
+
return Boolean(event.res);
|
|
279
268
|
}
|
|
280
269
|
function getEncryptKey(key) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
} else if ("publicKey" in key && isPublicJWK(key.publicKey)) {
|
|
290
|
-
_key = key.publicKey;
|
|
291
|
-
} else if ("privateKey" in key && isPrivateJWK(key.privateKey)) {
|
|
292
|
-
_key = key.privateKey;
|
|
293
|
-
}
|
|
294
|
-
if (!_key) {
|
|
295
|
-
throw new Error(
|
|
296
|
-
"Session: Invalid JWE key. It must be a password string or valid JWK.",
|
|
297
|
-
{ cause: key }
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
return _key;
|
|
270
|
+
if (!key) throw new Error("Session: JWE key is required.");
|
|
271
|
+
let _key;
|
|
272
|
+
if (typeof key === "string") _key = key;
|
|
273
|
+
else if (isSymmetricJWK(key) || isPrivateJWK(key)) _key = key;
|
|
274
|
+
else if ("publicKey" in key && isPublicJWK(key.publicKey)) _key = key.publicKey;
|
|
275
|
+
else if ("privateKey" in key && isPrivateJWK(key.privateKey)) _key = key.privateKey;
|
|
276
|
+
if (!_key) throw new Error("Session: Invalid JWE key. It must be a password string or valid JWK.", { cause: key });
|
|
277
|
+
return _key;
|
|
301
278
|
}
|
|
302
279
|
function getDecryptKey(key) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
_key = key;
|
|
311
|
-
} else if ("privateKey" in key) {
|
|
312
|
-
_key = key.privateKey;
|
|
313
|
-
}
|
|
314
|
-
if (!_key) {
|
|
315
|
-
throw new Error(
|
|
316
|
-
"Session: Invalid JWE key. It must be a password string or a valid private JWK.",
|
|
317
|
-
{ cause: key }
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
return _key;
|
|
280
|
+
if (!key) throw new Error("Session: JWE key is required.");
|
|
281
|
+
let _key = void 0;
|
|
282
|
+
if (typeof key === "string") _key = key;
|
|
283
|
+
else if (isSymmetricJWK(key)) _key = key;
|
|
284
|
+
else if ("privateKey" in key) _key = key.privateKey;
|
|
285
|
+
if (!_key) throw new Error("Session: Invalid JWE key. It must be a password string or a valid private JWK.", { cause: key });
|
|
286
|
+
return _key;
|
|
321
287
|
}
|
|
322
288
|
function findSetCookie$1(setCookie, name) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
289
|
+
const regex = new RegExp(`(?:^|,\\s*)${name}=([^;]+)`);
|
|
290
|
+
const match = setCookie.match(regex);
|
|
291
|
+
return match ? match[1] : void 0;
|
|
326
292
|
}
|
|
327
|
-
|
|
293
|
+
//#endregion
|
|
294
|
+
//#region src/adapters/h3v2/session/jws.ts
|
|
328
295
|
const kGetSessionPromise = Symbol("h3_jws_getSession");
|
|
296
|
+
const kSessionToken = Symbol("h3_jws_sessionToken");
|
|
329
297
|
const DEFAULT_NAME = "h3-jws";
|
|
330
298
|
const DEFAULT_COOKIE = {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
299
|
+
path: "/",
|
|
300
|
+
secure: true,
|
|
301
|
+
httpOnly: false
|
|
334
302
|
};
|
|
335
303
|
async function useJWSSession(event, config) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
304
|
+
const sessionName = config.name || DEFAULT_NAME;
|
|
305
|
+
await getJWSSession(event, config);
|
|
306
|
+
const sessionManager = {
|
|
307
|
+
get id() {
|
|
308
|
+
return getSessionFromContext(event, sessionName)?.id;
|
|
309
|
+
},
|
|
310
|
+
get createdAt() {
|
|
311
|
+
return getSessionFromContext(event, sessionName)?.createdAt ?? Date.now();
|
|
312
|
+
},
|
|
313
|
+
get expiresAt() {
|
|
314
|
+
return getSessionFromContext(event, sessionName)?.expiresAt;
|
|
315
|
+
},
|
|
316
|
+
get data() {
|
|
317
|
+
return getSessionFromContext(event, sessionName)?.data || {};
|
|
318
|
+
},
|
|
319
|
+
get token() {
|
|
320
|
+
return getSessionFromContext(event, sessionName)?.[kSessionToken] ?? getJWSSessionToken(event, config);
|
|
321
|
+
},
|
|
322
|
+
update: async (update) => {
|
|
323
|
+
await updateJWSSession(event, config, update);
|
|
324
|
+
return sessionManager;
|
|
325
|
+
},
|
|
326
|
+
clear: async () => {
|
|
327
|
+
await clearJWSSession(event, config);
|
|
328
|
+
return sessionManager;
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
return sessionManager;
|
|
364
332
|
}
|
|
365
333
|
async function getJWSSession(event, config) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
if (!session.id) {
|
|
428
|
-
await updateJWSSession(event, config);
|
|
429
|
-
}
|
|
430
|
-
await config.hooks?.onRead?.({
|
|
431
|
-
event,
|
|
432
|
-
session,
|
|
433
|
-
config
|
|
434
|
-
});
|
|
435
|
-
return session;
|
|
334
|
+
const sessionName = config.name || DEFAULT_NAME;
|
|
335
|
+
const context = getEventContext(event);
|
|
336
|
+
if (!context.sessions) context.sessions = new NullProtoObj();
|
|
337
|
+
const existingSession = context.sessions[sessionName];
|
|
338
|
+
if (existingSession) {
|
|
339
|
+
const session = existingSession[kGetSessionPromise] ? await existingSession[kGetSessionPromise] : existingSession;
|
|
340
|
+
if (session.expiresAt !== void 0 && session.expiresAt < Date.now() && hasWritableResponse(event)) {
|
|
341
|
+
await config.hooks?.onExpire?.({
|
|
342
|
+
event,
|
|
343
|
+
error: /* @__PURE__ */ new Error(`JWT "exp" (Expiration Time) Claim validation failed: Token has expired (exp: ${(/* @__PURE__ */ new Date(session.expiresAt * 1e3)).toISOString()})`),
|
|
344
|
+
config
|
|
345
|
+
});
|
|
346
|
+
return clearJWSSession(event, config).then(() => getJWSSession(event, config));
|
|
347
|
+
}
|
|
348
|
+
await config.hooks?.onRead?.({
|
|
349
|
+
event,
|
|
350
|
+
session,
|
|
351
|
+
config
|
|
352
|
+
});
|
|
353
|
+
return session;
|
|
354
|
+
}
|
|
355
|
+
const now = config.jws?.signOptions?.currentDate?.getTime() ?? Date.now();
|
|
356
|
+
const createdAt = now - now % 1e3;
|
|
357
|
+
const session = {
|
|
358
|
+
id: void 0,
|
|
359
|
+
createdAt,
|
|
360
|
+
expiresAt: config.maxAge === void 0 ? void 0 : createdAt + computeExpiresInSeconds(config.maxAge) * 1e3,
|
|
361
|
+
data: new NullProtoObj()
|
|
362
|
+
};
|
|
363
|
+
context.sessions[sessionName] = session;
|
|
364
|
+
const token = getJWSSessionToken(event, config);
|
|
365
|
+
if (token) {
|
|
366
|
+
session[kSessionToken] = token;
|
|
367
|
+
const promise = verifyJWSSession(event, config, token).catch(async (error_) => {
|
|
368
|
+
if (error_ instanceof Error && (error_.message.includes("Token has expired") || error_.message.includes("Token is too old"))) {
|
|
369
|
+
await config.hooks?.onExpire?.({
|
|
370
|
+
event,
|
|
371
|
+
error: error_,
|
|
372
|
+
config
|
|
373
|
+
});
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
await config.hooks?.onError?.({
|
|
377
|
+
event,
|
|
378
|
+
error: error_,
|
|
379
|
+
config
|
|
380
|
+
});
|
|
381
|
+
}).then((unsealed) => {
|
|
382
|
+
if (unsealed) Object.assign(session, unsealed);
|
|
383
|
+
delete session[kGetSessionPromise];
|
|
384
|
+
return session;
|
|
385
|
+
});
|
|
386
|
+
session[kGetSessionPromise] = promise;
|
|
387
|
+
await promise;
|
|
388
|
+
}
|
|
389
|
+
await config.hooks?.onRead?.({
|
|
390
|
+
event,
|
|
391
|
+
session,
|
|
392
|
+
config
|
|
393
|
+
});
|
|
394
|
+
return session;
|
|
436
395
|
}
|
|
437
396
|
function getJWSSessionToken(event, config) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
if (!token) {
|
|
454
|
-
token = getChunkedCookie(event, sessionName);
|
|
455
|
-
}
|
|
456
|
-
return token;
|
|
397
|
+
const sessionName = config.name || DEFAULT_NAME;
|
|
398
|
+
let token;
|
|
399
|
+
if (config.sessionHeader !== false) {
|
|
400
|
+
const headerName = typeof config.sessionHeader === "string" ? config.sessionHeader.toLowerCase() : `x-${sessionName.toLowerCase()}-session`;
|
|
401
|
+
const headerValue = event.req.headers.get(headerName);
|
|
402
|
+
if (typeof headerValue === "string") token = headerValue.startsWith("Bearer ") ? headerValue.slice(7).trim() : headerValue;
|
|
403
|
+
}
|
|
404
|
+
if (config.cookie !== false && hasWritableResponse(event)) {
|
|
405
|
+
const setCookie = event.res.headers.get("set-cookie");
|
|
406
|
+
if (typeof setCookie === "string") token = findSetCookie(setCookie, sessionName);
|
|
407
|
+
}
|
|
408
|
+
if (!token) token = getChunkedCookie(event, sessionName);
|
|
409
|
+
return token;
|
|
457
410
|
}
|
|
458
411
|
async function updateJWSSession(event, config, update) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
return session;
|
|
412
|
+
const sessionName = config.name || DEFAULT_NAME;
|
|
413
|
+
const session = getEventContext(event).sessions?.[sessionName] || await getJWSSession(event, config);
|
|
414
|
+
if (typeof update === "function") update = update(session.data);
|
|
415
|
+
if (update) {
|
|
416
|
+
const oldSession = {
|
|
417
|
+
...session,
|
|
418
|
+
data: { ...session.data }
|
|
419
|
+
};
|
|
420
|
+
Object.assign(session.data, update);
|
|
421
|
+
await config.hooks?.onUpdate?.({
|
|
422
|
+
session,
|
|
423
|
+
oldSession,
|
|
424
|
+
event,
|
|
425
|
+
config
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
const now = config.jws?.signOptions?.currentDate?.getTime() ?? Date.now();
|
|
429
|
+
const createdAt = now - now % 1e3;
|
|
430
|
+
Object.assign(session, {
|
|
431
|
+
id: config.generateId?.() || crypto.randomUUID(),
|
|
432
|
+
createdAt,
|
|
433
|
+
expiresAt: config.maxAge === void 0 ? void 0 : createdAt + computeExpiresInSeconds(config.maxAge) * 1e3
|
|
434
|
+
});
|
|
435
|
+
if (config.cookie !== false && hasWritableResponse(event)) {
|
|
436
|
+
const token = await signJWSSession(event, config);
|
|
437
|
+
session[kSessionToken] = token;
|
|
438
|
+
setChunkedCookie(event, sessionName, token, {
|
|
439
|
+
...DEFAULT_COOKIE,
|
|
440
|
+
expires: config.maxAge === void 0 ? void 0 : new Date(session.createdAt + computeExpiresInSeconds(config.maxAge) * 1e3),
|
|
441
|
+
...config.cookie
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
return session;
|
|
493
445
|
}
|
|
494
446
|
async function signJWSSession(event, config) {
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
...config.jws?.signOptions?.protectedHeader,
|
|
519
|
-
kid: "kid" in key ? key.kid : void 0,
|
|
520
|
-
typ: typ || "JWT",
|
|
521
|
-
cty: "application/json"
|
|
522
|
-
}
|
|
523
|
-
});
|
|
524
|
-
return token;
|
|
447
|
+
const key = getSignKey(config.key);
|
|
448
|
+
const sessionName = config.name || DEFAULT_NAME;
|
|
449
|
+
const session = getEventContext(event).sessions?.[sessionName] || await getJWSSession(event, config);
|
|
450
|
+
const iat = Math.floor(session.createdAt / 1e3);
|
|
451
|
+
const exp = session.expiresAt ? Math.floor(session.expiresAt / 1e3) : void 0;
|
|
452
|
+
const payload = {
|
|
453
|
+
...session.data,
|
|
454
|
+
jti: session.id,
|
|
455
|
+
iat
|
|
456
|
+
};
|
|
457
|
+
if (exp) payload.exp = exp;
|
|
458
|
+
let typ;
|
|
459
|
+
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;
|
|
460
|
+
return await sign(payload, key, {
|
|
461
|
+
...config.jws?.signOptions,
|
|
462
|
+
expiresIn: void 0,
|
|
463
|
+
protectedHeader: {
|
|
464
|
+
...config.jws?.signOptions?.protectedHeader,
|
|
465
|
+
kid: "kid" in key ? key.kid : void 0,
|
|
466
|
+
typ: typ || "JWT",
|
|
467
|
+
cty: "application/json"
|
|
468
|
+
}
|
|
469
|
+
});
|
|
525
470
|
}
|
|
526
471
|
async function verifyJWSSession(event, config, token) {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
createdAt: iat * 1e3,
|
|
558
|
-
expiresAt: exp ? exp * 1e3 : void 0,
|
|
559
|
-
data: data && typeof data === "object" ? data : new NullProtoObj()
|
|
560
|
-
};
|
|
472
|
+
const alg = config.jws?.signOptions?.alg;
|
|
473
|
+
const jwk = config.hooks?.onVerifyKeyLookup ? (header) => config.hooks.onVerifyKeyLookup({
|
|
474
|
+
header,
|
|
475
|
+
event,
|
|
476
|
+
config
|
|
477
|
+
}) : getVerifyKey(config.key);
|
|
478
|
+
let typ;
|
|
479
|
+
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;
|
|
480
|
+
const { payload } = await verify(token, jwk, {
|
|
481
|
+
...config.jws?.verifyOptions,
|
|
482
|
+
requiredClaims: [...new Set([
|
|
483
|
+
...config.jws?.verifyOptions?.requiredClaims || [],
|
|
484
|
+
"jti",
|
|
485
|
+
"iat"
|
|
486
|
+
])],
|
|
487
|
+
typ: typ || "JWT",
|
|
488
|
+
algorithms: alg ? [alg] : void 0,
|
|
489
|
+
forceUint8Array: false,
|
|
490
|
+
validateJWT: true
|
|
491
|
+
}).catch((error_) => {
|
|
492
|
+
const message = error_ instanceof Error ? error_.message : String(error_);
|
|
493
|
+
throw new Error(`Invalid session token: ${message}`);
|
|
494
|
+
});
|
|
495
|
+
const { jti, iat, exp, ...data } = payload;
|
|
496
|
+
return {
|
|
497
|
+
id: jti,
|
|
498
|
+
createdAt: iat * 1e3,
|
|
499
|
+
expiresAt: exp ? exp * 1e3 : void 0,
|
|
500
|
+
data: data && typeof data === "object" ? data : new NullProtoObj()
|
|
501
|
+
};
|
|
561
502
|
}
|
|
562
503
|
async function clearJWSSession(event, config) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
event,
|
|
582
|
-
config
|
|
583
|
-
});
|
|
584
|
-
}
|
|
504
|
+
const context = getEventContext(event);
|
|
505
|
+
const sessionName = config.name || DEFAULT_NAME;
|
|
506
|
+
let session = context.sessions?.[sessionName];
|
|
507
|
+
if (session && session[kGetSessionPromise]) session = await session[kGetSessionPromise];
|
|
508
|
+
if (context.sessions?.[sessionName]) delete context.sessions[sessionName];
|
|
509
|
+
if (config.cookie !== false && hasWritableResponse(event)) {
|
|
510
|
+
setChunkedCookie(event, sessionName, "", {
|
|
511
|
+
...DEFAULT_COOKIE,
|
|
512
|
+
...config.cookie,
|
|
513
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
514
|
+
maxAge: void 0
|
|
515
|
+
});
|
|
516
|
+
await config.hooks?.onClear?.({
|
|
517
|
+
session,
|
|
518
|
+
event,
|
|
519
|
+
config
|
|
520
|
+
});
|
|
521
|
+
}
|
|
585
522
|
}
|
|
586
523
|
function getSessionFromContext(event, sessionName) {
|
|
587
|
-
|
|
588
|
-
return context.sessions?.[sessionName];
|
|
524
|
+
return getEventContext(event).sessions?.[sessionName];
|
|
589
525
|
}
|
|
590
526
|
function hasWritableResponse(event) {
|
|
591
|
-
|
|
527
|
+
return Boolean(event.res);
|
|
592
528
|
}
|
|
593
529
|
function getSignKey(key) {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
} else if ("privateKey" in key && isPrivateJWK(key.privateKey)) {
|
|
601
|
-
_key = key.privateKey;
|
|
602
|
-
}
|
|
603
|
-
if (!_key) {
|
|
604
|
-
throw new Error(
|
|
605
|
-
"Session: Invalid JWS key. It must be a symmetric JWK or a private JWK.",
|
|
606
|
-
{ cause: key }
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
return _key;
|
|
530
|
+
if (!key) throw new Error("Session: JWS key is required.");
|
|
531
|
+
let _key;
|
|
532
|
+
if (isSymmetricJWK(key)) _key = key;
|
|
533
|
+
else if ("privateKey" in key && isPrivateJWK(key.privateKey)) _key = key.privateKey;
|
|
534
|
+
if (!_key) throw new Error("Session: Invalid JWS key. It must be a symmetric JWK or a private JWK.", { cause: key });
|
|
535
|
+
return _key;
|
|
610
536
|
}
|
|
611
537
|
function getVerifyKey(key) {
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
}
|
|
629
|
-
} else if (publicKey && typeof publicKey === "object" && Array.isArray(publicKey.keys)) {
|
|
630
|
-
const keys = publicKey.keys.filter(
|
|
631
|
-
(candidate) => isPublicJWK(candidate)
|
|
632
|
-
);
|
|
633
|
-
if (keys.length > 0) {
|
|
634
|
-
_key = { keys };
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
if (!_key) {
|
|
639
|
-
throw new Error(
|
|
640
|
-
"Session: Invalid JWS key. It must be a symmetric JWK or a public JWK/set.",
|
|
641
|
-
{ cause: key }
|
|
642
|
-
);
|
|
643
|
-
}
|
|
644
|
-
return _key;
|
|
538
|
+
if (!key) throw new Error("Session: JWS key is required.");
|
|
539
|
+
let _key;
|
|
540
|
+
if (isSymmetricJWK(key)) _key = key;
|
|
541
|
+
else if ("publicKey" in key) {
|
|
542
|
+
const publicKey = key.publicKey;
|
|
543
|
+
if (isPublicJWK(publicKey)) _key = publicKey;
|
|
544
|
+
else if (Array.isArray(publicKey)) {
|
|
545
|
+
const keys = publicKey.filter((candidate) => isPublicJWK(candidate));
|
|
546
|
+
if (keys.length > 0) _key = { keys };
|
|
547
|
+
} else if (publicKey && typeof publicKey === "object" && Array.isArray(publicKey.keys)) {
|
|
548
|
+
const keys = publicKey.keys.filter((candidate) => isPublicJWK(candidate));
|
|
549
|
+
if (keys.length > 0) _key = { keys };
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
if (!_key) throw new Error("Session: Invalid JWS key. It must be a symmetric JWK or a public JWK/set.", { cause: key });
|
|
553
|
+
return _key;
|
|
645
554
|
}
|
|
646
555
|
function findSetCookie(setCookie, name) {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
556
|
+
const regex = new RegExp(`(?:^|,\\s*)${name}=([^;]+)`);
|
|
557
|
+
const match = setCookie.match(regex);
|
|
558
|
+
return match ? match[1] : void 0;
|
|
650
559
|
}
|
|
651
|
-
|
|
652
|
-
export { clearJWESession, clearJWSSession, getJWESession, getJWESessionToken, getJWSSession, getJWSSessionToken, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|
|
560
|
+
//#endregion
|
|
561
|
+
export { clearJWESession, clearJWSSession, deriveJWKFromPassword, exportJWKToPEM, generateJWK, getJWESession, getJWESessionToken, getJWSSession, getJWSSessionToken, importJWKFromPEM, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|