tough-cookie 1.2.0 → 2.0.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 +180 -116
- package/lib/cookie.js +271 -50
- package/lib/memstore.js +31 -3
- package/lib/store.js +5 -1
- package/package.json +1 -1
- package/public-suffix.txt +302 -72
- package/test/cookie_sorting_test.js +66 -0
- package/test/cookie_to_json_test.js +2 -2
- package/test/ietf_test.js +1 -2
- package/test/jar_serialization_test.js +348 -0
package/lib/cookie.js
CHANGED
|
@@ -35,6 +35,7 @@ var pubsuffix = require('./pubsuffix');
|
|
|
35
35
|
var Store = require('./store').Store;
|
|
36
36
|
var MemoryCookieStore = require('./memstore').MemoryCookieStore;
|
|
37
37
|
var pathMatch = require('./pathMatch').pathMatch;
|
|
38
|
+
var VERSION = require('../package.json').version;
|
|
38
39
|
|
|
39
40
|
var punycode;
|
|
40
41
|
try {
|
|
@@ -84,8 +85,6 @@ var YEAR = /^(\d{2}|\d{4})$/; // 2 to 4 digits
|
|
|
84
85
|
var MAX_TIME = 2147483647000; // 31-bit max
|
|
85
86
|
var MIN_TIME = 0; // 31-bit min
|
|
86
87
|
|
|
87
|
-
var cookiesCreated = 0; // Number of cookies created in runtime
|
|
88
|
-
|
|
89
88
|
|
|
90
89
|
// RFC6265 S5.1.1 date parser:
|
|
91
90
|
function parseDate(str) {
|
|
@@ -458,47 +457,60 @@ function parse(str) {
|
|
|
458
457
|
}
|
|
459
458
|
}
|
|
460
459
|
|
|
461
|
-
// ensure a default date for sorting:
|
|
462
|
-
c.creation = new Date();
|
|
463
|
-
//NOTE: add runtime index for the cookieCompare() to resolve the situation when Date's precision is not enough .
|
|
464
|
-
//Store initial UTC time as well, so we will be able to determine if we need to fallback to the Date object.
|
|
465
|
-
c._creationRuntimeIdx = ++cookiesCreated;
|
|
466
|
-
c._initialCreationTime = c.creation.getTime();
|
|
467
460
|
return c;
|
|
468
461
|
}
|
|
469
462
|
|
|
463
|
+
// avoid the V8 deoptimization monster!
|
|
464
|
+
function jsonParse(str) {
|
|
465
|
+
var obj;
|
|
466
|
+
try {
|
|
467
|
+
obj = JSON.parse(str);
|
|
468
|
+
} catch (e) {
|
|
469
|
+
return e;
|
|
470
|
+
}
|
|
471
|
+
return obj;
|
|
472
|
+
}
|
|
473
|
+
|
|
470
474
|
function fromJSON(str) {
|
|
471
475
|
if (!str) {
|
|
472
476
|
return null;
|
|
473
477
|
}
|
|
474
478
|
|
|
475
479
|
var obj;
|
|
476
|
-
|
|
477
|
-
obj =
|
|
478
|
-
|
|
479
|
-
|
|
480
|
+
if (typeof str === 'string') {
|
|
481
|
+
obj = jsonParse(str);
|
|
482
|
+
if (obj instanceof Error) {
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
} else {
|
|
486
|
+
// assume it's an Object
|
|
487
|
+
obj = str;
|
|
480
488
|
}
|
|
481
489
|
|
|
482
490
|
var c = new Cookie();
|
|
483
|
-
for (var i=0; i<
|
|
484
|
-
var prop =
|
|
485
|
-
if (obj[prop]
|
|
486
|
-
|
|
491
|
+
for (var i=0; i<Cookie.serializableProperties.length; i++) {
|
|
492
|
+
var prop = Cookie.serializableProperties[i];
|
|
493
|
+
if (obj[prop] === undefined ||
|
|
494
|
+
obj[prop] === Cookie.prototype[prop])
|
|
495
|
+
{
|
|
496
|
+
continue; // leave as prototype default
|
|
487
497
|
}
|
|
498
|
+
|
|
488
499
|
if (prop === 'expires' ||
|
|
489
500
|
prop === 'creation' ||
|
|
490
501
|
prop === 'lastAccessed')
|
|
491
502
|
{
|
|
492
|
-
|
|
503
|
+
if (obj[prop] === null) {
|
|
504
|
+
c[prop] = null;
|
|
505
|
+
} else {
|
|
506
|
+
c[prop] = obj[prop] == "Infinity" ?
|
|
507
|
+
"Infinity" : new Date(obj[prop]);
|
|
508
|
+
}
|
|
493
509
|
} else {
|
|
494
510
|
c[prop] = obj[prop];
|
|
495
511
|
}
|
|
496
512
|
}
|
|
497
513
|
|
|
498
|
-
|
|
499
|
-
// ensure a default date for sorting:
|
|
500
|
-
c.creation = c.creation || new Date();
|
|
501
|
-
|
|
502
514
|
return c;
|
|
503
515
|
}
|
|
504
516
|
|
|
@@ -512,23 +524,28 @@ function fromJSON(str) {
|
|
|
512
524
|
*/
|
|
513
525
|
|
|
514
526
|
function cookieCompare(a,b) {
|
|
527
|
+
var cmp = 0;
|
|
528
|
+
|
|
515
529
|
// descending for length: b CMP a
|
|
516
|
-
var
|
|
517
|
-
|
|
518
|
-
|
|
530
|
+
var aPathLen = a.path ? a.path.length : 0;
|
|
531
|
+
var bPathLen = b.path ? b.path.length : 0;
|
|
532
|
+
cmp = bPathLen - aPathLen;
|
|
533
|
+
if (cmp !== 0) {
|
|
534
|
+
return cmp;
|
|
519
535
|
}
|
|
520
536
|
|
|
537
|
+
// ascending for time: a CMP b
|
|
521
538
|
var aTime = a.creation ? a.creation.getTime() : MAX_TIME;
|
|
522
539
|
var bTime = b.creation ? b.creation.getTime() : MAX_TIME;
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
if(aTime === bTime && aTime === a._initialCreationTime && bTime === b._initialCreationTime) {
|
|
527
|
-
return a._creationRuntimeIdx - b._creationRuntimeIdx;
|
|
540
|
+
cmp = aTime - bTime;
|
|
541
|
+
if (cmp !== 0) {
|
|
542
|
+
return cmp;
|
|
528
543
|
}
|
|
529
544
|
|
|
530
|
-
//
|
|
531
|
-
|
|
545
|
+
// break ties for the same millisecond (precision of JavaScript's clock)
|
|
546
|
+
cmp = a.creationIndex - b.creationIndex;
|
|
547
|
+
|
|
548
|
+
return cmp;
|
|
532
549
|
}
|
|
533
550
|
|
|
534
551
|
// Gives the permutation of all possible pathMatch()es of a given path. The
|
|
@@ -569,17 +586,31 @@ function getCookieContext(url) {
|
|
|
569
586
|
return urlParse(url);
|
|
570
587
|
}
|
|
571
588
|
|
|
572
|
-
function Cookie
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
589
|
+
function Cookie(opts) {
|
|
590
|
+
opts = opts || {};
|
|
591
|
+
|
|
592
|
+
Object.keys(opts).forEach(function(prop) {
|
|
593
|
+
if (Cookie.prototype.hasOwnProperty(prop) &&
|
|
594
|
+
Cookie.prototype[prop] !== opts[prop] &&
|
|
595
|
+
prop.substr(0,1) !== '_')
|
|
596
|
+
{
|
|
597
|
+
this[prop] = opts[prop];
|
|
579
598
|
}
|
|
580
|
-
}
|
|
599
|
+
}, this);
|
|
600
|
+
|
|
601
|
+
this.creation = this.creation || new Date();
|
|
602
|
+
|
|
603
|
+
// used to break creation ties in cookieCompare():
|
|
604
|
+
Object.defineProperty(this, 'creationIndex', {
|
|
605
|
+
configurable: false,
|
|
606
|
+
enumerable: false, // important for assert.deepEqual checks
|
|
607
|
+
writable: true,
|
|
608
|
+
value: ++Cookie.cookiesCreated
|
|
609
|
+
});
|
|
581
610
|
}
|
|
582
611
|
|
|
612
|
+
Cookie.cookiesCreated = 0; // incremented each time a cookie is created
|
|
613
|
+
|
|
583
614
|
Cookie.parse = parse;
|
|
584
615
|
Cookie.fromJSON = fromJSON;
|
|
585
616
|
|
|
@@ -599,17 +630,22 @@ Cookie.prototype.extensions = null;
|
|
|
599
630
|
Cookie.prototype.hostOnly = null; // boolean when set
|
|
600
631
|
Cookie.prototype.pathIsDefault = null; // boolean when set
|
|
601
632
|
Cookie.prototype.creation = null; // Date when set; defaulted by Cookie.parse
|
|
602
|
-
Cookie.prototype._initialCreationTime = null; // Used to determine if cookie.creation was modified
|
|
603
|
-
Cookie.prototype._creationRuntimeIdx = null; // Runtime index of the created cookie, used in cookieCompare()
|
|
604
633
|
Cookie.prototype.lastAccessed = null; // Date when set
|
|
634
|
+
Object.defineProperty(Cookie.prototype, 'creationIndex', {
|
|
635
|
+
configurable: true,
|
|
636
|
+
enumerable: false,
|
|
637
|
+
writable: true,
|
|
638
|
+
value: 0
|
|
639
|
+
});
|
|
605
640
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
return
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
641
|
+
Cookie.serializableProperties = Object.keys(Cookie.prototype)
|
|
642
|
+
.filter(function(prop) {
|
|
643
|
+
return !(
|
|
644
|
+
Cookie.prototype[prop] instanceof Function ||
|
|
645
|
+
prop === 'creationIndex' ||
|
|
646
|
+
prop.substr(0,1) === '_'
|
|
647
|
+
);
|
|
648
|
+
});
|
|
613
649
|
|
|
614
650
|
Cookie.prototype.inspect = function inspect() {
|
|
615
651
|
var now = Date.now();
|
|
@@ -620,6 +656,46 @@ Cookie.prototype.inspect = function inspect() {
|
|
|
620
656
|
'"';
|
|
621
657
|
};
|
|
622
658
|
|
|
659
|
+
Cookie.prototype.toJSON = function() {
|
|
660
|
+
var obj = {};
|
|
661
|
+
|
|
662
|
+
var props = Cookie.serializableProperties;
|
|
663
|
+
for (var i=0; i<props.length; i++) {
|
|
664
|
+
var prop = props[i];
|
|
665
|
+
if (this[prop] === Cookie.prototype[prop]) {
|
|
666
|
+
continue; // leave as prototype default
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (prop === 'expires' ||
|
|
670
|
+
prop === 'creation' ||
|
|
671
|
+
prop === 'lastAccessed')
|
|
672
|
+
{
|
|
673
|
+
if (this[prop] === null) {
|
|
674
|
+
obj[prop] = null;
|
|
675
|
+
} else {
|
|
676
|
+
obj[prop] = this[prop] == "Infinity" ? // intentionally not ===
|
|
677
|
+
"Infinity" : this[prop].toISOString();
|
|
678
|
+
}
|
|
679
|
+
} else if (prop === 'maxAge') {
|
|
680
|
+
if (this[prop] !== null) {
|
|
681
|
+
// again, intentionally not ===
|
|
682
|
+
obj[prop] = (this[prop] == Infinity || this[prop] == -Infinity) ?
|
|
683
|
+
this[prop].toString() : this[prop];
|
|
684
|
+
}
|
|
685
|
+
} else {
|
|
686
|
+
if (this[prop] !== Cookie.prototype[prop]) {
|
|
687
|
+
obj[prop] = this[prop];
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
return obj;
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
Cookie.prototype.clone = function() {
|
|
696
|
+
return fromJSON(this.toJSON());
|
|
697
|
+
};
|
|
698
|
+
|
|
623
699
|
Cookie.prototype.validate = function validate() {
|
|
624
700
|
if (!COOKIE_OCTETS.test(this.value)) {
|
|
625
701
|
return false;
|
|
@@ -744,7 +820,7 @@ Cookie.prototype.TTL = function TTL(now) {
|
|
|
744
820
|
// elsewhere)
|
|
745
821
|
Cookie.prototype.expiryTime = function expiryTime(now) {
|
|
746
822
|
if (this.maxAge != null) {
|
|
747
|
-
var relativeTo = this.creation ||
|
|
823
|
+
var relativeTo = now || this.creation || new Date();
|
|
748
824
|
var age = (this.maxAge <= 0) ? -Infinity : this.maxAge*1000;
|
|
749
825
|
return relativeTo.getTime() + age;
|
|
750
826
|
}
|
|
@@ -782,7 +858,6 @@ Cookie.prototype.canonicalizedDomain = function canonicalizedDomain() {
|
|
|
782
858
|
return canonicalDomain(this.domain);
|
|
783
859
|
};
|
|
784
860
|
|
|
785
|
-
|
|
786
861
|
function CookieJar(store, rejectPublicSuffixes) {
|
|
787
862
|
if (rejectPublicSuffixes != null) {
|
|
788
863
|
this.rejectPublicSuffixes = rejectPublicSuffixes;
|
|
@@ -895,6 +970,7 @@ CookieJar.prototype.setCookie = function(cookie, url, options, cb) {
|
|
|
895
970
|
return cb(options.ignoreError ? null : err);
|
|
896
971
|
}
|
|
897
972
|
cookie.creation = oldCookie.creation; // step 11.3
|
|
973
|
+
cookie.creationIndex = oldCookie.creationIndex; // preserve tie-breaker
|
|
898
974
|
cookie.lastAccessed = now;
|
|
899
975
|
// Step 11.4 (delete cookie) is implied by just setting the new one:
|
|
900
976
|
store.updateCookie(oldCookie, cookie, next); // step 12
|
|
@@ -1041,6 +1117,151 @@ CookieJar.prototype.getSetCookieStrings = function(/*..., cb*/) {
|
|
|
1041
1117
|
this.getCookies.apply(this,args);
|
|
1042
1118
|
};
|
|
1043
1119
|
|
|
1120
|
+
CAN_BE_SYNC.push('serialize');
|
|
1121
|
+
CookieJar.prototype.serialize = function(cb) {
|
|
1122
|
+
var type = this.store.constructor.name;
|
|
1123
|
+
if (type === 'Object') {
|
|
1124
|
+
type = null;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// update README.md "Serialization Format" if you change this, please!
|
|
1128
|
+
var serialized = {
|
|
1129
|
+
// The version of tough-cookie that serialized this jar. Generally a good
|
|
1130
|
+
// practice since future versions can make data import decisions based on
|
|
1131
|
+
// known past behavior. When/if this matters, use `semver`.
|
|
1132
|
+
version: 'tough-cookie@'+VERSION,
|
|
1133
|
+
|
|
1134
|
+
// add the store type, to make humans happy:
|
|
1135
|
+
storeType: type,
|
|
1136
|
+
|
|
1137
|
+
// CookieJar configuration:
|
|
1138
|
+
rejectPublicSuffixes: !!this.rejectPublicSuffixes,
|
|
1139
|
+
|
|
1140
|
+
// this gets filled from getAllCookies:
|
|
1141
|
+
cookies: []
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
if (!(this.store.getAllCookies &&
|
|
1145
|
+
typeof this.store.getAllCookies === 'function'))
|
|
1146
|
+
{
|
|
1147
|
+
return cb(new Error('store does not support getAllCookies and cannot be serialized'));
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
this.store.getAllCookies(function(err,cookies) {
|
|
1151
|
+
if (err) {
|
|
1152
|
+
return cb(err);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
serialized.cookies = cookies.map(function(cookie) {
|
|
1156
|
+
// convert to serialized 'raw' cookies
|
|
1157
|
+
cookie = (cookie instanceof Cookie) ? cookie.toJSON() : cookie;
|
|
1158
|
+
|
|
1159
|
+
// Remove the index so new ones get assigned during deserialization
|
|
1160
|
+
delete cookie.creationIndex;
|
|
1161
|
+
|
|
1162
|
+
return cookie;
|
|
1163
|
+
});
|
|
1164
|
+
|
|
1165
|
+
return cb(null, serialized);
|
|
1166
|
+
});
|
|
1167
|
+
};
|
|
1168
|
+
|
|
1169
|
+
// well-known name that JSON.stringify calls
|
|
1170
|
+
CookieJar.prototype.toJSON = function() {
|
|
1171
|
+
return this.serializeSync();
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1174
|
+
// use the class method CookieJar.deserialize instead of calling this directly
|
|
1175
|
+
CAN_BE_SYNC.push('_importCookies');
|
|
1176
|
+
CookieJar.prototype._importCookies = function(serialized, cb) {
|
|
1177
|
+
var jar = this;
|
|
1178
|
+
var cookies = serialized.cookies;
|
|
1179
|
+
if (!cookies || !Array.isArray(cookies)) {
|
|
1180
|
+
return cb(new Error('serialized jar has no cookies array'));
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
function putNext(err) {
|
|
1184
|
+
if (err) {
|
|
1185
|
+
return cb(err);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
if (!cookies.length) {
|
|
1189
|
+
return cb(err, jar);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
var cookie;
|
|
1193
|
+
try {
|
|
1194
|
+
cookie = fromJSON(cookies.shift());
|
|
1195
|
+
} catch (e) {
|
|
1196
|
+
return cb(e);
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
if (cookie === null) {
|
|
1200
|
+
return putNext(null); // skip this cookie
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
jar.store.putCookie(cookie, putNext);
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
putNext();
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
CookieJar.deserialize = function(strOrObj, store, cb) {
|
|
1210
|
+
if (arguments.length !== 3) {
|
|
1211
|
+
// store is optional
|
|
1212
|
+
cb = store;
|
|
1213
|
+
store = null;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
var serialized;
|
|
1217
|
+
if (typeof strOrObj === 'string') {
|
|
1218
|
+
serialized = jsonParse(strOrObj);
|
|
1219
|
+
if (serialized instanceof Error) {
|
|
1220
|
+
return cb(serialized);
|
|
1221
|
+
}
|
|
1222
|
+
} else {
|
|
1223
|
+
serialized = strOrObj;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
var jar = new CookieJar(store, serialized.rejectPublicSuffixes);
|
|
1227
|
+
jar._importCookies(serialized, function(err) {
|
|
1228
|
+
if (err) {
|
|
1229
|
+
return cb(err);
|
|
1230
|
+
}
|
|
1231
|
+
cb(null, jar);
|
|
1232
|
+
});
|
|
1233
|
+
};
|
|
1234
|
+
|
|
1235
|
+
CookieJar.fromJSON = CookieJar.deserializeSync;
|
|
1236
|
+
CookieJar.deserializeSync = function(strOrObj, store) {
|
|
1237
|
+
var serialized = typeof strOrObj === 'string' ?
|
|
1238
|
+
JSON.parse(strOrObj) : strOrObj;
|
|
1239
|
+
var jar = new CookieJar(store, serialized.rejectPublicSuffixes);
|
|
1240
|
+
|
|
1241
|
+
// catch this mistake early:
|
|
1242
|
+
if (!jar.store.synchronous) {
|
|
1243
|
+
throw new Error('CookieJar store is not synchronous; use async API instead.');
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
jar._importCookiesSync(serialized);
|
|
1247
|
+
return jar;
|
|
1248
|
+
};
|
|
1249
|
+
|
|
1250
|
+
CAN_BE_SYNC.push('clone');
|
|
1251
|
+
CookieJar.prototype.clone = function(newStore, cb) {
|
|
1252
|
+
if (arguments.length === 1) {
|
|
1253
|
+
cb = newStore;
|
|
1254
|
+
newStore = null;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
this.serialize(function(err,serialized) {
|
|
1258
|
+
if (err) {
|
|
1259
|
+
return cb(err);
|
|
1260
|
+
}
|
|
1261
|
+
CookieJar.deserialize(newStore, serialized, cb);
|
|
1262
|
+
});
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1044
1265
|
// Use a closure to provide a true imperative API for synchronous stores.
|
|
1045
1266
|
function syncWrap(method) {
|
|
1046
1267
|
return function() {
|
package/lib/memstore.js
CHANGED
|
@@ -41,6 +41,8 @@ function MemoryCookieStore() {
|
|
|
41
41
|
util.inherits(MemoryCookieStore, Store);
|
|
42
42
|
exports.MemoryCookieStore = MemoryCookieStore;
|
|
43
43
|
MemoryCookieStore.prototype.idx = null;
|
|
44
|
+
|
|
45
|
+
// Since it's just a struct in RAM, this Store is synchronous
|
|
44
46
|
MemoryCookieStore.prototype.synchronous = true;
|
|
45
47
|
|
|
46
48
|
// force a default depth:
|
|
@@ -116,21 +118,21 @@ MemoryCookieStore.prototype.putCookie = function(cookie, cb) {
|
|
|
116
118
|
cb(null);
|
|
117
119
|
};
|
|
118
120
|
|
|
119
|
-
MemoryCookieStore.prototype.updateCookie = function
|
|
121
|
+
MemoryCookieStore.prototype.updateCookie = function(oldCookie, newCookie, cb) {
|
|
120
122
|
// updateCookie() may avoid updating cookies that are identical. For example,
|
|
121
123
|
// lastAccessed may not be important to some stores and an equality
|
|
122
124
|
// comparison could exclude that field.
|
|
123
125
|
this.putCookie(newCookie,cb);
|
|
124
126
|
};
|
|
125
127
|
|
|
126
|
-
MemoryCookieStore.prototype.removeCookie = function
|
|
128
|
+
MemoryCookieStore.prototype.removeCookie = function(domain, path, key, cb) {
|
|
127
129
|
if (this.idx[domain] && this.idx[domain][path] && this.idx[domain][path][key]) {
|
|
128
130
|
delete this.idx[domain][path][key];
|
|
129
131
|
}
|
|
130
132
|
cb(null);
|
|
131
133
|
};
|
|
132
134
|
|
|
133
|
-
MemoryCookieStore.prototype.removeCookies = function
|
|
135
|
+
MemoryCookieStore.prototype.removeCookies = function(domain, path, cb) {
|
|
134
136
|
if (this.idx[domain]) {
|
|
135
137
|
if (path) {
|
|
136
138
|
delete this.idx[domain][path];
|
|
@@ -140,3 +142,29 @@ MemoryCookieStore.prototype.removeCookies = function removeCookies(domain, path,
|
|
|
140
142
|
}
|
|
141
143
|
return cb(null);
|
|
142
144
|
};
|
|
145
|
+
|
|
146
|
+
MemoryCookieStore.prototype.getAllCookies = function(cb) {
|
|
147
|
+
var cookies = [];
|
|
148
|
+
var idx = this.idx;
|
|
149
|
+
|
|
150
|
+
var domains = Object.keys(idx);
|
|
151
|
+
domains.forEach(function(domain) {
|
|
152
|
+
var paths = Object.keys(idx[domain]);
|
|
153
|
+
paths.forEach(function(path) {
|
|
154
|
+
var keys = Object.keys(idx[domain][path]);
|
|
155
|
+
keys.forEach(function(key) {
|
|
156
|
+
if (key !== null) {
|
|
157
|
+
cookies.push(idx[domain][path][key]);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Sort by creationIndex so deserializing retains the creation order.
|
|
164
|
+
// When implementing your own store, this SHOULD retain the order too
|
|
165
|
+
cookies.sort(function(a,b) {
|
|
166
|
+
return (a.creationIndex||0) - (b.creationIndex||0);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
cb(null, cookies);
|
|
170
|
+
};
|
package/lib/store.js
CHANGED
|
@@ -62,6 +62,10 @@ Store.prototype.removeCookie = function(domain, path, key, cb) {
|
|
|
62
62
|
throw new Error('removeCookie is not implemented');
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
Store.prototype.removeCookies = function
|
|
65
|
+
Store.prototype.removeCookies = function(domain, path, cb) {
|
|
66
66
|
throw new Error('removeCookies is not implemented');
|
|
67
67
|
};
|
|
68
|
+
|
|
69
|
+
Store.prototype.getAllCookies = function(cb) {
|
|
70
|
+
throw new Error('getAllCookies is not implemented (therefore jar cannot be serialized)');
|
|
71
|
+
};
|