2020-01-02 15:13:47 -05:00
|
|
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
2020-09-27 06:22:32 -04:00
|
|
|
import { Response, ServerRequest } from "./server.ts";
|
|
|
|
import { deleteCookie, getCookies, setCookie } from "./cookie.ts";
|
2020-11-17 15:06:06 -05:00
|
|
|
import { assert, assertEquals, assertThrows } from "../testing/asserts.ts";
|
2019-04-24 07:38:52 -04:00
|
|
|
|
2020-06-12 15:23:38 -04:00
|
|
|
Deno.test({
|
2020-02-26 10:48:35 -05:00
|
|
|
name: "Cookie parser",
|
2019-04-24 07:38:52 -04:00
|
|
|
fn(): void {
|
2019-10-05 12:02:34 -04:00
|
|
|
const req = new ServerRequest();
|
2019-04-24 07:38:52 -04:00
|
|
|
req.headers = new Headers();
|
2019-04-27 19:07:11 -04:00
|
|
|
assertEquals(getCookies(req), {});
|
2019-04-24 07:38:52 -04:00
|
|
|
req.headers = new Headers();
|
|
|
|
req.headers.set("Cookie", "foo=bar");
|
2019-04-27 19:07:11 -04:00
|
|
|
assertEquals(getCookies(req), { foo: "bar" });
|
2019-04-24 07:38:52 -04:00
|
|
|
|
|
|
|
req.headers = new Headers();
|
|
|
|
req.headers.set("Cookie", "full=of ; tasty=chocolate");
|
2019-04-27 19:07:11 -04:00
|
|
|
assertEquals(getCookies(req), { full: "of ", tasty: "chocolate" });
|
2019-04-24 07:38:52 -04:00
|
|
|
|
|
|
|
req.headers = new Headers();
|
|
|
|
req.headers.set("Cookie", "igot=99; problems=but...");
|
2019-04-27 19:07:11 -04:00
|
|
|
assertEquals(getCookies(req), { igot: "99", problems: "but..." });
|
2019-04-29 10:49:50 -04:00
|
|
|
|
|
|
|
req.headers = new Headers();
|
|
|
|
req.headers.set("Cookie", "PREF=al=en-GB&f1=123; wide=1; SID=123");
|
|
|
|
assertEquals(getCookies(req), {
|
|
|
|
PREF: "al=en-GB&f1=123",
|
|
|
|
wide: "1",
|
2020-03-28 13:03:49 -04:00
|
|
|
SID: "123",
|
2019-04-29 10:49:50 -04:00
|
|
|
});
|
2020-03-28 13:03:49 -04:00
|
|
|
},
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
|
2020-11-17 15:06:06 -05:00
|
|
|
Deno.test({
|
|
|
|
name: "Cookie Name Validation",
|
|
|
|
fn(): void {
|
|
|
|
const res: Response = {};
|
|
|
|
const tokens = [
|
|
|
|
'"id"',
|
|
|
|
"id\t",
|
|
|
|
"i\td",
|
|
|
|
"i d",
|
|
|
|
"i;d",
|
|
|
|
"{id}",
|
|
|
|
"[id]",
|
|
|
|
'"',
|
|
|
|
"id\u0091",
|
|
|
|
];
|
|
|
|
res.headers = new Headers();
|
|
|
|
tokens.forEach((name) => {
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
setCookie(res, {
|
|
|
|
name,
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
maxAge: 3,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
'Invalid cookie name: "' + name + '".',
|
|
|
|
);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2020-11-22 09:34:31 -05:00
|
|
|
Deno.test({
|
|
|
|
name: "Cookie Path Validation",
|
|
|
|
fn(): void {
|
|
|
|
const res: Response = {};
|
|
|
|
const path = "/;domain=sub.domain.com";
|
|
|
|
res.headers = new Headers();
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
path,
|
|
|
|
maxAge: 3,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
path + ": Invalid cookie path char ';'",
|
|
|
|
);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2020-06-12 15:23:38 -04:00
|
|
|
Deno.test({
|
2020-02-26 10:48:35 -05:00
|
|
|
name: "Cookie Delete",
|
2019-04-27 19:07:11 -04:00
|
|
|
fn(): void {
|
2019-10-05 12:02:34 -04:00
|
|
|
const res: Response = {};
|
2020-06-07 07:53:36 -04:00
|
|
|
deleteCookie(res, "deno");
|
2019-04-27 19:07:11 -04:00
|
|
|
assertEquals(
|
2020-02-07 02:23:38 -05:00
|
|
|
res.headers?.get("Set-Cookie"),
|
2020-07-14 15:24:17 -04:00
|
|
|
"deno=; Expires=Thu, 01 Jan 1970 00:00:00 GMT",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
2020-03-28 13:03:49 -04:00
|
|
|
},
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
|
2020-06-12 15:23:38 -04:00
|
|
|
Deno.test({
|
2020-02-26 10:48:35 -05:00
|
|
|
name: "Cookie Set",
|
2019-04-27 19:07:11 -04:00
|
|
|
fn(): void {
|
2019-10-05 12:02:34 -04:00
|
|
|
const res: Response = {};
|
2019-04-27 19:07:11 -04:00
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, { name: "Space", value: "Cat" });
|
|
|
|
assertEquals(res.headers.get("Set-Cookie"), "Space=Cat");
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, { name: "Space", value: "Cat", secure: true });
|
|
|
|
assertEquals(res.headers.get("Set-Cookie"), "Space=Cat; Secure");
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, { name: "Space", value: "Cat", httpOnly: true });
|
|
|
|
assertEquals(res.headers.get("Set-Cookie"), "Space=Cat; HttpOnly");
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
2020-03-28 13:03:49 -04:00
|
|
|
secure: true,
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(res.headers.get("Set-Cookie"), "Space=Cat; Secure; HttpOnly");
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
2020-03-28 13:03:49 -04:00
|
|
|
maxAge: 2,
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2020-07-14 15:24:17 -04:00
|
|
|
"Space=Cat; Secure; HttpOnly; Max-Age=2",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
let error = false;
|
|
|
|
res.headers = new Headers();
|
|
|
|
try {
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
2020-03-28 13:03:49 -04:00
|
|
|
maxAge: 0,
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
assert(error);
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
maxAge: 2,
|
2020-03-28 13:03:49 -04:00
|
|
|
domain: "deno.land",
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2020-07-14 15:24:17 -04:00
|
|
|
"Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
maxAge: 2,
|
|
|
|
domain: "deno.land",
|
2020-03-28 13:03:49 -04:00
|
|
|
sameSite: "Strict",
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2019-06-19 00:22:01 -04:00
|
|
|
"Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; " +
|
2020-07-14 15:24:17 -04:00
|
|
|
"SameSite=Strict",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
maxAge: 2,
|
|
|
|
domain: "deno.land",
|
2020-03-28 13:03:49 -04:00
|
|
|
sameSite: "Lax",
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2020-07-14 15:24:17 -04:00
|
|
|
"Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; SameSite=Lax",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
maxAge: 2,
|
|
|
|
domain: "deno.land",
|
2020-03-28 13:03:49 -04:00
|
|
|
path: "/",
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2020-07-14 15:24:17 -04:00
|
|
|
"Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; Path=/",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
maxAge: 2,
|
|
|
|
domain: "deno.land",
|
|
|
|
path: "/",
|
2020-03-28 13:03:49 -04:00
|
|
|
unparsed: ["unparsed=keyvalue", "batman=Bruce"],
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2019-06-19 00:22:01 -04:00
|
|
|
"Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; Path=/; " +
|
2020-07-14 15:24:17 -04:00
|
|
|
"unparsed=keyvalue; batman=Bruce",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "Space",
|
|
|
|
value: "Cat",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
maxAge: 2,
|
|
|
|
domain: "deno.land",
|
|
|
|
path: "/",
|
2020-03-28 13:03:49 -04:00
|
|
|
expires: new Date(Date.UTC(1983, 0, 7, 15, 32)),
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2019-06-19 00:22:01 -04:00
|
|
|
"Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; Path=/; " +
|
2020-07-14 15:24:17 -04:00
|
|
|
"Expires=Fri, 07 Jan 1983 15:32:00 GMT",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, { name: "__Secure-Kitty", value: "Meow" });
|
|
|
|
assertEquals(res.headers.get("Set-Cookie"), "__Secure-Kitty=Meow; Secure");
|
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, {
|
|
|
|
name: "__Host-Kitty",
|
|
|
|
value: "Meow",
|
2020-03-28 13:03:49 -04:00
|
|
|
domain: "deno.land",
|
2019-04-27 19:07:11 -04:00
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2020-07-14 15:24:17 -04:00
|
|
|
"__Host-Kitty=Meow; Secure; Path=/",
|
2019-04-27 19:07:11 -04:00
|
|
|
);
|
2020-04-01 09:37:11 -04:00
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, { name: "cookie-1", value: "value-1", secure: true });
|
|
|
|
setCookie(res, { name: "cookie-2", value: "value-2", maxAge: 3600 });
|
|
|
|
assertEquals(
|
|
|
|
res.headers.get("Set-Cookie"),
|
2020-07-14 15:24:17 -04:00
|
|
|
"cookie-1=value-1; Secure, cookie-2=value-2; Max-Age=3600",
|
2020-04-01 09:37:11 -04:00
|
|
|
);
|
2020-04-10 10:12:42 -04:00
|
|
|
|
|
|
|
res.headers = new Headers();
|
|
|
|
setCookie(res, { name: "", value: "" });
|
|
|
|
assertEquals(res.headers.get("Set-Cookie"), null);
|
2020-03-28 13:03:49 -04:00
|
|
|
},
|
2019-04-24 07:38:52 -04:00
|
|
|
});
|