749 lines
23 KiB
JavaScript
749 lines
23 KiB
JavaScript
/*!
|
|
* Copyright (c) 2015, Salesforce.com, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of Salesforce.com nor the names of its contributors may
|
|
* be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
"use strict";
|
|
const vows = require("vows");
|
|
const assert = require("assert");
|
|
const async = require("async");
|
|
const tough = require("../lib/cookie");
|
|
const Cookie = tough.Cookie;
|
|
const CookieJar = tough.CookieJar;
|
|
|
|
const atNow = Date.now();
|
|
|
|
function at(offset) {
|
|
return { now: new Date(atNow + offset) };
|
|
}
|
|
|
|
vows
|
|
.describe("API")
|
|
.addBatch({
|
|
"All defined": function() {
|
|
assert.ok(Cookie);
|
|
assert.ok(CookieJar);
|
|
}
|
|
})
|
|
.addBatch({
|
|
Version: function() {
|
|
assert.equal(tough.version, require("../package.json").version);
|
|
}
|
|
})
|
|
.addBatch({
|
|
Constructor: {
|
|
topic: function() {
|
|
return new Cookie({
|
|
key: "test",
|
|
value: "b",
|
|
maxAge: 60
|
|
});
|
|
},
|
|
"check for key property": function(c) {
|
|
assert.ok(c);
|
|
assert.equal(c.key, "test");
|
|
},
|
|
"check for value property": function(c) {
|
|
assert.equal(c.value, "b");
|
|
},
|
|
"check for maxAge": function(c) {
|
|
assert.equal(c.maxAge, 60);
|
|
},
|
|
"check for default values for unspecified properties": function(c) {
|
|
assert.equal(c.expires, "Infinity");
|
|
assert.equal(c.secure, false);
|
|
assert.equal(c.httpOnly, false);
|
|
}
|
|
}
|
|
})
|
|
.addBatch({
|
|
"CookieJar Promises": {
|
|
topic: () => new CookieJar(),
|
|
setCookie: {
|
|
topic(jar) {
|
|
jar
|
|
.setCookie("foo=bar", "http://example.com")
|
|
.then(c => this.callback(null, c), this.callback);
|
|
},
|
|
"resolves to a Cookie"(cookie) {
|
|
assert.ok(cookie instanceof Cookie);
|
|
assert.strictEqual(cookie.key, "foo");
|
|
assert.strictEqual(cookie.value, "bar");
|
|
}
|
|
},
|
|
getCookies: {
|
|
topic(jar) {
|
|
jar
|
|
.getCookies("http://example.com")
|
|
.then(cookies => this.callback(null, cookies), this.callback);
|
|
},
|
|
"resolves to an array of cookies"(cookies) {
|
|
assert.ok(Array.isArray(cookies), "not an array");
|
|
assert.ok(cookies.length > 0, "array is empty");
|
|
for (const cookie of cookies) {
|
|
assert.ok(cookie instanceof Cookie, "not instanceof Cookie");
|
|
}
|
|
}
|
|
},
|
|
getCookieString: {
|
|
topic(jar) {
|
|
jar
|
|
.getCookieString("http://example.com")
|
|
.then(cookies => this.callback(null, cookies), this.callback);
|
|
},
|
|
"resolves to a string"(cookies) {
|
|
assert.ok(typeof cookies === "string", "not a string");
|
|
}
|
|
},
|
|
getSetCookieStrings: {
|
|
topic(jar) {
|
|
jar
|
|
.getSetCookieStrings("http://example.com")
|
|
.then(cookies => this.callback(null, cookies), this.callback);
|
|
},
|
|
"resolves to a an array of strings"(cookies) {
|
|
assert.ok(Array.isArray(cookies), "not an array");
|
|
assert.ok(cookies.length > 0, "array is empty");
|
|
for (const cookie of cookies) {
|
|
assert.ok(typeof cookie === "string", "not a string");
|
|
}
|
|
}
|
|
},
|
|
removeAllCookies: {
|
|
topic(jar) {
|
|
jar.removeAllCookies().then(this.callback, this.callback);
|
|
},
|
|
"resolves to undefined"(arg) {
|
|
assert.ok(arg === undefined, "was not undefined");
|
|
}
|
|
},
|
|
serialize: {
|
|
topic(jar) {
|
|
jar
|
|
.serialize()
|
|
.then(data => this.callback(null, data), this.callback);
|
|
},
|
|
"resolves to an object"(data) {
|
|
assert.ok(data instanceof Object, "not an object");
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.addBatch({
|
|
"expiry option": {
|
|
topic: function() {
|
|
const cb = this.callback;
|
|
const cj = new CookieJar();
|
|
cj.setCookie(
|
|
"near=expiry; Domain=example.com; Path=/; Max-Age=1",
|
|
"http://www.example.com",
|
|
at(-1),
|
|
(err, cookie) => {
|
|
cb(err, { cj: cj, cookie: cookie });
|
|
}
|
|
);
|
|
},
|
|
"set the cookie": function(t) {
|
|
assert.ok(t.cookie, "didn't set?!");
|
|
assert.equal(t.cookie.key, "near");
|
|
},
|
|
"then, retrieving": {
|
|
topic: function(t) {
|
|
const cb = this.callback;
|
|
setTimeout(() => {
|
|
t.cj.getCookies(
|
|
"http://www.example.com",
|
|
{ http: true, expire: false },
|
|
(err, cookies) => {
|
|
t.cookies = cookies;
|
|
cb(err, t);
|
|
}
|
|
);
|
|
}, 2000);
|
|
},
|
|
"got the cookie": function(t) {
|
|
assert.lengthOf(t.cookies, 1);
|
|
assert.equal(t.cookies[0].key, "near");
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.addBatch({
|
|
"allPaths option": {
|
|
topic: function() {
|
|
const cj = new CookieJar();
|
|
const apex = "http://example.com";
|
|
const www = "http://www.example.com";
|
|
const other = "http://other.example.com";
|
|
const tasks = [
|
|
["nopath_dom=qq; Path=/; Domain=example.com", apex, {}],
|
|
["path_dom=qq; Path=/foo; Domain=example.com", apex, {}],
|
|
["nopath_host=qq; Path=/", www, {}],
|
|
["path_host=qq; Path=/foo", www, {}],
|
|
["other=qq; Path=/", other, {}],
|
|
["other2=qq; Path=/foo", `${other}/foo`, {}]
|
|
].map(args => cb => cj.setCookie(...args, cb));
|
|
const cb = this.callback;
|
|
async.parallel(tasks, (err, results) => {
|
|
cb(err, { cj: cj, cookies: results });
|
|
});
|
|
},
|
|
"all set": function(t) {
|
|
assert.equal(t.cookies.length, 6);
|
|
assert.ok(
|
|
t.cookies.every(c => {
|
|
return !!c;
|
|
})
|
|
);
|
|
},
|
|
"getting without allPaths": {
|
|
topic: function(t) {
|
|
const cb = this.callback;
|
|
const cj = t.cj;
|
|
cj.getCookies("http://www.example.com/", {}, (err, cookies) => {
|
|
cb(err, { cj: cj, cookies: cookies });
|
|
});
|
|
},
|
|
"found just two cookies": function(t) {
|
|
assert.equal(t.cookies.length, 2);
|
|
},
|
|
"all are path=/": function(t) {
|
|
assert.ok(
|
|
t.cookies.every(c => {
|
|
return c.path === "/";
|
|
})
|
|
);
|
|
},
|
|
"no 'other' cookies": function(t) {
|
|
assert.ok(
|
|
!t.cookies.some(c => {
|
|
return /^other/.test(c.name);
|
|
})
|
|
);
|
|
}
|
|
},
|
|
"getting without allPaths for /foo": {
|
|
topic: function(t) {
|
|
const cb = this.callback;
|
|
const cj = t.cj;
|
|
cj.getCookies("http://www.example.com/foo", {}, (err, cookies) => {
|
|
cb(err, { cj: cj, cookies: cookies });
|
|
});
|
|
},
|
|
"found four cookies": function(t) {
|
|
assert.equal(t.cookies.length, 4);
|
|
},
|
|
"no 'other' cookies": function(t) {
|
|
assert.ok(
|
|
!t.cookies.some(c => {
|
|
return /^other/.test(c.name);
|
|
})
|
|
);
|
|
}
|
|
},
|
|
"getting with allPaths:true": {
|
|
topic: function(t) {
|
|
const cb = this.callback;
|
|
const cj = t.cj;
|
|
cj.getCookies(
|
|
"http://www.example.com/",
|
|
{ allPaths: true },
|
|
(err, cookies) => {
|
|
cb(err, { cj: cj, cookies: cookies });
|
|
}
|
|
);
|
|
},
|
|
"found four cookies": function(t) {
|
|
assert.equal(t.cookies.length, 4);
|
|
},
|
|
"no 'other' cookies": function(t) {
|
|
assert.ok(
|
|
!t.cookies.some(c => {
|
|
return /^other/.test(c.name);
|
|
})
|
|
);
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.addBatch({
|
|
"Remove cookies": {
|
|
topic: function() {
|
|
const jar = new CookieJar();
|
|
const cookie = Cookie.parse("a=b; Domain=example.com; Path=/");
|
|
const cookie2 = Cookie.parse("a=b; Domain=foo.com; Path=/");
|
|
const cookie3 = Cookie.parse("foo=bar; Domain=foo.com; Path=/");
|
|
async.parallel(
|
|
[
|
|
[cookie, "http://example.com/index.html"],
|
|
[cookie2, "http://foo.com/index.html"],
|
|
[cookie3, "http://foo.com/index.html"]
|
|
].map(args => cb => jar.setCookie(...args, cb)),
|
|
err => {
|
|
this.callback(err, jar);
|
|
}
|
|
);
|
|
},
|
|
"all from matching domain": function(jar) {
|
|
jar.store.removeCookies("example.com", null, err => {
|
|
assert(err == null);
|
|
|
|
jar.store.findCookies("example.com", null, (err, cookies) => {
|
|
assert(err == null);
|
|
assert(cookies != null);
|
|
assert(cookies.length === 0, "cookie was not removed");
|
|
});
|
|
|
|
jar.store.findCookies("foo.com", null, (err, cookies) => {
|
|
assert(err == null);
|
|
assert(cookies != null);
|
|
assert(
|
|
cookies.length === 2,
|
|
"cookies should not have been removed"
|
|
);
|
|
});
|
|
});
|
|
},
|
|
"from cookie store matching domain and key": function(jar) {
|
|
jar.store.removeCookie("foo.com", "/", "foo", err => {
|
|
assert(err == null);
|
|
|
|
jar.store.findCookies("foo.com", null, (err, cookies) => {
|
|
assert(err == null);
|
|
assert(cookies != null);
|
|
assert(cookies.length === 1, "cookie was not removed correctly");
|
|
assert(cookies[0].key === "a", "wrong cookie was removed");
|
|
});
|
|
});
|
|
}
|
|
}
|
|
})
|
|
.addBatch({
|
|
"Synchronous CookieJar": {
|
|
setCookieSync: {
|
|
topic: function() {
|
|
const jar = new CookieJar();
|
|
let cookie = Cookie.parse("a=b; Domain=example.com; Path=/");
|
|
cookie = jar.setCookieSync(cookie, "http://example.com/index.html");
|
|
return cookie;
|
|
},
|
|
"returns a copy of the cookie": function(cookie) {
|
|
assert.instanceOf(cookie, Cookie);
|
|
}
|
|
},
|
|
|
|
getCookiesSync: {
|
|
topic: function() {
|
|
const jar = new CookieJar();
|
|
const url = "http://example.com/index.html";
|
|
jar.setCookieSync("a=b; Domain=example.com; Path=/", url);
|
|
jar.setCookieSync("c=d; Domain=example.com; Path=/", url);
|
|
return jar.getCookiesSync(url);
|
|
},
|
|
"returns the cookie array": function(err, cookies) {
|
|
assert.ok(!err);
|
|
assert.ok(Array.isArray(cookies));
|
|
assert.lengthOf(cookies, 2);
|
|
cookies.forEach(cookie => {
|
|
assert.instanceOf(cookie, Cookie);
|
|
});
|
|
}
|
|
},
|
|
|
|
getCookieStringSync: {
|
|
topic: function() {
|
|
const jar = new CookieJar();
|
|
const url = "http://example.com/index.html";
|
|
jar.setCookieSync("a=b; Domain=example.com; Path=/", url);
|
|
jar.setCookieSync("c=d; Domain=example.com; Path=/", url);
|
|
return jar.getCookieStringSync(url);
|
|
},
|
|
"returns the cookie header string": function(err, str) {
|
|
assert.ok(!err);
|
|
assert.typeOf(str, "string");
|
|
}
|
|
},
|
|
|
|
getSetCookieStringsSync: {
|
|
topic: function() {
|
|
const jar = new CookieJar();
|
|
const url = "http://example.com/index.html";
|
|
jar.setCookieSync("a=b; Domain=example.com; Path=/", url);
|
|
jar.setCookieSync("c=d; Domain=example.com; Path=/", url);
|
|
return jar.getSetCookieStringsSync(url);
|
|
},
|
|
"returns the cookie header string": function(err, headers) {
|
|
assert.ok(!err);
|
|
assert.ok(Array.isArray(headers));
|
|
assert.lengthOf(headers, 2);
|
|
headers.forEach(header => {
|
|
assert.typeOf(header, "string");
|
|
});
|
|
}
|
|
},
|
|
|
|
removeAllCookiesSync: {
|
|
topic: function() {
|
|
const jar = new CookieJar();
|
|
const cookie1 = Cookie.parse("a=b; Domain=example.com; Path=/");
|
|
const cookie2 = Cookie.parse("a=b; Domain=foo.com; Path=/");
|
|
const cookie3 = Cookie.parse("foo=bar; Domain=foo.com; Path=/");
|
|
jar.setCookieSync(cookie1, "http://example.com/index.html");
|
|
jar.setCookieSync(cookie2, "http://foo.com/index.html");
|
|
jar.setCookieSync(cookie3, "http://foo.com/index.html");
|
|
|
|
jar.removeAllCookiesSync();
|
|
|
|
jar.store.getAllCookies(this.callback);
|
|
},
|
|
"no cookies in the jar": function(err, cookies) {
|
|
assert(err == null);
|
|
assert(cookies != null);
|
|
assert(cookies.length === 0, "cookies were not removed");
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.addBatch({
|
|
"Synchronous API on async CookieJar": {
|
|
topic: function() {
|
|
return new tough.Store();
|
|
},
|
|
setCookieSync: {
|
|
topic: function(store) {
|
|
const jar = new CookieJar(store);
|
|
try {
|
|
jar.setCookieSync("a=b", "http://example.com/index.html");
|
|
return false;
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
},
|
|
fails: function(err) {
|
|
assert.instanceOf(err, Error);
|
|
assert.equal(
|
|
err.message,
|
|
"CookieJar store is not synchronous; use async API instead."
|
|
);
|
|
}
|
|
},
|
|
getCookiesSync: {
|
|
topic: function(store) {
|
|
const jar = new CookieJar(store);
|
|
try {
|
|
jar.getCookiesSync("http://example.com/index.html");
|
|
return false;
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
},
|
|
fails: function(err) {
|
|
assert.instanceOf(err, Error);
|
|
assert.equal(
|
|
err.message,
|
|
"CookieJar store is not synchronous; use async API instead."
|
|
);
|
|
}
|
|
},
|
|
getCookieStringSync: {
|
|
topic: function(store) {
|
|
const jar = new CookieJar(store);
|
|
try {
|
|
jar.getCookieStringSync("http://example.com/index.html");
|
|
return false;
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
},
|
|
fails: function(err) {
|
|
assert.instanceOf(err, Error);
|
|
assert.equal(
|
|
err.message,
|
|
"CookieJar store is not synchronous; use async API instead."
|
|
);
|
|
}
|
|
},
|
|
getSetCookieStringsSync: {
|
|
topic: function(store) {
|
|
const jar = new CookieJar(store);
|
|
try {
|
|
jar.getSetCookieStringsSync("http://example.com/index.html");
|
|
return false;
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
},
|
|
fails: function(err) {
|
|
assert.instanceOf(err, Error);
|
|
assert.equal(
|
|
err.message,
|
|
"CookieJar store is not synchronous; use async API instead."
|
|
);
|
|
}
|
|
},
|
|
removeAllCookies: {
|
|
topic: function(store) {
|
|
const jar = new CookieJar(store);
|
|
try {
|
|
jar.removeAllCookiesSync();
|
|
return false;
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
},
|
|
fails: function(err) {
|
|
assert.instanceOf(err, Error);
|
|
assert.equal(
|
|
err.message,
|
|
"CookieJar store is not synchronous; use async API instead."
|
|
);
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.addBatch({
|
|
"loose option": {
|
|
"cookie jar with loose": {
|
|
topic: function() {
|
|
const jar = new CookieJar();
|
|
const url = "http://example.com/index.html";
|
|
return jar.setCookieSync("=b", url, { loose: true });
|
|
},
|
|
succeeds: function(err, c) {
|
|
assert.equal(err, null);
|
|
assert(c);
|
|
assert.equal(c.value, "b");
|
|
}
|
|
},
|
|
"cookie jar without loose": {
|
|
topic: function() {
|
|
const jar = new CookieJar();
|
|
const url = "http://example.com/index.html";
|
|
return jar.setCookieSync("=b", url);
|
|
},
|
|
fails: function(err, c) {
|
|
assert.instanceOf(err, Error);
|
|
assert.equal(err.message, "Cookie failed to parse");
|
|
}
|
|
},
|
|
"map doesn't default to loose": {
|
|
topic: function() {
|
|
const some = [
|
|
"=a;domain=example.com", // index 0, falsey
|
|
"=b;domain=example.com", // index 1, truthy
|
|
"c=d;domain=example.com" // index 2, truthy
|
|
];
|
|
return some.map(Cookie.parse);
|
|
},
|
|
parses: function(err, val) {
|
|
assert.equal(err, null);
|
|
assert.isArray(val);
|
|
assert.lengthOf(val, 3);
|
|
},
|
|
"doesn't parse first cookie loose": function(val) {
|
|
assert.isUndefined(val[0]);
|
|
},
|
|
"doesn't parse second cookie loose": function(val) {
|
|
assert.isUndefined(val[1]);
|
|
},
|
|
"parses third cookie normally": function(val) {
|
|
assert.instanceOf(val[2], Cookie);
|
|
assert.equal(val[2].key, "c");
|
|
assert.equal(val[2].value, "d");
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.addBatch(allowSpecialUseOptionVows())
|
|
.export(module);
|
|
|
|
function allowSpecialUseOptionVows() {
|
|
const specialUseDomains = [
|
|
"local",
|
|
"example",
|
|
"invalid",
|
|
"localhost",
|
|
"test"
|
|
];
|
|
|
|
const specialTreatmentDomains = ["localhost", "invalid"];
|
|
|
|
return specialUseDomains.reduce((vows, specialUseDomain) => {
|
|
if (specialTreatmentDomains.includes(specialUseDomain)) {
|
|
vows[
|
|
`cookie jar with allowSpecialUseDomain set to the default value and domain is "${specialUseDomain}"`
|
|
] = {
|
|
topic: function() {
|
|
const cb = this.callback;
|
|
const cj = new CookieJar();
|
|
cj.setCookie(
|
|
`settingThisShouldPass=true; Domain=${specialUseDomain}; Path=/;`,
|
|
`http://${specialUseDomain}`,
|
|
at(-1),
|
|
(err, cookie) => {
|
|
cb(err, { cj: cj, cookie: cookie });
|
|
}
|
|
);
|
|
},
|
|
"set the cookie": function(t) {
|
|
assert.ok(t.cookie, "didn't set?!");
|
|
assert.equal(t.cookie.key, "settingThisShouldPass");
|
|
},
|
|
"then, retrieving": {
|
|
topic: function(t) {
|
|
const cb = this.callback;
|
|
setTimeout(() => {
|
|
t.cj.getCookies(
|
|
`http://${specialUseDomain}`,
|
|
{ http: true },
|
|
(err, cookies) => {
|
|
t.cookies = cookies;
|
|
cb(err, t);
|
|
}
|
|
);
|
|
}, 2000);
|
|
},
|
|
"got the cookie": function(t) {
|
|
assert.lengthOf(t.cookies, 1);
|
|
assert.equal(t.cookies[0].key, "settingThisShouldPass");
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
vows[
|
|
`cookie jar with allowSpecialUseDomain set to the default value and domain is "dev.${specialUseDomain}"`
|
|
] = {
|
|
topic: function() {
|
|
const cb = this.callback;
|
|
const cj = new CookieJar();
|
|
cj.setCookie(
|
|
`settingThisShouldPass=true; Domain=dev.${specialUseDomain}; Path=/;`,
|
|
`http://dev.${specialUseDomain}`,
|
|
at(-1),
|
|
(err, cookie) => {
|
|
cb(err, { cj: cj, cookie: cookie });
|
|
}
|
|
);
|
|
},
|
|
"set the cookie": function(t) {
|
|
assert.ok(t.cookie, "didn't set?!");
|
|
assert.equal(t.cookie.key, "settingThisShouldPass");
|
|
},
|
|
"then, retrieving": {
|
|
topic: function(t) {
|
|
const cb = this.callback;
|
|
setTimeout(() => {
|
|
t.cj.getCookies(
|
|
`http://dev.${specialUseDomain}`,
|
|
{ http: true },
|
|
(err, cookies) => {
|
|
t.cookies = cookies;
|
|
cb(err, t);
|
|
}
|
|
);
|
|
}, 2000);
|
|
},
|
|
"got the cookie": function(t) {
|
|
assert.lengthOf(t.cookies, 1);
|
|
assert.equal(t.cookies[0].key, "settingThisShouldPass");
|
|
}
|
|
}
|
|
};
|
|
|
|
vows[
|
|
`cookie jar with allowSpecialUseDomain enabled and domain is "dev.${specialUseDomain}"`
|
|
] = {
|
|
topic: function() {
|
|
const cb = this.callback;
|
|
const cj = new CookieJar(new tough.MemoryCookieStore(), {
|
|
rejectPublicSuffixes: true,
|
|
allowSpecialUseDomain: true
|
|
});
|
|
cj.setCookie(
|
|
`settingThisShouldPass=true; Domain=dev.${specialUseDomain}; Path=/;`,
|
|
`http://dev.${specialUseDomain}`,
|
|
at(-1),
|
|
(err, cookie) => {
|
|
cb(err, { cj: cj, cookie: cookie });
|
|
}
|
|
);
|
|
},
|
|
"set the cookie": function(t) {
|
|
assert.ok(t.cookie, "didn't set?!");
|
|
assert.equal(t.cookie.key, "settingThisShouldPass");
|
|
},
|
|
"then, retrieving": {
|
|
topic: function(t) {
|
|
const cb = this.callback;
|
|
setTimeout(() => {
|
|
t.cj.getCookies(
|
|
`http://dev.${specialUseDomain}`,
|
|
{ http: true },
|
|
(err, cookies) => {
|
|
t.cookies = cookies;
|
|
cb(err, t);
|
|
}
|
|
);
|
|
}, 2000);
|
|
},
|
|
"got the cookie": function(t) {
|
|
assert.lengthOf(t.cookies, 1);
|
|
assert.equal(t.cookies[0].key, "settingThisShouldPass");
|
|
}
|
|
}
|
|
};
|
|
|
|
vows[
|
|
`cookie jar with allowSpecialUseDomain disabled and domain is "dev.${specialUseDomain}"`
|
|
] = {
|
|
topic: function() {
|
|
const cj = new CookieJar(new tough.MemoryCookieStore(), {
|
|
allowSpecialUseDomain: false,
|
|
rejectPublicSuffixes: true
|
|
});
|
|
cj.setCookie(
|
|
`settingThisShouldFail=true; Domain=dev.${specialUseDomain}; Path=/;`,
|
|
`http://dev.${specialUseDomain}`,
|
|
this.callback
|
|
);
|
|
},
|
|
errors: function(err, cookie) {
|
|
assert.ok(err);
|
|
assert.ok(!cookie);
|
|
assert.equal(
|
|
err.message,
|
|
`Cookie has domain set to the public suffix "${specialUseDomain}" which is a special use domain. To allow this, configure your CookieJar with {allowSpecialUseDomain:true, rejectPublicSuffixes: false}.`
|
|
);
|
|
}
|
|
};
|
|
|
|
return vows;
|
|
}, {});
|
|
}
|