@xylex-group/athena 2.0.0 → 2.3.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 +287 -95
- package/dist/browser.cjs +4791 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +25 -0
- package/dist/browser.d.ts +25 -0
- package/dist/browser.js +4745 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli/index.cjs +2087 -220
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -2
- package/dist/cli/index.d.ts +3 -2
- package/dist/cli/index.js +2089 -222
- package/dist/cli/index.js.map +1 -1
- package/dist/cookies.cjs +890 -0
- package/dist/cookies.cjs.map +1 -0
- package/dist/cookies.d.cts +174 -0
- package/dist/cookies.d.ts +174 -0
- package/dist/cookies.js +869 -0
- package/dist/cookies.js.map +1 -0
- package/dist/index.cjs +3046 -1200
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -408
- package/dist/index.d.ts +8 -408
- package/dist/index.js +3045 -1202
- package/dist/index.js.map +1 -1
- package/dist/{model-form-CVOtC8jq.d.ts → model-form-BpDXlbxb.d.ts} +97 -2
- package/dist/{model-form-hXkvHS_3.d.cts → model-form-hoE2jHIi.d.cts} +97 -2
- package/dist/pipeline-BNIw8pDQ.d.ts +8 -0
- package/dist/pipeline-DNIpEsN8.d.cts +8 -0
- package/dist/react-email-BvyCZnfW.d.cts +610 -0
- package/dist/react-email-qPA1wjFV.d.ts +610 -0
- package/dist/react.cjs +30 -9
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +4 -4
- package/dist/react.d.ts +4 -4
- package/dist/react.js +30 -9
- package/dist/react.js.map +1 -1
- package/dist/{types-BnzoaNRC.d.cts → types-A5e97acl.d.cts} +2 -1
- package/dist/{types-BnzoaNRC.d.ts → types-A5e97acl.d.ts} +2 -1
- package/dist/{pipeline-CQgV-Yfo.d.ts → types-BnD22-vb.d.ts} +2 -7
- package/dist/{pipeline-C-cN0ACi.d.cts → types-bDlr4u7p.d.cts} +2 -7
- package/dist/utils.cjs +153 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +23 -0
- package/dist/utils.d.ts +23 -0
- package/dist/utils.js +146 -0
- package/dist/utils.js.map +1 -0
- package/package.json +87 -9
package/dist/cookies.js
ADDED
|
@@ -0,0 +1,869 @@
|
|
|
1
|
+
// src/cookies/base64.ts
|
|
2
|
+
function getAtob() {
|
|
3
|
+
const candidate = globalThis.atob;
|
|
4
|
+
return typeof candidate === "function" ? candidate : void 0;
|
|
5
|
+
}
|
|
6
|
+
function getBtoa() {
|
|
7
|
+
const candidate = globalThis.btoa;
|
|
8
|
+
return typeof candidate === "function" ? candidate : void 0;
|
|
9
|
+
}
|
|
10
|
+
function bytesToBinaryString(bytes) {
|
|
11
|
+
let result = "";
|
|
12
|
+
for (const byte of bytes) {
|
|
13
|
+
result += String.fromCharCode(byte);
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
function binaryStringToBytes(binary) {
|
|
18
|
+
const bytes = new Uint8Array(binary.length);
|
|
19
|
+
for (let i = 0; i < binary.length; i++) {
|
|
20
|
+
bytes[i] = binary.charCodeAt(i);
|
|
21
|
+
}
|
|
22
|
+
return bytes;
|
|
23
|
+
}
|
|
24
|
+
function encodeBase64(bytes) {
|
|
25
|
+
const btoaFn = getBtoa();
|
|
26
|
+
if (btoaFn) {
|
|
27
|
+
return btoaFn(bytesToBinaryString(bytes));
|
|
28
|
+
}
|
|
29
|
+
return Buffer.from(bytes).toString("base64");
|
|
30
|
+
}
|
|
31
|
+
function decodeBase64(base64) {
|
|
32
|
+
const atobFn = getAtob();
|
|
33
|
+
if (atobFn) {
|
|
34
|
+
return binaryStringToBytes(atobFn(base64));
|
|
35
|
+
}
|
|
36
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
37
|
+
}
|
|
38
|
+
function encodeBytesToBase64Url(bytes) {
|
|
39
|
+
return encodeBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
40
|
+
}
|
|
41
|
+
function encodeStringToBase64Url(value) {
|
|
42
|
+
const bytes = new TextEncoder().encode(value);
|
|
43
|
+
return encodeBytesToBase64Url(bytes);
|
|
44
|
+
}
|
|
45
|
+
function decodeBase64UrlToBytes(value) {
|
|
46
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
47
|
+
const paddingLength = normalized.length % 4;
|
|
48
|
+
const padded = paddingLength === 0 ? normalized : `${normalized}${"=".repeat(4 - paddingLength)}`;
|
|
49
|
+
return decodeBase64(padded);
|
|
50
|
+
}
|
|
51
|
+
function decodeBase64UrlToString(value) {
|
|
52
|
+
return new TextDecoder().decode(decodeBase64UrlToBytes(value));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/cookies/cookie-utils.ts
|
|
56
|
+
function tryDecode(str) {
|
|
57
|
+
if (str.indexOf("%") === -1) {
|
|
58
|
+
return str;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
return decodeURIComponent(str);
|
|
62
|
+
} catch {
|
|
63
|
+
return str;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
var SECURE_COOKIE_PREFIX = "__Secure-";
|
|
67
|
+
var HOST_COOKIE_PREFIX = "__Host-";
|
|
68
|
+
function stripSecureCookiePrefix(cookieName) {
|
|
69
|
+
if (cookieName.startsWith(SECURE_COOKIE_PREFIX)) {
|
|
70
|
+
return cookieName.slice(SECURE_COOKIE_PREFIX.length);
|
|
71
|
+
}
|
|
72
|
+
if (cookieName.startsWith(HOST_COOKIE_PREFIX)) {
|
|
73
|
+
return cookieName.slice(HOST_COOKIE_PREFIX.length);
|
|
74
|
+
}
|
|
75
|
+
return cookieName;
|
|
76
|
+
}
|
|
77
|
+
function splitSetCookieHeader(setCookie) {
|
|
78
|
+
if (!setCookie) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
const result = [];
|
|
82
|
+
let start = 0;
|
|
83
|
+
let i = 0;
|
|
84
|
+
while (i < setCookie.length) {
|
|
85
|
+
if (setCookie[i] === ",") {
|
|
86
|
+
let j = i + 1;
|
|
87
|
+
while (j < setCookie.length && setCookie[j] === " ") {
|
|
88
|
+
j++;
|
|
89
|
+
}
|
|
90
|
+
while (j < setCookie.length && setCookie[j] !== "=" && setCookie[j] !== ";" && setCookie[j] !== ",") {
|
|
91
|
+
j++;
|
|
92
|
+
}
|
|
93
|
+
if (j < setCookie.length && setCookie[j] === "=") {
|
|
94
|
+
const part = setCookie.slice(start, i).trim();
|
|
95
|
+
if (part) {
|
|
96
|
+
result.push(part);
|
|
97
|
+
}
|
|
98
|
+
start = i + 1;
|
|
99
|
+
while (start < setCookie.length && setCookie[start] === " ") {
|
|
100
|
+
start++;
|
|
101
|
+
}
|
|
102
|
+
i = start;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
i++;
|
|
107
|
+
}
|
|
108
|
+
const last = setCookie.slice(start).trim();
|
|
109
|
+
if (last) {
|
|
110
|
+
result.push(last);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
function parseSetCookieHeader(setCookie) {
|
|
115
|
+
const cookies = /* @__PURE__ */ new Map();
|
|
116
|
+
const cookieArray = splitSetCookieHeader(setCookie);
|
|
117
|
+
for (const cookieString of cookieArray) {
|
|
118
|
+
const parts = cookieString.split(";").map((part) => part.trim());
|
|
119
|
+
const [nameValue, ...attributes] = parts;
|
|
120
|
+
const [name, ...valueParts] = (nameValue || "").split("=");
|
|
121
|
+
if (!name) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const value = unquoteCookieValue(valueParts.join("="));
|
|
125
|
+
const decodedValue = tryDecode(value);
|
|
126
|
+
const attrObj = { value: decodedValue };
|
|
127
|
+
for (const attribute of attributes) {
|
|
128
|
+
const [attrName, ...attrValueParts] = attribute.split("=");
|
|
129
|
+
const attrValue = attrValueParts.join("=");
|
|
130
|
+
const normalizedAttrName = attrName.trim().toLowerCase();
|
|
131
|
+
switch (normalizedAttrName) {
|
|
132
|
+
case "max-age":
|
|
133
|
+
attrObj["max-age"] = attrValue ? parseInt(attrValue.trim(), 10) : void 0;
|
|
134
|
+
break;
|
|
135
|
+
case "expires":
|
|
136
|
+
attrObj.expires = attrValue ? new Date(attrValue.trim()) : void 0;
|
|
137
|
+
break;
|
|
138
|
+
case "domain":
|
|
139
|
+
attrObj.domain = attrValue ? attrValue.trim() : void 0;
|
|
140
|
+
break;
|
|
141
|
+
case "path":
|
|
142
|
+
attrObj.path = attrValue ? attrValue.trim() : void 0;
|
|
143
|
+
break;
|
|
144
|
+
case "secure":
|
|
145
|
+
attrObj.secure = true;
|
|
146
|
+
break;
|
|
147
|
+
case "httponly":
|
|
148
|
+
attrObj.httponly = true;
|
|
149
|
+
break;
|
|
150
|
+
case "samesite":
|
|
151
|
+
attrObj.samesite = attrValue ? attrValue.trim().toLowerCase() : void 0;
|
|
152
|
+
break;
|
|
153
|
+
case "partitioned":
|
|
154
|
+
attrObj.partitioned = true;
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
attrObj[normalizedAttrName] = attrValue ? attrValue.trim() : true;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
cookies.set(name, attrObj);
|
|
162
|
+
}
|
|
163
|
+
return cookies;
|
|
164
|
+
}
|
|
165
|
+
function toCookieOptions(attributes) {
|
|
166
|
+
return {
|
|
167
|
+
maxAge: attributes["max-age"],
|
|
168
|
+
expires: attributes.expires,
|
|
169
|
+
domain: attributes.domain,
|
|
170
|
+
path: attributes.path,
|
|
171
|
+
secure: attributes.secure,
|
|
172
|
+
httpOnly: attributes.httponly,
|
|
173
|
+
sameSite: attributes.samesite,
|
|
174
|
+
partitioned: attributes.partitioned
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
var cookieNameRegex = /^[\w!#$%&'*.^`|~+-]+$/;
|
|
178
|
+
function unquoteCookieValue(value) {
|
|
179
|
+
if (value.length < 2 || !value.startsWith('"') || !value.endsWith('"')) {
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
182
|
+
return value.slice(1, -1);
|
|
183
|
+
}
|
|
184
|
+
function parseCookies(cookieHeader) {
|
|
185
|
+
const cookies = cookieHeader.split("; ");
|
|
186
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
187
|
+
cookies.forEach((cookie) => {
|
|
188
|
+
const [name, value] = cookie.split(/=(.*)/s);
|
|
189
|
+
cookieMap.set(name, value);
|
|
190
|
+
});
|
|
191
|
+
return cookieMap;
|
|
192
|
+
}
|
|
193
|
+
function setRequestCookie(headers, name, value) {
|
|
194
|
+
const cookieMap = parseCookies(headers.get("cookie") || "");
|
|
195
|
+
if (cookieNameRegex.test(name)) {
|
|
196
|
+
cookieMap.set(name, value);
|
|
197
|
+
}
|
|
198
|
+
headers.set(
|
|
199
|
+
"cookie",
|
|
200
|
+
Array.from(cookieMap, ([key, currentValue]) => `${key}=${encodeURIComponent(currentValue)}`).join("; ")
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
function applySetCookies(target, setCookieValues) {
|
|
204
|
+
const cookieMap = parseCookies(target.get("cookie") || "");
|
|
205
|
+
for (const setCookie of setCookieValues) {
|
|
206
|
+
for (const [name, attr] of parseSetCookieHeader(setCookie)) {
|
|
207
|
+
if (cookieNameRegex.test(name)) {
|
|
208
|
+
cookieMap.set(name, attr.value);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
target.set(
|
|
213
|
+
"cookie",
|
|
214
|
+
Array.from(cookieMap, ([key, currentValue]) => `${key}=${encodeURIComponent(currentValue)}`).join("; ")
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
function setCookieToHeader(headers) {
|
|
218
|
+
return (context) => {
|
|
219
|
+
const setCookieHeader = context.response.headers.get("set-cookie");
|
|
220
|
+
if (!setCookieHeader) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
applySetCookies(headers, [setCookieHeader]);
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/cookies/crypto.ts
|
|
228
|
+
var HS256_ALG = "HS256";
|
|
229
|
+
async function getSubtleCrypto() {
|
|
230
|
+
const globalCrypto = globalThis.crypto;
|
|
231
|
+
if (globalCrypto?.subtle) {
|
|
232
|
+
return globalCrypto.subtle;
|
|
233
|
+
}
|
|
234
|
+
const { webcrypto } = await import('crypto');
|
|
235
|
+
const subtle = webcrypto.subtle;
|
|
236
|
+
if (!subtle) {
|
|
237
|
+
throw new Error("Web Crypto subtle API is unavailable.");
|
|
238
|
+
}
|
|
239
|
+
return subtle;
|
|
240
|
+
}
|
|
241
|
+
async function importHmacKey(secret, usage) {
|
|
242
|
+
const subtle = await getSubtleCrypto();
|
|
243
|
+
return subtle.importKey(
|
|
244
|
+
"raw",
|
|
245
|
+
new TextEncoder().encode(secret),
|
|
246
|
+
{
|
|
247
|
+
name: "HMAC",
|
|
248
|
+
hash: "SHA-256"
|
|
249
|
+
},
|
|
250
|
+
false,
|
|
251
|
+
[usage]
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
function bufferToBytes(buffer) {
|
|
255
|
+
return new Uint8Array(buffer);
|
|
256
|
+
}
|
|
257
|
+
function parseJwtPayload(payloadSegment) {
|
|
258
|
+
try {
|
|
259
|
+
const decoded = decodeBase64UrlToString(payloadSegment);
|
|
260
|
+
const payload = JSON.parse(decoded);
|
|
261
|
+
if (!payload || typeof payload !== "object") {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
return payload;
|
|
265
|
+
} catch {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function isJwtExpired(payload) {
|
|
270
|
+
const exp = payload.exp;
|
|
271
|
+
if (typeof exp !== "number") {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
return exp < Math.floor(Date.now() / 1e3);
|
|
275
|
+
}
|
|
276
|
+
async function signHmacBase64Url(secret, value) {
|
|
277
|
+
const subtle = await getSubtleCrypto();
|
|
278
|
+
const key = await importHmacKey(secret, "sign");
|
|
279
|
+
const signature = await subtle.sign("HMAC", key, new TextEncoder().encode(value));
|
|
280
|
+
return encodeBytesToBase64Url(bufferToBytes(signature));
|
|
281
|
+
}
|
|
282
|
+
async function signJwtHS256(payload, secret, expiresIn = 60 * 5) {
|
|
283
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
284
|
+
const header = { alg: HS256_ALG, typ: "JWT" };
|
|
285
|
+
const fullPayload = {
|
|
286
|
+
...payload,
|
|
287
|
+
iat: now,
|
|
288
|
+
exp: now + expiresIn
|
|
289
|
+
};
|
|
290
|
+
const headerPart = encodeStringToBase64Url(JSON.stringify(header));
|
|
291
|
+
const payloadPart = encodeStringToBase64Url(JSON.stringify(fullPayload));
|
|
292
|
+
const message = `${headerPart}.${payloadPart}`;
|
|
293
|
+
const signature = await signHmacBase64Url(secret, message);
|
|
294
|
+
return `${message}.${signature}`;
|
|
295
|
+
}
|
|
296
|
+
async function verifyJwtHS256(token, secret) {
|
|
297
|
+
const parts = token.split(".");
|
|
298
|
+
if (parts.length !== 3) {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
const [headerPart, payloadPart, signaturePart] = parts;
|
|
302
|
+
if (!headerPart || !payloadPart || !signaturePart) {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
let header = null;
|
|
306
|
+
try {
|
|
307
|
+
header = JSON.parse(decodeBase64UrlToString(headerPart));
|
|
308
|
+
} catch {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
if (!header || header.alg !== HS256_ALG) {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
const payload = parseJwtPayload(payloadPart);
|
|
315
|
+
if (!payload) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
const expectedSignature = await signHmacBase64Url(secret, `${headerPart}.${payloadPart}`);
|
|
319
|
+
if (expectedSignature !== signaturePart) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
if (isJwtExpired(payload)) {
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
return payload;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// src/cookies/session-store.ts
|
|
329
|
+
var ALLOWED_COOKIE_SIZE = 4096;
|
|
330
|
+
var ESTIMATED_EMPTY_COOKIE_SIZE = 200;
|
|
331
|
+
var CHUNK_SIZE = ALLOWED_COOKIE_SIZE - ESTIMATED_EMPTY_COOKIE_SIZE;
|
|
332
|
+
function getChunkIndex(cookieName) {
|
|
333
|
+
const parts = cookieName.split(".");
|
|
334
|
+
const lastPart = parts[parts.length - 1];
|
|
335
|
+
const index = parseInt(lastPart || "0", 10);
|
|
336
|
+
return Number.isNaN(index) ? 0 : index;
|
|
337
|
+
}
|
|
338
|
+
function readExistingChunks(cookieName, ctx) {
|
|
339
|
+
const chunks = {};
|
|
340
|
+
const cookies = parseCookies(ctx.headers?.get("cookie") || "");
|
|
341
|
+
for (const [name, value] of cookies) {
|
|
342
|
+
if (name.startsWith(cookieName)) {
|
|
343
|
+
chunks[name] = value;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return chunks;
|
|
347
|
+
}
|
|
348
|
+
function joinChunks(chunks) {
|
|
349
|
+
const sortedKeys = Object.keys(chunks).sort((left, right) => getChunkIndex(left) - getChunkIndex(right));
|
|
350
|
+
return sortedKeys.map((key) => chunks[key]).join("");
|
|
351
|
+
}
|
|
352
|
+
function chunkCookie(storeName, cookie, chunks, ctx) {
|
|
353
|
+
const chunkCount = Math.ceil(cookie.value.length / CHUNK_SIZE);
|
|
354
|
+
if (chunkCount === 1) {
|
|
355
|
+
chunks[cookie.name] = cookie.value;
|
|
356
|
+
return [cookie];
|
|
357
|
+
}
|
|
358
|
+
const cookies = [];
|
|
359
|
+
for (let index = 0; index < chunkCount; index++) {
|
|
360
|
+
const name = `${cookie.name}.${index}`;
|
|
361
|
+
const start = index * CHUNK_SIZE;
|
|
362
|
+
const value = cookie.value.substring(start, start + CHUNK_SIZE);
|
|
363
|
+
cookies.push({
|
|
364
|
+
...cookie,
|
|
365
|
+
name,
|
|
366
|
+
value
|
|
367
|
+
});
|
|
368
|
+
chunks[name] = value;
|
|
369
|
+
}
|
|
370
|
+
ctx.logger?.debug?.(`CHUNKING_${storeName.toUpperCase()}_COOKIE`, {
|
|
371
|
+
message: `${storeName} cookie exceeds allowed ${ALLOWED_COOKIE_SIZE} bytes.`,
|
|
372
|
+
emptyCookieSize: ESTIMATED_EMPTY_COOKIE_SIZE,
|
|
373
|
+
valueSize: cookie.value.length,
|
|
374
|
+
chunkCount,
|
|
375
|
+
chunks: cookies.map((entry) => entry.value.length + ESTIMATED_EMPTY_COOKIE_SIZE)
|
|
376
|
+
});
|
|
377
|
+
return cookies;
|
|
378
|
+
}
|
|
379
|
+
function getCleanCookies(chunks, cookieOptions) {
|
|
380
|
+
const cleanedChunks = {};
|
|
381
|
+
for (const name in chunks) {
|
|
382
|
+
cleanedChunks[name] = {
|
|
383
|
+
name,
|
|
384
|
+
value: "",
|
|
385
|
+
attributes: {
|
|
386
|
+
...cookieOptions,
|
|
387
|
+
maxAge: 0
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
return cleanedChunks;
|
|
392
|
+
}
|
|
393
|
+
var storeFactory = (storeName) => (cookieName, cookieOptions, ctx) => {
|
|
394
|
+
const chunks = readExistingChunks(cookieName, ctx);
|
|
395
|
+
return {
|
|
396
|
+
getValue() {
|
|
397
|
+
return joinChunks(chunks);
|
|
398
|
+
},
|
|
399
|
+
hasChunks() {
|
|
400
|
+
return Object.keys(chunks).length > 0;
|
|
401
|
+
},
|
|
402
|
+
chunk(value, options) {
|
|
403
|
+
const cleanedChunks = getCleanCookies(chunks, cookieOptions);
|
|
404
|
+
for (const name in chunks) {
|
|
405
|
+
delete chunks[name];
|
|
406
|
+
}
|
|
407
|
+
const cookies = cleanedChunks;
|
|
408
|
+
const chunked = chunkCookie(
|
|
409
|
+
storeName,
|
|
410
|
+
{
|
|
411
|
+
name: cookieName,
|
|
412
|
+
value,
|
|
413
|
+
attributes: {
|
|
414
|
+
...cookieOptions,
|
|
415
|
+
...options
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
chunks,
|
|
419
|
+
ctx
|
|
420
|
+
);
|
|
421
|
+
for (const chunk of chunked) {
|
|
422
|
+
cookies[chunk.name] = chunk;
|
|
423
|
+
}
|
|
424
|
+
return Object.values(cookies);
|
|
425
|
+
},
|
|
426
|
+
clean() {
|
|
427
|
+
const cleanedChunks = getCleanCookies(chunks, cookieOptions);
|
|
428
|
+
for (const name in chunks) {
|
|
429
|
+
delete chunks[name];
|
|
430
|
+
}
|
|
431
|
+
return Object.values(cleanedChunks);
|
|
432
|
+
},
|
|
433
|
+
setCookies(cookies) {
|
|
434
|
+
for (const cookie of cookies) {
|
|
435
|
+
ctx.setCookie(cookie.name, cookie.value, cookie.attributes);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
};
|
|
440
|
+
var createSessionStore = storeFactory("Session");
|
|
441
|
+
var createAccountStore = storeFactory("Account");
|
|
442
|
+
function getChunkedCookie(ctx, cookieName) {
|
|
443
|
+
const value = ctx.getCookie?.(cookieName);
|
|
444
|
+
if (value) {
|
|
445
|
+
return value;
|
|
446
|
+
}
|
|
447
|
+
const chunks = [];
|
|
448
|
+
const cookieHeader = ctx.headers?.get("cookie");
|
|
449
|
+
if (!cookieHeader) {
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
452
|
+
for (const [name, parsedValue] of parseCookies(cookieHeader)) {
|
|
453
|
+
if (!name.startsWith(`${cookieName}.`)) {
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
const parts = name.split(".");
|
|
457
|
+
const indexStr = parts.at(-1);
|
|
458
|
+
const index = parseInt(indexStr || "0", 10);
|
|
459
|
+
if (!Number.isNaN(index)) {
|
|
460
|
+
chunks.push({ index, value: parsedValue });
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (chunks.length === 0) {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
chunks.sort((left, right) => left.index - right.index);
|
|
467
|
+
return chunks.map((entry) => entry.value).join("");
|
|
468
|
+
}
|
|
469
|
+
async function getAccountCookie(ctx, cookieName = ctx.context.authCookies.accountData.name) {
|
|
470
|
+
const value = getChunkedCookie(ctx, cookieName);
|
|
471
|
+
if (!value) {
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
try {
|
|
475
|
+
return JSON.parse(value);
|
|
476
|
+
} catch {
|
|
477
|
+
}
|
|
478
|
+
try {
|
|
479
|
+
return JSON.parse(decodeBase64UrlToString(value));
|
|
480
|
+
} catch {
|
|
481
|
+
return value;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// src/cookies/index.ts
|
|
486
|
+
var DEFAULT_COOKIE_PREFIX = "athena-auth";
|
|
487
|
+
var LEGACY_COOKIE_PREFIX = "better-auth";
|
|
488
|
+
var DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60;
|
|
489
|
+
var DEFAULT_CACHE_MAX_AGE = 60 * 5;
|
|
490
|
+
function isProductionRuntime() {
|
|
491
|
+
return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
492
|
+
}
|
|
493
|
+
function getEnvironmentSecret() {
|
|
494
|
+
if (typeof process === "undefined") {
|
|
495
|
+
return void 0;
|
|
496
|
+
}
|
|
497
|
+
return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET;
|
|
498
|
+
}
|
|
499
|
+
function isDynamicBaseURLConfig(baseURL) {
|
|
500
|
+
return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
|
|
501
|
+
}
|
|
502
|
+
function resolveCookiePrefixes(primaryPrefix) {
|
|
503
|
+
const prefixes = [primaryPrefix];
|
|
504
|
+
if (!prefixes.includes(DEFAULT_COOKIE_PREFIX)) {
|
|
505
|
+
prefixes.push(DEFAULT_COOKIE_PREFIX);
|
|
506
|
+
}
|
|
507
|
+
if (!prefixes.includes(LEGACY_COOKIE_PREFIX)) {
|
|
508
|
+
prefixes.push(LEGACY_COOKIE_PREFIX);
|
|
509
|
+
}
|
|
510
|
+
return prefixes;
|
|
511
|
+
}
|
|
512
|
+
function createError(message) {
|
|
513
|
+
return new Error(`@xylex-group/athena/cookies: ${message}`);
|
|
514
|
+
}
|
|
515
|
+
function getSecretOrThrow(secret) {
|
|
516
|
+
const resolved = secret || getEnvironmentSecret();
|
|
517
|
+
if (!resolved) {
|
|
518
|
+
throw createError(
|
|
519
|
+
"getCookieCache requires a secret. Pass `secret` or set ATHENA_AUTH_SECRET/BETTER_AUTH_SECRET/AUTH_SECRET."
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
return resolved;
|
|
523
|
+
}
|
|
524
|
+
function asObject(value) {
|
|
525
|
+
if (!value || typeof value !== "object") {
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
return value;
|
|
529
|
+
}
|
|
530
|
+
function getSessionTokenFromPair(session) {
|
|
531
|
+
const token = session.session?.token;
|
|
532
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
533
|
+
throw createError("setSessionCookie requires `session.session.token` to be a non-empty string.");
|
|
534
|
+
}
|
|
535
|
+
return token;
|
|
536
|
+
}
|
|
537
|
+
async function resolveCookieVersion(versionConfig, session, user) {
|
|
538
|
+
if (!versionConfig) {
|
|
539
|
+
return "1";
|
|
540
|
+
}
|
|
541
|
+
if (typeof versionConfig === "string") {
|
|
542
|
+
return versionConfig;
|
|
543
|
+
}
|
|
544
|
+
return versionConfig(session, user);
|
|
545
|
+
}
|
|
546
|
+
function getSessionCookieCacheName(cookiePrefix, cookieName, isSecure) {
|
|
547
|
+
return isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`;
|
|
548
|
+
}
|
|
549
|
+
async function setCookieValue(ctx, name, value, attributes) {
|
|
550
|
+
const secret = ctx.context.secret;
|
|
551
|
+
if (secret && typeof ctx.setSignedCookie === "function") {
|
|
552
|
+
await ctx.setSignedCookie(name, value, secret, attributes);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
ctx.setCookie(name, value, attributes);
|
|
556
|
+
}
|
|
557
|
+
function parseJsonSafely(value) {
|
|
558
|
+
try {
|
|
559
|
+
return JSON.parse(value);
|
|
560
|
+
} catch {
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
function getIsSecureCookie(config) {
|
|
565
|
+
if (config?.isSecure !== void 0) {
|
|
566
|
+
return config.isSecure;
|
|
567
|
+
}
|
|
568
|
+
return isProductionRuntime();
|
|
569
|
+
}
|
|
570
|
+
function createCookieGetter(options) {
|
|
571
|
+
const baseURLString = typeof options.baseURL === "string" ? options.baseURL : void 0;
|
|
572
|
+
const dynamicProtocol = typeof options.baseURL === "object" && options.baseURL !== null ? options.baseURL.protocol : void 0;
|
|
573
|
+
const secure = options.advanced?.useSecureCookies !== void 0 ? options.advanced.useSecureCookies : dynamicProtocol === "https" ? true : dynamicProtocol === "http" ? false : baseURLString ? baseURLString.startsWith("https://") : isProductionRuntime();
|
|
574
|
+
const secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : "";
|
|
575
|
+
const crossSubdomainEnabled = !!options.advanced?.crossSubDomainCookies?.enabled;
|
|
576
|
+
const domain = crossSubdomainEnabled ? options.advanced?.crossSubDomainCookies?.domain || (baseURLString ? new URL(baseURLString).hostname : void 0) : void 0;
|
|
577
|
+
if (crossSubdomainEnabled && !domain && !isDynamicBaseURLConfig(options.baseURL)) {
|
|
578
|
+
throw createError("baseURL is required when `crossSubDomainCookies.enabled` is true.");
|
|
579
|
+
}
|
|
580
|
+
function createCookie(cookieName, overrideAttributes = {}) {
|
|
581
|
+
const prefix = options.advanced?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
|
|
582
|
+
const name = options.advanced?.cookies?.[cookieName]?.name || `${prefix}.${cookieName}`;
|
|
583
|
+
const attributes = options.advanced?.cookies?.[cookieName]?.attributes || {};
|
|
584
|
+
return {
|
|
585
|
+
name: `${secureCookiePrefix}${name}`,
|
|
586
|
+
attributes: {
|
|
587
|
+
secure: !!secureCookiePrefix,
|
|
588
|
+
sameSite: "lax",
|
|
589
|
+
path: "/",
|
|
590
|
+
httpOnly: true,
|
|
591
|
+
...crossSubdomainEnabled ? { domain } : {},
|
|
592
|
+
...options.advanced?.defaultCookieAttributes,
|
|
593
|
+
...overrideAttributes,
|
|
594
|
+
...attributes
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
return createCookie;
|
|
599
|
+
}
|
|
600
|
+
function getCookies(options) {
|
|
601
|
+
const createCookie = createCookieGetter(options);
|
|
602
|
+
const sessionToken = createCookie("session_token", { maxAge: options.session?.expiresIn || DEFAULT_SESSION_MAX_AGE });
|
|
603
|
+
const sessionData = createCookie("session_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
|
|
604
|
+
const accountData = createCookie("account_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
|
|
605
|
+
const dontRememberToken = createCookie("dont_remember");
|
|
606
|
+
return {
|
|
607
|
+
sessionToken: {
|
|
608
|
+
name: sessionToken.name,
|
|
609
|
+
attributes: sessionToken.attributes
|
|
610
|
+
},
|
|
611
|
+
sessionData: {
|
|
612
|
+
name: sessionData.name,
|
|
613
|
+
attributes: sessionData.attributes
|
|
614
|
+
},
|
|
615
|
+
dontRememberToken: {
|
|
616
|
+
name: dontRememberToken.name,
|
|
617
|
+
attributes: dontRememberToken.attributes
|
|
618
|
+
},
|
|
619
|
+
accountData: {
|
|
620
|
+
name: accountData.name,
|
|
621
|
+
attributes: accountData.attributes
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
async function setCookieCache(ctx, session, dontRememberMe) {
|
|
626
|
+
const cookieCacheConfig = ctx.context.options?.session?.cookieCache;
|
|
627
|
+
if (!cookieCacheConfig?.enabled) {
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
const version = await resolveCookieVersion(
|
|
631
|
+
cookieCacheConfig.version,
|
|
632
|
+
session.session,
|
|
633
|
+
session.user
|
|
634
|
+
);
|
|
635
|
+
const sessionData = {
|
|
636
|
+
session: session.session,
|
|
637
|
+
user: session.user,
|
|
638
|
+
updatedAt: Date.now(),
|
|
639
|
+
version
|
|
640
|
+
};
|
|
641
|
+
const baseAttributes = ctx.context.authCookies.sessionData.attributes;
|
|
642
|
+
const maxAge = dontRememberMe ? void 0 : baseAttributes.maxAge;
|
|
643
|
+
const options = {
|
|
644
|
+
...baseAttributes,
|
|
645
|
+
maxAge
|
|
646
|
+
};
|
|
647
|
+
const expiresAt = Date.now() + (options.maxAge || 60) * 1e3;
|
|
648
|
+
const strategy = cookieCacheConfig.strategy || "compact";
|
|
649
|
+
const secret = getSecretOrThrow(ctx.context.secret);
|
|
650
|
+
let encoded;
|
|
651
|
+
if (strategy === "jwt") {
|
|
652
|
+
encoded = await signJwtHS256(sessionData, secret, options.maxAge || DEFAULT_CACHE_MAX_AGE);
|
|
653
|
+
} else if (strategy === "jwe") {
|
|
654
|
+
throw createError("`jwe` strategy is not supported by the SDK cookie helper.");
|
|
655
|
+
} else {
|
|
656
|
+
const signature = await signHmacBase64Url(
|
|
657
|
+
secret,
|
|
658
|
+
JSON.stringify({
|
|
659
|
+
...sessionData,
|
|
660
|
+
expiresAt
|
|
661
|
+
})
|
|
662
|
+
);
|
|
663
|
+
encoded = encodeStringToBase64Url(
|
|
664
|
+
JSON.stringify({
|
|
665
|
+
session: sessionData,
|
|
666
|
+
expiresAt,
|
|
667
|
+
signature
|
|
668
|
+
})
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
if (encoded.length > 4093) {
|
|
672
|
+
const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
|
|
673
|
+
const cookies = store.chunk(encoded, options);
|
|
674
|
+
store.setCookies(cookies);
|
|
675
|
+
} else {
|
|
676
|
+
const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
|
|
677
|
+
if (store.hasChunks()) {
|
|
678
|
+
store.setCookies(store.clean());
|
|
679
|
+
}
|
|
680
|
+
ctx.setCookie(ctx.context.authCookies.sessionData.name, encoded, options);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
async function setSessionCookie(ctx, session, dontRememberMe, overrides) {
|
|
684
|
+
if (dontRememberMe === void 0 && typeof ctx.getSignedCookie === "function" && ctx.context.secret) {
|
|
685
|
+
const existingFlag = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
|
|
686
|
+
dontRememberMe = !!existingFlag;
|
|
687
|
+
}
|
|
688
|
+
const resolvedDontRememberMe = dontRememberMe ?? false;
|
|
689
|
+
const token = getSessionTokenFromPair(session);
|
|
690
|
+
const options = ctx.context.authCookies.sessionToken.attributes;
|
|
691
|
+
const maxAge = resolvedDontRememberMe ? void 0 : ctx.context.sessionConfig?.expiresIn;
|
|
692
|
+
await setCookieValue(ctx, ctx.context.authCookies.sessionToken.name, token, {
|
|
693
|
+
...options,
|
|
694
|
+
maxAge,
|
|
695
|
+
...overrides
|
|
696
|
+
});
|
|
697
|
+
if (resolvedDontRememberMe) {
|
|
698
|
+
await setCookieValue(
|
|
699
|
+
ctx,
|
|
700
|
+
ctx.context.authCookies.dontRememberToken.name,
|
|
701
|
+
"true",
|
|
702
|
+
ctx.context.authCookies.dontRememberToken.attributes
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
await setCookieCache(ctx, session, resolvedDontRememberMe);
|
|
706
|
+
ctx.context.setNewSession?.(session);
|
|
707
|
+
}
|
|
708
|
+
function expireCookie(ctx, cookie) {
|
|
709
|
+
ctx.setCookie(cookie.name, "", {
|
|
710
|
+
...cookie.attributes,
|
|
711
|
+
maxAge: 0
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
function deleteSessionCookie(ctx, skipDontRememberMe) {
|
|
715
|
+
expireCookie(ctx, ctx.context.authCookies.sessionToken);
|
|
716
|
+
expireCookie(ctx, ctx.context.authCookies.sessionData);
|
|
717
|
+
if (ctx.context.options?.account?.storeAccountCookie) {
|
|
718
|
+
expireCookie(ctx, ctx.context.authCookies.accountData);
|
|
719
|
+
const accountStore = createAccountStore(
|
|
720
|
+
ctx.context.authCookies.accountData.name,
|
|
721
|
+
ctx.context.authCookies.accountData.attributes,
|
|
722
|
+
ctx
|
|
723
|
+
);
|
|
724
|
+
accountStore.setCookies(accountStore.clean());
|
|
725
|
+
}
|
|
726
|
+
const sessionStore = createSessionStore(
|
|
727
|
+
ctx.context.authCookies.sessionData.name,
|
|
728
|
+
ctx.context.authCookies.sessionData.attributes,
|
|
729
|
+
ctx
|
|
730
|
+
);
|
|
731
|
+
sessionStore.setCookies(sessionStore.clean());
|
|
732
|
+
if (!skipDontRememberMe) {
|
|
733
|
+
expireCookie(ctx, ctx.context.authCookies.dontRememberToken);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
var getSessionCookie = (request, config) => {
|
|
737
|
+
const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
|
|
738
|
+
if (!cookies) {
|
|
739
|
+
return null;
|
|
740
|
+
}
|
|
741
|
+
const { cookieName = "session_token", cookiePrefix = "athena-auth" } = config || {};
|
|
742
|
+
const parsedCookie = parseCookies(cookies);
|
|
743
|
+
const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
|
|
744
|
+
const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
|
|
745
|
+
if (sessionToken) {
|
|
746
|
+
return sessionToken;
|
|
747
|
+
}
|
|
748
|
+
return null;
|
|
749
|
+
};
|
|
750
|
+
var getCookieCache = async (request, config) => {
|
|
751
|
+
const headers = request instanceof Headers || !("headers" in request) ? request : request.headers;
|
|
752
|
+
const cookieHeader = headers.get("cookie");
|
|
753
|
+
if (!cookieHeader) {
|
|
754
|
+
return null;
|
|
755
|
+
}
|
|
756
|
+
const parsedCookie = parseCookies(cookieHeader);
|
|
757
|
+
const cookieName = config?.cookieName || "session_data";
|
|
758
|
+
const requestedPrefix = config?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
|
|
759
|
+
const strategy = config?.strategy || "compact";
|
|
760
|
+
const cookiePrefixes = resolveCookiePrefixes(requestedPrefix);
|
|
761
|
+
const isSecure = getIsSecureCookie(config);
|
|
762
|
+
const secret = getSecretOrThrow(config?.secret);
|
|
763
|
+
let sessionData;
|
|
764
|
+
for (const prefix of cookiePrefixes) {
|
|
765
|
+
const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
|
|
766
|
+
const cookieValue = parsedCookie.get(candidate);
|
|
767
|
+
if (cookieValue) {
|
|
768
|
+
sessionData = cookieValue;
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
if (!sessionData) {
|
|
773
|
+
const reconstructedChunks = [];
|
|
774
|
+
for (const prefix of cookiePrefixes) {
|
|
775
|
+
const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
|
|
776
|
+
for (const [name, value] of parsedCookie.entries()) {
|
|
777
|
+
if (!name.startsWith(`${candidate}.`)) {
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
const parts = name.split(".");
|
|
781
|
+
const indexStr = parts[parts.length - 1];
|
|
782
|
+
const index = parseInt(indexStr || "0", 10);
|
|
783
|
+
if (!Number.isNaN(index)) {
|
|
784
|
+
reconstructedChunks.push({ index, value });
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (reconstructedChunks.length > 0) {
|
|
788
|
+
break;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
if (reconstructedChunks.length > 0) {
|
|
792
|
+
reconstructedChunks.sort((left, right) => left.index - right.index);
|
|
793
|
+
sessionData = reconstructedChunks.map((chunk) => chunk.value).join("");
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
if (!sessionData) {
|
|
797
|
+
return null;
|
|
798
|
+
}
|
|
799
|
+
if (strategy === "jwe") {
|
|
800
|
+
throw createError(
|
|
801
|
+
"`jwe` strategy is not supported by the SDK cookie helper. Use compact/jwt or pass cookie data through the auth server."
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
if (strategy === "jwt") {
|
|
805
|
+
const payload = await verifyJwtHS256(sessionData, secret);
|
|
806
|
+
if (!payload) {
|
|
807
|
+
return null;
|
|
808
|
+
}
|
|
809
|
+
const sessionRecord = asObject(payload.session);
|
|
810
|
+
const userRecord = asObject(payload.user);
|
|
811
|
+
const updatedAt = payload.updatedAt;
|
|
812
|
+
if (!sessionRecord || !userRecord || typeof updatedAt !== "number") {
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
if (config?.version) {
|
|
816
|
+
const cookieVersion = typeof payload.version === "string" ? payload.version : "1";
|
|
817
|
+
const expectedVersion = typeof config.version === "string" ? config.version : await config.version(sessionRecord, userRecord);
|
|
818
|
+
if (cookieVersion !== expectedVersion) {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return {
|
|
823
|
+
session: sessionRecord,
|
|
824
|
+
user: userRecord,
|
|
825
|
+
updatedAt,
|
|
826
|
+
version: typeof payload.version === "string" ? payload.version : void 0
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
const compactPayload = parseJsonSafely(decodeBase64UrlToString(sessionData));
|
|
830
|
+
if (!compactPayload) {
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
const expectedSignature = await signHmacBase64Url(
|
|
834
|
+
secret,
|
|
835
|
+
JSON.stringify({
|
|
836
|
+
...compactPayload.session,
|
|
837
|
+
expiresAt: compactPayload.expiresAt
|
|
838
|
+
})
|
|
839
|
+
);
|
|
840
|
+
if (expectedSignature !== compactPayload.signature) {
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
843
|
+
if (compactPayload.expiresAt <= Date.now()) {
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
846
|
+
const resolvedSession = compactPayload.session;
|
|
847
|
+
if (config?.version) {
|
|
848
|
+
const cookieVersion = resolvedSession.version || "1";
|
|
849
|
+
const expectedVersion = typeof config.version === "string" ? config.version : await config.version(resolvedSession.session, resolvedSession.user);
|
|
850
|
+
if (cookieVersion !== expectedVersion) {
|
|
851
|
+
return null;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
const sessionObject = asObject(resolvedSession.session);
|
|
855
|
+
const userObject = asObject(resolvedSession.user);
|
|
856
|
+
if (!sessionObject || !userObject) {
|
|
857
|
+
return null;
|
|
858
|
+
}
|
|
859
|
+
return {
|
|
860
|
+
session: sessionObject,
|
|
861
|
+
user: userObject,
|
|
862
|
+
updatedAt: resolvedSession.updatedAt,
|
|
863
|
+
version: resolvedSession.version
|
|
864
|
+
};
|
|
865
|
+
};
|
|
866
|
+
|
|
867
|
+
export { HOST_COOKIE_PREFIX, SECURE_COOKIE_PREFIX, createCookieGetter, createSessionStore, deleteSessionCookie, expireCookie, getAccountCookie, getChunkedCookie, getCookieCache, getCookies, getSessionCookie, parseCookies, parseSetCookieHeader, setCookieCache, setCookieToHeader, setRequestCookie, setSessionCookie, splitSetCookieHeader, stripSecureCookiePrefix, toCookieOptions };
|
|
868
|
+
//# sourceMappingURL=cookies.js.map
|
|
869
|
+
//# sourceMappingURL=cookies.js.map
|