75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
import { Request } from "express";
|
|
import { describe, expect, it } from "vitest";
|
|
import {
|
|
CSRF_CLIENT_COOKIE_NAME,
|
|
getCsrfClientCookieValue,
|
|
getCsrfValidationClientIds,
|
|
getLegacyClientId,
|
|
parseCookies,
|
|
} from "./csrfClient";
|
|
|
|
const makeRequest = (overrides?: Partial<Request>): Request =>
|
|
({
|
|
headers: {
|
|
cookie: "",
|
|
"user-agent": "UnitTestAgent/1.0",
|
|
},
|
|
ip: "203.0.113.10",
|
|
connection: { remoteAddress: "198.51.100.8" },
|
|
...overrides,
|
|
}) as unknown as Request;
|
|
|
|
describe("csrfClient helpers", () => {
|
|
it("parses cookies and tolerates bad encoding", () => {
|
|
const parsed = parseCookies("a=1; b=hello%20world; c=%E0%A4%A");
|
|
expect(parsed).toEqual({
|
|
a: "1",
|
|
b: "hello world",
|
|
c: "%E0%A4%A",
|
|
});
|
|
});
|
|
|
|
it("reads only valid csrf cookie values", () => {
|
|
const validReq = makeRequest({
|
|
headers: {
|
|
cookie: `${CSRF_CLIENT_COOKIE_NAME}=abcDEF1234567890_-`,
|
|
},
|
|
});
|
|
expect(getCsrfClientCookieValue(validReq)).toBe("abcDEF1234567890_-");
|
|
|
|
const invalidReq = makeRequest({
|
|
headers: {
|
|
cookie: `${CSRF_CLIENT_COOKIE_NAME}=bad!`,
|
|
},
|
|
});
|
|
expect(getCsrfClientCookieValue(invalidReq)).toBeNull();
|
|
});
|
|
|
|
it("builds legacy client id from IP + user agent and truncates", () => {
|
|
const longAgent = "x".repeat(600);
|
|
const req = makeRequest({
|
|
headers: {
|
|
"user-agent": longAgent,
|
|
},
|
|
});
|
|
const id = getLegacyClientId(req);
|
|
expect(id.startsWith("203.0.113.10:")).toBe(true);
|
|
expect(id.length).toBeLessThanOrEqual(256);
|
|
});
|
|
|
|
it("returns validation candidates with cookie id first when present", () => {
|
|
const req = makeRequest({
|
|
headers: {
|
|
cookie: `${CSRF_CLIENT_COOKIE_NAME}=cookieToken123456`,
|
|
"user-agent": "Agent",
|
|
},
|
|
ip: "10.0.0.1",
|
|
});
|
|
|
|
const candidates = getCsrfValidationClientIds(req);
|
|
expect(candidates[0]).toBe("cookie:cookieToken123456");
|
|
expect(candidates[1]).toContain("10.0.0.1:Agent");
|
|
expect(new Set(candidates).size).toBe(candidates.length);
|
|
});
|
|
});
|