tough-cookie 6.0.1 → 6.1.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 +41 -13
- package/dist/index.cjs +61 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -32
- package/dist/index.d.ts +59 -32
- package/dist/index.js +61 -12
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -384,7 +384,7 @@ var ParameterError = class extends Error {
|
|
|
384
384
|
};
|
|
385
385
|
|
|
386
386
|
// lib/version.ts
|
|
387
|
-
var version = "6.0
|
|
387
|
+
var version = "6.1.0";
|
|
388
388
|
|
|
389
389
|
// lib/cookie/constants.ts
|
|
390
390
|
var PrefixSecurityEnum = {
|
|
@@ -438,6 +438,17 @@ function formatDate(date) {
|
|
|
438
438
|
return date.toUTCString();
|
|
439
439
|
}
|
|
440
440
|
|
|
441
|
+
// lib/cookie/cookieName.ts
|
|
442
|
+
var INVALID_TOKEN_CHARACTER = /[^\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]/;
|
|
443
|
+
var CookieName = {
|
|
444
|
+
parse(input) {
|
|
445
|
+
if (input.length === 0 || INVALID_TOKEN_CHARACTER.test(input)) {
|
|
446
|
+
return void 0;
|
|
447
|
+
}
|
|
448
|
+
return input;
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
|
|
441
452
|
// lib/cookie/parseDate.ts
|
|
442
453
|
function parseDate(cookieDate) {
|
|
443
454
|
if (!cookieDate) {
|
|
@@ -612,8 +623,8 @@ function parse(str, options) {
|
|
|
612
623
|
return c;
|
|
613
624
|
}
|
|
614
625
|
const cookie_avs = unparsed.split(";");
|
|
615
|
-
|
|
616
|
-
const av =
|
|
626
|
+
for (const cookie_av of cookie_avs) {
|
|
627
|
+
const av = cookie_av.trim();
|
|
617
628
|
if (av.length === 0) {
|
|
618
629
|
continue;
|
|
619
630
|
}
|
|
@@ -896,10 +907,17 @@ var _Cookie = class _Cookie {
|
|
|
896
907
|
*
|
|
897
908
|
* @remarks
|
|
898
909
|
* Works for a few things, but is by no means comprehensive.
|
|
910
|
+
* Checks that the cookie name is a non-empty token as defined in RFC 6265 Section 4.1.1.
|
|
911
|
+
* Nameless cookies (including those parsed in loose mode or created with `new Cookie({ value })`)
|
|
912
|
+
* and names containing characters outside the token grammar (such as `a b`) return `false`.
|
|
913
|
+
* Parsing and storage remain permissive; this check only applies to explicit validation.
|
|
899
914
|
*
|
|
900
915
|
* @beta
|
|
901
916
|
*/
|
|
902
917
|
validate() {
|
|
918
|
+
if (CookieName.parse(this.key) === void 0) {
|
|
919
|
+
return false;
|
|
920
|
+
}
|
|
903
921
|
if (!this.value || !COOKIE_OCTETS.test(this.value)) {
|
|
904
922
|
return false;
|
|
905
923
|
}
|
|
@@ -918,7 +936,7 @@ var _Cookie = class _Cookie {
|
|
|
918
936
|
return false;
|
|
919
937
|
}
|
|
920
938
|
const suffix = getPublicSuffix(cdomain);
|
|
921
|
-
if (suffix == null) {
|
|
939
|
+
if (suffix == null && !IP_V4_REGEX_OBJECT.test(cdomain) && !IP_V6_REGEX_OBJECT.test(cdomain)) {
|
|
922
940
|
return false;
|
|
923
941
|
}
|
|
924
942
|
}
|
|
@@ -994,11 +1012,13 @@ var _Cookie = class _Cookie {
|
|
|
994
1012
|
if (this.httpOnly) {
|
|
995
1013
|
str += "; HttpOnly";
|
|
996
1014
|
}
|
|
997
|
-
if (this.sameSite
|
|
1015
|
+
if (this.sameSite) {
|
|
998
1016
|
if (this.sameSite.toLowerCase() === _Cookie.sameSiteCanonical.lax.toLowerCase()) {
|
|
999
1017
|
str += `; SameSite=${_Cookie.sameSiteCanonical.lax}`;
|
|
1000
1018
|
} else if (this.sameSite.toLowerCase() === _Cookie.sameSiteCanonical.strict.toLowerCase()) {
|
|
1001
1019
|
str += `; SameSite=${_Cookie.sameSiteCanonical.strict}`;
|
|
1020
|
+
} else if (this.sameSite.toLowerCase() === _Cookie.sameSiteCanonical.none.toLowerCase()) {
|
|
1021
|
+
str += `; SameSite=${_Cookie.sameSiteCanonical.none}`;
|
|
1002
1022
|
} else {
|
|
1003
1023
|
str += `; SameSite=${this.sameSite}`;
|
|
1004
1024
|
}
|
|
@@ -1045,6 +1065,9 @@ var _Cookie = class _Cookie {
|
|
|
1045
1065
|
*/
|
|
1046
1066
|
expiryTime(now) {
|
|
1047
1067
|
if (this.maxAge != null) {
|
|
1068
|
+
if (this.maxAge === "Infinity") {
|
|
1069
|
+
return Infinity;
|
|
1070
|
+
}
|
|
1048
1071
|
const relativeTo = now || this.lastAccessed || /* @__PURE__ */ new Date();
|
|
1049
1072
|
const maxAge = typeof this.maxAge === "number" ? this.maxAge : -Infinity;
|
|
1050
1073
|
const age = maxAge <= 0 ? -Infinity : maxAge * 1e3;
|
|
@@ -1177,7 +1200,8 @@ _Cookie.sameSiteLevel = {
|
|
|
1177
1200
|
*/
|
|
1178
1201
|
_Cookie.sameSiteCanonical = {
|
|
1179
1202
|
strict: "Strict",
|
|
1180
|
-
lax: "Lax"
|
|
1203
|
+
lax: "Lax",
|
|
1204
|
+
none: "None"
|
|
1181
1205
|
};
|
|
1182
1206
|
/**
|
|
1183
1207
|
* Cookie properties that will be serialized when using {@link Cookie.fromJSON} and {@link Cookie.toJSON}.
|
|
@@ -1336,23 +1360,34 @@ var defaultGetCookieOptions = {
|
|
|
1336
1360
|
var SAME_SITE_CONTEXT_VAL_ERR = 'Invalid sameSiteContext option for getCookies(); expected one of "strict", "lax", or "none"';
|
|
1337
1361
|
function getCookieContext(url) {
|
|
1338
1362
|
if (url && typeof url === "object" && "hostname" in url && typeof url.hostname === "string" && "pathname" in url && typeof url.pathname === "string" && "protocol" in url && typeof url.protocol === "string") {
|
|
1363
|
+
let pathname = url.pathname;
|
|
1364
|
+
try {
|
|
1365
|
+
pathname = decodeURI(pathname);
|
|
1366
|
+
} catch {
|
|
1367
|
+
}
|
|
1339
1368
|
return {
|
|
1340
1369
|
hostname: url.hostname,
|
|
1341
|
-
pathname
|
|
1370
|
+
pathname,
|
|
1342
1371
|
protocol: url.protocol
|
|
1343
1372
|
};
|
|
1344
1373
|
} else if (typeof url === "string") {
|
|
1374
|
+
const parsed = new URL(url);
|
|
1375
|
+
let pathname = parsed.pathname;
|
|
1345
1376
|
try {
|
|
1346
|
-
|
|
1377
|
+
pathname = decodeURI(pathname);
|
|
1347
1378
|
} catch {
|
|
1348
|
-
return new URL(url);
|
|
1349
1379
|
}
|
|
1380
|
+
return {
|
|
1381
|
+
hostname: parsed.hostname,
|
|
1382
|
+
pathname,
|
|
1383
|
+
protocol: parsed.protocol
|
|
1384
|
+
};
|
|
1350
1385
|
} else {
|
|
1351
1386
|
throw new ParameterError("`url` argument is not a string or URL.");
|
|
1352
1387
|
}
|
|
1353
1388
|
}
|
|
1354
1389
|
function checkSameSiteContext(value) {
|
|
1355
|
-
const context =
|
|
1390
|
+
const context = value.toLowerCase();
|
|
1356
1391
|
if (context === "none" || context === "lax" || context === "strict") {
|
|
1357
1392
|
return context;
|
|
1358
1393
|
} else {
|
|
@@ -1366,7 +1401,7 @@ function isSecurePrefixConditionMet(cookie) {
|
|
|
1366
1401
|
function isHostPrefixConditionMet(cookie) {
|
|
1367
1402
|
const startsWithHostPrefix = typeof cookie.key === "string" && cookie.key.startsWith("__Host-");
|
|
1368
1403
|
return !startsWithHostPrefix || Boolean(
|
|
1369
|
-
cookie.secure && cookie.hostOnly && cookie.path != null && cookie.path === "/"
|
|
1404
|
+
cookie.secure && cookie.hostOnly && cookie.path != null && cookie.path === "/" && !cookie.pathIsDefault
|
|
1370
1405
|
);
|
|
1371
1406
|
}
|
|
1372
1407
|
function getNormalizedPrefixSecurity(prefixSecurity) {
|
|
@@ -1399,6 +1434,7 @@ var CookieJar = class _CookieJar {
|
|
|
1399
1434
|
this.enableLooseMode = options?.looseMode ?? false;
|
|
1400
1435
|
this.allowSpecialUseDomain = options?.allowSpecialUseDomain ?? true;
|
|
1401
1436
|
this.allowSecureOnLocal = options?.allowSecureOnLocal ?? true;
|
|
1437
|
+
this.enforceSecureOriginOnStorage = options?.enforceSecureOriginOnStorage ?? true;
|
|
1402
1438
|
this.prefixSecurity = getNormalizedPrefixSecurity(
|
|
1403
1439
|
options?.prefixSecurity ?? "silent"
|
|
1404
1440
|
);
|
|
@@ -1486,7 +1522,7 @@ var CookieJar = class _CookieJar {
|
|
|
1486
1522
|
allowSpecialUseDomain: this.allowSpecialUseDomain,
|
|
1487
1523
|
ignoreError: options?.ignoreError
|
|
1488
1524
|
}) : null;
|
|
1489
|
-
if (suffix == null && !IP_V6_REGEX_OBJECT.test(
|
|
1525
|
+
if (suffix == null && !IP_V4_REGEX_OBJECT.test(cdomain ?? "") && !IP_V6_REGEX_OBJECT.test(cdomain ?? "")) {
|
|
1490
1526
|
const err = new Error("Cookie has domain set to a public suffix");
|
|
1491
1527
|
return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
|
|
1492
1528
|
}
|
|
@@ -1515,6 +1551,12 @@ var CookieJar = class _CookieJar {
|
|
|
1515
1551
|
cookie.path = defaultPath(context.pathname);
|
|
1516
1552
|
cookie.pathIsDefault = true;
|
|
1517
1553
|
}
|
|
1554
|
+
if (this.enforceSecureOriginOnStorage && cookie.secure && !isPotentiallyTrustworthy(url, this.allowSecureOnLocal)) {
|
|
1555
|
+
const err = new Error(
|
|
1556
|
+
"Cookie is Secure but this is not a secure connection"
|
|
1557
|
+
);
|
|
1558
|
+
return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
|
|
1559
|
+
}
|
|
1518
1560
|
if (options?.http === false && cookie.httpOnly) {
|
|
1519
1561
|
const err = new Error("Cookie is HttpOnly and this isn't an HTTP API");
|
|
1520
1562
|
return options.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
|
|
@@ -1839,6 +1881,7 @@ var CookieJar = class _CookieJar {
|
|
|
1839
1881
|
rejectPublicSuffixes: this.rejectPublicSuffixes,
|
|
1840
1882
|
enableLooseMode: this.enableLooseMode,
|
|
1841
1883
|
allowSpecialUseDomain: this.allowSpecialUseDomain,
|
|
1884
|
+
enforceSecureOriginOnStorage: this.enforceSecureOriginOnStorage,
|
|
1842
1885
|
prefixSecurity: getNormalizedPrefixSecurity(this.prefixSecurity),
|
|
1843
1886
|
// this gets filled from getAllCookies:
|
|
1844
1887
|
cookies: []
|
|
@@ -2085,6 +2128,9 @@ var CookieJar = class _CookieJar {
|
|
|
2085
2128
|
rejectPublicSuffixes: readSerializedBoolean("rejectPublicSuffixes"),
|
|
2086
2129
|
looseMode: readSerializedBoolean("enableLooseMode"),
|
|
2087
2130
|
allowSpecialUseDomain: readSerializedBoolean("allowSpecialUseDomain"),
|
|
2131
|
+
enforceSecureOriginOnStorage: readSerializedBoolean(
|
|
2132
|
+
"enforceSecureOriginOnStorage"
|
|
2133
|
+
),
|
|
2088
2134
|
prefixSecurity: getNormalizedPrefixSecurity(
|
|
2089
2135
|
readSerializedString("prefixSecurity") ?? "silent"
|
|
2090
2136
|
)
|
|
@@ -2130,6 +2176,9 @@ var CookieJar = class _CookieJar {
|
|
|
2130
2176
|
rejectPublicSuffixes: readSerializedBoolean("rejectPublicSuffixes"),
|
|
2131
2177
|
looseMode: readSerializedBoolean("enableLooseMode"),
|
|
2132
2178
|
allowSpecialUseDomain: readSerializedBoolean("allowSpecialUseDomain"),
|
|
2179
|
+
enforceSecureOriginOnStorage: readSerializedBoolean(
|
|
2180
|
+
"enforceSecureOriginOnStorage"
|
|
2181
|
+
),
|
|
2133
2182
|
prefixSecurity: getNormalizedPrefixSecurity(
|
|
2134
2183
|
readSerializedString("prefixSecurity") ?? "silent"
|
|
2135
2184
|
)
|